<!-- title: 工具返回消化力实测：调对不等于读懂 -->

工具使用能力的评测，已经被 BFCL 和 τ-bench 雕琢到了"调对"的极致——选对工具、填对参数、JSON 合规、多轮串并。可真正决定 Agent 能否把一个工具调用变成一次正确决策的，是工具**返回之后**的那一段：读懂返回值里的数值、分辨空与错的区别、追踪多跳结果之间的依赖、从嵌套结构里挖出埋在第四层的字段。这一段，恰恰是当前所有主流评测的公共盲区。本文实测六大"返回消化"退化模式，并给出对应的对冲工程。

## 一、被三大评测同时跳过的"消化段"

先厘清一条事实链：工具调用的生命周期可以切成四段——**意图理解 → 调用合成 → 结果返回 → 结果消化**。BFCL V1–V4 几乎把火力全部压在第二段，V3 引入 multi-turn/multi-step 后开始触及第四段，但它的判分仍以"最终答案字符串是否匹配 ground truth"为准，过程里 Agent 是真的读懂了返回值还是蒙对了答案，无从分辨；τ-bench / τ²-bench（Sierra）用 dual-control 双控制环境测多轮客服任务，同样只在**任务级**打分。结果就是：一个"调对工具、参数完美、却把返回值里的 `total: 0` 当成 `total: null` 从而胡乱补救"的 Agent，在两者榜单上都能拿高分。

这就是本文要钉死的那条缝——**消化力（result comprehension）**。下面六态，是把这条缝撑开后的实测图谱。

| 评测体系 | 核心测什么 | 是否覆盖"返回消化" | 典型盲区 |
|---------|-----------|------------------|---------|
| BFCL V1–V2 | 工具选择 + 参数格式（串行/并行） | 否 | 完全不验证返回值是否被正确理解 |
| BFCL V3 | Multi-turn / Multi-step 链式调用 | 间接（仅看终态匹配） | 过程消化质量被答案匹配掩盖 |
| BFCL V4 | 多跳 web search、agentic 检索 | 部分 | 多跳结果链的中间断裂不可见 |
| τ-bench / τ²-bench | 多轮客服任务、用户+工具双控制 | 任务级 | 返回值误读被后续对话"自圆其说" |

## 二、六大消化退化模式实测

### 模式一：长返回中段失明（Lost-in-the-Middle）

这是最被低估也最致命的一态。Transformer 的注意力呈 U 型曲线：开头和结尾的 token 被牢牢抓住，中段无论多关键都会被稀释。原研究在多个长上下文模型上测得的"关键信息置于中段时"准确率仅 **76%–82%**，而置于首尾时接近 100%。把这个结论平移到工具返回上：当一个 `search_orders` 返回 40 条记录、而正确答案藏在第 18–22 条里时，Agent 漏判率会陡升。

工程上的对冲很直接——**重排（reranking）与去中段化**。在把工具结果写回上下文前，做一次摘要前置 + 关键字段置顶：

```python
def reshape_tool_result(rows, key_fields):
    # 把命中的关键字段提到结果头部，打破 U 型谷底
    head = [{k: r[k] for k in key_fields} for r in rows if matches(r)]
    tail = {"total_returned": len(rows), "full_rows": rows}
    return {"highlighted_hits": head, "context": tail}
```

这一步在 BFCL 评测里拿不到分（因为它不关心你怎么摆），但在真实生产里能把漏判率压下一个数量级。

### 模式二：数值失真——提取、比较、运算三连错

Agent 读返回值里的数字，常在三处翻车：**单位剥离**（`"price": "30 USD"` 被当 30 个单位，与另一处 `"amount": 3000 cents` 直接比大小）、**量级误读**（`1_000_000` 与 `1000000` 在某些分词下被拆解后比较出错）、**聚合自造**（返回里没有总和，Agent 凭"看起来像"自己算一个并当成返回值的一部分）。

这背后是 LLM 对结构化数值的"读"和"算"是两个脱钩的能力。对冲工程是**把数值推理外包给确定性工具**——任何涉及比较、求和、排序的，强制走一个 `calculator` 工具而非让模型脑算：

```python
# 错误：让模型直接读 JSON 算总额
agent.run("从返回结果里算出这批订单的总退款")

# 正确：强制走工具，模型只负责提取数值、不负责算
agent.run("用 calc.sum 提取每单 refund 字段求和，再返回结果")
```

