跳转至

OpenAI 聊天补全

Gateway 可以提供一个兼容 OpenAI 的小型 Chat Completions 接口。它默认处于禁用状态。

启用后,它会在与 Gateway 相同的端口(WS + HTTP 多路复用)上提供以下所有接口:

方法 路径
POST /v1/chat/completions
GET /v1/models
GET /v1/models/{id}
POST /v1/embeddings

POST /v1/responses 通过 gateway.http.endpoints.responses.enabled 单独启用。参见 OpenResponses API。

请求以普通 Gateway agent 运行方式执行(与 openclaw agent 相同的代码路径),因此路由、权限和配置都与你的 Gateway 匹配。

启用该端点

{
  gateway: {
    http: {
      endpoints: {
        chatCompletions: { enabled: true },
      },
    },
  },
}

将 enabled 设为 false(或省略该字段)即可禁用。

安全边界(重要)

请将此端点视为对 Gateway 实例的完整 operator 访问权限:

  • 此端点的有效 Gateway token/password 等同于 owner/operator 凭证,而不是狭窄的单用户作用域。
  • 请求会与受信任的 operator 操作走相同的控制平面 agent 路径,因此,如果目标 agent 的策略允许使用敏感工具,此端点也可以使用它们。
  • 请仅将其保留在 loopback/tailnet/私有入口。不要将其暴露到公共互联网。

认证矩阵:

认证路径 行为
gateway.auth.mode="token" 或 "password" + Authorization: Bearer ... 证明调用方拥有共享的 Gateway 机密。忽略任何 x-openclaw-scopes 请求头,并恢复完整的默认 operator 作用域集合:operator.admin、operator.approvals、operator.pairing、operator.read、operator.talk.secrets、operator.write。将聊天轮次视为由 owner 作为发送者发起的轮次。
携带可信身份的 HTTP(trusted-proxy 认证,或在私有入口上使用 gateway.auth.mode="none") 当存在 x-openclaw-scopes 时遵循其中定义的作用域;不存在时回退到默认的 operator 作用域集合。仅当调用方显式收窄作用域并省略 operator.admin 时,才会失去 owner 语义。对于 x-openclaw-model 等 owner 级控制,需要 operator.admin。

参见 Operator scopes、Security 和 Remote access。

认证

使用 Gateway 的认证配置(该模式的详细信息参见 Trusted proxy auth):

模式 认证方式
gateway.auth.mode="token" Authorization: Bearer <token>。通过 gateway.auth.token 或 OPENCLAW_GATEWAY_TOKEN 设置。
gateway.auth.mode="password" Authorization: Bearer <password>。通过 gateway.auth.password 或 OPENCLAW_GATEWAY_PASSWORD 设置。
gateway.auth.mode="trusted-proxy" 通过所配置的身份感知代理进行路由;该代理会注入所需的身份请求头。同主机上的 loopback 代理需要显式设置 gateway.auth.trustedProxy.allowLoopback = true。
gateway.auth.mode="none" 无需认证请求头(仅限私有入口)。

注意:

  • 在 trusted-proxy 网关上绕过代理的同主机调用方,可以直接回退到 gateway.auth.password / OPENCLAW_GATEWAY_PASSWORD。只要存在 Forwarded、X-Forwarded-* 或 X-Real-IP 请求头,请求就会保持在 trusted-proxy 路径上,而不是回退。
  • 如果配置了 gateway.auth.rateLimit,且认证失败次数过多,该端点将返回 429,并附带 Retry-After 请求头。

何时使用此端点

  • 当你的集成只是同一 Gateway 的另一个 operator/client 界面时,请优先使用此端点,而不是添加新的内置 channel。
  • 对于直接连接到远程 Gateway 的原生移动客户端,请优先使用 WebChat 或采用 paired-device bootstrap/device-token 流程的 Gateway Protocol,这样设备就不需要共享的 HTTP token/password。
  • 在集成拥有自己的用户、房间、webhook 投递或出站传输的外部消息网络时,应改为构建 channel 插件。参见 Building plugins。

以 Agent 为先的模型契约

OpenClaw 将 OpenAI 的 model 字段视为 agent 目标,而不是原始的 provider 模型 ID。

