- POST /ai/v1/tts:xAI 官方 TTS 格式转换层(text/voice_id→input/voice),复用 Speech 编排,model 缺省 xai.grok-tts;实测 output_format/speed 透传生效 - 「过滤弃用模型」开关(GET/PUT /api/v1/ai-settings,settings 表持久化):开启后已宣布弃用(未退役)模型从列表与路由排除;同步入库与退役提醒不受影响 - AI 网关文档更名 docs/AI网关.md,补 tts 矩阵段与开关说明;README 引用同步 - CHANGELOG 0.5.0(0.4.0 已发版冻结);DASH_VERSION v0.5.0
24 KiB
AI 网关
本文是 OCI Portal AI 网关的完整使用与兼容性文档:端点定位、协议兼容边界、已知上游限制与字段兼容矩阵。 路由与鉴权的机器可读定义以 Swagger YAML 或运行时 Swagger UI 为准;无法由 OpenAPI 表达的兼容边界以本文为准。
AI 网关使用面板创建的独立密钥鉴权,支持 Authorization: Bearer sk-... 和 x-api-key: sk-...。密钥可绑定渠道分组和模型白名单;全局模型黑名单会从模型列表、路由和探测候选中同时排除目标模型。
| 端点 | 定位 | 流式 |
|---|---|---|
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,文本转语音(xAI Voice) | 否 |
POST /ai/v1/tts |
xAI 官方格式文本转语音(同一上游,网关转换) | 否 |
POST /ai/v1/rerank |
文档重排(Cohere Rerank,Jina 风格协议) | 否 |
POST /ai/v1/moderations |
内容审核(OCI Guardrails:内容审核 / PII / 提示注入) | 否 |
GET /ai/v1/models |
当前密钥可见的模型列表 | 否 |
兼容边界:
- 对话请求统一转发 OCI OpenAI 兼容面,当前供给以
xai.、meta.、openai.前缀模型为主;Cohere Embeddings 不受该对话模型范围影响 - 网关不保存会话历史,客户端需要携带完整上下文;Responses 拒绝非空
previous_response_id、非nullconversation和background:true - Responses 支持 Oracle 文档化的 xAI 服务端工具
web_search/x_search/code_interpreter与远程mcp工具(非流式与流式均可),工具参数与限制遵循 xAI 规格;code_interpreter的命名容器管理(containers API)与 File Search 不提供 - Responses 的
reasoning.effort、Messages 的output_config.effort和 Chat Completions 的reasoning_effort会传给上游,实际档位和效果由模型决定 - Chat Completions 只承担协议转换与兼容修复;新能力优先在 Responses 和 Messages 提供
- 单次请求最多尝试三个渠道;可重试错误会切换渠道,流式响应建立后不会换渠道重试
- Audio Speech 直通 OCI 兼容面(模型
xai.grok-tts,voice 取 xAI Grok Voice 列表:ara/eve/leo/rex/sal);上游把language当必填,缺省时网关自动注入"auto",xAI 专属参数(output_format等)可平铺在请求体透传;仅单请求返回音频,不提供 WebSocket 流式 /ai/v1/tts为 xAI 官方 TTS 格式(text/language必填、voice_id、output_format对象)的转换端点:网关转换为 OpenAI 兼容形态后走同一上游与渠道调度,model为网关扩展字段(缺省xai.grok-tts);实测output_format(codec/sample_rate/bit_rate)与speed透传生效- Rerank 走 OCI typed 面(
cohere.rerank-v4.0-pro/-fast),请求{model, query, documents[], top_n?, return_documents?},响应results[].index指向入参下标;无 token 用量口径,调用日志只记时延 - Moderations 是 OpenAI moderations 外壳映射 OCI Guardrails:
input为字符串或字符串数组(至多 8 条),categories 用 OCI 原生维度overall/blocklist/prompt_injection(阈值 0.5 判定flagged),PII 命中放扩展字段results[].pii(不参与 flagged);model字段接受但忽略,无模型白名单维度;实测中文人名/手机号识别较弱,英文 PII 识别正常 - Responses 的
input_file内容块(file_url / file_data)实测被上游拒绝:File content is currently unsupported for ZDR customers——网关强制store:false属 ZDR 形态,该能力在上游侧不可用
已知上游限制:大 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 或运行时 Swagger UI 为准;无法由 OpenAPI 完整表达的兼容边界列于上方。
字段兼容矩阵
以下矩阵以 2026-07-13 的 OpenAI Responses、Chat Completions、Embeddings、Audio Speech、Moderations 和 Anthropic Messages 为标准基线,并与当前实现逐项核对;Rerank 无 OpenAI 对应端点,基线取 Cohere Rerank 协议。
这是一份兼容性快照,不替代 Swagger。标准接口和 OCI 上游都可能变化,最终行为以当前版本代码与实测为准。
矩阵只列网关支持的字段;不支持(本地拒绝)与被忽略的字段不入表,在各端点段落末尾以文字简述。
| 标记 | 含义 |
|---|---|
| ✅ | 网关直接支持 |
| ➡️ | 网关原样透传;是否生效由 OCI 上游决定 |
| 🔄 | 网关进行字段或协议转换后支持 |
| ◐ | 部分支持、存在前置条件或语义降级 |
POST /ai/v1/responses 对比 OpenAI Responses
Responses 是“原始 JSON 直通 + 本地门禁”。除 store 外,网关不会重建请求体;未知顶层字段也会保留并送往 OCI。
| 标准字段 | 状态 | 网关行为 |
|---|---|---|
model |
◐ | 必须非空,还要通过密钥模型白名单并匹配可用渠道;随后原样透传 |
input |
➡️ | 支持标准的字符串或 item 数组,原始内容透传;网关不逐项保证 OCI 能处理所有 item 类型 |
instructions、max_output_tokens |
➡️ | 类型可解析后原样透传,不做范围或模型能力校验 |
temperature、top_p、parallel_tool_calls |
➡️ | 原样透传,不做取值范围校验 |
text / text.format / text.verbosity |
➡️ | 整个原始对象透传;结构化输出是否可用由 OCI 模型决定 |
reasoning |
➡️ | 整个原始对象透传;effort 不校验档位,summary 等字段不会被网关删除 |
tool_choice |
➡️ | 任意 JSON 原样透传,本地不校验枚举或结构 |
store |
🔄 | 无论客户端传什么,上游请求都强制改写为 false |
stream |
✅ | 普通请求、function 与服务端工具均支持 SSE |
tools[].type=function |
➡️ | 非流式和流式均可,工具对象原样透传 |
tools[].type=web_search / x_search / code_interpreter |
◐ | Oracle 文档化的 xAI 服务端工具,参数与限制遵循 xAI 规格(如 allowed_domains 上限 10、container 支持 {"type":"auto"}),非流式与流式均实测可用;x_search 不是 OpenAI 标准工具 |
tools[].type=mcp |
➡️ | 远程 MCP 服务由上游直连调用(server_url / require_approval / authorization 等原样透传),非流式与流式均实测可用 |
| 其余标准与未知顶层字段 | ➡️ | context_management、include、metadata、prompt、prompt_cache_key、service_tier、truncation、user 等未建模字段一律保留在原始请求中,由 OCI 决定是否接受 |
不支持(请求到达上游前返回 400):非空 previous_response_id、非 null 的 conversation、background:true——网关无状态,不保存历史响应;以及 function / xAI 服务端工具 / mcp 之外的工具类型(web_search_preview、file_search、computer、image_generation、shell、custom 等)。
响应边界:
- 非流式成功响应不做转换,OCI JSON 原样返回;usage 解析只用于面板调用日志
- SSE 事件逐行原样转发,不补
data: [DONE],推理增量也不会被网关过滤 - 流建立前最多切换三个渠道;流建立后中断不重试,客户端可能只收到部分事件
- 未知模型返回 404、无渠道返回 503;上游错误会套入 OpenAI 风格错误体,不保证与标准 OpenAI 错误字段完全相同
实现依据:airesponses.go · responses.go · aigateway.go
POST /ai/v1/chat/completions 对比 OpenAI Chat Completions
Chat Completions 会先转换为 Responses 请求,再把 OCI Responses 响应桥接回 Chat Completions 形态。转换器只搬运下表字段,其余字段不进入上游请求。
| 标准字段 | 状态 | 网关行为 |
|---|---|---|
model |
◐ | 必填,受密钥白名单和可用渠道限制;模型名保留到上游请求 |
messages |
🔄 | 必填并转换为 Responses input / instructions |
system / developer 消息 |
◐ | 文本按出现顺序合并为 instructions;块数组中的非文本内容被忽略 |
user / assistant 文本内容 |
🔄 | 字符串及 text 块分别转为 input_text / output_text |
image_url 内容块 |
◐ | URL 或 data URI 转为 input_image;image_url.detail 被忽略 |
assistant tool_calls / role=tool |
🔄 | 转为 function_call / function_call_output,保留调用 ID、函数名和参数 |
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];上游断流且尚无输出时自动降级非流式重做,结果按 chunk 序列一次推送 |
stream_options.include_usage |
🔄 | 控制网关在终块后追加 choices: [] 的 usage 块 |
tools[].type=function |
◐ | name、description、parameters 支持;function.strict 被忽略 |
tool_choice |
◐ | 支持 auto / none / required 和具名 function;非法或未知值被静默忽略 |
response_format |
◐ | json_object、json_schema 转为 Responses text.format;未知类型交给 OCI 处理 |
reasoning_effort |
◐ | 转小写后映射为 reasoning.effort,不校验模型或档位 |
store |
🔄 | 客户端取值被忽略,转换后的上游请求始终使用 store:false |
不支持(返回 400):input_audio、file、refusal 等消息内容块;function 以外的工具类型(含 custom)。
静默忽略(转换后的上游请求不包含):消息级 name / refusal / audio / 旧式 function_call;采样与输出控制类 stop、seed、n(恒返回单个 choice)、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 及其他未知字段。
响应边界:
- 非流式固定生成一个
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 - 已建立的流中断或上游
response.failed不会转换成标准 SSE 错误事件
实现依据:chatresponses.go · openai.go · aigateway.go
POST /ai/v1/embeddings 对比 OpenAI Embeddings
| 标准字段 | 状态 | 网关行为 |
|---|---|---|
model |
◐ | 必填,受密钥白名单限制,并且必须存在具有 EMBEDDING 能力的渠道 |
input 为字符串 |
✅ | 包装为单个输入后调用 OCI |
input 为字符串数组 |
✅ | 按原顺序调用 OCI;空字符串不在本地拒绝,由 OCI 决定 |
dimensions |
◐ | 映射为 OCI 输出维度,不做范围或模型能力校验 |
encoding_format=float |
✅ | 返回 float 数组;省略时行为相同 |
不支持(返回 400):token ID 数组(一维或二维)形态的 input、空数组、null,以及 encoding_format=base64。静默忽略:user 及其他未知字段。
响应使用标准的 object:"list"、data[].object:"embedding"、index、model 和可选 usage 外壳;向量为 float32 数组,不支持流式。
实现依据:embeddings.go · aigateway_chat.go · aigateway.go
POST /ai/v1/messages 对比 Anthropic Messages
网关接受 Authorization: Bearer 或 x-api-key,但不会校验或使用标准 Anthropic anthropic-version、anthropic-beta 请求头。
| 标准字段 | 状态 | 网关行为 |
|---|---|---|
model |
◐ | 用于模型与渠道选择,但空字符串不会在 handler 中按参数错误拒绝,通常最终返回模型不存在 |
max_tokens |
🔄 | 可缺省(缺省或 ≤0 时按默认值 8192),转换为 max_output_tokens |
messages |
◐ | 必须非空;角色、交替顺序和空内容不做完整校验 |
system |
◐ | 支持字符串或 text 块数组;多个文本块直接拼接,cache_control 等附加字段被忽略 |
temperature、top_p |
◐ | 写入 Responses 请求,不做取值范围或模型能力校验 |
stream |
🔄 | Responses SSE 桥接为 Anthropic 事件序列;上游断流且尚无输出时自动降级非流式重做,结果按事件序列一次推送 |
tools |
◐ | 每个工具都转换成 Responses function;自定义客户端工具可用,Anthropic 服务端工具类型不保留原语义 |
tool_choice |
◐ | 支持 auto、any、none、具名 tool;disable_parallel_tool_use 等附加字段被忽略 |
output_config.effort |
🔄 | 转小写后映射为 Responses reasoning.effort |
顶层静默忽略(能解析但不传上游):top_k、stop_sequences(响应 stop_sequence 恒为 null)、metadata、thinking(不控制上游思考预算)、output_config 其余子字段、cache_control、container、inference_geo、service_tier 及其他未知顶层字段。
messages[].content:
| 标准内容块 | 状态 | 网关行为 |
|---|---|---|
字符串 / text |
🔄 | user 转 input_text,assistant 历史转 output_text |
image |
◐ | 仅支持 base64 和 url source;缺字段或其他 source 类型返回 400 |
tool_use |
🔄 | 转为 function_call,保留 ID、名称和输入 |
tool_result |
◐ | 转为 function_call_output;块数组只拼接 text,is_error 和非文本结果丢失 |
null / 空块数组 |
◐ | 该消息可能从上游 input 中消失,不返回参数错误 |
不支持的内容块(返回 400):document、服务端工具结果及其他未知块。历史 thinking / redacted_thinking 块会被删除,不进入上游上下文。
响应边界:
- 非流式只把 Responses
output_text转成text、function_call转成tool_use 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;上游错误事件与无终态断流会转成 Anthropicerror事件
实现依据:anthresponses.go · anthropic.go · aigateway.go
POST /ai/v1/audio/speech 对比 OpenAI Audio Speech
Audio Speech 与 Responses 同为“原始 JSON 直通 + 本地门禁”:除缺省注入 language 外不重建请求体,未知字段原样透传。
| 标准字段 | 状态 | 网关行为 |
|---|---|---|
model |
◐ | 必填,受密钥白名单限制,并且必须存在具有 TTS 能力的渠道(当前上游仅 xai.grok-tts) |
input |
◐ | 必填非空,随后原样透传 |
voice |
➡️ | 原样透传;取 xAI Grok Voice 音色(ara / eve / leo / rex / sal),OpenAI 标准音色名不可用 |
response_format |
➡️ | 原样透传;实测 mp3 可用,其余格式由上游决定 |
language(扩展字段) |
🔄 | 上游必填;客户端缺省时网关自动注入 "auto" |
speed、instructions 及其他未知字段 |
➡️ | 原样透传(含 xAI 专属参数如 output_format),是否生效由上游决定 |
不支持:流式音频(stream_format 等流式选项无效,响应恒为一次性完整音频)与 WebSocket 语音会话。
响应边界:
- 成功响应为音频字节,
Content-Type透传上游(缺省audio/mpeg) - 无 token 用量口径,调用日志只记时延与渠道
实现依据:genai_speech.go · service/aigateway_extras.go · api/aigateway_extras.go
POST /ai/v1/tts 对比 xAI TTS
/ai/v1/tts 接受 xAI 官方 TTS 格式(OCI 无 HTTP 版 xAI 面,网关转换为 OpenAI 兼容形态后与 /ai/v1/audio/speech 走同一上游与调度)。
| 标准字段 | 状态 | 网关行为 |
|---|---|---|
text |
🔄 | 必填非空,转换为上游 input |
language |
◐ | 必填(对齐 xAI 官方;接受 BCP-47 或 auto),原样透传 |
voice_id |
🔄 | 转换为上游 voice;缺省交上游默认(eve) |
output_format |
➡️ | {codec, sample_rate, bit_rate} 对象原样透传,实测生效(44.1kHz/192kbps 验证) |
speed |
➡️ | 原样透传,实测接受 |
model(网关扩展) |
◐ | xAI 官方无此字段;缺省注入 xai.grok-tts,可显式覆盖,受密钥白名单限制 |
optimize_streaming_latency、text_normalization、with_timestamps 及其他未知字段 |
➡️ | 原样透传,是否生效由上游决定 |
不支持:流式音频输出(xAI 官方 optimize_streaming_latency 面向流式场景,本端点响应恒为一次性完整音频);WebSocket 流式(OCI 另有 wss://…/xai/v1/tts 私有协议面,网关未代理)。
响应边界:
- 成功响应为音频字节,
Content-Type透传上游(缺省audio/mpeg) - 无 token 用量口径,调用日志只记时延与渠道(端点名
tts)
POST /ai/v1/rerank 对比 Cohere Rerank
Rerank 无 OpenAI 对应端点,协议取 Jina / Cohere 通行风格,上游走 OCI typed 面(cohere.rerank-v4.0-pro / -fast)。
| 字段 | 状态 | 网关行为 |
|---|---|---|
model |
◐ | 必填,受密钥白名单限制,并且必须存在具有 RERANK 能力的渠道 |
query |
✅ | 必填非空 |
documents |
◐ | 必填,仅接受字符串数组;Cohere 旧版 {"text": ...} 对象数组形态返回 400 |
top_n |
✅ | 可选,传给上游限制返回条数;缺省返回全部文档的重排结果 |
return_documents |
✅ | 可选,true 时 results[].document.text 回带原文 |
静默忽略:max_tokens_per_doc 等 Cohere 专属参数及其他未知字段。
响应边界:
results[]按相关度降序,index指向入参documents下标,relevance_score为 0–1 浮点;响应model回显请求值- 无 token 用量口径,调用日志只记时延与渠道
实现依据:genai_guard.go · rerank.go · service/aigateway_extras.go
POST /ai/v1/moderations 对比 OpenAI Moderations
Moderations 是 OpenAI moderations 外壳映射 OCI Guardrails(内容审核 / PII / 提示注入)。上游是服务级 API,没有模型与白名单维度;渠道按分组直接挑选。
| 标准字段 | 状态 | 网关行为 |
|---|---|---|
input 为字符串 |
✅ | 单条审核 |
input 为字符串数组 |
✅ | 逐条审核,单次 1~8 条 |
不支持(返回 400):多模态 input(图片等对象数组形态)、空字符串条目、空数组或超过 8 条的数组。静默忽略:model(接受任意值,不校验白名单)及其他未知字段。
响应边界:
categories/category_scores用 OCI 原生维度overall/blocklist/prompt_injection,而非 OpenAI 标准类目(hate/violence等);任一维度得分 ≥ 0.5 判定flagged- PII 命中放扩展字段
results[].pii(text/label/score/offset/length),不参与flagged判定;实测中文人名 / 手机号识别较弱,英文 PII 识别正常 - 响应
model恒为oci-guardrails
实现依据:genai_guard.go · moderations.go · service/aigateway_extras.go
GET /ai/v1/models 使用 OpenAI Models 列表外壳(object、data[].id/object/created/owned_by),但只返回当前渠道目录中通过分组、全局黑名单和密钥白名单筛选后的模型;网关不提供标准的单模型检索端点。面板「过滤弃用模型」开关开启时,OCI 已宣布弃用(即使未到退役日)的模型同时从模型列表与路由中排除,关闭后恢复。