Files
oci-portal/docs/AI网关.md
T

529 lines
23 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI 网关
> [!NOTE]
> OCI Portal AI 网关将多个 OCI GenAI 渠道统一为 OpenAI、Anthropic 与 xAI
> 兼容接口,并集中处理鉴权、模型访问控制、渠道调度和协议适配。
>
> 路径、参数与响应结构以 [Swagger YAML](swagger.yaml) 或运行时 Swagger UI
> 为准;协议差异、兼容改写和实测边界以本文为准。
**兼容快照:2026-07-15**
## 快速导航
- [快速接入](#quick-start)
- [端点一览](#endpoints)
- [路由与全局行为](#routing)
- [Codex 接入](#codex)
- [已知限制](#limitations)
- [字段兼容矩阵](#compatibility)
- [实现索引](#implementation)
<a id="quick-start"></a>
## 快速接入
### 基础地址与鉴权
```text
Base URL: https://<网关地址>/ai/v1
```
网关密钥在管理面板中创建,支持以下任一请求头:
```http
Authorization: Bearer sk-...
```
```http
x-api-key: sk-...
```
密钥可绑定渠道分组和模型白名单。全局模型黑名单会同时作用于模型列表、
请求路由和探测候选;开启「过滤弃用模型」后,OCI 已宣布弃用的模型也会从
列表与路由中移除。
可先用模型列表验证地址与密钥:
```bash
curl "https://<网关地址>/ai/v1/models" \
-H "Authorization: Bearer $OCI_PORTAL_KEY"
```
<a id="endpoints"></a>
## 端点一览
| 协议域 | 端点 | 角色 | 流式 |
| --- | --- | --- | :---: |
| 对话 | `POST /ai/v1/responses` | OpenAI Responses,无状态主接口 | SSE |
| 对话 | `POST /ai/v1/chat/completions` | OpenAI Chat Completions 兼容层 | SSE |
| 对话 | `POST /ai/v1/messages` | Anthropic Messages 转换层 | SSE |
| 向量 | `POST /ai/v1/embeddings` | OpenAI Embeddings | — |
| 语音 | `POST /ai/v1/audio/speech` | OpenAI Audio Speech 外壳 | — |
| 语音 | `POST /ai/v1/tts` | xAI TTS 格式转换层 | — |
| 检索 | `POST /ai/v1/rerank` | Cohere / Jina 风格文档重排 | — |
| 安全 | `POST /ai/v1/moderations` | OpenAI 外壳映射 OCI Guardrails | — |
| 发现 | `GET /ai/v1/models` | 当前密钥可见模型列表 | — |
选择建议:
- 新客户端优先使用 **Responses**
- Anthropic SDK 或 Claude 生态客户端使用 **Messages**
- 仅支持旧 OpenAI 对话协议的客户端使用 **Chat Completions**
- Embeddings、TTS、Rerank 与 Moderations 使用各自专用端点
<a id="routing"></a>
## 路由与全局行为
### 请求链路
```mermaid
flowchart LR
A[客户端] --> B[网关密钥鉴权]
B --> C[分组、白名单与全局过滤]
C --> D[模型与能力匹配]
D --> E[选择最小 Priority]
E --> F[同优先级按 Weight 加权]
F --> G[OCI GenAI]
G -. 可重试且流未建立 .-> D
```
单次请求最多尝试三个渠道。模型不可用、限流、上游服务错误或网络错误可触发
换渠道;流式连接建立后不会切换渠道重试。
### 全局兼容边界
| 主题 | 当前行为 |
| --- | --- |
| 会话状态 | 网关不保存会话历史,客户端必须在每次请求中携带完整上下文 |
| 上游存储 | Responses 请求始终强制 `store:false` |
| 有状态字段 | Responses 拒绝非空 `previous_response_id`、非 `null``conversation``background:true` |
| 对话上游 | 对话请求统一进入 OCI OpenAI 兼容面,当前供给以 `xai.``meta.``openai.` 前缀模型为主 |
| 推理强度 | Responses `reasoning.effort`、Messages `output_config.effort`、Chat `reasoning_effort` 会传给上游;可用档位由模型决定 |
| 服务端工具 | Responses 支持 `web_search``x_search``code_interpreter` 和远程 `mcp`;命名容器管理与 File Search 不提供 |
| 文件输入 | `input_file` 会被 OCI ZDR 形态拒绝,详见[已知限制](#limitations) |
| Chat 定位 | Chat Completions 只承担协议转换与兼容修复;新能力优先落在 Responses 与 Messages |
<a id="codex"></a>
## Codex 接入
### 主配置
自定义模型提供方必须写在用户级 `~/.codex/config.toml`。Codex 的项目级
`.codex/config.toml` 不允许改写 `model_provider``model_providers`
```toml
model = "xai.grok-4.3"
model_provider = "oci"
[model_providers.oci]
name = "oci-portal"
base_url = "https://<网关地址>/ai/v1"
env_key = "OCI_PORTAL_KEY"
wire_api = "responses"
```
### 自定义子代理
新版 Codex 可在 `~/.codex/agents/` 或项目级 `.codex/agents/` 放置独立 TOML
文件,并为子代理覆盖模型。每个文件都需要 `name``description`
`developer_instructions`
```toml
# .codex/agents/oci-worker.toml
name = "oci-worker"
description = "通过 OCI Portal 网关执行通用开发任务。"
developer_instructions = """
完成被分配的开发任务,保持改动聚焦,并返回验证结果。
"""
model = "xai.grok-4.3"
```
> [!IMPORTANT]
> `codex-cli 0.144.1` 已实测主会话和 multi-agent 子代理全链路可用。
> 内置 worker 可能先尝试 `gpt-5.6-luna` 或 `gpt-5.4`;网关没有对应渠道时
> 会出现少量 404,随后由 Codex 回落到可用模型。自定义 agent 的模型覆盖是否
> 直接生效取决于 Codex 版本;0.144.1 的实测主要依赖自动回落。
Codex 工具兼容现状:
| 工具形态 | 网关处理 | 验证状态 |
| --- | --- | --- |
| `function` | 原样透传 | 可用 |
| `namespace` | 子工具拍平为限定名 `function`,响应时还原 | multi-agent 已端到端实测;MCP 同路径有单测 |
| `custom` | 顶层普通工具转换为 `function`,调用与历史记录双向回转 | 可用,但存在降级边界 |
| `custom:apply_patch` | 直接剥离,让模型回落到其他编辑方式 | 有意限制 |
| `tool_search` | namespace 已完整展开,目录搜索语义冗余,直接剥离 | 有意降级 |
配置语法参考 [Codex Subagents](https://learn.chatgpt.com/docs/agent-configuration/subagents)
与 [Codex Advanced Configuration](https://learn.chatgpt.com/docs/config-file/config-advanced)。
<a id="limitations"></a>
## 已知限制
### 超大流式请求
上游流式断流有两个独立触发维度,状态不同:
> [!WARNING]
> **instructions + tools 合计超过约 64.5 KB** 的流式请求,上游会在推理阶段
> 静默断连(纯 EOF,无 error / 终态事件);同请求非流式总是成功,`input`
> 正文完全不计入。2026-07-13 定位(字节级二分),**2026-07-16 复测仍存在**
> 70.4 KB 断 / 59.7 KB 过,ChicagoAPI Key 与签名行为一致)。
> [!NOTE]
> **完整请求体超过约 82 KB**(含 input)的纯体积断流(2026-07-15 定位)
> **已被上游修复**2026-07-16 复核 83 KB、真实 codex 形态 104.5 KB、200 KB、
> 400 KB 流式均正常完成(Chicago 与 Phoenix 两区、签名与 API Key 两路径对照)。
网关当前行为:
- **Chat Completions / Messages**:若上游在客户端收到任何内容前断流,自动用
非流式重做,并合成对应 chunk / event 序列(可兜住 64.5 KB 断流)
- **Responses**:直通协议中途无法透明重试(客户端已收到事件)。流式保险丝按
`instructions + tools` 字节和判定:超过阈值时预防性改非流式上游 + 合成最小
SSE 事件序列(`response.created``response.output_item.done`
`response.completed`),语义保留但无增量输出。默认开、60 KB,可在
**设置 → AI → 流式保险丝** 调整或关闭
- **已开始输出的流**:不能透明重试;调用日志会记录提前终止,客户端可能只拿到
部分事件
### grok 服务端搜索工具默认注入
`xai.` 前缀模型的 Responses 请求,网关按开关默认注入 `web_search` /
`x_search` 工具;请求 tools 已包含同名工具时保持原样,不覆盖参数。默认双开,
可在 **设置 → AI → grok 服务端搜索工具** 关闭。
### ZDR 与文件输入
Responses 的 `input_file` 内容块(`file_url` / `file_data`)实测会被上游拒绝:
```text
File content is currently unsupported for ZDR customers
```
网关强制 `store:false`,属于 ZDR 请求形态,因此当前不能通过该端点上传或引用文件。
### 规格与实测边界
本项目提供的是兼容接口,而不是 OpenAI、Anthropic 或 xAI 协议的完整实现。
部分 OCI OpenAI 兼容行为来自实测,未见 Oracle 文档合同,可能随上游调整。
<a id="compatibility"></a>
## 字段兼容矩阵
矩阵基线:
- [OpenAI Responses](https://developers.openai.com/api/reference/resources/responses/methods/create)
- [OpenAI Chat Completions](https://developers.openai.com/api/reference/resources/chat/subresources/completions/methods/create)
- [OpenAI Embeddings](https://developers.openai.com/api/reference/resources/embeddings/methods/create)
- [OpenAI Audio Speech](https://developers.openai.com/api/reference/resources/audio/methods/speech)
- [OpenAI Moderations](https://developers.openai.com/api/reference/resources/moderations/methods/create)
- [Anthropic Messages](https://platform.claude.com/docs/en/api/messages/create)
- [Cohere Rerank](https://docs.cohere.com/reference/rerank)
| 标记 | 含义 |
| :---: | --- |
| ✅ | 网关直接支持 |
| ➡️ | 原样保留或透传;是否生效由 OCI 上游决定 |
| 🔄 | 网关执行字段或协议转换后支持 |
| ◐ | 部分支持、存在前置条件或语义降级 |
### OpenAI Responses
**`POST /ai/v1/responses` · 无状态主接口**
网关以原始 JSON 为基底保留未知字段,但会强制关闭上游存储,并执行下表列出的
Codex 工具兼容改写。请求会重新编码,不承诺字节级原样转发。
<details open>
<summary><strong>核心字段</strong></summary>
| 标准字段 | 状态 | 网关行为 |
| --- | :---: | --- |
| `model` | ◐ | 必填;通过密钥白名单并匹配可用渠道后送往上游 |
| `input` | ➡️ | 支持字符串或 item 数组;普通内容保留,Codex 工具历史项可能改写 |
| `instructions``max_output_tokens` | ➡️ | 类型可解析后保留,不做范围或模型能力校验 |
| `temperature``top_p` | ➡️ | 保留,不做取值范围校验 |
| `parallel_tool_calls` | ◐ | 通常保留;若全部工具被剥离,则与 `tool_choice` 一并删除 |
| `text` / `text.format` / `text.verbosity` | ➡️ | 整个对象保留;是否生效由 OCI 模型决定 |
| `reasoning` | ➡️ | 整个对象保留;`effort` 不校验档位 |
| `tool_choice` | ◐ | 普通形态保留;namespace 对象会重限定,全部工具被剥离时删除 |
| `store` | 🔄 | 无论客户端传什么,上游请求都强制改写为 `false` |
| `stream` | ◐ | 支持 SSE;网关按 instructions+tools 字节和触发预防性非流式回退(保险丝,默认开 60 KB,见[已知限制](#limitations) |
| 其余标准与未知顶层字段 | ➡️ | `context_management``include``metadata``prompt``prompt_cache_key``service_tier``truncation``user` 等均保留,由 OCI 决定是否接受 |
</details>
<details open>
<summary><strong>工具兼容</strong></summary>
| 工具或参数 | 状态 | 网关行为 |
| --- | :---: | --- |
| `tools[].type=function` | ➡️ | 非流式与流式均可,工具对象保留 |
| `web_search` / `x_search` / `code_interpreter` | ◐ | Oracle 文档化的 xAI 服务端工具;参数与限制遵循 [xAI 规格](https://docs.oracle.com/en-us/iaas/Content/generative-ai/get-started-agents.htm#xai-compatible-tools) |
| `tools[].type=mcp` | ➡️ | 远程 MCP 由上游直连,`server_url``require_approval``authorization` 等保留 |
| `tools[].type=namespace` | 🔄 | 子 `function` 上提并限定命名;响应、历史调用和 `tool_choice` 会反向还原;组内非 `function` 子工具被剥离 |
| `tools[].type=custom` | ◐ | 顶层非 `apply_patch` 工具转为带 `input` schema 的 `function`;响应与多轮历史双向回转;`format` 会删除 |
| `custom:apply_patch` | ◐ | 整体剥离;grok 系未针对 Codex 补丁格式训练,模型应回落其他编辑方式 |
| `tools[].type=tool_search` | ◐ | 请求可被接受,但工具本身直接剥离 |
| `web_search.external_web_access=true` | 🔄 | 删除上游不识别的字段,保留 `web_search` |
| `web_search.external_web_access=false` | ◐ | 上游没有“仅缓存检索”对应能力,按不越权原则剥离整个工具 |
</details>
本地拒绝(返回 400):
- 非空 `previous_response_id`
-`null``conversation`
- `background:true`
- 未列入白名单的工具类型,例如 `web_search_preview``file_search`
`computer``image_generation``shell`
响应边界:
- 无工具还原且未触发流式升级时,普通响应保持直通语义
- namespace / custom 调用会在非流式响应与命中的 SSE `data` 事件中定向还原
- 普通 SSE 不补 `data: [DONE]`reasoning 增量不会被过滤
- 未知模型返回 404,无可用渠道返回 503
- 上游错误使用 OpenAI 风格错误外壳,但不保证字段与标准 OpenAI 完全一致
### OpenAI Chat Completions
**`POST /ai/v1/chat/completions` · 存量客户端兼容层**
请求先转换为 Responses,再将 OCI Responses 响应桥接回 Chat Completions。
只有下表字段会进入上游请求。
<details>
<summary><strong>展开字段矩阵</strong></summary>
| 标准字段 | 状态 | 网关行为 |
| --- | :---: | --- |
| `model` | ◐ | 必填,受密钥白名单和可用渠道限制 |
| `messages` | 🔄 | 必填,转换为 Responses `input` / `instructions` |
| `system` / `developer` 消息 | ◐ | 文本按顺序合并为 `instructions`;块数组中的非文本内容忽略 |
| `user` / `assistant` 文本 | 🔄 | 字符串和 `text` 块分别转为 `input_text` / `output_text` |
| `image_url` | ◐ | URL 或 data URI 转为 `input_image``detail` 忽略 |
| assistant `tool_calls` / `role=tool` | 🔄 | 转为 `function_call` / `function_call_output` |
| `max_completion_tokens` | 🔄 | 转为 `max_output_tokens`,优先于 `max_tokens` |
| `max_tokens` | 🔄 | 未提供 `max_completion_tokens` 时转为 `max_output_tokens` |
| `temperature``top_p``parallel_tool_calls` | ◐ | 写入 Responses,不校验范围或模型能力 |
| `stream` | 🔄 | Responses SSE 转为 `chat.completion.chunk`,末尾补 `data: [DONE]` |
| `stream_options.include_usage` | 🔄 | 控制终块后的独立 usage 块 |
| `tools[].type=function` | ◐ | 支持 `name``description``parameters``strict` 忽略 |
| `tool_choice` | ◐ | 支持 `auto` / `none` / `required` 和具名 function |
| `response_format` | ◐ | `json_object``json_schema` 转为 Responses `text.format` |
| `reasoning_effort` | ◐ | 转小写后映射为 `reasoning.effort` |
| `store` | 🔄 | 客户端取值忽略,上游始终使用 `store:false` |
</details>
不支持(返回 400):`input_audio``file``refusal` 等消息内容块,以及
`function` 之外的工具类型。
<details>
<summary><strong>静默忽略字段</strong></summary>
消息级 `name` / `refusal` / `audio` / 旧式 `function_call``stop``seed`
`n``frequency_penalty``presence_penalty``logprobs``top_logprobs`
`logit_bias``user``audio``modalities``prediction``metadata`
`moderation``prompt_cache_key``safety_identifier``service_tier`
`verbosity``web_search_options``stream_options.include_obfuscation`
及其他未知字段。
</details>
响应边界:
- 非流式固定生成一个 `choices[0]`;文本合并,函数调用转为 `tool_calls`
- `finish_reason` 只生成 `stop``tool_calls``length`
- reasoning、logprobs、refusal、annotations、audio、service tier 和 system fingerprint 不返回
- usage 保留 `prompt_tokens``completion_tokens``total_tokens`
`prompt_tokens_details.cached_tokens`
- 已开始输出的流中断不会转换成标准 SSE 错误事件
### Anthropic Messages
**`POST /ai/v1/messages` · Anthropic 协议转换层**
支持 `Authorization: Bearer``x-api-key`,但不校验或使用
`anthropic-version``anthropic-beta` 请求头。
<details>
<summary><strong>展开顶层字段矩阵</strong></summary>
| 标准字段 | 状态 | 网关行为 |
| --- | :---: | --- |
| `model` | ◐ | 用于模型与渠道选择;空字符串通常最终返回模型不存在 |
| `max_tokens` | 🔄 | 缺省或 ≤0 时使用 8192,再转为 `max_output_tokens` |
| `messages` | ◐ | 必须非空;角色、交替顺序和空内容不做完整校验 |
| `system` | ◐ | 支持字符串或 text 块数组;文本块拼接,附加字段忽略 |
| `temperature``top_p` | ◐ | 写入 Responses,不校验范围或模型能力 |
| `stream` | 🔄 | Responses SSE 桥接为 Anthropic 标准事件序列 |
| `tools` | ◐ | 每个工具转为 Responses `function`;服务端工具类型不保留原语义 |
| `tool_choice` | ◐ | 支持 `auto``any``none`、具名 `tool` |
| `output_config.effort` | 🔄 | 转小写后映射为 `reasoning.effort` |
</details>
内容块兼容:
| `messages[].content` | 状态 | 网关行为 |
| --- | :---: | --- |
| 字符串 / `text` | 🔄 | user 转 `input_text`assistant 历史转 `output_text` |
| `image` | ◐ | 仅支持 `base64``url` source |
| `tool_use` | 🔄 | 转为 `function_call`,保留 ID、名称与输入 |
| `tool_result` | ◐ | 转为 `function_call_output`;块数组只拼接 text`is_error` 与非文本结果丢失 |
| `null` / 空块数组 | ◐ | 消息可能从上游 input 中消失,不返回参数错误 |
不支持(返回 400):`document`、服务端工具结果及未知内容块。历史
`thinking` / `redacted_thinking` 会删除。
<details>
<summary><strong>静默忽略字段</strong></summary>
`top_k``stop_sequences``metadata``thinking``output_config` 其余子字段、
`cache_control``container``inference_geo``service_tier` 及其他未知顶层字段。
</details>
响应边界:
- 仅将 Responses `output_text` 转为 `text``function_call` 转为 `tool_use`
- `stop_reason` 只生成 `end_turn``tool_use``max_tokens`
- 不生成 Anthropic thinking / signature 内容块
- usage 只保留 `input_tokens``output_tokens``cache_read_input_tokens`
- 流式上游错误与无终态断流会转成 Anthropic `error` 事件
### OpenAI Embeddings
**`POST /ai/v1/embeddings` · 向量化专用端点**
| 标准字段 | 状态 | 网关行为 |
| --- | :---: | --- |
| `model` | ◐ | 必填,受白名单限制,且需要 `EMBEDDING` 能力渠道 |
| 字符串 `input` | ✅ | 包装为单个输入后调用 OCI |
| 字符串数组 `input` | ✅ | 按原顺序调用 OCI |
| `dimensions` | ◐ | 映射为 OCI 输出维度,不校验范围或模型能力 |
| `encoding_format=float` | ✅ | 返回 float 数组;省略时相同 |
不支持(返回 400):token ID 数组、空数组、`null`
`encoding_format=base64``user` 与其他未知字段静默忽略。
响应使用标准 `object:"list"` 外壳,向量为 `float32` 数组,不支持流式。
### 语音生成
两个端点最终使用同一 OCI xAI TTS 上游与渠道调度:
#### OpenAI Audio Speech
**`POST /ai/v1/audio/speech`**
| 标准字段 | 状态 | 网关行为 |
| --- | :---: | --- |
| `model` | ◐ | 必填,受白名单限制,需要 `TTS` 能力渠道;当前为 `xai.grok-tts` |
| `input` | ◐ | 必填非空,随后保留 |
| `voice` | ➡️ | 使用 xAI 音色 `ara` / `eve` / `leo` / `rex` / `sal` |
| `response_format` | ➡️ | 实测 `mp3` 可用,其余格式由上游决定 |
| `language`(扩展) | 🔄 | 上游必填;缺省时注入 `"auto"` |
| `speed``instructions` 与未知字段 | ➡️ | 保留,是否生效由上游决定 |
#### xAI TTS
**`POST /ai/v1/tts`**
接受 [xAI 官方 TTS 格式](https://docs.x.ai/developers/model-capabilities/audio/text-to-speech)
转换为 OpenAI 兼容形态后进入同一上游。
| 字段 | 状态 | 网关行为 |
| --- | :---: | --- |
| `text` | 🔄 | 必填非空,转换为 `input` |
| `language` | ◐ | 必填,接受 BCP-47 或 `auto` |
| `voice_id` | 🔄 | 转为 `voice`;缺省交给上游默认值 `eve` |
| `output_format` | ➡️ | `{codec, sample_rate, bit_rate}` 对象保留,实测生效 |
| `speed` | ➡️ | 保留,实测可用 |
| `model`(网关扩展) | ◐ | 缺省注入 `xai.grok-tts`,可覆盖,受白名单限制 |
| 其余未知字段 | ➡️ | 保留,是否生效由上游决定 |
共同响应边界:
- 成功响应为一次性完整音频,`Content-Type` 透传上游,缺省 `audio/mpeg`
- 不提供 HTTP 流式音频或 WebSocket 代理
- 无 token 用量口径,调用日志只记时延与渠道
### Rerank
**`POST /ai/v1/rerank` · Cohere / Jina 风格协议**
上游走 OCI typed 面,模型为 `cohere.rerank-v4.0-pro``-fast`
| 字段 | 状态 | 网关行为 |
| --- | :---: | --- |
| `model` | ◐ | 必填,受白名单限制,需要 `RERANK` 能力渠道 |
| `query` | ✅ | 必填非空 |
| `documents` | ◐ | 仅接受字符串数组;旧版 `{"text": ...}` 对象数组返回 400 |
| `top_n` | ✅ | 可选,限制返回条数 |
| `return_documents` | ✅ | 为 `true` 时回带原文 |
`max_tokens_per_doc` 与未知字段静默忽略。响应按相关度降序,
`results[].index` 指向输入下标,`relevance_score` 为 0~1 浮点;无 token 用量口径。
### Moderations
**`POST /ai/v1/moderations` · OpenAI 外壳映射 OCI Guardrails**
| 标准字段 | 状态 | 网关行为 |
| --- | :---: | --- |
| 字符串 `input` | ✅ | 单条审核 |
| 字符串数组 `input` | ✅ | 逐条审核,单次 1~8 条 |
不支持(返回 400):多模态 input、空字符串条目、空数组或超过 8 条。
`model` 接受但忽略,不参与白名单判断。
响应边界:
- categories 使用 OCI 原生维度 `overall` / `blocklist` / `prompt_injection`
- 任一维度得分 ≥ 0.5 时 `flagged=true`
- PII 命中放在扩展字段 `results[].pii`,包含 `text``label``score`
`offset``length`,不参与 `flagged`
- 实测中文人名与手机号识别较弱,英文 PII 识别正常
- 响应 `model` 恒为 `oci-guardrails`
### Models
**`GET /ai/v1/models` · 当前密钥可见模型列表**
响应使用 OpenAI Models 列表外壳,只返回同时通过以下条件的模型:
1. 存在于当前渠道目录
2. 匹配密钥绑定的渠道分组
3. 不在全局模型黑名单
4. 命中密钥模型白名单(配置时)
5. 未被「过滤弃用模型」开关排除
网关不提供标准的单模型检索端点。
<a id="implementation"></a>
## 实现索引
| 端点 / 能力 | 主要实现 |
| --- | --- |
| Responses 直通与 Codex 工具兼容 | [`airesponses.go`](../internal/service/airesponses.go) · [`responses.go`](../internal/aiwire/responses.go) |
| Chat Completions 转换 | [`chatresponses.go`](../internal/service/chatresponses.go) · [`openai.go`](../internal/aiwire/openai.go) |
| Anthropic Messages 转换 | [`anthresponses.go`](../internal/service/anthresponses.go) · [`anthropic.go`](../internal/aiwire/anthropic.go) |
| 渠道路由与 Embeddings | [`aigateway_chat.go`](../internal/service/aigateway_chat.go) |
| TTS 上游 | [`genai_speech.go`](../internal/oci/genai_speech.go) · [`aigateway_extras.go`](../internal/service/aigateway_extras.go) |
| Rerank / Moderations 上游 | [`genai_guard.go`](../internal/oci/genai_guard.go) · [`rerank.go`](../internal/aiwire/rerank.go) · [`moderations.go`](../internal/aiwire/moderations.go) |
| HTTP Handler 与流式桥接 | [`aigateway.go`](../internal/api/aigateway.go) · [`aigateway_extras.go`](../internal/api/aigateway_extras.go) |
本文是兼容性快照,不替代 Swagger。标准接口、Codex 客户端与 OCI 上游均可能
变化,最终行为以当前版本代码、运行时 Swagger 和实测结果为准。