Spring AI 智能体模式(第四部分):子智能体编排

预估阅读时长:10分钟

Spring AI 智能体模式(第四部分):子智能体编排

不再让一个”通才”智能体包揽所有工作,而是将任务委托给专门的智能体。这样能保持上下文窗口专注,避免杂乱的上下文导致性能下降。

Task 工具是 spring-ai-agent-utils 工具包的一部分,它是一个可移植、与模型无关的 Spring AI 实现,灵感源自 Claude Code 的子智能体。它支持分层智能体架构,让专门的子智能体在独立的上下文窗口中处理聚焦任务,仅将关键结果返回给父智能体。该架构不仅兼容 Claude 基于 Markdown 的格式,还具备可扩展性——支持 A2A 及其他智能体协议,实现异构智能体的编排(更多信息将在后续文章中提供)。

这是 Spring AI 智能体模式系列的第四部分。我们已介绍过 Agent Skills、AskUserQuestionTool 和 TodoWriteTool。现在,我们将探索分层子智能体。

准备好深入了解了吗?跳到 快速开始

工作原理

主智能体通过 Task 工具将任务委托给专门的子智能体,每个子智能体都在自己隔离的上下文窗口中运行。子智能体架构包含三个关键组件:

  1. 主智能体(编排器) 与用户交互的主要智能体。它的 LLM 可以访问 Task 工具,并通过智能体注册表(Agent Registry)获知可用的子智能体——该注册表是在启动时填充的子智能体名称和描述目录。主智能体根据每个子智能体的 description 字段自动决定何时进行委托。

  2. 智能体配置文件 子智能体被定义为 agents/ 文件夹中的 Markdown 文件(例如 agent-x.mdagent-y.md)。每个文件指定子智能体的名称、描述、允许的工具、首选模型和系统提示。这些配置在启动时填充智能体注册表和 Task 工具。

  3. 子智能体 在隔离的上下文窗口中执行的独立智能体实例。每个子智能体可以使用不同的 LLM(LLM-X、LLM-Y、LLM-Z),拥有自己的系统提示、工具和技能——从而能够根据任务复杂度进行多模型路由。

下图展示了执行流程:

  • 启动时:Task 工具加载已配置的子智能体引用,解析其名称和描述,并填充智能体注册表。
  • 用户向主智能体发送一个复杂问题。
  • 主智能体的 LLM 评估请求,并检查注册表中的可用子智能体。
  • LLM 决定通过调用 Task 工具进行委托,同时传入子智能体名称和任务描述。
  • Task 工具根据智能体配置生成相应的子智能体。
  • 子智能体在其专用的上下文窗口中自主工作。
  • 结果流回主智能体(仅包含关键发现,而非中间步骤)。
  • 主智能体综合信息,向用户返回最终答案。

每个子智能体运行时具备:

  • 专用上下文窗口 —— 与主对话隔离,防止上下文杂乱。
  • 自定义系统提示 —— 为特定领域量身定制的专业能力。
  • 可配置的工具访问权限 —— 限制为仅必要的功能。
  • 多模型路由 —— 将简单任务路由到更便宜的模型,将复杂分析交给更强的模型。
  • 并行执行 —— 同时启动多个子智能体。
  • 后台任务 —— 长时间运行的操作异步执行。

内置子智能体

Spring AI Agent Utils 提供了四个内置子智能体,配置 TaskTool 时自动注册:

子智能体用途工具
Explore快速的只读代码库探索——查找文件、搜索代码、分析内容Read, Grep, Glob
General-Purpose多步骤研究与执行,拥有完整的读写权限所有工具
Plan软件架构师,用于设计实现策略和识别权衡只读 + 搜索
Bash命令执行专家,用于 git 操作、构建和终端任务仅 Bash

详细能力请参阅参考文档。多个子智能体可以并发运行——例如,在代码评审期间同时运行 style-checker、security-scanner 和 test-coverage。


快速开始

1. 添加依赖

<dependency>
    <groupId>org.springaicommunity</groupId>
    <artifactId>spring-ai-agent-utils</artifactId>
    <version>0.4.2</version>
</dependency>

2. 配置你的智能体

import org.springaicommunity.agent.tools.task.TaskToolCallbackProvider;

@Configuration
public class AgentConfig {

    @Bean
    CommandLineRunner demo(ChatClient.Builder chatClientBuilder) {
        return args -> {
            // 配置 Task 工具
            var taskTools = TaskToolCallbackProvider.builder()
                .chatClientBuilder("default", chatClientBuilder)
                .subagentReferences(
                    ClaudeSubagentReferences.fromRootDirectory("src/main/resources/agents"))
                .build();

            // 使用 Task 工具构建主聊天客户端
            ChatClient chatClient = chatClientBuilder
                .defaultToolCallbacks(taskTools)
                .build();

            // 自然使用——智能体将委托给子智能体
            String response = chatClient
                .prompt("探索认证模块并解释其工作原理")
                .call()
                .content();
        };
    }
}

主智能体会根据子智能体的描述字段自动识别何时进行委托。

3. (可选)多模型路由

根据任务复杂度将子智能体路由到不同模型:

var taskTools = TaskToolCallbackProvider.builder()
    .chatClientBuilder("default", sonnetBuilder)   // 默认模型
    .chatClientBuilder("haiku", haikuBuilder)      // 快速、便宜
    .chatClientBuilder("opus", opusBuilder)        // 复杂分析
    .build();

子智能体在其定义中指定首选模型,Task 工具会据此进行路由。

创建自定义子智能体

自定义子智能体是带 YAML 前置元数据的 Markdown 文件,通常存储在 .claude/agents/ 中:

project-root/
├── .claude/
│   └── agents/
│       ├── code-reviewer.md
│       └── test-runner.md

子智能体文件格式

---
name: code-reviewer
description: 专家代码审查员。编写代码后主动使用。
tools: Read, Grep, Glob
disallowedTools: Edit, Write
model: sonnet
---

你是一位资深代码审查员,精通软件质量。

**被调用时:**
1. 运行 `git diff` 查看最近的更改
2. 将分析重点放在修改过的文件上
3. 检查相关的上下文代码

**审查清单:**
- 代码清晰度和可读性
- 正确的命名约定
- 错误处理
- 安全漏洞

**输出:** 清晰、可操作的反馈,并附有文件引用。

配置字段

字段必需描述
name唯一标识符(小写加连字符)
description何时使用此子智能体的自然语言描述
tools允许的工具名称(如果省略则继承所有工具)
disallowedTools显式禁止的工具
model模型偏好:haiku, sonnet, opus

其他字段如 skillspermissionMode 请参阅参考文档。

重要提示:子智能体不能生成它们自己的子智能体。切勿将 Task 包含在子智能体的工具列表中。

加载自定义子智能体

import org.springaicommunity.agent.tools.task.subagent.claude.ClaudeSubagentReferences;

var taskTools = TaskToolCallbackProvider.builder()
    .chatClientBuilder("default", chatClientBuilder)
    .subagentReferences(
        ClaudeSubagentReferences.fromRootDirectory("src/main/resources/agents")
    )
    .build();

后台执行

长时间运行的子智能体可以异步执行。主智能体在后台子智能体执行期间继续工作。需要时使用 TaskOutputTool 检索结果。有关跨实例持久化任务存储,请参阅 TaskRepository 文档。


总结

Task 工具为 Spring AI 带来了分层子智能体架构,实现了上下文隔离、专门化指令和高效的多模型路由。通过将复杂任务委托给专注的子智能体,你的主智能体可以保持轻量级和高响应性。

接下来:在第五部分,我们将探索 A2A 集成——使用 Agent2Agent 协议构建可互操作的智能体。在后续文章中,我们将介绍子智能体扩展框架——一种协议无关的抽象,用于通过 A2A、MCP 或自定义协议集成远程智能体。


资源

相关资源

系列链接

相关 Spring AI 博客


【注】本文译自:Spring AI Agentic Patterns (Part 4): Subagent Orchestration