修复 AI 网关流式断流:错误透传、自动降级,max_tokens 可缺省
This commit is contained in:
@@ -216,6 +216,16 @@ AI 网关使用面板创建的独立密钥鉴权,支持 `Authorization: Bearer
|
||||
- Chat Completions 只承担协议转换与兼容修复;新能力优先在 Responses 和 Messages 提供
|
||||
- 单次请求最多尝试三个渠道;可重试错误会切换渠道,流式响应建立后不会换渠道重试
|
||||
|
||||
### 已知上游限制:大 system 区流式断流
|
||||
|
||||
实测(2026-07-13)OCI 兼容面对 `instructions` 与 `tools` 合计超约 64.5KB 的**流式**请求会在发出少量事件后静默断开连接(无任何错误事件;同请求非流式正常),与模型、字符集、消息正文大小均无关——消息正文(`input`)不计入该限制。Chat Completions 与 Messages 的 system/developer 提示会转换为 `instructions`,因此 Claude Code 等自带大体量系统提示与工具定义的客户端极易触发。
|
||||
|
||||
网关侧应对:
|
||||
|
||||
- Messages 与 Chat Completions 的流式请求在客户端尚未收到任何输出时遭遇上游断流,会自动降级为非流式重做,并按标准事件/chunk 序列一次推送;调用日志记 `retries=1` 与降级标记
|
||||
- Responses 直通因初始事件已转发、协议上无法透明降级,调用日志记「上游流提前终止」,客户端需自行回退非流式
|
||||
- 应急规避:将超长 system 内容移入首条 user 消息正文可绕过该限制(正文不计入),但语义有别,根治有待上游修复
|
||||
|
||||
这里提供的是兼容接口而非 OpenAI / Anthropic 协议的完整实现。OCI OpenAI 兼容面的部分行为来自实测,未见 Oracle 文档承诺,可能随上游调整。路由与鉴权定义以 [Swagger YAML](docs/swagger.yaml) 或运行时 Swagger UI 为准;无法由 OpenAPI 完整表达的兼容边界列于上方。
|
||||
|
||||
### 字段兼容矩阵
|
||||
@@ -289,7 +299,7 @@ Chat Completions 会先转换为 Responses 请求,再把 OCI Responses 响应
|
||||
| `max_completion_tokens` | 🔄 | 转为 `max_output_tokens`,优先于 `max_tokens` |
|
||||
| `max_tokens` | 🔄 | 未提供 `max_completion_tokens` 时转为 `max_output_tokens` |
|
||||
| `temperature`、`top_p`、`parallel_tool_calls` | ◐ | 原值写入 Responses 请求,但不校验范围或模型能力 |
|
||||
| `stream` | 🔄 | OCI Responses SSE 桥接为 `chat.completion.chunk`,末尾补 `data: [DONE]` |
|
||||
| `stream` | 🔄 | OCI Responses SSE 桥接为 `chat.completion.chunk`,末尾补 `data: [DONE]`;上游断流且尚无输出时自动降级非流式重做,结果按 chunk 序列一次推送 |
|
||||
| `stream_options.include_usage` | 🔄 | 控制网关在终块后追加 `choices: []` 的 usage 块 |
|
||||
| `stream_options.include_obfuscation` | ⚠️ | 未建模,静默忽略 |
|
||||
| `tools[].type=function` | ◐ | `name`、`description`、`parameters` 支持;`function.strict` 被忽略 |
|
||||
@@ -346,13 +356,13 @@ Chat Completions 会先转换为 Responses 请求,再把 OCI Responses 响应
|
||||
| 标准字段 | 状态 | 网关行为 |
|
||||
| --- | :---: | --- |
|
||||
| `model` | ◐ | 用于模型与渠道选择,但空字符串不会在 handler 中按参数错误拒绝,通常最终返回模型不存在 |
|
||||
| `max_tokens` | 🔄 | 必填且必须大于 0,转换为 `max_output_tokens` |
|
||||
| `max_tokens` | 🔄 | 可缺省(缺省或 ≤0 时按默认值 8192),转换为 `max_output_tokens` |
|
||||
| `messages` | ◐ | 必须非空;角色、交替顺序和空内容不做完整校验 |
|
||||
| `system` | ◐ | 支持字符串或 text 块数组;多个文本块直接拼接,`cache_control` 等附加字段被忽略 |
|
||||
| `temperature`、`top_p` | ◐ | 写入 Responses 请求,不做取值范围或模型能力校验 |
|
||||
| `top_k` | ⚠️ | 能解析但不会传给上游 |
|
||||
| `stop_sequences` | ⚠️ | 能解析但不会传给上游;响应 `stop_sequence` 恒为 `null` |
|
||||
| `stream` | 🔄 | Responses SSE 桥接为 Anthropic 事件序列 |
|
||||
| `stream` | 🔄 | Responses SSE 桥接为 Anthropic 事件序列;上游断流且尚无输出时自动降级非流式重做,结果按事件序列一次推送 |
|
||||
| `tools` | ◐ | 每个工具都转换成 Responses `function`;自定义客户端工具可用,Anthropic 服务端工具类型不保留原语义 |
|
||||
| `tool_choice` | ◐ | 支持 `auto`、`any`、`none`、具名 `tool`;`disable_parallel_tool_use` 等附加字段被忽略 |
|
||||
| `metadata` | ⚠️ | 能解析但不会传给上游 |
|
||||
@@ -380,7 +390,7 @@ Chat Completions 会先转换为 Responses 请求,再把 OCI Responses 响应
|
||||
- `stop_reason` 只生成 `end_turn`、`tool_use`、`max_tokens`;`stop_sequence` 恒为 `null`
|
||||
- reasoning 不会生成 Anthropic `thinking` / `redacted_thinking` 块,也没有 signature
|
||||
- usage 只保留 `input_tokens`、`output_tokens` 和 `cache_read_input_tokens`,不提供 `cache_creation_input_tokens`
|
||||
- 流式输出标准事件骨架,但不生成 `thinking_delta`、`signature_delta` 或上游失败对应的 Anthropic `error` 事件
|
||||
- 流式输出标准事件骨架,但不生成 `thinking_delta` 和 `signature_delta`;上游错误事件与无终态断流会转成 Anthropic `error` 事件
|
||||
|
||||
实现依据:[`anthresponses.go`](internal/service/anthresponses.go) · [`anthropic.go`](internal/aiwire/anthropic.go) · [`aigateway.go`](internal/api/aigateway.go)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user