model 值 路由到
model 值 路由到
openclaw 已配置的默认代理
openclaw/default 已配置的默认代理(稳定别名;即使真实默认代理 ID 在不同环境之间变化,也可以安全地硬编码)
openclaw/<agentId> 或 openclaw:<agentId> 特定代理
agent:<agentId> 特定代理(兼容性别名)

可选请求头:

请求头 效果
x-openclaw-model: <provider/model-or-bare-id> 覆盖所选代理的后端模型。共享密钥 bearer 调用方可以直接使用;携带身份的调用方(trusted-proxy,或带有 x-openclaw-scopes 的私有无认证入口)需要 operator.admin,否则返回 403 missing scope: operator.admin。
x-openclaw-agent-id: <agentId> 代理选择的兼容性覆盖。
x-openclaw-session-key: <sessionKey> 显式会话路由。如果使用保留的内部命名空间(subagent:、cron:、acp:),会以 400 invalid_request_error 拒绝。
x-openclaw-message-channel: <channel> 为通道感知的提示/策略设置合成入口通道上下文。

/v1/models 列出顶层代理目标(openclaw、openclaw/default、openclaw/<agentId>),而不是后端提供商模型,也不是子代理;子代理保持为内部执行拓扑。如果省略 x-openclaw-model,所选代理将使用其正常配置的模型运行。

模型列表和详情端点需要 operator.read 或包含它的 scope,因为它们会暴露全局代理目标清单。

/v1/embeddings 使用相同的代理目标 model ID。发送 x-openclaw-model(来自共享密钥调用方,或具有 operator.admin 的携带身份调用方)以选择特定的嵌入模型;否则请求将使用所选代理的正常嵌入配置。

会话行为

默认情况下,该端点每次请求无状态(每次调用都会生成新的会话密钥)。

如果请求包含 OpenAI user 字符串,Gateway 会从中派生稳定的会话密钥,以便重复调用可以共享一个代理会话。对于自定义应用,请在每个对话线程中复用相同的 user 值;除非你希望多个对话/设备共享同一个 OpenClaw 会话,否则避免使用账户级标识符。仅当需要在多个客户端/线程之间进行显式路由控制时,才使用 x-openclaw-session-key,并使用由应用拥有的密钥,避免上述保留命名空间。

显式隐身会话延续

使用 x-openclaw-session-key(即 sessionKey 覆盖)显式选择或继续隐身对话,需要有效的 operator.admin 权限。该规则遵循权限,而不是入口:它既拒绝没有 owner/admin 权限的 trusted-proxy 调用方,也拒绝显式将 x-openclaw-scopes 缩小到 admin 以下的私有 gateway.auth.mode="none" 调用方(例如缩小到 operator.write)。两者都会收到带有 forbidden 错误的 HTTP 403。在此路径上,无 profile 的私有无认证调用方会得到 missing scope: operator.admin;对于基于 profile 的调用方,响应会以以下错误格式隐藏私有目标(其中 <sessionKey> 是请求的覆盖值):

{
  "error": {
    "message": "Incognito session \"<sessionKey>\" was not found.",
    "type": "forbidden"
  }
}

Owner/admin 调用方保留显式隐身会话延续。没有 x-openclaw-scopes 的私有无认证请求会获得默认 operator scopes,包括 operator.admin,因此被视为 owner/admin。保留的内部命名空间覆盖(subagent:、cron:、acp:)仍然是单独的验证失败,并返回 HTTP 400 和 invalid_request_error。

请求限制

该端点使用内置限制:每个请求体 20 MB,来自最新用户消息的 8 个 image_url 部分,以及累计 20 MB 的已解码图像数据。图像源策略仍可在 gateway.http.endpoints.chatCompletions.images 下配置:

{
  gateway: {
    http: {
      endpoints: {
        chatCompletions: {
          enabled: true,
          images: {
            allowUrl: false,
            urlAllowlist: ["cdn.example.com", "*.assets.example.com"],
            allowedMimes: [
              "image/jpeg",
              "image/png",
              "image/gif",
              "image/webp",
              "image/heic",
              "image/heif",
            ],
            maxBytes: 10485760,
            maxRedirects: 3,
            timeoutMs: 10000,
          },
        },
      },
    },
  },
}

图像设置默认为:

键 默认值
images.allowUrl false(未启用时,来自 URL 的 image_url 部分会被拒绝)
images.maxBytes 每张图像 10MB
images.maxRedirects 3
images.timeoutMs 10s

接受 HEIC/HEIF image_url 源,并通过共享的 OpenClaw 图像处理器(Rastermill)在交付给提供商之前将其规范化为 JPEG;对于需要外部编解码器支持的格式,它会回退到系统转换器(sips、ImageMagick、GraphicsMagick 或 ffmpeg)。

安全说明:将主机名加入允许列表不会绕过私有/内部 IP 阻止。对于暴露在互联网上的网关,除应用层防护外,还应应用网络出站控制。参见 安全。

聊天工具契约

/v1/chat/completions 支持与常见 OpenAI Chat 客户端兼容的函数工具子集。

支持的请求字段

字段 说明
tools { "type": "function", "function": { ... } } 数组
tool_choice "auto"、"none"、"required" 或 { "type": "function", "function": { "name": "..." } }
messages[*].role: "tool" 后续轮次
messages[*].tool_call_id 将工具结果绑定回先前的工具调用
max_completion_tokens 正的安全整数;每次调用对总 completion token 数(包括推理 token)的上限。当前字段名;当两个字段均非空时使用。为 null 或省略时保持未设置。
max_tokens 正的安全整数;旧版别名。当 max_completion_tokens 非空时仍会验证,然后因优先级而被忽略。为 null 或省略时保持未设置。
temperature 0-2 的数字;尽力而为,转发给上游提供商。超出范围时返回 400 invalid_request_error。
top_p 0-1 的数字;尽力而为。超出范围时返回 400 invalid_request_error。
frequency_penalty -2.0 到 2.0 的数字;尽力而为。超出范围时返回 400 invalid_request_error。
presence_penalty -2.0 到 2.0 的数字;尽力而为。超出范围时返回 400 invalid_request_error。
seed 整数;尽力而为。非整数值返回 400 invalid_request_error。
stop 字符串或最多 4 个字符串的数组;尽力而为。超过 4 个序列或包含非字符串/空条目时返回 400 invalid_request_error。

所有采样和 token 上限字段都通过同一个代理流参数通道传输,并尽力转发:

  • token 上限:传输字段名由提供商传输层选择:OpenAI 系端点使用 max_completion_tokens,仅接受旧版名称的提供商(Mistral、Chutes)使用 max_tokens。
  • stop 映射到传输层的停止字段:Chat Completions 后端使用 stop,Anthropic 使用 stop_sequences。OpenAI Responses API 没有 stop 参数,因此在基于 Responses 的模型上不会应用 stop。
  • 基于 ChatGPT 的 Codex Responses 后端使用固定的服务器端采样,并在请求到达该后端之前移除 temperature/top_p(以及 max_output_tokens、metadata、prompt_cache_retention、service_tier)。

不支持的变体

以下情况返回 400 invalid_request_error:

  • 非数组的 tools、非 function 工具条目,或缺少 tool.function.name
  • tool_choice 变体,例如 allowed_tools 和 custom
  • 与所提供工具不匹配的 tool_choice.function.name 值

对于 tool_choice: "required" 和固定函数的 tool_choice,端点会缩小暴露的客户端函数工具集,指示运行时在响应前调用客户端工具,并在代理响应中没有匹配的客户端工具结构化调用时返回错误。这适用于调用方提供的 HTTP tools 列表,而不是每个内部 OpenClaw 代理工具。

非流式工具响应结构

当代理调用工具时,响应使用:

  • choices[0].finish_reason = "tool_calls"
  • 带有 id、type: "function"、function.name、function.arguments(JSON 字符串)的 choices[0].message.tool_calls[] 条目
  • 工具调用前的助手评论,位于 choices[0].message.content(可能为空)

流式工具响应结构

当 stream: true 时,工具调用会以增量 SSE 块到达:一个初始 assistant 角色增量、可选的 assistant 评论增量、一个或多个携带工具标识和参数片段的 delta.tool_calls 块,然后是一个带有 finish_reason: "tool_calls" 和 data: [DONE] 的最终块。

对于必需或固定到函数的工具选择,文本会被暂缓,直到匹配调用被确认。当运行返回最终文本时,流会使用该文本,而不是临时增量。

