Spring AI Alibaba - 智能体作为工具(Agent Tool)

Multi-agent 将复杂的应用程序分解为多个协同工作的专业化Agent。与依赖单个Agent处理所有步骤不同,Multi-agent架构允许你将更小、更专注的Agent组合成协调的工作流。

Multi-agent系统在以下情况下很有用:

  • 单个Agent拥有太多工具,难以做出正确的工具选择决策
  • 上下文或记忆增长过大,单个Agent难以有效跟踪
  • 任务需要专业化(例如:规划器、研究员、数学专家)

Multi-agent模式

Spring AI Alibaba支持以下Multi-agent模式:

模式 工作原理 控制流 使用场景
Tool Calling Supervisor Agent将其他Agent作为工具调用。"工具"Agent不直接与用户对话------它们只执行任务并返回结果。 集中式:所有路由都通过调用Agent。 任务编排、结构化工作流。
Handoffs 当前的Agent决定将控制权转移给另一个Agent。活动Agent随之变更,用户可以继续与新的Agent直接交互。 去中心化:Agent可以改变当前由谁来担当活跃Agent。 跨领域对话、专家接管。

选择模式

问题 工具调用 交接(Handoffs)
需要集中控制工作流程? ✅ 是 ❌ 否
希望Agent直接与用户交互? ❌ 否 ✅ 是
专家之间复杂的、类人对话? ❌ 有限 ✅ 强

你可以混合使用两种模式------使用交接 进行Agent切换,并让每个Agent将子Agent作为工具调用来执行专门任务。

自定义Agent上下文

Multi-agent设计的核心是上下文工程------决定每个Agent看到什么信息。Spring AI Alibaba 为你提供细粒度的控制:

  • 将对话或状态的哪些部分传递给每个Agent
  • 为子Agent定制专门的提示
  • 包含/排除中间推理
  • 为每个Agent自定义输入/输出格式

系统的质量在很大程度上取决于上下文工程。目标是确保每个Agent都能访问执行任务所需的正确数据,无论它是作为工具还是作为活动Agent。

工具调用(Tool Calling)

工具调用 中,一个Agent("控制器 ")将其他Agent视为工具(AgentTool),在需要时调用。控制器管理编排,而工具Agent执行特定任务并返回结果。

流程:

  1. 控制器接收输入并决定调用哪个工具(子Agent)
  2. 工具Agent根据控制器的指令运行其任务
  3. 工具Agent将结果返回给控制器
  4. 控制器决定下一步或完成任务

作为工具使用的Agent通常不期望与用户继续对话。它们的角色是执行任务并将结果返回给控制器Agent。如果你需要子Agent能够与用户对话,请改用**交接(HandOff)**模式。

关于工具调用模式的使用请查看 HandOffs 模式文档

实现

下面是一个最小示例,其中主Agent通过工具定义访问单个子Agent:

AgentTool 基础示例查看完整代码

复制代码
import com.alibaba.cloud.ai.graph.agent.ReactAgent;
import com.alibaba.cloud.ai.graph.agent.AgentTool;
import org.springframework.ai.chat.model.ChatModel;

// 创建子Agent
ReactAgent writerAgent = ReactAgent.builder()
  .name("writer_agent")
  .model(chatModel)
  .description("可以写文章")
  .instruction("你是一个知名的作家,擅长写作和创作。请根据用户的提问进行回答。")
  .build();

// 创建主Agent,将子Agent作为工具
ReactAgent blogAgent = ReactAgent.builder()
  .name("blog_agent")
  .model(chatModel)
  .instruction("根据用户给定的主题写一篇文章。使用写作工具来完成任务。")
  .tools(AgentTool.getFunctionToolCallback(writerAgent)) 
  .build();

// 使用
Optional<OverAllState> result = blogAgent.invoke("帮我写一个100字左右的散文");

在这种模式中:

  1. 主Agent在决定任务匹配子Agent的描述时调用工具
  2. 子Agent独立运行并返回结果
  3. 主Agent接收结果并继续编排

自定义点

