<!-- title: 流式工具调用：首字即执行 -->

# 流式函数调用：从 buffer 到投机执行

## 概述

工具调用（function calling）的延迟瓶颈不在推理，而在"等"。传统模式下，模型必须把整个 `tool_use` 块的 JSON 参数完整生成、服务端校验、一次性返回，Agent 才能解析并执行——这段从"首字生成"到"工具可执行"的真空期，正是用户感知卡顿的元凶。2026 年，流式函数调用（Streaming Function Calling）成为 Agent 工具使用能力的分水岭：从最朴素的"buffer 整包等待"，到"增量部分 JSON 解析"，再到 Anthropic 的"细粒度工具流"，最终演进到"推测执行"（speculative tool execution）——在参数尚未生成完毕时就预测并启动工具。实测五条技术栈，首字节到工具执行的延迟能从 800ms 压到 60ms 量级，但每向下一层，正确性、校验、回滚的工程复杂度就翻一倍。这是一场用复杂度换延迟的交易。

下面把五条栈的对比、关键代码、踩坑、Mermaid 管线、变现评估一次性摊开。

## 五栈对比表

| 栈 | 核心机制 | 首执行延迟 | 正确性风险 | 实现难度 | 适用场景 |
|---|---|---|---|---|---|
| ① buffer 整包等待 | 攒齐 input_json_delta 再解析 | 高（~600-900ms）| 零 | 极低 | Demo、原型 |
| ② 增量部分 JSON 解析 | jiter/partial-json 流式补全 | 中（~200-400ms）| 低 | 中 | 生产基线 |
| ③ 细粒度工具流 | 服务端跳过 JSON 校验，更早吐 chunk | 中低（~150ms）| 低 | 中低 | Anthropic 原生 |
| ④ 推测执行 (PASTE) | 参数未完即预测并启动工具 | 极低（~60-100ms）| 中高（需回滚）| 高 | 只读查询/搜索 |
| ⑤ Act While Thinking | 边推理边执行，pattern 感知 | 极低（与推理重叠）| 高 | 极高 | 特定任务模式 |

## 深度分析

### 栈① buffer 整包等待：被默认行为坑掉的 600ms

这是所有 Agent 框架的默认行为，也是延迟最高的一档。Anthropic 流式协议中，工具调用的参数不是一次性到达，而是以 `input_json_delta` 事件分片流出，这些分片在拼完整之前根本不是合法 JSON。新手最常这样写：

```python
# 反例：把所有 delta 攒进字符串，循环结束才解析
buf = ""
async for event in client.messages.stream(...):
    if event.type == "input_json_delta":
        buf += event.partial_json   # 累积，啥也不干
# 循环退出后才执行 ↓
tool_input = json.loads(buf)        # 此时才合法
execute(tool_input)
```

问题在于：从首个 `input_json_delta` 到 `buf` 完整，中间隔了模型的整个参数生成过程。对一个 6 参数的 SQL 查询工具，光生成 JSON 就要 400-700ms。这期间 CPU 空转、用户干等。栈①的唯一优点是正确性 100%、实现零成本——所以它只适合做 demo。任何把 Agent 卖给真实用户的产品，第一件事就是甩掉它。诊断它很简单：在 `input_json_delta` 第一个事件和 `json.loads` 之间打两个时间戳，差值超过 300ms 就说明你在白白烧延迟。

### 栈② 增量部分 JSON 解析：生产基线的诞生

`input_json_delta` 不是"必须等齐"，而是"可以增量解析"。关键工具是 `jiter`（Rust 写的高性能 JSON 迭代器，Anthropic SDK 内部就用它）和 partial-json 这类流式补全库：每当一个字段闭合，立刻就能拿到 `{"db": "prod"}` 这样的部分结果。

```python
import partial_json_parser
current = {}
async for event in stream:
    if event.type == "input_json_delta":
        buf += event.partial_json
        current = partial_json_parser.loads(buf)   # 容忍截断
        if "query" in current:                     # 关键参数一到就预热
            warm_connection_pool(current.get("db"))
```

这里有一个被反复证明有效的工程技巧——**早绑定依赖**。工具执行往往有 IO 前置（建连接、预热缓存、鉴权），这些前置步骤不依赖完整参数，只依赖一两个字段。一旦 `db` 字段流式到位，立刻预热连接池；等 `query` 字段到位，连接已就绪，直接执行。这样把"等参数"和"做前置 IO"并行起来，端到端延迟直接砍半。栈②是大多数生产 Agent 该采用的基线：它最终仍会做一次完整 JSON 校验（正确性有保障），又把可并行的前置工作提前了。性价比之选。

