Sidecar:Web Search 与 Vision
不同路由模型对托管 Web Search 和原生图像输入的支持并不相同。opencodex 通过两个
sidecar 补齐这些能力;它们可以使用 ChatGPT 登录(forward)provider,也可以使用已存储的
Anthropic OAuth provider。Sidecar 错误会转换成长度受限的工具结果或图像提示,不会让整个 turn
失败。
Web-search sidecar
Section titled “Web-search sidecar”当 Codex 为非透传的路由模型请求托管 web_search 时,opencodex 会:
- 移除托管的
web_search工具,改为向路由模型提供一个合成的web_search(query)function 工具。原托管工具的选项会保留并用于 sidecar 调用。 - 让路由模型在一个小型 agentic 循环中运行。模型调用
web_search时,opencodex 使用所选 后端:OpenAI 默认以gpt-5.6-luna运行托管web_search;Anthropic 默认以claude-sonnet-5运行web_search_20250305。Streaming 答案及引用会解析为工具结果。 - 循环直到模型回答,或真实查询总数达到
maxSearchesPerTurn(默认 3)。达到上限后会移除 search 工具并强制生成最终答案。如果模型调用apply_patch或 shell 等真实客户端工具,当前 turn 会结束,以便这些调用到达 Codex。
路由模型的每次迭代都会向上游请求 stream: true,但 opencodex 会在决定搜索还是返回最终答案前,
在内部完整缓冲所有语义 event。只有第一次迭代的最终 header/status 和 429 key rotation 会被提前
取得。因此,合成搜索调用和中间输出不会作为模型输出暴露给客户端。
注入结果会包裹在不可信数据边界中,限制长度,并按来源 URL 去重。在结构化输出 turn
(json_schema / json_object)中,结果会以紧凑 JSON 而不是普通文本传入。若路由模型是纯文本
模型,search 模型还会收到指令,用文字描述相关图像并附上来源 URL。
{ "webSearchSidecar": { "enabled": true, "backend": "anthropic", "model": "claude-sonnet-5", "reasoning": "low", "maxSearchesPerTurn": 3, "routedModelStallTimeoutMs": 200000, "timeoutMs": 200000 }}托管后端不允许在 minimal reasoning 下使用工具,因此默认值为 low。搜索失败时,路由模型会
收到长度受限的错误结果,仍可依据已有上下文继续回答。
此路径采用四个相互独立的时钟。stallTimeoutSec 是基础 bridge event-stall 预算。
connectTimeoutMs(默认 200000)只限制 DNS/TCP/TLS 和最终响应 header。仅可在配置文件中
设置的 webSearchSidecar.routedModelStallTimeoutMs(默认 200000,整数
1..2147483647)限制每次路由模型迭代中原始响应 byte 连续无活动的时间,并在收到每个非空 byte
时重置。webSearchSidecar.timeoutMs 独立限制单次托管搜索请求。实际 bridge watchdog 为
max(基础 stall, connect timeout, 路由模型 stall, sidecar timeout) + 30 秒。路由模型 stall
不是总生成 timeout。SSE 开始前的失败会返回非 2xx JSON;响应 header 开始后发生的生成失败则以
response.failed SSE 传递。
Vision sidecar
Section titled “Vision sidecar”当路由模型列在其 provider 的 noVisionModels 中,并且请求包含图像时,opencodex 会在主调用
之前描述每张图像,并用文字替换图像。Dashboard 和管理 API 当前显示的默认值是
gpt-5.6-luna,启动时也会把明确保存的旧 gpt-5.4-mini 值迁移到 Luna。只有在
visionSidecar.model 字段完全不存在时,vision 执行路径才会使用代码中的 gpt-5.4-mini 回退值。
- 图像可以来自 user、developer 和 tool-result message,也包括 Codex 的
view_image结果。 - 每张图像会以
reasoning.effort: "low"发送给配置的原生 vision 模型,描述结果会就地替换 图像部分。 - 描述任务最多同时处理 3 张图像,并保持输入顺序。发送给描述模型的用户上下文最多 800 个字符,
每张图像注入的描述最多 2,000 个字符。请求不会发送 ChatGPT 后端不支持的
max_output_tokens。 - 图像 URL 会在转发前校验。data URL 必须是
png/jpeg/jpg/webp/gif,base64 数据限制在约 20 MB;只接受data:和https:scheme。远程https图像由 OpenAI 后端获取, 而不是代理。 noVisionModels匹配会忽略 Ollama 风格的:size后缀,因此一个gpt-oss条目也能覆盖gpt-oss:120b。- 如果描述失败,模型会收到简短的处理错误提示。若根本无法建立 sidecar plan,原始图像会被 移除,而不会继续转发给纯文本后端。
maxDescriptionsPerTurn(默认 8)限制每个主模型 turn 的新增描述次数。缓存命中和同一 turn 的重复请求不会消耗配额。成功的data:图像描述会按后端、模型、detail、图像字节和消息上下文 缓存;内容可变的https:图像不会缓存。
{ "visionSidecar": { "enabled": true, "backend": "anthropic", "model": "claude-sonnet-5", "maxDescriptionsPerTurn": 8, "timeoutMs": 45000 }}纯文本模型按 provider 标记:
{ "providers": { "ollama-cloud": { "adapter": "openai-chat", "baseUrl": "https://ollama.com/v1", "noVisionModels": ["glm-5.2", "gpt-oss", "qwen3-coder", "deepseek-v4-pro"] } }}仪表盘设置与禁用
Section titled “仪表盘设置与禁用”配置文件字段现在即可使用。如需禁用某个 sidecar,请在 config.json 中把对应的 enabled 设为
false。Anthropic OAuth 搜索和图像描述沿用现有 Claude Code OAuth fingerprint 先例,但仍应使用
目标账户和实际负载充分 soak test。所有字段见
配置参考。