这条规则在"自主智能体完成幻觉破局"之外，是另一个独立的数值层——它解决的是**读对却算错**，而非声称做完了实际没做。

### 模式三：空值语义混淆——[]/null/{}/error 四态塌缩

这是最隐蔽的一态。工具返回有四种"没有东西"的语义：空数组 `[]`（查到了、但确实没有）、`null`（字段不存在）、空对象 `{}`（资源存在但无内容）、以及 `error`（调用失败）。当前 Agent 倾向于把这四态**塌缩成同一个"为空"**，然后给出统一的"未找到"或更糟的——统一触发兜底编造。

实测场景：一个 `get_user_coupon(user_id)` 返回 `[]`（用户没有任何优惠券）时，Agent 若把它当 `null`（不确定有没有），就可能去**自造一张优惠券参数**去调 `apply_coupon`——这正好踩中"最大似然填补"的本能。对冲工程是**给工具结果加结构化语义标记**，让模型不靠猜：

```python
@tool
def get_user_coupon(uid):
    rows = db.query(uid)
    return {
        "status": "ok",                 # ok / empty / not_found / error
        "count": len(rows),
        "rows": rows,
        "semantic": "user_has_no_coupons" if not rows else "ok"
    }
```

把"为什么是空"显式写出来，比指望模型从 `[]` 推断出"用户确实没有"要可靠得多。

### 模式四：多跳结果链断裂——BFCL V4 已经踩到的坑

BFCL V4 引入多跳（multihop）web search 任务，本质就是"前一个工具的返回值要喂给后一个工具"。这正是消化力被压测的地方：第一跳返回的实体 ID、时间戳、坐标，必须在第二跳的参数里被**原样且正确地**传递。实测发现的高频断裂点是**实体消歧**——第一跳返回 `Paris`（法国）和 `Paris`（德州），Agent 在第二跳参数里传了一个模糊的 `Paris`，导致整条链偏航。

BFCL V4 用 DuckDuckGo API 做数据源、用多跳判分，已经暴露了这个问题，但它仍只在**终态**打分，中间跳的断裂会被"换条路也到了终点"掩盖。生产环境的对冲是**显式的跳间契约（hop contract）**：每一跳必须输出一个类型化的中间凭证，下一跳的参数 schema 强制引用它，类型不匹配直接拒绝。

```python
@dataclass
class HopResult:
    entity_id: str        # 强类型凭证，带命名空间
    entity_type: str
    source_hop: int
```

### 模式五：嵌套结构盲区——第四层字段失语

工具返回一个四层嵌套的 JSON，关键决策字段埋在 `data.results[0].policy.refund.eligible` 时，Agent 的命中率会断崖式下跌。这不是 lost-in-the-middle（位置问题），而是**深度问题**——模型的"结构指针"能力随嵌套深度衰减。同一份信息，平铺成 `eligible=True` 时几乎全对，埋进第四层时漏过半。

对冲工程是**工具侧做投影（projection）**，而不是寄望模型爬深。让工具支持 `fields=` 参数，按调用方需求只返回扁平后的相关字段；或在结果回写上下文前，用一个廉价的确定性抽取层把深层字段拍到表层。这是"工具调用上下文工程"在消化端的延伸——前者管"塞进去的形状"，这里管"读出来的形状"。

### 模式六：结果到决策的因果短路

最后一态最危险：返回值明明**不支持**某个结论，Agent 却做出了这个结论。典型表现是工具返回 `confidence: 0.4` 的低置信结果，Agent 报告时把它当成确定事实；或返回 `approx_count` 却被当成精确计数用于下游。这与"完成幻觉"的区别在于——它发生在**单次工具调用的消化窗口内**，而不是整轮任务收尾时。

对冲工程是**强制置信度传播**：任何带 `confidence` / `estimated` / `caveat` 字段的返回，必须在 Agent 的最终输出里原样回显，并在低于阈值时触发追问或降级。用一个轻量的结果校验器挂在 agent loop 的工具返回回调上即可：

```python
def on_tool_return(result: dict):
    if result.get("confidence", 1.0) < 0.6:
        inject_system_note(
            "上一条工具结果为低置信，禁止据此下确定性结论，需追问或换工具。"
        )
```

## 三、消化力的工程化总账