### 栈③ Anthropic 细粒度工具流：服务端让出的 400ms

细粒度工具流（fine-grained tool streaming）把延迟优化推到了服务端层面。传统模式下，服务端会在整个 `tool_use` 参数生成完、并通过 JSON 校验后，才开始往 SSE 通道推 chunk。细粒度模式跳过了这个"等齐再校验"步骤，参数 chunk 一生成就推。这意味着：栈②的客户端增量解析依然要做，但**第一个 chunk 到达的时间**从约 400ms 提前到约 150ms——上游提前，下游全部受益。

```python
response = client.messages.create(
    model="claude-...",
    tools=[...],
    # 关键开关：开启细粒度工具流
    extra_headers={"anthropic-beta": "fine-grained-tool-streaming-2025-05-14"}
)
```

代价是必须自己处理"半截 JSON"。实战中记录的一个高频坑：细粒度模式下偶尔会收到不合法的中间 JSON 片段（引号未闭合、转义未完成），用严格的 `json.loads` 会直接抛异常、中断整条流。正确做法是全程用容错解析器，并对每个增量做 try/except 兜底——宁可暂时拿不到部分值，也不能让流崩掉。栈③是 Anthropic 生态的最优解，但它是厂商锁定，切到别的模型这条优化就失效，跨厂商产品要回退到栈②。

### 栈④ 推测执行：参数没生完就开始干活

这是 2026 年最激进、也最有想象力的方向。核心洞察：参数流式生成时，模型行为有强 pattern——比如"查天气"工具，参数永远是 `{city, date}`，且 `city` 通常先流出。既然如此，为什么不趁 `city` 已知、`date` 还没生成完时，**并行预测**一个最可能的 `date`（比如"今天"），启动一次推测性工具调用？等真实 `date` 流完，猜对了，结果已备好；猜错了，回滚重发。

arXiv 2512.15834（Optimizing Agentic LM Inference via Speculative Tool Calls）系统化了这套范式。它的关键贡献是量化了 LLM 工具调用参数的可预测性，并设计了"乐观预测 + 回滚"执行引擎：

```python
# 伪代码：推测执行内核
async def speculative_execute(partial_args, predicted_full):
    spec_task = asyncio.create_task(call_tool(predicted_full))  # 投机启动
    await stream_complete()                                     # 等真实参数
    if real_args == predicted_full:
        return await spec_task       # 命中 → 零等待返回
    spec_task.cancel()               # 未命中 → 回滚
    return await call_tool(real_args)
```

PASTE 风格的实测（基于约 300 LOC 的 harness）显示：在搜索/查询类任务上，工具调用延迟砍掉约 48.5%。另一篇针对搜索 Agent 的论文（arXiv 2511.20048）也报告通过推测算法显著降低多步搜索延迟。但推测执行有一个硬前提——**工具必须是幂等或低成本的**。一次只读查询重发无妨；一次扣款、发邮件、下单的工具绝不能投机，回滚不了。所以栈④天生只适合查询密集型场景（RAG 检索、知识库搜索、监控聚合），写操作必须排除在外。命中率监控是另一个硬要求：命中率掉到 70% 以下，投机的回滚成本会反吃收益，这时应自动降级回栈②。

### 栈⑤ Act While Thinking：pattern 感知的边想边做

微软研究院的"Act While Thinking"（pattern-aware speculative tool execution）把推测推到极致：不是等模型吐参数，而是**直接从思维链 pattern 预测整条工具调用序列**。模型在 reasoning 阶段往往先暴露意图（"我需要先查 A，再聚合 B"），这个意图本身就是强信号。栈⑤在 reasoning token 流出时就启动预测工具调用，让"思考"和"执行"在时间上完全重叠。

代价是架构复杂度极高：你需要一个 pattern 匹配器识别意图、一个预测器生成调用、一个校验器比对真实输出、一个回滚/提交控制器。任何一个环节错位都会触发幽灵工具调用，污染下游状态。栈⑤目前主要见于学术和头部厂商内部，工程化产品极少。它的价值在于指明了延迟优化的理论上限：当推理和执行彻底重叠时，Agent 的"思考延迟"可以趋近于零——但落地这条路，是给有 3-6 个月工程预算的团队准备的。