你可以在几个点控制主Agent和子Agent之间的上下文传递:

  1. 子Agent名称"writer_agent"):这是主Agent引用子Agent的方式。由于它影响提示,请谨慎选择。
  2. 子Agent描述"可以写文章"):这是主Agent"知道"的关于子Agent的内容。它直接影响主Agent决定何时调用它。
  3. 子Agent的输入:你可以自定义此输入以更好地塑造子Agent如何解释任务。
  4. 子Agent的输出 :这是传递回主Agent的响应。你可以调整返回的内容以控制主Agent如何解释结果。

控制子Agent的输入

有两个主要杠杆来控制主Agent传递给子Agent的输入:

  • 修改提示词------调整主Agent的提示或工具元数据(即子Agent的名称和描述),以更好地指导何时以及如何调用子Agent。
  • 上下文注入 ------通过使用 inputSchemainputType 来定义结构化输入,使子Agent能够接收更丰富的上下文信息。
使用 inputSchema

使用标准的 JSON Schema 格式定义输入结构,确保子Agent能够接收结构化的输入信息:

使用 inputSchema 示例查看完整代码

复制代码
import com.alibaba.cloud.ai.graph.agent.ReactAgent;
import com.alibaba.cloud.ai.graph.agent.AgentTool;

// 定义子Agent的输入Schema(标准 JSON Schema 格式)
String writerInputSchema = """
  {
      "type": "object",
      "properties": {
          "topic": {
              "type": "string"
          },
          "wordCount": {
              "type": "integer"
          },
          "style": {
              "type": "string"
          }
      },
      "required": ["topic", "wordCount", "style"]
  }
  """;

ReactAgent writerAgent = ReactAgent.builder()
  .name("structured_writer_agent")
  .model(chatModel)
  .description("根据结构化输入写文章")
  .instruction("你是一个专业作家。请严格按照输入的主题、字数和风格要求创作文章。")
  .inputSchema(writerInputSchema) 
  .build();

ReactAgent coordinatorAgent = ReactAgent.builder()
  .name("coordinator_agent")
  .model(chatModel)
  .instruction("你需要调用写作工具来完成用户的写作请求。请根据用户需求,使用结构化的参数调用写作工具。")
  .tools(AgentTool.getFunctionToolCallback(writerAgent))
  .build();

Optional<OverAllState> result = coordinatorAgent.invoke("请写一篇关于春天的散文,大约150字");
使用 inputType

使用 Java 类型定义输入,框架会自动生成 JSON Schema:

使用 inputType 示例查看完整代码

复制代码
import com.alibaba.cloud.ai.graph.agent.ReactAgent;
import com.alibaba.cloud.ai.graph.agent.AgentTool;

// 定义输入类型
public record ArticleRequest(
  String topic,      // 文章主题
  int wordCount,     // 字数要求
  String style       // 文章风格
) {}

ReactAgent writerAgent = ReactAgent.builder()
  .name("typed_writer_agent")
  .model(chatModel)
  .description("根据类型化输入写文章")
  .instruction("你是一个专业作家。请严格按照输入的 topic(主题)、wordCount(字数)和 style(风格)要求创作文章。")
  .inputType(ArticleRequest.class) 
  .build();

ReactAgent coordinatorAgent = ReactAgent.builder()
  .name("coordinator_with_type_agent")
  .model(chatModel)
  .instruction("你需要调用写作工具来完成用户的写作请求。工具接收 JSON 格式的参数。")
  .tools(AgentTool.getFunctionToolCallback(writerAgent))
  .build();

Optional<OverAllState> result = coordinatorAgent.invoke("请写一篇关于秋天的现代诗,大约100字");

控制子Agent的输出

塑造主Agent从子Agent接收的内容的常见策略:

  • 修改提示词 ------优化子Agent的提示以指定应返回的确切内容。
    • 当输出不完整、过于冗长或缺少关键细节时很有用。
    • 常见的失败模式是子Agent执行工具调用或推理但不在最终消息中包含结果。提醒它控制器(和用户)只看到最终输出,因此必须在那里包含所有相关信息。
  • 自定义输出格式 ------使用 outputSchemaoutputType 定义结构化输出格式。
使用 outputSchema

使用 BeanOutputConverter 生成输出 Schema,提供类型安全和自动 schema 生成:

使用 outputSchema 示例查看完整代码

