23 KiB
AI 网关
Note
OCI Portal AI 网关将多个 OCI GenAI 渠道统一为 OpenAI、Anthropic 与 xAI 兼容接口,并集中处理鉴权、模型访问控制、渠道调度和协议适配。
路径、参数与响应结构以 Swagger YAML 或运行时 Swagger UI 为准;协议差异、兼容改写和实测边界以本文为准。
兼容快照:2026-07-15
快速导航
快速接入
基础地址与鉴权
Base URL: https://<网关地址>/ai/v1
网关密钥在管理面板中创建,支持以下任一请求头:
Authorization: Bearer sk-...
x-api-key: sk-...
密钥可绑定渠道分组和模型白名单。全局模型黑名单会同时作用于模型列表、 请求路由和探测候选;开启「过滤弃用模型」后,OCI 已宣布弃用的模型也会从 列表与路由中移除。
可先用模型列表验证地址与密钥:
curl "https://<网关地址>/ai/v1/models" \
-H "Authorization: Bearer $OCI_PORTAL_KEY"
端点一览
| 协议域 | 端点 | 角色 | 流式 |
|---|---|---|---|
| 对话 | 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 使用各自专用端点
路由与全局行为
请求链路
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 形态拒绝,详见已知限制 |
| Chat 定位 | Chat Completions 只承担协议转换与兼容修复;新能力优先落在 Responses 与 Messages |
Codex 接入
主配置
自定义模型提供方必须写在用户级 ~/.codex/config.toml。Codex 的项目级
.codex/config.toml 不允许改写 model_provider 与 model_providers。
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:
# .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 与 Codex Advanced Configuration。
已知限制
超大流式请求
上游流式断流有两个独立触发维度,状态不同:
Warning
instructions + tools 合计超过约 64.5 KB 的流式请求,上游会在推理阶段 静默断连(纯 EOF,无 error / 终态事件);同请求非流式总是成功,
input正文完全不计入。2026-07-13 定位(字节级二分),2026-07-16 复测仍存在 (70.4 KB 断 / 59.7 KB 过,Chicago,API 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)实测会被上游拒绝:
File content is currently unsupported for ZDR customers
网关强制 store:false,属于 ZDR 请求形态,因此当前不能通过该端点上传或引用文件。
规格与实测边界
本项目提供的是兼容接口,而不是 OpenAI、Anthropic 或 xAI 协议的完整实现。 部分 OCI OpenAI 兼容行为来自实测,未见 Oracle 文档合同,可能随上游调整。
字段兼容矩阵
矩阵基线:
- OpenAI Responses
- OpenAI Chat Completions
- OpenAI Embeddings
- OpenAI Audio Speech
- OpenAI Moderations
- Anthropic Messages
- Cohere Rerank
| 标记 | 含义 |
|---|---|
| ✅ | 网关直接支持 |
| ➡️ | 原样保留或透传;是否生效由 OCI 上游决定 |
| 🔄 | 网关执行字段或协议转换后支持 |
| ◐ | 部分支持、存在前置条件或语义降级 |
OpenAI Responses
POST /ai/v1/responses · 无状态主接口
网关以原始 JSON 为基底保留未知字段,但会强制关闭上游存储,并执行下表列出的 Codex 工具兼容改写。请求会重新编码,不承诺字节级原样转发。
核心字段
| 标准字段 | 状态 | 网关行为 |
|---|---|---|
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,见已知限制) |
| 其余标准与未知顶层字段 | ➡️ | context_management、include、metadata、prompt、prompt_cache_key、service_tier、truncation、user 等均保留,由 OCI 决定是否接受 |
工具兼容
| 工具或参数 | 状态 | 网关行为 |
|---|---|---|
tools[].type=function |
➡️ | 非流式与流式均可,工具对象保留 |
web_search / x_search / code_interpreter |
◐ | Oracle 文档化的 xAI 服务端工具;参数与限制遵循 xAI 规格 |
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 |
◐ | 上游没有“仅缓存检索”对应能力,按不越权原则剥离整个工具 |
本地拒绝(返回 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。 只有下表字段会进入上游请求。
展开字段矩阵
| 标准字段 | 状态 | 网关行为 |
|---|---|---|
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 |
不支持(返回 400):input_audio、file、refusal 等消息内容块,以及
function 之外的工具类型。
静默忽略字段
消息级 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
及其他未知字段。
响应边界:
- 非流式固定生成一个
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 请求头。
展开顶层字段矩阵
| 标准字段 | 状态 | 网关行为 |
|---|---|---|
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 |
内容块兼容:
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 会删除。
静默忽略字段
top_k、stop_sequences、metadata、thinking、output_config 其余子字段、
cache_control、container、inference_geo、service_tier 及其他未知顶层字段。
响应边界:
- 仅将 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 格式, 转换为 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 列表外壳,只返回同时通过以下条件的模型:
- 存在于当前渠道目录
- 匹配密钥绑定的渠道分组
- 不在全局模型黑名单
- 命中密钥模型白名单(配置时)
- 未被「过滤弃用模型」开关排除
网关不提供标准的单模型检索端点。
实现索引
| 端点 / 能力 | 主要实现 |
|---|---|
| Responses 直通与 Codex 工具兼容 | airesponses.go · responses.go |
| Chat Completions 转换 | chatresponses.go · openai.go |
| Anthropic Messages 转换 | anthresponses.go · anthropic.go |
| 渠道路由与 Embeddings | aigateway_chat.go |
| TTS 上游 | genai_speech.go · aigateway_extras.go |
| Rerank / Moderations 上游 | genai_guard.go · rerank.go · moderations.go |
| HTTP Handler 与流式桥接 | aigateway.go · aigateway_extras.go |
本文是兼容性快照,不替代 Swagger。标准接口、Codex 客户端与 OCI 上游均可能 变化,最终行为以当前版本代码、运行时 Swagger 和实测结果为准。