### 配套层：部分结果改变 UX

技术栈解决的是"快"，但流式工具调用还带来一个被严重低估的副产品——**部分结果可直接驱动 UI**。当工具参数（比如搜索 query）流式生成时，前端可以实时展示"Agent 正在搜索：'2026 年 5G 核心网…'"，这种渐进式 UI 把"等待"变成了"参与"，主观延迟感大幅下降。

这部分不需要复杂后端，但需要前后端契约：SSE 通道不仅要推 `text_delta`、`tool_delta`，还要推一个"意图"层的轻量事件（`tool_call_started`、`arg_progress`），让 UI 渲染进度条或气泡。这是把后端延迟优势转化为用户体验优势的最后一公里——很多团队把后端优化到 200ms，前端却仍是"转圈圈直到结果全返回"，等于把优化浪费了一半。UX 层和解析层必须配套上线，否则用户感知不到你的 60ms。

## Mermaid：流式工具调用管线时间线

```mermaid
sequenceDiagram
    participant U as 用户
    participant A as Agent
    participant M as 模型(SSE)
    participant P as 解析/推测内核
    participant T as 工具

    U->>A: 提问
    A->>M: 请求(开启细粒度流)
    Note over M: 首 token t≈0
    M-->>P: text_delta(思考)
    M-->>P: input_json_delta {db:"prod"} @t=150ms
    P->>T: 预热连接(栈②早绑定)
    M-->>P: input_json_delta {query:"sel...} @t=300ms
    P->>T: 推测执行(栈④ 预测 date=今天)
    M-->>P: input_json_delta 完整 @t=450ms
    alt 预测命中
        T-->>P: 结果已备好(零等待)
    else 未命中
        P->>T: 回滚 + 重发真实参数
    end
    T-->>A: 结果
    A-->>U: 流式回答
```

## 推荐方案

**做 demo / 内部工具**：栈①，别折腾，正确性第一。

**做生产级 Agent 的默认选择**：栈② + 栈③。用 jiter/partial-json 做增量解析，Anthropic 生态再叠加 fine-grained tool streaming。这是性价比最高的组合，覆盖 90% 场景，正确性可控，跨厂商时栈②仍能独立成立。

**做低延迟对话 / 搜索 / RAG 产品**：在栈②③基础上叠加栈④（推测执行），但严格限定在**只读、幂等工具**上，写操作工具走栈②。务必给每个投机调用配回滚路径和命中率监控，命中率低于 70% 自动降级。

**做研究 / 头部厂商内部**：栈⑤，pattern 感知，做好 3-6 个月工程预算。

**变现评估**：流式工具调用是训练营的极佳进阶模块——它直接对应"Agent 为什么慢"这个高频痛点，学员能立刻看到 800ms→200ms 的延迟曲线，冲击力强。可包装成《Agent 延迟优化实战》专题，从栈①到栈④递进，附 partial JSON 解析和推测执行的可跑代码。产品化方向则是"低延迟 Agent 网关"——把栈②③④封装成一个中间件，给现有 Agent 框架做加速，按节省的延迟或调用量计费。

## 参考来源

1. [Tool Input Streaming and Partial JSON — anthropic-sdk-python DeepWiki](https://deepwiki.com/anthropics/anthropic-sdk-python/6.3-tool-input-streaming-and-partial-json) — 官方 SDK 的 partial JSON 缓冲策略与 jiter 容错解析
2. [Fine-grained tool streaming — Claude API Docs](https://platform.claude.com/docs/en/agents-and-tools/tool-use/fine-grained-tool-streaming) — Anthropic 服务端跳过 JSON 校验、提前推送 chunk 的官方机制
3. [Optimizing Agentic Language Model Inference via Speculative Tool Calls (arXiv 2512.15834)](https://arxiv.org/pdf/2512.15834) — 推测工具执行的学术范式与参数可预测性分析
4. [Reducing Latency of LLM Search Agent via Speculation-based Algorithm (arXiv 2511.20048)](https://arxiv.org/abs/2511.20048) — 多步搜索 Agent 的推测算法延迟优化
5. [Act While Thinking: Accelerating LLM Agents via Pattern-Aware Speculative Tool Execution — Microsoft Research](https://www.microsoft.com/en-us/research/publication/act-while-thinking-accelerating-llm-agents-via-pattern-aware-speculative-tool-execution/) — pattern 感知、思考与执行重叠的激进方案

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