<!-- title: 强制即乱调：工具触发四栈实测 -->

# 强制即乱调：工具触发四栈实测

把一个智能体接上十几个工具，跑一遍，它调得又快又准——于是你认为"工具使用能力没问题"。这是当下最普遍的误判。第四轮把放大镜对准工具使用最薄的一层：**触发判断**——"这一步到底该不该调、调哪个"。在 OpenAI、Anthropic Claude、Google Gemini、Microsoft Semantic Kernel 四套栈上跑同一组门控探针，结论很反直觉：单次表现（pass@1）几乎全栈漂亮，可一旦把口径从"做对一次"换成"连做八次都对"（pass⁸），连 GPT-4o 在 τ-bench 零售域的成功率都跌到 25% 以下；而当你为了"保证它调"把 `tool_choice` 拧到 `required`，无关查询上立刻冒出幻觉调用。**能力是有的，触发是脆的**——这才是工具使用落地时真正的裂缝。

## 四栈触发控制对比

| 维度 | OpenAI (Responses/Agents) | Anthropic Claude | Google Gemini | Microsoft Semantic Kernel |
|------|---------------------------|------------------|---------------|----------------------------|
| 触发枚举 | `auto` / `none` / `required` / 指定函数 | `auto` / `any` / `tool` / `none` | `AUTO` / `ANY` / `NONE` + `allowed_function_names` | `Auto()` / `None()` / `Required()` |
| 强制单工具 | `{type:function,name:"f"}` | `{type:tool,name:"f"}` | `allowed_function_names:["f"]` | `Required("f")` |
| 无关查询(auto) | 多数拒绝，偶发幻觉 | 相对克制 | 偶发误调 | 取决于底层模型 |
| `required` 副作用 | 冗余/强行调用 | 同样强行调 | `ANY` 下强行调 | 已知过度调用（#2879） |
| pass@1 表象 | 优秀 | 优秀 | 优秀 | 优秀 |
| pass⁸ 可靠性 | 显著坍塌（零售域 <25%） | 同源脆弱 | 同源脆弱 | 同源脆弱 |
| 强制粒度可调 | ✅ 函数级 | ✅ 函数级 | ✅ 白名单级 | ⚠️ 行为级 |

## 一、触发的三态语义：auto / none / required 不是开关而是策略

很多人把 `tool_choice` 当成"开/关工具"的二值开关，这是第一个坑。四栈其实都在表达同一个三态策略，只是命名不同：**auto**（由模型决定调不调）、**none`/`NONE`**（禁止调用，纯文本应答）、**required`/`any`/`ANY`**（强制必须调用至少一个）。真正的工程含义是"把触发决策权交给谁"：auto 把判断权交给模型，required 把判断权从模型手里夺走，none 则是"我比你更清楚这步不需要工具"。

关键在于，这三个状态之间不是平滑过渡，而是断崖。auto 下模型会权衡"调工具值不值得"，required 下它**不再判断该不该，只判断调哪个**——这正是后续所有"乱调"的根源。`none` 则经常被忽视：在纯聊天、确认、闲聊轮次里设 `none`，能显著降低误触发率和 token 成本，但四栈里没有一栈默认这么做。理解三态的工程价值是：触发策略应当**逐轮显式设置**，而不是全程 `auto` 挂着。

## 二、强制即乱调：`required` 是幻觉调用的发动机

这是本轮最实锤的发现。把 `tool_choice` 设成 `required`，意图是"确保模型走工具路径别偷懒"。但实测里，当查询与所有工具都无关时（典型："你好"、"今天真热"），`required` 仍会逼模型吐出一个工具调用——它会把无关输入硬塞进某个工具的参数槽，造出**幻觉调用**。这不是模型 bug，是契约要求：`required` 的语义就是"必须返回一个 tool call"，模型在"必须调"的约束下只能瞎调。

