第 10 章:Tool Orchestration

本章导读

  • 核心问题:如何组织多个 Tool 的顺序、并行、批量、重试和聚合。
  • 关键词:ToolPlan、Parallel Tool Calls、Batch、Retry、Result Aggregation
  • 学习产出:为 build #4312 设计并行收集、顺序调查和证据聚合的工具计划。

1. 本章要解决什么问题

上一章讨论了单个 Tool 如何设计。

但真实 Agent 很少只调用一个工具。

例如“分析 CI 失败原因”这个任务,可能需要:

读取 CI 摘要
  ↓
查找失败测试
  ↓
搜索测试类
  ↓
读取业务代码
  ↓
查看最近 Git Diff
  ↓
运行局部测试
  ↓
汇总结论

这里涉及多个工具之间的协作。

这就是 Tool Orchestration。

Tool Engineering 关注:

单个工具如何设计得好用。

Tool Orchestration 关注:

多个工具如何被选择、组合、并行、重试、验证和压缩。

本章核心观点是:

Agent 的工具能力不只是“能调用工具”,而是能在受控运行时中组织一组工具调用,形成可靠的行动链。

本章回答:

  • 工具编排解决什么问题;
  • 什么时候顺序调用,什么时候并行调用;
  • 什么是 Batch Tool Use、Parallel Tool Use、Programmatic Tool Calling;
  • 如何处理工具失败、重试和幂等;
  • 如何验证工具结果;
  • 如何在 Java / Spring Boot 中设计 ToolPlanner、ToolExecutor、ToolRetryPolicy。

2. 对应 Anthropic 文章

本章主要对应:

  • Writing effective tools for agents — with agents
  • Introducing advanced tool use on the Claude Developer Platform

Anthropic 在 advanced tool use 中提到一些关键能力:

  • 更高效地组织工具调用;
  • 使用程序化工具调用处理大数据和多步骤工具流;
  • 让模型只看到必要结果,而不是所有中间数据;
  • 对可并行、可重试的工具进行更高效编排。

这些能力都指向一个问题:

工具越多,越需要编排层。

3. 为什么需要 Tool Orchestration

3.1 降低模型负担

如果每一步工具选择都完全交给模型,模型需要在上下文中理解:

  • 当前有哪些工具;
  • 每个工具怎么用;
  • 上一步返回什么;
  • 下一步应该调用什么;
  • 是否需要重试;
  • 是否可以并行。

这会占用大量注意力。

Orchestration Layer 可以把一部分确定性逻辑交给程序。

例如:

如果任务是 CI 失败分析,默认先调用 summarize_ci_failure。
如果失败类型是 test_failure,再调用 find_failed_tests。
如果有失败类名,再调用 search_code。

这不需要每次都让模型重新发明流程。

3.2 降低 token 消耗

工具调用可能返回大量中间结果。

如果每个中间结果都进入模型,上下文会迅速膨胀。

Programmatic Tool Calling 的思想是:

工具调用 → 程序处理/过滤/聚合 → 只把最终高价值结果给模型

例如检查 50 个服务端点状态,不应该把 50 个完整响应都给模型。

程序可以先聚合:

50 个端点中 3 个失败:A 500、B timeout、C 403。

模型只需要看到聚合结果。

3.3 提高延迟效率

很多工具调用互不依赖,可以并行。

例如技术调研任务中:

搜索官方文档
搜索 GitHub issue
搜索 StackOverflow
搜索内部 Wiki

这些可以并行执行,然后汇总。

并行编排可以显著减少总耗时。

3.4 提高可靠性

工具调用会失败。

失败原因可能包括:

  • 网络超时;
  • 权限不足;
  • 参数错误;
  • 资源不存在;
  • 工具内部异常;
  • 返回结果过大;
  • 外部系统限流。

不同失败需要不同处理。

不能所有失败都让模型猜。

4. 工具编排模式

4.1 Sequential Tool Calls:顺序调用

顺序调用适合有依赖关系的工具。

例如:

search_code
  ↓
read_file_range
  ↓
run_test_command

后一步依赖前一步结果。

顺序调用简单、可控,但延迟较高。

4.2 Parallel Tool Calls:并行调用

并行调用适合互不依赖的工具。

例如:

get_git_diff
get_recent_commits
summarize_ci_failure
read_agents_md

这些可以同时执行。

