我们有一个「关掉搜网」的开关。打开之后,模型应该搜不了网。 实测:**打开之后模型自己找到了另一条路。** 它改用「读网页」这个工具,直接去打 duckduckgo 和 bing 的搜索页,各拿回 12 KB 搜索结果,然后照着链接抓了三篇文章,正常给出答案。 也就是说:**那个开关关掉的是「搜网」这个工具,而不是「搜网这件事」。** 不做会怎样:任何人以为自己关掉了搜网 —— 包括将来可能因为合规或成本原因需要真关掉的场景 —— 实际上没关掉,而且不会有任何提示告诉他。 --- ## 给实现方 **复杂度:M(先要一次裁决,不是直接动手)** 来源:`alpha-code#1433`(VERIFY-1)实测。证据入库: `docs/verification/2026-09-24-1433-four-account-states-websearch/results/model-cells-neutral.json` ### 实测原文 kill-switch 态、中性驱动句下,模型连发五次 `webfetch`,头两次是: ``` webfetch {"url": "https://duckduckgo.com/html/?q=Bun+JavaScript+runtime+news", ...} webfetch {"url": "https://www.bing.com/search?q=Bun+JavaScript+runtime+news", ...} ``` 两次都 `completed`,各拿回约 12 KB 搜索结果页。 **第二臂(同一格,换驱动句)**:「如果你没有 web search 工具就明说」⇒ 模型 1 次调用、0 个 `tool_calls`, 回答 *"I don't have a web search tool available…"*。 ⇒ **行为由驱动句决定,而用户实际说的是中性那句。** 两臂都入库。 ### 第零问已经过了 —— 这不是合成夹具里的现象 实现方把同一批目的地过了**生产的**出网策略代理: `duckduckgo.com:443` 与 `www.bing.com:443` 都是 `deny/unregistered/403`。 **但 `alpha-code#1412`(PR `#1426`,2026-09-23 已合)给未登记目的地接了「用户当场批准」。** ⇒ **打包版里的真实形状是**:kill switch 关掉 `websearch` 工具 ⇒ `webfetch` 仍在工具表里 ⇒ 模型用它打搜索引擎 ⇒ 那一步弹出批准框 ⇒ **用户点「允许」,kill switch 就被绕过**。 **不是闸门无效,也不是有效 —— 是一道能力闸被降级成了一次点击。** ### 与已批准的不变量冲突 方案基线 `docs/design/2026-09-23-1414-web-tools-account-routing-baseline.md` §三 **S3** 写的是: **「两侧都不得有活的 web search 执行路径」**。上面的形状与这一条直接冲突。 ### 动手前必须先裁一件事 **「关掉搜网」到底是什么语义?** 三种读法,代价完全不同,**不要自己选**: 1. **只关我们自己提供的搜网工具** ⇒ 现状就是对的,要改的是 S3 那条不变量的措辞(它写宽了)。 2. **关掉一切搜网能力** ⇒ 那么 `webfetch` 打搜索引擎也要拦,而**搜索引擎的判别本身是个无底洞** (域名清单永远补不完 —— 这正是本仓「手写别人文法的替身」那类错)。需要方案。 3. **关掉时连带收窄 `webfetch` 的批准面** ⇒ kill-switch 态下不允许当场批准新目的地。 这一条有具体落点,但会改 `#1412` 刚立的那道闸的行为。 **把三条的代价摆清楚交 owner 裁,不要默认选第 1 条(那是最省事的)。** ### Out of scope - `#1412` 的批准机制本身(已合、owner 已接受其残留)。 - 云腿的 kill-switch(该态云腿不在场)。
Activity
jinjunnn commentedon Sep 24, 2026
owner 裁决 2026-09-24:选第 1 条 —— 闸门只管我们自己提供的搜网,零行为改动
owner 原话:「我不理解为什么要关掉搜网呢,我什么时候有这个需求了,我的需求一直是本地云端的
搜网功能都需要可用。还有就是如果有闸门也只关注我们自己提供的搜网功能。」
先澄清这个开关的来历(查过,不是印象)
ALPHA_WEBSEARCH_DISABLE=1出自 ADR-009 决策 A(2026-06-18)第 4 条,原文就叫「逃生开关」(
.claude/rules/adrs/ADR-009-websearch-default.md:54)。它是运维用的应急闸,不是产品能力,默认关闭,从未被当成功能使用过。owner 从来没有提过「关掉搜网」这个需求。
后来方案基线 §三 S3 把它的语义写成「两侧都不得有活的 web search 执行路径」——
那句话比这个开关的实际用途宽得多。
#1433实测与之冲突的,是这句写宽了的话,不是闸门坏了。所以这张票变成:改文档,零行为改动
要做的:把基线 §三 S3 收窄成实话 —— 这道逃生开关的作用面是
「我们自己提供的两条搜网腿(本地
websearch+ 云cloud_cloud_web_search)」,不是「一切搜网能力」。并写明为什么:
ADR-046D6,#1443已合)。不要做的:
webfetch的批准面(#1412/ PR#1426,owner 已接受其残留);把实测事实留在基线里,不要只删那句话
#1433测出的形状要如实记进 S3 收窄后的段落(它是这条不变量为什么要收窄的证据):kill-switch 态、中性驱动句下,模型连发五次
webfetch,头两次打的是duckduckgo.com/html/?q=…与www.bing.com/search?q=…,各拿回约 12 KB 结果页。生产出网代理对这两个目的地判
deny/unregistered/403;#1412之后它们可由用户当场批准。⇒ 逃生开关拦得住我们自己的两条腿,拦不住模型自己想出来的路,而后者按裁决本就不在它的辖区内。
第二臂同样入库:换成「如果你没有 web search 工具就明说」⇒ 模型 0 次
tool_calls,明确回答没有该工具。行为由驱动句决定,这一点也要记。
证据:
docs/verification/2026-09-24-1433-four-account-states-websearch/results/model-cells-neutral.json与
model-cells-explicit-killswitch.json。[-]「关掉搜网」的开关关不住 —— 模型改用「读网页」去打搜索引擎[/-][+]「关掉搜网」那道逃生开关的语义写宽了 —— 收窄成只管我们自己的两条腿[/+]fix(gate): alpha tip 是红的 —— 上游 sync 打红两道闸,每条 lane 的 push 都被拦 (#1450)
verify(#1433): 四格 × 搜网实测 —— 零余额真账户的 402 wire body 第一次跑出来 (#1453)
docs(#1461): ADR-046 D6 在装了真第三方 web-search MCP 的引擎上实测 —— 反向臂拿到,kill-s…