OpenAI 社区和 Microsoft agent-framework 的 issue #2879（"Excessive tool calls with tool_choice=required"）把这件事定性得很清楚——这是规范内的预期行为。BFCL（Berkeley 函数调用榜单）专门设了 **irrelevance detection** 类目，就是测模型在"无合适工具可用时是否拒绝调用"，这一项恰恰是各模型在强制态下崩得最厉害的地方。结论很直接：**`required` 只能用在"我已经判定该调，只待模型填参"的场景**，不能当成"提高调用率"的万灵药。拿它当兜底，等于在系统里埋了一台幻觉发生器。

```python
# OpenAI Agents SDK：强制调用的"正确姿势"——先判定，再强制
from agents import Agent, ModelSettings

# ❌ 全程强制：无关查询也会被硬塞进工具
agent_bad = Agent(model="gpt-4o", tools=[search, refund],
                  model_settings=ModelSettings(tool_choice="required"))

# ✅ 让模型自主判断该不该调；只在已知要调的子流程里局部强制
agent_good = Agent(model="gpt-4o", tools=[search, refund],
                   model_settings=ModelSettings(tool_choice="auto"))  # 默认 auto
# 局部强制：在已经走完意图识别、确认要退货的子 agent 里
refund_agent = Agent(model="gpt-4o", tools=[refund],
                     model_settings=ModelSettings(
                         tool_choice={"type": "function", "function": {"name": "refund"}}))
```

## 三、auto 即漏调：边界查询上"该调没调"

和"乱调"对称的另一极是**漏调**。auto 模式下模型会自作主张"这个我知道，不调工具了"——当用户的查询正好落在模型训练知识能覆盖的区间，它会直接用记忆里的旧数据回答，而那个数据可能正是工具要去核实的实时数据。典型案例：账户余额、库存、订单状态、汇率。模型觉得"我知道余额大概是多少"，就跳过了 `get_balance` 调用，给了一个自洽但过时的数字。

漏调比乱调更危险，因为它**看起来正确**。系统不会报错，用户也察觉不到，只有当答案与现实不符时才暴露。四栈里没有任何一栈在 auto 下能可靠区分"模型已知且正确"和"模型在猜"——这是触发判断上最难的一道线。工程上的对冲是两条：一是用系统提示把"凡是涉及 X/Y/Z 类实时量的，必须先调工具再回答"写成硬约束；二是把这类查询路由到一个**只挂相关工具、且 tool_choice 锁定为指定函数**的子智能体，从结构上消灭"该不该调"这个判断。

## 四、错调：触发了，但调错了工具

触发决策里还有一层——**调是调了，工具选错了**。这一点要和此前"撞名即错调（同义碰撞税）"区分开：那一轮讲的是两个工具名字语义相近导致模型在它们之间选错；本轮的"错调"是模型对一个**该调工具**的查询，选了一个**存在但语义不对**的工具。区别在于：前者是"工具箱设计问题"，后者是"模型理解问题"。

错调往往发生在工具描述模糊、或工具之间存在功能包含关系时（比如 `search_orders` 和 `search_all`）。实测里，给一组功能有重叠的工具，auto 模式下的选择在多次运行中会**漂移**——第一次调 `search_orders`，第三次调 `search_all`，参数也随之不同。这直接关系到下一节的可靠性：错调不是偶发噪声，而是触发判断里一个稳定存在的错误模式，它会被 passᵏ 的多次采样放大成肉眼可见的失败。

## 五、passᵏ 坍塌：做对一次，不等于每次都做对

这是本轮最该被记住的数字。Sierra 提出的 τ-bench（arXiv 2406.12045）测的是多轮、工具-智能体-用户三方交互的**任务完成率**，并引入了一个新指标 **passᵏ**——同一个任务独立跑 k 次，只有 k 次全部成功才算通过。它的数学含义是 `passᵏ = (pass@1)ᵏ`（在成功率独立同分布的假设下），意味着即便单次 pass@1 高达 90%，pass⁸ 也只剩 0.9⁸ ≈ 43%；而搜索结果给出的实测是：**GPT-4o 在 τ-bench 零售域的 pass⁸ 跌到 25% 以下**。