如果 stream_options.include_usage=true,会在 [DONE] 之前发出一个尾随 usage 块。

工具后续循环

收到 tool_calls 后,执行请求的函数,并发送一个后续请求,其中包含之前的 assistant 工具调用消息,以及一个或多个带有匹配 tool_call_id 的 role: "tool" 消息。这会继续同一个 agent 推理循环以生成最终答案。

如果工具没有产生文本,仍应使用 content: "" 或空文本部分数组包含其结果。空结果会完成该调用;省略结果则不会。旧版 role: "function" 结果可以与其函数 name 一起使用 content: null。

流式(SSE)

流式会保留来自不同 assistant 消息的重复内容。如果某个更正无法通过追加到已发送文本来表示,流会报告错误,而不是以不一致的内容完成。

设置 stream: true 以接收服务器发送事件(SSE):

  • Content-Type: text/event-stream
  • 每个事件行是 data: <json>
  • 流以 data: [DONE] 结束

失败的 agent 运行(包括整个 agent 超时)会返回错误,而不是成功完成。流式失败会发出一个 error 对象,随后是 [DONE];部分内容可能已经到达客户端。超时设置遵循 代理循环。

断开 HTTP 客户端会取消正在进行的 source-URL 下载和 agent 运行。如果取消发生在准备输入期间,Gateway 会释放该下载,并且不会启动另一个输入下载或 agent 运行。这适用于流式和非流式请求。

Open WebUI 快速设置

  • 基础 URL:http://127.0.0.1:18789/v1
  • macOS 上 Docker 的基础 URL:http://host.docker.internal:18789/v1
  • API 密钥:你的 Gateway bearer token
  • 模型:openclaw/default

预期行为:GET /v1/models 会列出 openclaw/default,Open WebUI 会将其用作聊天模型 id。对于特定的后端提供商/模型,请设置 agent 的常规默认模型,或发送 x-openclaw-model(共享密钥调用方,或具有 operator.admin 的携带身份调用方)。

快速冒烟测试:

curl -sS http://127.0.0.1:18789/v1/models \
  -H 'Authorization: Bearer YOUR_TOKEN'

如果返回 openclaw/default,大多数 Open WebUI 配置可以使用相同的基础 URL 和 token 连接。

示例

为单个应用会话保持稳定会话:

curl -sS http://127.0.0.1:18789/v1/chat/completions \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "openclaw/default",
    "user": "conv:YOUR_CONVERSATION_ID",
    "messages": [{"role":"user","content":"Summarize my tasks for today"}]
  }'

在该会话的后续调用中复用相同的 user 值,以继续同一个 agent 会话。

非流式:

curl -sS http://127.0.0.1:18789/v1/chat/completions \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "openclaw/default",
    "messages": [{"role":"user","content":"hi"}]
  }'

流式:

curl -N http://127.0.0.1:18789/v1/chat/completions \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'x-openclaw-model: openai/gpt-5.4' \
  -d '{
    "model": "openclaw/research",
    "stream": true,
    "messages": [{"role":"user","content":"hi"}]
  }'

列出模型:

curl -sS http://127.0.0.1:18789/v1/models \
  -H 'Authorization: Bearer YOUR_TOKEN'

获取单个模型:

curl -sS http://127.0.0.1:18789/v1/models/openclaw%2Fdefault \
  -H 'Authorization: Bearer YOUR_TOKEN'

创建嵌入:

curl -sS http://127.0.0.1:18789/v1/embeddings \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'x-openclaw-model: openai/text-embedding-3-small' \
  -d '{
    "model": "openclaw/default",
    "input": ["alpha", "beta"]
  }'

/v1/embeddings 支持将 input 作为字符串或字符串数组。

提供商故障使用与 chat completions 相同的错误映射:缺少提供商凭据会返回 401 authentication_error 并附带设置指导,未知的提供商模型会返回 404 invalid_request_error,提供商过载会返回 503 api_error。凭据值会被脱敏。意外故障会返回 500 api_error 并带有 internal error。

对于支持的模型,正整数 dimensions 用于请求输出向量大小。它会覆盖所选 agent 当前生效的 memory.search.outputDimensionality,并且在禁用记忆搜索时也会生效。省略它会保留已配置或提供商默认大小。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw