Claude Code 源码十大亮点解读 02|语义化工具并发:为什么它既快又不乱
Digital Strategy Review | 2026
Claude Code 十大亮点解读 02|语义化工具并发:为什么它既快又不乱
文 / 果叔 · 阅读时间 / 8 Min

写在前面
这一篇值得单独拆出来,是因为很多 Agent 一到真实代码库就会同时暴露两个问题:慢,或者乱。Claude Code 的处理很成熟,它不是盲目追求并发数量,而是把并发放进运行时语义里做。
01
语义化工具并发:为什么它既快又不乱
多工具 Agent 系统一旦进入真实使用,就会遇到一个非常现实的问题:
• 全串行执行,慢
• 全并发执行,乱
Claude Code 在这个问题上的答案很漂亮:不是拍脑袋决定并发,而是让工具自己声明并发语义,再由运行时按语义切批执行。
对应实现主要在:
• src/services/tools/toolOrchestration.ts
• src/tools.ts
• src/query.ts
02
一、问题到底出在哪里
在 coding 场景里,一轮推理常常会产生很多工具调用,比如:
• 搜文件
• 搜文本
• 读多个文件
• 查 MCP 资源
• 编辑文件
• 跑 shell
这些调用的性质非常不一样。
适合并发的
• Glob
• Grep
• FileRead
• 某些只读型 MCP 工具
不适合并发的
• 文件编辑
• 写文件
• 依赖最新上下文状态的工具
• 带副作用的 shell / powershell 调用
如果系统没有中间层来理解这些差别,就只能在两个坏选择之间二选一:
01 全部串行,保证安全但体验差
02 全部并发,追求速度但容易踩状态
Claude Code 选择了第三条路。
并发不是默认态,而是工具自己声明语义之后,运行时再做批次切分。
03
二、Claude Code 的做法:先让工具表达自己的并发语义
toolOrchestration.ts 的核心不是“开并发”,而是 partitionToolCalls(...)。
它会做这些事:
01 遍历一轮 assistant message 里的 tool_use
02 找到对应工具定义
03 用工具 schema 解析输入
04 调用该工具的 isConcurrencySafe(...)
05 按顺序把工具调用划成若干批次
结果是:
• 连续且安全的工具调用会被归成一组,并发执行
• 其他调用会退回串行
这比简单的“读工具都并发、写工具都串行”更稳,因为判断权其实交给了工具实现本身。
04
三、为什么这套设计很高级
1. 它把复杂性从模型侧移到了运行时侧
大模型本身不擅长做精确并发控制。 你当然可以在 prompt 里告诉它“读操作可以并行”,但那只是建议,不是保障。
Claude Code 干脆不依赖模型记住这件事,而是让运行时在执行阶段自动完成安全编排。
这是成熟系统常见的思路:
• 模型负责表达意图
• 运行时负责保证执行策略
2. 它保留了顺序语义
注意这里不是把所有可并发工具打散成任意拓扑,而是按调用序列中的连续安全片段分批。
这非常重要,因为它保留了 assistant 原始推理的局部顺序。
也就是说,Claude Code 追求的是“尽可能安全地快”,而不是“极限并行地重排”。
3. 它天然适合代码探索场景
在代码探索阶段,一轮里最常见的就是大量只读调用。 这正是并发收益最大的地方。
因此这个设计对 Claude Code 这种 coding agent 特别合适:
• 搜索快得多
• 不容易破坏状态
• 模型不需要额外学习复杂执行规则
05
四、这个亮点和 query.ts 的关系
query.ts 负责从 assistant 输出里提取 tool_use,再调用 runTools(...)。 真正决定并发与串行策略的是 toolOrchestration.ts。
这意味着 Claude Code 的主循环并不是简单“看见一个工具就执行一个工具”,而是:
01 先收集本轮工具调用
02 再在运行时层进行批处理规划
03 再把执行结果回灌回主循环
这使得工具系统从“即时反应式调用”升级成了“受调度的执行阶段”。
06
五、为什么这比简单线程池更有价值
有些系统也会说自己支持并发工具调用,但本质上只是:
• 异步发出去
• Promise.all
这种实现的问题在于,它对工具本身的语义视而不见。
Claude Code 的不同点是:
• 并发不是默认的,而是经过工具定义确认的
• 上下文修改不是乱序套用,而是有 contextModifier 收敛顺序
• 工具执行本身仍然在统一的权限、hook、telemetry 体系里
所以它不是一个“快一点的工具执行器”,而是一个有语义的调度器。
07
六、这对用户体验有什么直接影响
1. 探索速度更快
当 Agent 需要搜很多位置、读很多文件时,响应明显更顺滑。
2. 不容易出现状态竞争
编辑类操作仍然保守串行,避免文件状态互踩。
3. Agent 更像“会做事的系统”
用户看到的是 Agent 能迅速展开一批只读探索,而不是机械地一个一个查。
这会让系统整体感觉更像熟练工程师,而不是单线程脚本。
08
七、这一设计的代价是什么
当然,这种设计也不是免费的。
1. 工具实现必须承担语义声明责任
每个工具都得正确实现自己的并发安全判断,否则调度器就无法做出正确决定。
2. 调试复杂度上升
一旦某些上下文修改来自并发工具,系统就必须更仔细处理 contextModifier 的套用顺序。
3. 需要谨慎处理“看起来只读、实际上有副作用”的工具
这类工具如果误标成 concurrency-safe,风险会很大。
但总体上,这个代价是值得的,因为收益直接作用在真实使用最频繁的探索阶段。
09
八、一张图看懂这件事

10
九、结论
Claude Code 这套“语义化工具并发”并不是 flashy feature,但它解决的是多工具 Agent 最现实、最频繁的性能与稳定性矛盾。
它的厉害之处在于:
• 不是把并发责任推给模型
• 不是靠硬编码列表粗暴分类
• 不是牺牲顺序语义换速度
而是把工具语义真正带进了运行时调度层。
简单说:
它让 Agent 的工具使用既像程序调度,又不失去大模型推理的自然性。
夜雨聆风