这个坍塌不是模型不够聪明，而是**触发判断的非确定性**在复利。每一轮"该不该调、调哪个、参数怎么填"都是一个概率分叉，k 次串联后，任何一次走偏都让整条任务失败。pass@1 衡量的是"能力天花板"，passᵏ 衡量的是"可上线的可靠性地板"。所有在 pass@1 上看起来都很好的四栈，在 pass⁸ 上都暴露同源的脆弱——这正是"做对一次不算会"在工具触发层的具体印证。**只看 pass@1 选模型，等于用天花板当地板。**

```mermaid
flowchart TD
    A[同一任务] -->|独立采样 k 次| R1[Run 1: 触发→调用→...]
    A --> R2[Run 2: 触发→调用→...]
    A --> Rk[Run k: 触发→调用→...]
    R1 --> P{每次都成功?}
    R2 --> P
    Rk --> P
    P -->|全过| OK[passᵏ = 1]
    P -->|任一失败| FAIL[passᵏ = 0]
    OK --> M["pass⁸ ≈ pass@1 的 8 次方<br/>0.9⁸≈43% / 实测 GPT-4o 零售域 &lt;25%"]
    FAIL --> M
```

## 六、门控设计模式：把"该调即调"做成结构而非运气

既然触发的不可靠是结构性的，解法也只能是结构性的。可上线的门控不是"配一个 tool_choice 然后祈祷"，而是三道闸门叠加：**路由闸**（意图分类，决定走哪个子智能体、挂哪些工具）、**触发闸**（在该子流程里用 auto 还是强制指定函数）、**兜底闸**（无关查询和纯闲聊轮次设 `none`）。核心思想是把"该不该调"这个最难的概率判断，从模型推理时挪到**设计时的静态结构**里——能不用模型判断的，就别让它判断。

落地上有几个可复用的模式：**(1) 闲聊轮 `none`**：检测到无工具意图的轮次直接 `tool_choice=none`，省 token 也防误触发；**(2) 已知意图强制指定函数**：意图识别确认后，`tool_choice` 锁到那个函数，把模型从"选不选"降级为"填参数"；**(3) 双 agent 校验**：执行 agent 调完工具，reviewer agent 判断调用是否合理，不合理则回退——这本质是给 passᵏ 加了一道人工/模型的重试与裁决。这些模式单独看都普通，组合起来才是把 passᵏ 从 25% 往上抬的实际杠杆。

```mermaid
flowchart LR
    U[用户查询] --> R{路由闸:意图分类}
    R -->|闲聊| N[tool_choice = none<br/>纯文本应答]
    R -->|需实时数据| A1[子Agent:auto]
    R -->|已确认动作| A2[子Agent:指定函数]
    A1 --> T1{该不该调?}
    T1 -->|该调| OK1[调对工具]
    T1 -->|漏调风险| RV[reviewer校验/重试]
    A2 --> OK2[直接填参执行]
    OK1 --> V[兜底闸:结果核验]
    OK2 --> V
    RV --> V
```

## 七、评测口径：BFCL irrelevance + τ-bench passᵏ 怎么读

工具触发的评测，要同时读两个榜单才不偏科。**BFCL（Berkeley 函数调用榜单，现已到 V4）** 是分项显微镜：它把函数调用拆成 AST 正确性（参数结构）、可执行性（真实跑通）、**irrelevance detection**（无关查询是否拒绝调用，即反幻觉）、多轮、并行调用等子项。读 BFCL 的正确姿势是**盯着 irrelevance 和多轮分**，而不是看总准确率——总分会被简单的单工具调用拉高，掩盖触发判断的弱点。

**τ-bench 是可靠性温度计**：它不细究单次调用对不对，而用 passᵏ 量"重复做能不能稳定做对"。两个榜单一横一纵：BFCL 告诉你"这个模型在哪些触发子能力上有洞"，τ-bench 告诉你"这个洞在多次串联里会变成多大的坍塌"。一个常见误区是只看 BFCL 总分选模型、然后被线上的 passᵏ 摔打——正确的流程是 BFCL 定位短板 → τ-bench/passᵏ 量化可靠性 → 门控模式针对性补 → 再用 pass⁸/ pass¹⁶ 回归。值得注意的是 τ²-bench（arXiv 2506.07982）已把双智能体协同纳入，未来多智能体触发的可靠性评估也有了口径。

## 八、变现与训练营评估

这个方向**变现确定性中等偏上，教学稀缺度高**。市面上的"AI Agent 训练营"九成停在"教会你写一个能调工具的 demo"——也就是 pass@1 的展示层，几乎没人讲触发可靠性、tool_choice 策略、passᵏ 回归。这恰好是"能跑 demo"和"能上线"之间的认知差，是知识付费的优质缝隙。

可包装的产品形态：(1) **"工具触发可靠性"专题课**，BFCL + τ-bench 双榜单解读 + 四栈 tool_choice 实操 + 门控设计模式；(2) **passᵏ 回归工具小课**，教团队给自己的 agent 加一套"同任务跑 N 次统计成功率"的评测管线，这是上线前最便宜也最值的一道质检；(3) **行业版门控模板**，金融/电商/客服等场景的"该调即调"触发器预制件。风险点在于内容偏硬核、受众是工程团队而非泛用户，走 ToB 培训或企业内训比 ToC 卖课更对路。

## 推荐方案

- **纯对话/客服闲聊场景**：默认 `auto`，并在无意图轮次显式切 `none`；绝不上 `required`。
- **强动作场景（退款、下单、转账）**：意图确认后用 `tool_choice` 锁定指定函数，把模型降级为填参器；配 reviewer 双 agent 校验。
- **实时数据场景（余额、库存、状态）**：路由到只挂相关工具的子智能体，并在提示里写死"涉及 X 必须先调工具"的硬约束，对冲漏调。
- **选模型/上线前**：BFCL 看 irrelevance + 多轮分，τ-bench 看 pass⁸，不要用 pass@1 当决策依据。
- **任何要上线的 agent**：必须配一条 passᵏ 回归（建议 pass⁸ 起步），把"做对一次"升级为"每次都做对"才算达标。

工具使用能力的真相，不在于这个模型会不会调工具，而在于它在**该调的时候每次都调对、不该调的时候一次都不乱调**——前者叫能力，后者叫可靠性，而线上死掉的 agent，几乎全是栽在后者。

## 参考来源

1. [τ-bench: A Benchmark for Tool-Agent-User Interaction in Real-World Domains (arXiv 2406.12045)](https://arxiv.org/abs/2406.12045) — Sierra 提出 τ-bench 与 passᵏ 可靠性指标的原始论文，零售/航空多轮工具交互基准。
2. [Tool-Use Reliability in 2026: What passᵏ on tau-bench Tells Us (CallSphere)](https://callsphere.ai/blog/vw1g-tool-use-reliability-tau-bench-pass-k-2026) — GPT-4o 在 τ-bench 零售域 pass⁸ 跌破 25% 的代表性解读，可靠性 vs 能力的核心论证。
3. [Berkeley Function Calling Leaderboard (BFCL) V4 (UC Berkeley/Gorilla)](https://gorilla.cs.berkeley.edu/leaderboard.html) — 函数调用权威榜单，含 irrelevance detection（无关查询反幻觉）、多轮、并行调用分项。
4. [BFCL V3: Multi-Turn & Multi-Step Function Calling (Gorilla blog)](https://gorilla.cs.berkeley.edu/blogs/13_bfcl_v3_multi_turn.html) — BFCL 多轮与多步调用评测的类别定义，触发判断的分项口径。
5. [Forcing function calling via `tool_choice: "required"` (OpenAI Community)](https://community.openai.com/t/new-api-feature-forcing-function-calling-via-tool-choice-required/731488) 与 [Microsoft agent-framework issue #2879: Excessive tool calls with tool_choice="required"](https://github.com/microsoft/agent-framework/issues/2879) — `required` 强制触发导致冗余/幻觉调用的官方语义与已知问题佐证。

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