```mermaid
flowchart LR
    A[用户意图] --> B[调用合成<br/>BFCL/τ-bench 覆盖]
    B --> C[工具执行]
    C --> D[结果返回]
    D --> E1[中段失明]
    D --> E2[数值失真]
    D --> E3[空值混淆]
    D --> E4[多跳断裂]
    D --> E5[嵌套盲区]
    D --> E6[因果短路]
    E1 --> F[结果消化层<br/>当前评测公共盲区]
    E2 --> F
    E3 --> F
    E4 --> F
    E5 --> F
    E6 --> F
    F --> G[决策输出]
    F -.对冲工程.-> H[重排/外包计算/语义标记/跳契约/投影/置信传播]

    style F fill:#fee,stroke:#c33,stroke-width:2px
    style H fill:#e8f5e9,stroke:#2e7d32
```

把六态摆在一起，能看到一条规律：**消化退化几乎都源于"模型用读自然语言的本能去读结构化数据"**。BFCL 和 τ-bench 给了行业一把测"调对"的尺子，却没人递上测"读懂"的尺子。在垂直行业落地（金融核对、医疗检索、法律引证）里，真正酿成事故的多半不是调错了工具，而是读懂错了返回——把 `0` 当成 `null`，把 `approx` 当成 `exact`，把第四层字段当成不存在。

对冲工程的共性也很清晰：**不要让模型在消化窗口里做它不擅长的事**。读，可以让它做；但比较、聚合、深度寻址、置信判定，都应该被推给确定性层或显式契约。这与"无框架智能体"所揭示的"抽象税"是同一枚硬币的另一面——不是抽象越少越好，而是该硬的地方必须硬。

## 四、分场景推荐

| 场景 | 首选对冲 | 次选 |
|------|---------|------|
| 高频检索类 Agent（订单/文档） | 返回重排 + 关键字段置顶（破 U 型谷） | 工具侧 `fields=` 投影 |
| 涉金额/计数的金融核对 | 数值推理强制外包 `calc` 工具 | 结果校验器卡量级与单位 |
| 多源融合决策 | 显式跳间契约 + 类型化凭证 | 多跳结果去重与冲突消解层 |
| 空结果敏感业务（库存/权限） | 结构化语义标记四态 | 空态触发追问而非兜底 |
| 低延迟流式场景 | 摘要前置（首字即消化） | 置信传播阈值降级 |

训练维度上，这六态恰好能直接落成一套独立于 BFCL 的"消化力小项"——给每个工具调用配一个**过程级判分**（返回值里的哪个字段被用到了、是否被正确解读），而非只看终态答案。这套小项本身就是一份可交付的训练营实训靶子：六个退化、六个对冲、一套可复现的探针，闭环完整。

工具调用评测的下一代竞争，大概率不在"调得更对"——那已经被 BFCL V4 卷到边际收益递减；而在"读得更懂"。谁先把消化力做成可量化的尺子，谁就拿到了生产级 Agent 可靠性的下一个定价权。

## 参考来源

1. [Berkeley Function Calling Leaderboard (BFCL) V4 · Web Search — Gorilla/Berkeley](https://gorilla.cs.berkeley.edu/blogs/15_bfcl_v4_web_search.html) — V4 引入多跳 web search，多跳结果链是本文"消化力"压测的基准来源
2. [τ²-Bench: Evaluating Conversational Agents in a Dual-Control Setting (arXiv 2506.07982)](https://arxiv.org/abs/2506.07982) — Sierra 的 dual-control 多轮评测，任务级打分掩盖过程消化质量
3. [Lost in the Middle: How Language Models Use Long Contexts (arXiv 2307.03172)](https://arxiv.org/abs/2307.03172) — U 型注意力曲线，中段关键信息准确率 76%–82%，支撑"模式一"实测
4. [Lost in the Middle: The U-Shaped Attention Curve — AgentPatterns.ai](https://agentpatterns.ai/context-engineering/lost-in-the-middle/) — 工程化的中段失明诊断与重排对冲
5. [Why Do LLM Function Calls Hallucinate Parameters — BestHub](https://www.besthub.dev/articles/why-do-llm-function-calls-hallucinate-parameters-and-how-to-prevent-it-a3198bba39b5) — 最大似然填补本能与参数幻觉五大模式，支撑"模式三/六"的兜底编造机制
6. [𝜏-bench · Sierra](https://sierra.ai/blog/tau-bench-shaping-development-evaluation-agents) — 工具-智能体-用户三方交互基准的设计出发点，对照"消化段"未被测的事实

> [!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)
