26 KiB
Note
网关集中处理密钥鉴权、模型访问控制、渠道调度与协议适配。路径、参数和 响应结构以 Swagger YAML 或运行时 Swagger UI 为准;协议差异、 兼容改写和实测边界以本文为准。
| 文档属性 | 当前值 |
|---|---|
| 兼容快照 | 2026-07-16 |
| API 基址 | /ai/v1 |
| 首选对话协议 | OpenAI Responses |
| 会话模式 | 无状态,客户端携带完整上下文 |
快速接入
基础地址与鉴权
网关密钥在管理面板中创建。连接信息如下:
| 项目 | 配置 |
|---|---|
| Base URL | https://<网关地址>/ai/v1 |
| Bearer 鉴权 | Authorization: Bearer sk-... |
| API Key 鉴权 | x-api-key: sk-... |
密钥可绑定渠道分组和模型白名单。全局模型黑名单会同时作用于模型列表、 请求路由和探测候选;开启「过滤弃用模型」后,OCI 已宣布弃用的模型也会从 列表与路由中移除。
可先用模型列表验证地址与密钥:
curl "https://<网关地址>/ai/v1/models" \
-H "Authorization: Bearer $OCI_PORTAL_KEY"
再发起一条最小 Responses 请求;请将示例模型替换为模型列表中的可见模型:
curl "https://<网关地址>/ai/v1/responses" \
-H "Authorization: Bearer $OCI_PORTAL_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"xai.grok-4.3","input":"你好,请用一句话介绍自己。"}'
端点一览
| 协议域 | 端点 | 角色 | 流式 |
|---|---|---|---|
| 对话 | 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 |
| 向量、语音、重排与安全审核 | 对应专用端点 |
路由与全局行为
请求链路
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 |
可配置运行策略
| 策略 | 默认行为 | 配置入口 |
|---|---|---|
| Responses 流式保险丝 | 开启;阈值 60 KB,按 instructions 与 tools 两个字段的原始 JSON 值计算 |
设置 → AI → 流式保险丝 |
| Grok 服务端搜索 | 对 xai. 模型默认注入 web_search 与 x_search;同名工具不重复覆盖 |
设置 → AI → Grok 服务端搜索工具 |
| 弃用模型过滤 | 开启后从模型列表、请求路由与探测候选中统一排除 | 设置 → AI → 模型治理 |
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。
已知限制
instructions / tools 大体量流式断流
Warning
instructions与tools两个字段的原始 JSON 值合计超过约 64.5 KB 时, 上游流式请求可能在推理阶段静默断连:连接直接 EOF,不发送error或终态事件。 同一请求改为非流式实测可正常完成;单独扩大input未触发该限制。
该问题于 2026-07-13 通过字节级二分定位,2026-07-16 在 Chicago 复测仍存在:
70.4 KB 断流、59.7 KB 正常,API Key 与签名鉴权表现一致。本文及设置页中的
KB 均按 1024 B 计算。
| 协议 | 网关保护 | 客户端表现 |
|---|---|---|
| Responses | 保险丝默认开启;超过 60 KB 时改走非流式上游,并合成最小 SSE 序列 |
结果语义保留,但不再增量输出 |
| Chat Completions / Messages | 客户端尚未收到内容就断流时,自动改用非流式重做 | 合成对应 chunk / event 序列 |
| 已开始输出的流 | 无法透明重试;调用日志记录提前终止 | 客户端可能只收到部分事件 |
Responses 合成的最小事件序列为:response.created →
response.output_item.done → response.completed。保险丝可在
设置 → AI → 流式保险丝 调整或关闭。
历史问题:完整请求体体积断流(已由上游修复)
2026-07-15 曾在完整请求体约 82 KB(含 input)时观测到纯体积流式断流。
2026-07-16 复核 83 KB、真实 Codex 形态 104.5 KB、200 KB 与 400 KB
请求均正常完成;Chicago 与 Phoenix、签名与 API Key 两条路径结果一致。
multi-agent 加密推理内容流式断流
Warning
当
multi-agent请求同时启用stream: true与include: ["reasoning.encrypted_content"]时,上游可能在序列化大体量encrypted_content事件期间静默断开连接,且不返回error或终态事件。已复现场景中的断点位于
output_index: 8附近:第三次搜索结束后,上游准备 发送较大的加密推理块时连接被中止。multi-agent产生的加密推理内容体积较大, 因而更容易暴露该上游流式序列化缺陷。
ZDR 与文件输入
Responses 的 input_file 内容块(file_url / file_data)实测会被上游拒绝:
File content is currently unsupported for ZDR customers
网关强制 store:false,属于 ZDR 请求形态,因此当前不能通过该端点上传或引用文件。
字段兼容矩阵
Important
本项目提供兼容接口,而不是 OpenAI、Anthropic 或 xAI 协议的完整实现。部分 OCI OpenAI 兼容行为来自实测,未见 Oracle 文档合同,可能随上游调整。
矩阵索引
Responses · Chat Completions · Messages · Embeddings · 语音生成 · Rerank · Moderations · Models
展开参考规格
| 标记 | 含义 |
|---|---|
| ✅ | 网关直接支持 |
| ➡️ | 原样保留或透传;是否生效由 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 的原始 JSON 值合计超过保险丝阈值时,预防性改走非流式上游(默认开启、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 和实测结果为准。