复制代码
import com.alibaba.cloud.ai.graph.agent.ReactAgent;
import com.alibaba.cloud.ai.graph.agent.AgentTool;
import org.springframework.ai.converter.BeanOutputConverter;

// 定义输出类型
public static class ArticleOutput {
  private String title;
  private String content;
  private int characterCount;

  // Getters and Setters
  public String getTitle() { return title; }
  public void setTitle(String title) { this.title = title; }
  public String getContent() { return content; }
  public void setContent(String content) { this.content = content; }
  public int getCharacterCount() { return characterCount; }
  public void setCharacterCount(int characterCount) { this.characterCount = characterCount; }
}

// 使用 BeanOutputConverter 生成 outputSchema
BeanOutputConverter<ArticleOutput> outputConverter = new BeanOutputConverter<>(ArticleOutput.class);
String format = outputConverter.getFormat();

ReactAgent writerAgent = ReactAgent.builder()
  .name("writer_with_output_schema")
  .model(chatModel)
  .description("写文章并返回结构化输出")
  .instruction("你是一个专业作家。请创作文章并严格按照指定的JSON格式返回结果。")
  .outputSchema(format) 
  .build();

ReactAgent coordinatorAgent = ReactAgent.builder()
  .name("coordinator_output_schema")
  .model(chatModel)
  .instruction("调用写作工具完成用户请求,工具会返回结构化的文章数据。")
  .tools(AgentTool.getFunctionToolCallback(writerAgent))
  .build();

Optional<OverAllState> result = coordinatorAgent.invoke("写一篇关于冬天的短文");
使用 outputType

使用 Java 类型定义输出,框架会自动生成输出 schema:

使用 outputType 示例查看完整代码

复制代码
import com.alibaba.cloud.ai.graph.agent.ReactAgent;
import com.alibaba.cloud.ai.graph.agent.AgentTool;
import org.springframework.ai.converter.BeanOutputConverter;

// 定义输出类型
public class ArticleOutput {
  private String title;
  private String content;
  private int characterCount;

  // getters and setters
}

ReactAgent writerAgent = ReactAgent.builder()
  .name("writer_with_output_type")
  .model(chatModel)
  .description("写文章并返回类型化输出")
  .instruction("你是一个专业作家。请创作文章并返回包含 title、content 和 characterCount 的结构化结果。")
  .outputType(ArticleOutput.class) 
  .build();

ReactAgent coordinatorAgent = ReactAgent.builder()
  .name("coordinator_output_type")
  .model(chatModel)
  .instruction("调用写作工具完成用户请求。")
  .tools(AgentTool.getFunctionToolCallback(writerAgent))
  .build();

Optional<OverAllState> result = coordinatorAgent.invoke("写一篇关于夏天的小诗");

完整类型化示例

同时使用 inputTypeoutputType 进行完整的类型化Agent工具调用:

完整类型化示例查看完整代码

复制代码
import com.alibaba.cloud.ai.graph.agent.ReactAgent;
import com.alibaba.cloud.ai.graph.agent.AgentTool;

// 定义输入和输出类型
public record ArticleRequest(String topic, int wordCount, String style) {}

public class ArticleOutput {
  private String title;
  private String content;
  private int characterCount;
  // getters and setters
}

public class ReviewOutput {
  private String comment;
  private boolean approved;
  private List<String> suggestions;
  // getters and setters
}

// 创建完整类型化的Agent
ReactAgent writerAgent = ReactAgent.builder()
  .name("full_typed_writer")
  .model(chatModel)
  .description("完整类型化的写作工具")
  .instruction("根据结构化输入(topic、wordCount、style)创作文章,并返回结构化输出(title、content、characterCount)。")
  .inputType(ArticleRequest.class) 
  .outputType(ArticleOutput.class) 
  .build();

ReactAgent reviewerAgent = ReactAgent.builder()
  .name("typed_reviewer")
  .model(chatModel)
  .description("完整类型化的评审工具")
  .instruction("对文章进行评审,返回评审意见(comment、approved、suggestions)。")
  .outputType(ReviewOutput.class) 
  .build();

