跳转至

第 7 章 Tool Use 机制设计

在很多 Agent 演示里,最容易让人产生“系统真的开始工作了”这种直觉的,通常不是模型说得多像人,而是它能够主动调用工具、查询外部信息、执行命令、修改状态,甚至把结果继续带回后续推理。也正因为如此,Tool Use 往往被视为 Agent 区别于普通问答系统的关键标志。

但如果只把 Tool Use 理解成“模型支持 function calling”,这个理解仍然太浅。对工程系统来说,真正重要的问题不是模型能不能生成一个工具调用格式,而是 Agent 是否能够建立一条稳定、安全、可恢复的外部行动通道。换句话说,Tool Use 的本质不是一个接口能力点,而是执行层的核心机制。

因此,本章关注的重点不是某个协议格式,也不是某个框架如何封装工具,而是一个更基础的问题:Agent 如何理解工具、选择工具、组织参数、解释结果、约束风险,并在失败时恢复控制。

7.1 Tool Use 的系统意义

从系统视角看,Tool Use 让 Agent 第一次真正从“文本推理器”进入“环境行动者”的角色。没有工具时,模型即使能够分析任务,也很难跨越自身参数知识的边界;有了工具后,系统才可能访问实时数据、获取外部状态、执行真实动作,并根据结果继续推进任务。

这意味着 Tool Use 带来的变化至少有三个层面。

第一,信息来源变了。Agent 不再只能依赖模型内部已有知识,而可以主动到外部世界取证。它可以读文件、查数据库、访问搜索系统、调用业务 API、查询监控指标。这让“依据什么判断”不再只是模型参数问题,而变成了系统设计问题。

第二,任务闭环变了。系统不再只是输出一个答案,而是可以通过工具把答案转化成动作。查询、写入、提交、验证、通知,这些都让 Agent 的职责从“解释问题”扩展到“推进问题”。

第三,风险性质变了。只要系统具备动作能力,错误就不再只是“回答错了”,还可能是“执行错了”。这也是 Tool Use 一旦进入生产环境,就必须同时讨论权限、审计、幂等、回滚和人工确认的原因。

从这个角度看,Tool Use 并不是一个锦上添花的增强模块,而是决定 Agent 是否真正具有执行力的基础设施。它的难点也不在于“怎么让模型会调工具”,而在于“怎么让系统在不确定环境中安全地使用工具”。

flowchart LR
    A["任务目标"] --> B["是否需要工具"]
    B --> C["工具选择"]
    C --> D["参数生成"]
    D --> E["调用执行"]
    E --> F["结果标准化"]
    F --> G["状态更新"]
    G --> H["下一轮决策"]

工程提示

如果一个 Agent 的工具能力只考虑“如何调用成功”,却不考虑“如何失败、如何停下、如何追踪”,那它更像是一个危险的自动脚本,而不是一个可控的执行系统。

7.2 工具抽象与分类

要把 Tool Use 设计清楚,第一步不是让模型去试,而是先在系统层把“工具到底是什么”定义清楚。对 Agent 来说,工具本质上是对外部能力的结构化封装。这个能力可以来自搜索、数据库、文件系统、命令执行器、HTTP API,也可以来自企业内部服务。

从动作性质上看,至少可以把常见工具分成五类。

第一类是查询型工具。它们读取结构化或半结构化数据,例如查订单状态、查数据库记录、查监控指标、查工单详情。这类工具的主要价值是获取当前世界状态。

第二类是检索型工具。它们通常面向文本、文档或知识库,帮助 Agent 获取候选信息片段。和查询型工具相比,它们返回的往往不是严格结构化结果,而更像检索候选集。

第三类是写操作工具。它们会修改外部状态,例如创建工单、更新记录、改配置、发通知、提交审批。这类工具风险通常最高,因为它们会直接改变环境。

第四类是执行型工具。它们负责触发某种可运行行为,例如执行脚本、运行测试、发起构建、操作终端、调用推理服务。它们不一定直接写业务数据,但可能引发连锁副作用。

第五类是代理型工具。它们本身不是最终动作,而是一个更上层的行动入口,例如调用另一个服务 Agent、触发一段子工作流、把任务交给某个专用处理器。它们常出现在多 Agent 或复杂工作流系统中。

从风险控制角度看,还可以再做一个更重要的划分:读环境改环境

读环境的工具主要负责观察世界,例如检索、读取、查询、解析。它们的风险通常集中在权限泄露、过度查询和结果误读上。

改环境的工具则会真正改变世界,例如写入、删除、执行、触发外部流程。它们除了权限问题,还会引入幂等、审批、回滚和审计等一整套控制需求。

这两种划分叠在一起,能帮助系统更清楚地定义工具边界。例如,一个执行测试的工具属于执行型,但大多属于读环境或低风险改环境;而一个修改生产配置的工具既是执行型,也是高风险改环境。工具分类本身不只是文档工作,它直接决定后续的调用门禁和恢复策略。

工程提示

如果系统对所有工具一视同仁,只给模型一份平铺的工具清单,那通常意味着风险分级和执行约束还没有进入架构设计。

7.3 工具选择机制

Tool Use 的第一个真正难点,不是调用语法,而是选择。Agent 必须先判断当前是不是应该调用工具,再决定调用哪个工具、调用一次还是串联多次。很多系统表面上“会用工具”,但不稳定的根源恰恰是选择逻辑过于松散。

首先是“何时应该调用工具”。原则上,只要当前任务依赖外部事实、实时状态、环境动作或权限受控操作,系统就不应该只靠模型内部知识硬答。例如查询最新状态、读取仓库当前文件、确认监控指标、提交外部动作,都应优先通过工具获得依据。反过来,如果任务只是解释概念、改写文本、做局部总结,那么未必需要调用工具。

其次是“何时不该调用工具”。如果输入信息已经足够、工具结果不会增加有效信息、调用成本过高、或者工具本身风险明显高于收益,那么系统应该优先保持静态回答或先向用户澄清。一个常见反模式是,只要系统有工具,模型就习惯性乱试,结果把本来一轮能解决的问题变成了低效的多步执行。

再往下是“选哪个工具”。单工具场景中,问题主要在于描述是否足够清晰。多工具场景则更复杂,因为名称相似、能力重叠、权限等级不同、结果格式不同,都会增加选择噪声。一个成熟的工具描述应该至少回答三件事:

  • 这个工具解决什么问题。
  • 它需要什么输入。
  • 它会返回什么类型的结果,以及有哪些边界条件。

如果系统需要多工具串联,选择逻辑还必须考虑顺序。例如先检索候选信息,再查询结构化详情;先读取上下文,再执行测试;先验证权限,再执行写操作。多工具链路不能只靠模型“临场灵感”,而应通过状态、规则或工作流约束其主顺序。

最后,工具描述质量会直接影响模型决策稳定性。一个含糊的工具说明、一个语义混乱的参数名、一个没有写清副作用的执行器,都可能让模型做出错误选择。很多所谓的“模型选错工具”,本质上不是模型太弱,而是系统没有把工具抽象做成可选对象。

工程提示

工具选择问题通常先是建模问题,后才是模型问题。工具描述越混乱,后面就越不该指望模型帮你兜底。

7.4 参数生成与结果解释

选对工具之后,下一个问题是:如何把自然语言任务稳定地转成结构化参数。很多 Tool Use 失败不是因为工具本身不可用,而是因为参数生成质量不稳定,或者返回结果没有被正确解释。

参数设计首先要尽量减少歧义。字段名应反映真实语义,必填项和可选项要清晰,默认值策略应可预期,危险参数必须有额外保护。一个好的工具接口应该让模型容易“填对”,而不是让模型在多个语义相近的参数之间猜测。

面对缺省字段或不完整输入,系统通常需要明确处理原则。例如:

  • 缺少关键参数时,先澄清,不盲猜。
  • 对存在安全风险的默认值,宁可不填也不自动补。
  • 对明显可推断的低风险字段,可以按约定默认补齐。

这类原则不应散落在模型偶然行为里,而应在工具协议或控制层中被清楚定义。

参数之外,结果解释同样重要。工具返回值可能是结构化 JSON、自然语言片段、错误码、文件内容、执行日志、状态对象,甚至是“什么也没查到”。如果系统不能把这些结果标准化,就很难进入下一轮状态更新和决策。

因此,结果处理至少要完成三件事:

第一,把工具原始输出转成 Agent 能理解的状态对象。系统需要知道这是成功、失败、空结果、部分成功,还是需要重试的临时异常。

第二,把结果按需压缩进下一轮上下文。不是所有原始输出都应该原样回灌给模型,很多时候需要摘要、裁剪或结构提炼。

