Repository navigation
Conversation
…WebSearch 走 CC 自带的 /alpha/web-search
Anthropic 的 `web_search_20250305` 是服务端工具,由 Anthropic 的 API 服务器执行;经 CC 上游时链路里
没有人执行它。现有实现按普通工具映射(`t.input_schema || {}`),模型拿到的是一个无描述、空参数的
function tool——要么不用,要么瞎调后客户端找不到处理器。Claude Code 的 WebSearch 是客户端工具,执行时
会另起一个约 1K token 的子请求、在子请求里带这个服务端工具——坏的正是这个子请求。
- feat: 新增开关 `CC_WEB_SEARCH=1`。默认关闭,此时服务端工具(`web_search_20250305` / `web_fetch_20250910`)被剥掉,不再变成坏工具
- feat: `convertAnthropicToOpenAI` 识别服务端工具类型;开启时把 `web_search` 改写成带真实 schema 的 function tool,`max_uses` / `allowed_domains` / `blocked_domains` 记入 `openaiReq._serverTools`
- feat: 新增 `executeWebSearch`:POST CC 的 `/alpha/web-search`(官方 CLI 内置搜索的同一端点、同一把 key,请求头与 `forwardToCC` 一致);经 `upstreamFetch` 发出,配置了 `CC_UPSTREAM_PROXY`(MAXeaglet#18)时同样走代理;剥掉 DDG 赞助结果并多要 3 条补位;域名白/黑名单按 hostname 过滤;错误码对齐 Anthropic(`too_many_requests` / `invalid_input` / `unavailable`);超时 `CC_WEB_SEARCH_TIMEOUT_MS`(默认 8s)
- feat: `createAnthropicSseTranslator` 把 `web_search` 的 tool-call 改发 `server_tool_use` 块(不当客户端 `tool_use` 下发)并登记 `ctx.pendingSearches`;有待执行搜索时 finalize 早退不发终结事件,usage 累进 `ctx.usageCarry`;块索引跨翻译器实例接续
- feat: `handleMessages` 流式路径改为搜索循环:执行搜索 → 发 `web_search_tool_result` 块 → 以 `tool_calls` + `tool` 消息追加历史(含本轮 reasoning,CC 在 thinking 模式下校验其随历史带回)→ 重建 `ccBody` 重发上游 → 模型续写;最终 `message_delta` 汇总各轮 usage 并补 `server_tool_use.web_search_requests`
- feat: `max_uses` 语义:超额返回 `web_search_tool_result_error: max_uses_exceeded`,并把该工具移出定义让模型用文本收尾(CC 的 `tool_choice` 只有 auto / any / tool,没有 none——真机 400 验证);模型连续两轮仍调则本地补终结事件,流一定有 `message_stop`
- feat: 历史回放支持 `server_tool_use` / `web_search_tool_result`(含 error 形态):一条 Anthropic assistant 消息拆成 `assistant{tool_calls}` → `tool{result}` → `assistant{text}`,`encrypted_content` 解回摘要
- fix: 非流式 `/v1/messages` 不走循环,服务端工具退回剥掉(Claude Code 只走流式)
- test: 新增 `test/web-search.test.mjs` 11 条(mock 上游,不需要真 key):完整循环与事件序列、块索引唯一递增、两轮 usage 汇总、上游第 2 轮请求形状、开关关闭 / 非流式剥掉、普通工具不误拦不循环、`max_uses` 超额与工具移除、失控封顶、搜索端点 5xx、并行双调用两例、两种历史回放;全量 33 条通过
- docs: README / README_zh 补充 `webSearch` / `CC_WEB_SEARCH` / `CC_WEB_SEARCH_TIMEOUT_MS` 与「Web search」小节
- chore: 启动日志增加 `webSearch` 状态行
真机验证:Go 档 key 直打 proxy,模型一轮并行搜索 2 次 → 额度用完工具被移除 → 作答并引用来源 →
`web_search_requests: 2` → `message_stop`,第 2 轮命中 prompt cache;Claude Code 端到端原生渲染
`Web Search(...) / Did 1 search`。
未实现:citations(模型不产出结构化引用)、`web_fetch_20250910`(一律剥掉)。
另:`convertAnthropicToOpenAI` 里既有的 Anthropic `tool_choice: {type:"none"}` → OpenAI `"none"` → CC `{type:"none"}`
映射同样会被 CC 拒绝,属既有问题,另开 issue。
atogumo
force-pushed
the
feat/web-search
branch
from
September 19, 2026 01:08
0037e93 to
59c7289
Compare
… + 释放 respReq 内存 (MAXeaglet#31) 从上游 MAXeaglet/commandcode-proxy@40b338e 挑入。CC 上游的 tool_choice 枚举只有 auto / any / tool,原样下发 { type: 'none' } 会被 400 拒绝;改为下发空 tools 列表且不带 tool_choice,等价于「本轮禁用工具」。同时在 /v1/responses 路径里 及时释放 respReq。 上游的回归测试写在 test/wire.test.mjs,本分支没有该文件,改放到 test/tool-choice-none.test.mjs,用本分支的 helpers 跑同样的两条断言。
带入上游 10 月的修复:finish 原因归一化(a474cbc)、/v1/responses 零输出 不再谎报 completed(aa4a3c1)、chat 路径的上游闪断透明重试(ce5a217、 639fc6e)、Codex 工具截图与用户图片的线格修正(2eccdbf、7f6bf21、8c45a05), 以及 MAXeaglet#47 的 tool_choice: none 处理(40b338e,此前已挑入)。 冲突一处:/v1/messages 入口上游把 anthropicReq / openaiReq 提前置空回收 内存,本分支的搜索循环要复用这棵树,流式路径后面也仍引用 openaiReq._serverTools,保留本分支版本;chat / responses 路径的提前回收照常 合入。README 功能行取上游版本并保留搜索一项。 上游 wire 测试已含 MAXeaglet#47 两条用例,删除本分支临时补的 test/tool-choice-none.test.mjs。合并后全套 158 条测试通过,web search 的 11 条原样通过。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
Anthropic 的
web_search_20250305是服务端工具,由 Anthropic 的 API 执行;经 CC 上游时没有人执行它。现有实现按普通工具映射(t.input_schema || {}),模型拿到的是一个无描述、空参数的 function tool——要么不用,要么调了之后客户端找不到处理器。Claude Code 的 WebSearch 正是通过这个工具类型实现的,因此在本代理后面不可用。改动
新增开关
CC_WEB_SEARCH=1,开启后由代理执行该工具,调 CC 自带的/alpha/web-search(官方 CLI 内置搜索用的同一端点、同一把 key):模型发出 web_search{query} → 代理 POST /alpha/web-search → 以 server_tool_use + web_search_tool_result 块回给客户端
→ 调用/结果对追加进历史、重发上游 → 模型在同一条消息里续写
server_tool_use/input_json_delta/web_search_tool_result(含 error 形态)/usage.server_tool_use.web_search_requests;Claude Code 按原生Web Search(...)渲染max_uses:超额返回max_uses_exceeded,并将该工具移出后续轮次的定义(CC 的tool_choice只有auto/any/tool,没有none);模型仍连续调用则本地收尾,保证message_stop一定发出server_tool_use/web_search_tool_result块拆成assistant{tool_calls}→tool→assistant{text}allowed_domains/blocked_domains按 hostname 生效;单次超时CC_WEB_SEARCH_TIMEOUT_MS(默认 8s)upstreamFetch发出,配置了CC_UPSTREAM_PROXY(feat: 支持为上游请求配置 HTTP(S) 代理(ProxyAgent / 环境变量) #18) 时与 generate 一样走代理默认行为变化
开关默认关闭。关闭时唯一的变化:Anthropic 服务端工具(
web_search_20250305/web_fetch_20250910)被剥掉,而不是压成坏工具转发。其余路径输出不变,既有 22 条测试未改全过。
范围
/v1/messages流式;非流式仍剥掉服务端工具/v1/chat/completions、/v1/responses、buildCcRequest、forwardToCC未动citations、web_fetch_20250910(Claude Code 的 Fetch 在客户端执行,不依赖它)测试
test/web-search.test.mjs11 条,mock 上游、不需要真 key:完整循环与事件序列、块索引唯一递增、多轮 usage 汇总、上游第 2 轮请求形状、开关关闭 / 非流式剥掉、普通工具不误拦、
max_uses超额与工具移除、失控封顶、搜索端点 5xx、并行双调用、历史回放。全量 33 条通过。
多次全量运行中偶见一条既有用例(
/v1/responses路径,本 PR 未触碰)时序抖动失败,单独复跑即过;新增测试抬高了并行进程数,CI 若偶发可重跑。
验证
真机(Go 档 key):模型一轮并行搜索 2 次 → 额度用完工具移除 → 作答引用来源 →
web_search_requests: 2→message_stop;Claude Code 端到端原生渲染
Web Search(...) / Did 1 search。改动:
proxy.mjs+378/−37,test/web-search.test.mjs+375,README / README_zh 补充配置项与「Web search」小节。