---
title: "模型回退"
description: "请求的模型没有 provider 可用时，pirouter 按请求或工作区里写的备用模型依次改用下一个模型，只为最终返回响应的那一次尝试计费。"
canonical: "https://pirouter.ai/zh/docs/guides/fallbacks"
last-updated: "2026-10-17"
lang: "zh"
source: "content/docs/zh/guides/fallbacks.mdx"
---

# 模型回退

请求的模型没有 provider 可用时，pirouter 按请求或工作区里写的备用模型依次改用下一个模型，只为最终返回响应的那一次尝试计费。

[Provider 路由](https://pirouter.ai/zh/docs/guides/routing.md)在一个模型内换 provider；模型回退在这个模型的所有 provider 都用不了时，改用你指定的下一个模型。备用模型写在请求的 `models` 数组里，或者在控制台给工作区设好。

## 在请求里写备用模型

在请求体里加一个 `models` 数组。pirouter 先试 `model`，不行再按数组顺序试。

```bash
curl https://api.pirouter.ai/v1/chat/completions \
  -H "Authorization: Bearer $PIROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-opus-5.5",
    "models": ["openai/gpt-6.1-sol", "google/gemini-4-argon"],
    "messages": [{ "role": "user", "content": "Hello!" }]
  }'
```

- `models` 最多 3 个，超过返回 `422`。
- 和 `model` 相同的、重复的条目会被去掉。
- 不写 `model` 时，`models` 的第一个就是主模型。
- 三种协议的请求都可以带 `models`。Gemini 协议的主模型在路径里，`models` 只是备用。

所有备用模型在请求一开始就会被核对。其中任何一个不存在，整个请求返回 `404 model_not_found`，`message` 指出是哪一个，此时还没有转发任何请求。备用模型已经下线时同样返回 `404 model_not_found`，`message` 写明它的下线日期。

`route` 字段可以不写：它只接受 `"fallback"`，写与不写效果相同。

## 在工作区里设备用模型

在控制台 **路由** 页的 **备用模型** 里添加，最多 3 个，只能选对话类的文本模型。只有工作区所有者能改。

工作区的备用模型只在请求自己没有写 `models` 时生效。请求写了 `models`，就只用请求里的，不会再追加工作区的。

工作区列表里已经下线的模型会被跳过，不报错。

![路由页的备用模型：依次为 Claude Sonnet 5.5、GPT-5.5、Gemini 3.5 Flash，最多 3 个](/docs/shots/fallbacks-models.zh.webp)

## 什么时候会切换

两种情况会换到下一个模型：

1. 当前模型没有可用的 provider：被[路由设置](https://pirouter.ai/zh/docs/guides/routing.md#没有可用的-provider-时)排空了，或者都处于不可用状态（例如部署已停用，或已过下线日期）。
2. 当前模型的 provider 在返回第一个字节之前失败，而且故障切换已经试完这个模型的所有 provider。哪些失败会触发故障切换，见 [Provider 路由](https://pirouter.ai/zh/docs/guides/routing.md#故障切换)。

pirouter 只在响应开始之前切换模型。响应一旦开始，不管后面出什么错，都不会再换模型。

下面几种情况不会换模型，整个请求直接结束：

- 模型不在你调用的端点上服务，返回 `422 validation_failed`。
- 输入超过模型的上下文上限，返回 `400 context_length_exceeded`。
- 请求被 pirouter 限流，返回 `429 rate_limited`。切换途中被限流也一样，整个请求返回 `429`，带 `Retry-After` 响应头。

一个请求在所有模型上合计最多尝试 5 次。

`provider` 里的 `"allow_fallbacks": false` 只限制 provider，不限制 `models`：换到下一个模型时，会重新在那个模型的 provider 里选。

## 计费

只为最终返回响应的那一次尝试付费，按它自己的模型和 provider 的价格算。中途失败、由下一次尝试接替的那次不计费。

在控制台 **日志** 里按 `X-Pi-Trace-Id` 搜索，能看到这个请求的每一次尝试：被接替的尝试记为失败，花费 $0.00；返回响应的那次才计费。见[请求日志](https://pirouter.ai/zh/docs/guides/logs.md#用-trace-id-找到一次请求)。

![按一个 trace ID 搜索日志：先是 openai/gpt-6-sol 失败、花费 $0.00，随后 openai/gpt-5.5 成功](/docs/shots/fallbacks-trace.zh.webp)

## 怎么知道用了哪个模型

响应体的 `model` 是实际返回响应的那个模型的 ID。它和你请求里写的 `model` 不同，就说明发生了回退。`X-Pi-Model` 响应头是同一个值，`X-Pi-Provider` 是处理它的 provider。等 provider 超过 90 秒的请求没有这两个响应头，看响应体或流式事件里的 `model`；此后也不会再回退。见[长请求](https://pirouter.ai/zh/docs/guides/timeouts.md#长请求)。

## 目前没有的能力

- **预设（preset）。** 请求里带 `preset` 会返回 `422`。
- **专门标明发生过回退的字段。** 比较响应的 `model` 和请求的 `model` 来判断。

## 下一步

- [Provider 路由](https://pirouter.ai/zh/docs/guides/routing.md): 在同一个模型的多个 provider 之间怎么选。
- [模型与协议](https://pirouter.ai/zh/docs/models.md): 模型 ID 怎么写，每个模型接受哪些协议。