并行调用需要处理:

  • 超时;
  • 部分失败;
  • 取消;
  • 汇总;
  • 结果顺序;
  • 资源限制。

4.3 Batch Tool Calls:批量调用

批量调用适合同一工具对多个对象执行。

例如:

read_file_range(fileA)
read_file_range(fileB)
read_file_range(fileC)

可以设计成:

read_files(ranges=[...])

批量调用减少多轮开销,但要注意单次返回过大。

4.4 Programmatic Tool Calling

Programmatic Tool Calling 是让程序而不是模型处理部分工具链。

适合:

  • 大数据过滤;
  • 排序;
  • 聚合;
  • 多步依赖工具调用;
  • 中间结果不需要模型推理;
  • 大量并行操作。

例如:

查询 1000 条订单
  ↓
程序过滤异常订单
  ↓
程序按金额排序
  ↓
只给模型 top 10 和统计摘要

这可以减少 token,也减少模型被无关中间数据干扰。

4.5 Human-gated Tool Calls

某些工具必须人工确认。

例如:

  • 修改代码;
  • 提交 PR;
  • 更新 Jira;
  • 运行危险命令;
  • 访问生产数据;
  • 发送外部邮件;
  • 部署服务。

这种工具编排应加入 Human Approval 节点。

5. Tool Planning

Tool Planning 决定调用哪些工具、按什么顺序、是否并行。

可以分三层。

5.1 模型规划

模型根据任务和上下文生成工具计划。

适合开放任务。

例如:

1. summarize_ci_failure(buildId)
2. search_code(failedTestName)
3. read_file_range(testFile)
4. get_git_diff()

5.2 规则规划

程序根据任务类型选择固定工具链。

适合稳定场景。

例如 CI 失败分析默认工具链。

5.3 混合规划

推荐企业使用混合规划:

规则给出安全默认流程
模型在流程中选择细节
程序负责权限和验证

例如:

固定:先读取 CI 摘要
模型决定:需要读哪些文件
固定:写操作前必须审批

6. Retry 与幂等

工具重试必须谨慎。

6.1 可重试错误

适合重试:

  • 网络超时;
  • 502 / 503;
  • 临时限流;
  • 外部系统短暂不可用。

6.2 不应重试错误

不适合重试:

  • 权限不足;
  • 参数格式错误;
  • 文件不存在;
  • 业务规则拒绝;
  • 非幂等写操作。

6.3 幂等性

工具定义中应标记是否幂等。

read_file:幂等
search_code:幂等
run_test:通常幂等,但有副作用成本
apply_patch:非幂等或需要 patch id
create_jira_issue:非幂等
send_email:非幂等

非幂等工具不能盲目重试。

7. Tool Result Validation

工具结果不能无条件相信。

需要验证:

  • 是否符合 Schema;
  • 是否被截断;
  • 是否包含错误;
  • 是否为空;
  • 是否过期;
  • 是否与其他结果冲突;
  • 是否需要进一步工具调用。

例如 search_code 返回 0 条,不代表代码不存在,可能是 query 不好。

Agent 应考虑换关键词搜索。

8. 架构图 / 流程图

Tool Orchestration 总览
图 10-1 Tool Orchestration 总览 这张图展示顺序、并行、批量等工具调用模式如何由 Runtime 统一管理。 Mermaid 源文件

8.1 Tool Orchestration 总览

Tool Orchestration 总览
图 10-2 Tool Orchestration 总览 Mermaid 源文件

8.2 Retry 策略

Retry 策略
图 10-3 Retry 策略 Mermaid 源文件

8.3 Programmatic Tool Calling

Programmatic Tool Calling
图 10-4 Programmatic Tool Calling Mermaid 源文件

9. Java / Spring Boot 落地方案

9.1 ToolPlan

public record ToolPlan(
    String planId,
    List<ToolPlanStep> steps,
    ToolPlanMode mode
) {}

public enum ToolPlanMode {
    SEQUENTIAL,
    PARALLEL,
    BATCH,
    MIXED
}

9.2 ToolPlanStep

public record ToolPlanStep(
    String stepId,
    String toolName,
    Object input,
    List<String> dependsOn,
    boolean requiresApproval,
    RetryPolicy retryPolicy
) {}

9.3 ToolPlanner

public interface ToolPlanner {
    ToolPlan plan(AgentTask task, AgentContext context, List<ToolDefinition> availableTools);
}

可以有多种实现:

RuleBasedToolPlanner
LlmToolPlanner
HybridToolPlanner

9.4 ToolOrchestrator

public class ToolOrchestrator {

    private final ToolExecutor toolExecutor;
    private final ToolResultValidator validator;
    private final ToolRetryHandler retryHandler;
    private final ToolResultAggregator aggregator;

    public AggregatedToolResult execute(ToolPlan plan, ToolExecutionContext context) {
        return switch (plan.mode()) {
            case SEQUENTIAL -> executeSequential(plan, context);
            case PARALLEL -> executeParallel(plan, context);
            case BATCH -> executeBatch(plan, context);
            case MIXED -> executeMixed(plan, context);
        };
    }
}

9.5 RetryPolicy

public record RetryPolicy(
    int maxAttempts,
    Duration initialDelay,
    double backoffMultiplier,
    Set<String> retryableErrorCodes
) {}

9.6 Result Aggregator

public interface ToolResultAggregator {
    AggregatedToolResult aggregate(List<ToolResult> results, AggregationRequest request);
}

聚合结果应包含:

public record AggregatedToolResult(
    boolean success,
    List<ToolResult> rawResults,
    String compactSummary,
    List<String> evidenceRefs,
    List<String> suggestedNextActions
) {}

注意:rawResults 可以存在存储中,但不一定全部进入模型上下文。

10. 常见误区

10.1 让模型独自管理所有工具调用

模型可以规划,但运行时必须负责权限、重试、超时和审计。

10.2 所有工具都串行执行

互不依赖的工具应并行,提高效率。

10.3 所有错误都重试

权限错误、参数错误、非幂等写操作不应盲目重试。

10.4 工具结果全部进入上下文

中间结果应过滤、聚合、压缩。

10.5 没有 Tool Call Trace

没有追踪就无法解释 Agent 为什么做出某个结论。

10.6 忽略部分失败

并行工具调用中,部分失败很常见。

系统应支持:

部分成功
部分失败
降级继续
人工介入

11. 贯穿案例:CI 失败分析 Agent

CI 失败分析需要多个工具协作。

合理的工具计划可以是:

Parallel:
  - summarize_ci_failure(buildId=#4312)
  - get_git_diff(prId=#882)
  - get_project_instructions(repo=order-service)

Then:
  - search_code(query=failedTestName)
  - read_file_range(OrderServiceTest)
  - read_file_range(OrderStateMachine)

Aggregate:
  - 生成失败原因、证据、疑似文件和建议修复方向

第一组工具互不依赖,可以并行执行。第二组依赖失败测试名和 Git Diff 结果,需要顺序执行。

工具结果不应全部进入上下文,而应由 Aggregator 压缩为:

关键错误栈
相关 Git Diff
相关测试片段
相关状态机片段
候选根因
证据引用

这个案例体现了 Tool Orchestration 的核心:让模型负责开放判断,让程序负责并行、重试、聚合、权限和上下文压缩。

12. 本章小结

本章讨论了 Tool Orchestration。

核心结论:

  1. Tool Orchestration 关注多个工具如何被组织成可靠行动链。
  2. 顺序、并行、批量和程序化工具调用适合不同场景。
  3. 工具调用需要权限、超时、重试、幂等和审计。
  4. 工具结果应验证、聚合和压缩后再进入上下文。
  5. 企业 Agent 应采用混合规划:规则控制边界,模型处理开放决策。

一句话总结:

单个工具让 Agent 能行动,工具编排让 Agent 能可靠、快速、可控地完成复杂行动。

13. 实践任务

任务 1:设计 CI 失败分析 ToolPlan

写出工具计划,标注:

  • 哪些步骤并行;
  • 哪些步骤串行;
  • 哪些工具可重试;
  • 哪些工具需要审批;
  • 哪些结果进入上下文。

任务 2:实现 RetryPolicy

设计一个 Java RetryPolicy,支持:

  • 最大次数;
  • 指数退避;
  • 错误码白名单;
  • 幂等性检查。

任务 3:实现 ParallelToolExecutor

CompletableFuture 或线程池实现并行工具执行。

要求支持:

  • 超时;
  • 部分失败;
  • 结果聚合;
  • trace 记录。

任务 4:工具结果压缩

给定三个工具结果:

CI summary
Git diff
Code search result

设计一个 Aggregator,把它们压缩成给 Agent 的下一步上下文。

results matching ""

    No results matching ""