ReactAgent orchestratorAgent = ReactAgent.builder()
  .name("orchestrator")
  .model(chatModel)
  .instruction("协调写作和评审流程。先调用写作工具创作文章,然后调用评审工具进行评审。")
  .tools(
      AgentTool.getFunctionToolCallback(writerAgent),
      AgentTool.getFunctionToolCallback(reviewerAgent)
  )
  .build();

Optional<OverAllState> result = orchestratorAgent.invoke("请写一篇关于友谊的散文,约200字,需要评审");

多个子Agent作为工具

在实际应用中,主Agent通常需要访问多个不同的子Agent工具,根据任务需求选择合适的工具进行调用。这种模式允许你构建更灵活、更强大的多Agent系统。

多个子Agent作为工具示例查看完整代码

复制代码
import com.alibaba.cloud.ai.graph.agent.ReactAgent;
import com.alibaba.cloud.ai.graph.agent.AgentTool;

// 创建写作Agent
ReactAgent writerAgent = ReactAgent.builder()
  .name("writer_agent")
  .model(chatModel)
  .description("专门负责创作文章和内容生成")
  .instruction("你是一个专业作家,擅长各类文章创作。")
  .build();

// 创建翻译Agent
ReactAgent translatorAgent = ReactAgent.builder()
  .name("translator_agent")
  .model(chatModel)
  .description("专门负责文本翻译工作")
  .instruction("你是一个专业翻译,能够准确翻译多种语言。")
  .build();

// 创建总结Agent
ReactAgent summarizerAgent = ReactAgent.builder()
  .name("summarizer_agent")
  .model(chatModel)
  .description("专门负责内容总结和提炼")
  .instruction("你是一个内容总结专家,擅长提炼关键信息。")
  .build();

// 创建主Agent,集成多个工具
ReactAgent multiToolAgent = ReactAgent.builder()
  .name("multi_tool_coordinator")
  .model(chatModel)
  .instruction("你可以访问多个专业工具:写作、翻译和总结。" +
          "根据用户需求选择合适的工具来完成任务。")
  .tools(
      AgentTool.getFunctionToolCallback(writerAgent),      
      AgentTool.getFunctionToolCallback(translatorAgent),  
      AgentTool.getFunctionToolCallback(summarizerAgent)   
  )
  .build();

// 使用 - 主Agent会根据需求自动选择合适的工具
Optional<OverAllState> result = multiToolAgent.invoke(
  "请写一篇关于AI的文章,然后翻译成英文,最后给出摘要");

在这种模式中:

  1. 专业化分工:每个子Agent专注于特定领域(写作、翻译、总结等)
  2. 灵活组合:主Agent可以根据任务需求调用一个或多个工具
  3. 智能路由:主Agent根据工具的描述和用户需求,自动选择合适的工具
  4. 顺序执行:主Agent可以按顺序调用多个工具,实现复杂的工作流

提示 :为每个子Agent提供清晰、准确的 description 非常重要,这直接影响主Agent如何选择合适的工具。描述应该简洁地说明Agent的职责和能力。

相关推荐
Hesionberger1 小时前
巧用异或找出唯一数字(多解)
java·数据结构·python·算法·leetcode
武雄(小星Ai)1 小时前
Gemini CLI 免费用户6月18日停服,Google Antigravity 2.0 深度解读
运维·人工智能·agent
铁链鞭策大师1 小时前
javaEE之多线程(2)
java·前端·java-ee
小北的AI科技分享1 小时前
iPaaS平台核心能力解读:五款产品功能与数据实录
人工智能·ipaas平台
Devin~Y1 小时前
从内容社区到AIGC客服:Spring Boot、Redis、Kafka、K8s、RAG的三轮大厂Java面试对话(附标准答案)
java·spring boot·redis·spring cloud·kafka·kubernetes·micrometer
KaMeidebaby1 小时前
卡梅德生物技术快报|生信实操:ChIP 染色质免疫共沉淀技术流程、短板与替代方案详解
前端·人工智能·物联网·百度·新浪微博
それども1 小时前
怎么理解TCP的状态
java·网络·网络协议·tcp/ip·dubbo
Xzh04231 小时前
Redis黑马点评 实战复盘与面试高频考点详解
java·数据库·redis·面试
新加坡内哥谈技术1 小时前
大规模可靠 LLM 推理服务的实践经验构建可靠 LLM 推理基础设施的经验总结
人工智能