工具调用(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 感知 | 极低(与推理重叠) | 高 | 极高 | 特定任务模式 |
这是所有 Agent 框架的默认行为,也是延迟最高的一档。Anthropic 流式协议中,工具调用的参数不是一次性到达,而是以 input_json_delta 事件分片流出,这些分片在拼完整之前根本不是合法 JSON。新手最常这样写:
# 反例:把所有 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 就说明你在白白烧延迟。
input_json_delta 不是"必须等齐",而是"可以增量解析"。关键工具是 jiter(Rust 写的高性能 JSON 迭代器,Anthropic SDK 内部就用它)和 partial-json 这类流式补全库:每当一个字段闭合,立刻就能拿到 {"db": "prod"} 这样的部分结果。
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 校验(正确性有保障),又把可并行的前置工作提前了。性价比之选。
细粒度工具流(fine-grained tool streaming)把延迟优化推到了服务端层面。传统模式下,服务端会在整个 tool_use 参数生成完、并通过 JSON 校验后,才开始往 SSE 通道推 chunk。细粒度模式跳过了这个"等齐再校验"步骤,参数 chunk 一生成就推。这意味着:栈②的客户端增量解析依然要做,但第一个 chunk 到达的时间从约 400ms 提前到约 150ms——上游提前,下游全部受益。
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 工具调用参数的可预测性,并设计了"乐观预测 + 回滚"执行引擎:
# 伪代码:推测执行内核
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-aware speculative tool execution)把推测推到极致:不是等模型吐参数,而是直接从思维链 pattern 预测整条工具调用序列。模型在 reasoning 阶段往往先暴露意图("我需要先查 A,再聚合 B"),这个意图本身就是强信号。栈⑤在 reasoning token 流出时就启动预测工具调用,让"思考"和"执行"在时间上完全重叠。
代价是架构复杂度极高:你需要一个 pattern 匹配器识别意图、一个预测器生成调用、一个校验器比对真实输出、一个回滚/提交控制器。任何一个环节错位都会触发幽灵工具调用,污染下游状态。栈⑤目前主要见于学术和头部厂商内部,工程化产品极少。它的价值在于指明了延迟优化的理论上限:当推理和执行彻底重叠时,Agent 的"思考延迟"可以趋近于零——但落地这条路,是给有 3-6 个月工程预算的团队准备的。
技术栈解决的是"快",但流式工具调用还带来一个被严重低估的副产品——部分结果可直接驱动 UI。当工具参数(比如搜索 query)流式生成时,前端可以实时展示"Agent 正在搜索:'2026 年 5G 核心网…'",这种渐进式 UI 把"等待"变成了"参与",主观延迟感大幅下降。
这部分不需要复杂后端,但需要前后端契约:SSE 通道不仅要推 text_delta、tool_delta,还要推一个"意图"层的轻量事件(tool_call_started、arg_progress),让 UI 渲染进度条或气泡。这是把后端延迟优势转化为用户体验优势的最后一公里——很多团队把后端优化到 200ms,前端却仍是"转圈圈直到结果全返回",等于把优化浪费了一半。UX 层和解析层必须配套上线,否则用户感知不到你的 60ms。
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 框架做加速,按节省的延迟或调用量计费。
[!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 等场景全覆盖。
