Agent 如何真正“动手”:从 ReAct 到 Tool Calling 的工程实践

大模型只会生成文本,如何真正查天气、算数据、读系统?Tool Calling 将 ReAct 循环中的“行动”步骤接到真实方法上,使 Agent 从会聊天走向能办事。

在 AI Agent 的技术演进中,大模型长期面临一个根本矛盾:它擅长生成文本,却难以直接操作外部系统。无论是查询天气、计算数值,还是读取数据库,仅靠语言模型本身无法完成真实任务。Tool Calling(工具调用)机制的出现,正是为了解决这一问题。它将模型推理与外部执行连接起来,使 Agent 从“会回答”走向“能执行”。

从 ReAct 循环看工具调用的位置

在典型的 ReAct 模式中,Agent 的工作流程并非一次性输出答案,而是在“推理”和“行动”之间循环推进:模型先判断当前问题是否需要外部数据,如果需要,就发起工具调用;工具返回结果后,模型再基于结果继续推理,直到生成最终答复。

这一过程的关键在于,“行动”环节不再依赖开发者手写规则。例如,无需编写类似“如果用户问天气,就调用天气接口”的硬编码逻辑,模型可以根据工具描述自行判断何时调用、调用哪个工具、传递哪些参数。这使得 Agent 的行为更接近自主决策,而不是固定流程图。

用 Java 方法定义 Agent 能力

在 AgentScope 的工程实践中,开发者可以通过注解方式将普通 Java 方法转换为模型可调用的工具。例如,使用 @Tool 标注方法名称和功能描述,再通过 @ToolParam 说明参数含义。框架会基于这些信息自动生成工具描述,供模型理解。

  • @Tool 的 name 是工具的唯一标识,模型调用时依赖该名称。
  • @Tool 的 description 决定模型是否知道该工具适用于当前任务。
  • @ToolParam 必须显式声明参数名,否则 Java 编译后可能丢失参数信息。
  • 方法返回值会作为 Observation 重新进入 ReAct 循环,供模型继续推理。

需要注意的是,这里的注解来自 AgentScope 自身体系,而非 Spring AI 中的同名注解。混用不同框架的注解,是新手常见的错误来源。

注册工具并接入 Agent

定义工具方法只是第一步,模型并不能自动发现这些方法。开发者还需要将工具对象注册到 Toolkit 中,再由 HarnessAgent 接入。这一过程中,各组件职责相对清晰:工具类负责具体业务逻辑,Toolkit 负责收集和分发工具,Agent 则负责组合模型、提示词与工具能力。

在实际调用中,当用户提出“查询北京天气”和“计算 23 乘以 7 加 4”这类复合请求时,模型会先读取工具描述,判断需要调用 get_weather 与 calculate,随后生成带参数的调用请求。框架将请求分发到对应方法执行,再将结果返回给模型。最终输出中的天气信息和计算结果来自工具执行,而不是模型自行生成。

这种机制的价值在于,它把大模型的语言能力与真实世界的数据接口连接起来。模型不再只是“编造合理答案”,而是可以基于外部结果作答。

工具描述决定调用质量

Tool Calling 的效果很大程度取决于工具描述的质量。模型完全依赖 @Tool 和 @ToolParam 中的说明来判断工具能力和参数格式。如果描述过于模糊,模型可能出现参数错误,甚至不调用工具。

例如,仅写“城市”作为参数说明,模型可能传入“中国”“北方”等歧义值;如果补充示例,如“城市名称,例如 ‘北京’ 或 ‘Shanghai’”,参数准确性会明显提升。同理,若工具描述写成“处理一些事”,模型几乎无法判断何时使用该工具。

因此,工具描述应当像写给工程师的接口文档一样,明确能力边界、参数含义和使用示例。同时,系统提示词也可以加入硬约束,例如要求模型在询问天气、温度时必须调用指定工具,不得编造数据。这类约束在医疗、金融等对准确性要求较高的场景中尤为重要。

从同步执行到规划模式

除基础调用外,AgentScope 也支持更复杂的工程形态。工具方法可以是实例方法或静态方法,可以同步返回,也可以返回 Reactive 类型,以适配非阻塞场景。

在 HarnessAgent 2.0 中,Agent 还支持计划模式:先进行只读规划,再执行具体操作。对于不会改变外部状态的工具,可以标记 readOnly = true,使其在规划阶段也能被调用。例如获取当前时间这类只读操作,就更适合在规划过程中提前使用。

此外,在工作区模式下,开发者还可以通过 workspace/tools.json 声明 MCP server 与工具白名单,在不修改 Java 代码的情况下扩展工具能力。这为后续接入 MCP 协议和动态工具管理留下了空间。

常见工程问题

在实际开发中,Tool Calling 的失败往往不是模型能力不足,而是工程细节不到位。常见问题包括:

  • @ToolParam 未显式写 name,导致参数 Schema 生成错误或参数错位。
  • 误用 Spring AI 的 @Tool 注解,导致 AgentScope 无法扫描到工具。
  • 只定义了工具方法,但忘记调用 toolkit.registerTool,模型根本不知道工具存在。
  • 工具描述过于简略,导致模型不调用或错误调用。
  • 未在系统提示词中约束“必须调用工具”,导致模型直接生成虚构数据。
  • 使用非 DashScope 模型时,未引入对应扩展包。

Agent 工程化的重要一步

Tool Calling 的本质,是把大模型从文本生成器扩展为任务执行入口。它位于 ReAct 循环的行动环节,将模型意图转化为真实方法调用,使 Agent 具备查询、计算、执行和协同外部系统的能力。

对于开发者而言,工具定义、描述质量、系统提示词约束和注册流程,共同决定了 Agent 是否可靠。模型提供推理能力,工具提供执行能力,而工程框架则负责把两者稳定连接起来。

在 Agent 逐渐进入实际业务系统的背景下,Tool Calling 不再只是一个演示特性,而是构建可用 AI 应用的基础能力。下一步,如何把模型输出的自由文本稳定转换为结构化对象,将成为 Java 工程师需要面对的另一类核心问题。

原创文章,作者:点点,如若转载,请注明出处:https://www.dian8dian.com/agent-ru-he-zhen-zheng-dong-shou-cong-react-dao-tool

Like (0)
点点的头像点点
Previous 17小时前
Next 15小时前

相关推荐