第三,把关键结果写入状态层。哪些文件已读、哪个命令已执行、哪个资源已修改、哪个工具连续失败,这些都必须在状态中留下痕迹,否则系统很容易重复劳动或前后矛盾。

Tool Use 稳不稳定,很多时候不取决于“这次有没有调通”,而取决于参数和结果能否被持续纳入可维护的运行机制。

工程提示

如果一个工具调用成功后,系统仍然不知道“这一步到底发生了什么”,那问题通常不在工具,而在结果标准化缺失。

7.5 失败恢复与防失控

一旦 Agent 开始调工具,失败就是常态,而不是例外。超时、空结果、权限不足、参数错误、外部依赖波动、返回格式异常,都会稳定出现。真正成熟的 Tool Use 设计,不是追求永不失败,而是让失败发生时系统仍然保持可控。

最常见的一类问题是调用失败后的恢复策略。不同失败类型应当有不同处理方式:

  • 超时和瞬时网络错误通常适合有限次重试。
  • 参数错误通常不应盲目重试,而应回到澄清或重新生成参数。
  • 权限不足通常应立即中止当前动作,并转入人工确认或权限提示。
  • 空结果通常不是报错,而是需要判断“是否换工具、换查询条件,还是直接承认没有依据”。

如果系统对所有失败一律重试,往往会在错误路径上越走越远。

另一类问题是失控执行。只要 Agent 可以连续调用工具,就会出现以下风险:

  • 工具死循环,例如反复检索同一问题却没有新信息。
  • 无意义重复调用,例如同一文件连续读取多次、同一命令重复执行。
  • 无依据写操作,例如没有充分证据就开始改状态、发通知或执行高风险动作。

防止这些问题,通常需要同时依赖几个机制:

  • 调用次数上限。
  • 重复调用检测。
  • 阶段门禁。
  • 高风险动作前确认。
  • 状态驱动的失败记忆。

这里最重要的原则是:恢复策略必须和失败原因相匹配,防失控机制必须在程序层可执行,而不能只靠 Prompt 说“请谨慎”。否则,系统在压力条件下会快速失去边界。

工程提示

比“工具失败了怎么办”更重要的问题是“工具连续失败时,系统是否知道该停下来”。

7.6 工具权限与安全边界

只要 Tool Use 进入真实业务环境,权限和安全问题就无法回避。一个系统如果允许模型接触外部动作能力,却没有明确的权限边界,那么它迟早会在错误、注入或误操作中暴露风险。

最基础的一层是工具白名单。并不是所有运行时可用工具都应该在每个阶段暴露给模型。系统需要根据任务类型、用户身份、执行阶段和风险等级,动态决定当前可见工具集合。

第二层是阶段门禁。即使某个工具对某个任务总体可用,也不意味着它在任何阶段都能被调用。例如在分析阶段允许读日志和查指标,但不允许改配置;在验证阶段允许跑测试,但不允许直接提交变更。阶段门禁本质上是把工作流控制和工具权限结合起来。

第三层是人工确认。高风险写操作、不可逆操作、跨系统联动操作,通常不应完全自动化。系统应把这些动作升级为需要人工批准的节点,而不是仅仅依靠模型自觉克制。

第四层是幂等和审计。只要工具会改环境,系统就必须知道:

  • 重复执行是否安全。
  • 执行动作是否可追踪。
  • 失败后是否可补偿。
  • 谁触发了这次动作,依据是什么。

这也是为什么很多企业 Agent 即使模型能力足够强,仍然不会轻易开放生产写权限。问题不在模型“聪不聪明”,而在系统是否准备好承接动作责任。

工程提示

权限边界永远不该只是“模型一般不会这么做”。真正的边界,必须在系统不信任模型的前提下依然成立。

7.7 本章小结

Tool Use 是 Agent 执行层的核心能力,但它真正解决的不是“如何多接几个工具”,而是“如何选择正确动作并安全落地”。从工具分类、工具选择、参数生成到结果解释、失败恢复和权限边界,这是一整套围绕外部行动构建的系统机制。

一个成熟的 Agent 并不会因为工具多就更强,而是因为它知道什么时候该调用、调用哪个、调用后如何解释结果、失败后如何停下,以及哪些动作无论如何都不能越界。只有在这些边界被设计清楚之后,Tool Use 才会成为稳定能力,而不是不受控的自动化入口。

下一章会继续把视角拉高到编排层,讨论当任务开始跨越多个阶段和多个执行单元时,Workflow 应该如何为 Agent 提供稳定主干。