当单个Agent的能力不足以应对复杂任务时,Subagent Orchestration提供了"分而治之"的解决方案——将大任务拆解为子任务,委派给专门的Subagent执行,最终聚合结果。
环境准备
本文示例代码基于以下技术栈:
| 组件 | 版本要求 |
|---|---|
| JDK | 17+ |
| Spring Boot | 3.2+ |
| Spring AI | 2.0.0-M3+ |
| spring-ai-agent-utils | 0.7.0 |
Maven依赖:
<dependencies>
<!-- Spring AI 核心 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-core</artifactId>
<version>2.0.0-M3</version>
</dependency>
<!-- Spring AI Agent Utils -->
<dependency>
<groupId>org.springaicommunity</groupId>
<artifactId>spring-ai-agent-utils</artifactId>
<version>0.7.0</version>
</dependency>
</dependencies>
💡 关于模型名称:本文示例中使用
haiku、sonnet、opus等模型简称,实际配置时需要使用完整模型名称如anthropic/claude-3-haiku、anthropic/claude-sonnet-4、anthropic/claude-opus-4等。不同提供商的模型命名规则可能不同,请根据实际使用的提供商调整。
一、核心问题:为什么需要Subagent?
1.1 单Agent的能力边界
场景:企业级代码库重构
1.2 Subagent的设计哲学
核心理念:分而治之 + 专业分工 + 结果聚合
二、架构设计详解
2.1 核心组件
2.2 SubagentConfig定义
public record SubagentConfig(
String name, // Subagent名称
String description, // 描述(供Orchestrator决策)
String model, // 模型标识
String systemPrompt, // 系统提示词
List<String> enabledTools, // 启用的工具
List<String> disabledTools, // 禁用的工具
int maxIterations, // 最大迭代次数
Map<String, String> metadata // 元数据(可选)
) {
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String name;
private String description;
private String model = "sonnet"; // 默认模型
private String systemPrompt = "";
private List<String> enabledTools = List.of();
private List<String> disabledTools = List.of();
private int maxIterations = 50;
private Map<String, String> metadata = Map.of();
// ... setter methods
}
}
2.3 委派流程
三、内置Subagent类型
Spring AI Agent Utils提供了四种内置Subagent:
3.1 Code Analyzer Subagent
用途:代码分析、安全审计、架构评估
@Bean
public SubagentConfig codeAnalyzerSubagent() {
return SubagentConfig.builder()
.name("code-analyzer")
.description("""
代码分析专家,用于:
- 代码质量评估
- 安全漏洞检测
- 架构合理性分析
- 性能问题识别
""")
.model("sonnet") // 分析任务使用高能力模型
.systemPrompt("""
你是一位资深代码分析师,擅长发现代码中的问题。
分析原则:
1. 先理解代码的整体结构
2. 逐层深入分析细节
3. 提供具体的问题位置和建议
输出格式:
## 分析报告
### 问题列表
| 严重程度 | 位置 | 问题描述 | 建议修复 |
|---------|------|---------|---------|
| ... | ... | ... | ... |
### 总体评价
...
""")
.enabledTools(List.of(
"read_file", "search_files", "terminal"
))
.maxIterations(30)
.build();
}
3.2 Test Writer Subagent
用途:编写单元测试、集成测试
@Bean
public SubagentConfig testWriterSubagent() {
return SubagentConfig.builder()
.name("test-writer")
.description("测试编写专家,根据代码生成高质量测试用例")
.model("sonnet")
.systemPrompt("""
你是一位测试工程师,专注于编写高质量的测试代码。
测试原则:
1. 覆盖正常路径和边界条件
2. 每个测试只验证一个行为
3. 使用有意义的测试名称
4. Mock外部依赖
技术栈:
- JUnit 5
- Mockito
- Spring Boot Test
输出要求:
- 完整可运行的测试类
- 包含必要的import
- 遵循AAA模式(Arrange-Act-Assert)
""")
.enabledTools(List.of(
"read_file", "write_file", "terminal"
))
.maxIterations(50)
.build();
}
3.3 Doc Generator Subagent
用途:生成API文档、README、架构文档
@Bean
public SubagentConfig docGeneratorSubagent() {
return SubagentConfig.builder()
.name("doc-generator")
.description("文档生成专家,根据代码生成清晰的文档")
.model("haiku") // 文档生成可以用更轻量的模型
.systemPrompt("""
你是一位技术文档撰写专家。
文档原则:
1. 结构清晰,层次分明
2. 代码示例完整可运行
3. 包含使用场景和注意事项
Markdown格式:
- 使用标准Markdown语法
- 代码块指定语言
- 表格用于参数说明
""")
.enabledTools(List.of(
"read_file", "search_files", "write_file"
))
.maxIterations(20)
.build();
}
3.4 Refactor Agent Subagent
用途:代码重构、架构调整
@Bean
public SubagentConfig refactorAgentSubagent() {
return SubagentConfig.builder()
.name("refactor-agent")
.description("代码重构专家,负责代码结构优化和设计模式应用")
.model("sonnet")
.systemPrompt("""
你是一位资深软件工程师,专注于代码重构。
重构原则:
1. 保持功能不变
2. 小步重构,每次只改一点
3. 确保测试通过
4. 不破坏现有接口
常用手法:
- 提取方法
- 提取类
- 引入设计模式
- 消除重复代码
安全措施:
- 重构前确认有测试覆盖
- 每次修改后运行测试
- 保留原始代码注释
""")
.enabledTools(List.of(
"read_file", "write_file", "patch", "terminal"
))
.maxIterations(100) // 重构可能需要更多迭代
.build();
}
四、自定义Subagent开发
4.1 创建自定义Subagent
场景:创建一个专门处理支付系统的Subagent
@Configuration
public class PaymentSubagentConfig {
@Bean
public SubagentConfig paymentExpertSubagent() {
return SubagentConfig.builder()
.name("payment-expert")
.description("""
支付系统专家,处理:
- 支付网关集成(支付宝、微信支付、Stripe)
- 订单状态管理
- 退款流程处理
- 幂等性保证
- 对账逻辑
""")
.model("sonnet")
.systemPrompt(loadPromptFromResource("prompts/payment-expert.md"))
.enabledTools(List.of(
"read_file", "write_file", "patch",
"search_files", "terminal"
))
.disabledTools(List.of(
"browser_navigate", "web_search" // 不需要网络工具
))
.maxIterations(80)
.metadata(Map.of(
"domain", "payment",
"expertise_level", "senior",
"requires_review", "true"
))
.build();
}
private String loadPromptFromResource(String path) {
try {
return new ClassPathResource(path)
.getContentAsString(StandardCharsets.UTF_8);
} catch (IOException e) {
throw new RuntimeException("Failed to load prompt: " + path, e);
}
}
}
prompts/payment-expert.md:
# 支付系统专家
你是一位资深的支付系统工程师,有10年以上的支付领域经验。
## 核心能力
### 1. 支付网关集成
- 支付宝:熟悉即时到账、手机网站支付、当面付
- 微信支付:熟悉JSAPI、H5、Native支付
- Stripe:熟悉 Charges、PaymentIntents、Webhooks
### 2. 核心问题处理
#### 幂等性设计
所有支付操作必须保证幂等性:
```java
// 使用唯一订单号作为幂等键
@Transactional
public PaymentResult processPayment(PaymentRequest request) {
// 检查是否已处理
Optional<Payment> existing = paymentRepository
.findByOrderId(request.getOrderId());
if (existing.isPresent()) {
return existing.get().toResult();
}
// 新处理...
}
状态机管理
订单状态必须严格遵循状态机:
CREATED → PENDING → PAID → COMPLETED
↘ FAILED
↘ REFUNDED
3. 安全检查清单
- 敏感信息加密存储
- 签名验证
- IP白名单
- 金额校验(防止篡改)
- 超时处理
4. 异常处理
| 异常类型 | 处理策略 |
|---|---|
| 网络超时 | 重试3次,间隔递增 |
| 余额不足 | 返回明确错误码 |
| 签名失败 | 记录日志,拒绝请求 |
| 系统异常 | 人工介入标记 |
输出规范
修改支付相关代码时:
- 保持幂等性
- 添加必要的日志
- 不改变现有接口签名
- 更新状态转换注释
### 4.2 注册自定义Subagent
```java
@Configuration
public class SubagentRegistryConfig {
@Bean
public SubagentRegistry subagentRegistry(
List<SubagentConfig> subagentConfigs) {
SubagentRegistry registry = new SubagentRegistry();
for (SubagentConfig config : subagentConfigs) {
registry.register(config);
}
return registry;
}
}
4.3 在Skill中引用Subagent
---
name: payment-migration
description: 支付系统迁移专家,处理支付模块的重构和迁移
tools: [delegate_task, read_file, write_file]
---
# 支付系统迁移
## 工作流程
1. 分析现有支付模块结构
2. 使用 `delegate_task` 委派给 `payment-expert` Subagent
3. 验证迁移结果
## 委达示例
delegate_task({ "subagent": "payment-expert", "goal": "将支付宝集成从v1迁移到v3", "context": "当前代码在 src/main/java/com/example/payment/alipay/" })
## 注意事项
- 支付相关修改必须经过 code review
- 测试覆盖率不能降低
- 保持向后兼容
五、多模型路由策略
5.1 为什么需要多模型路由?
不同任务适合不同模型:
| 任务类型 | 推荐模型 | 原因 |
|---|---|---|
| 简单文本处理 | haiku | 成本低、速度快 |
| 代码分析 | sonnet | 推理能力强 |
| 复杂架构设计 | opus | 需要深度思考 |
| 多模态处理 | vision模型 | 支持图像输入 |
5.2 路由配置
@Configuration
public class ModelRoutingConfig {
@Bean
public ChatModelRouter chatModelRouter(
@Qualifier("haikuChatModel") ChatModel haikuModel,
@Qualifier("sonnetChatModel") ChatModel sonnetModel,
@Qualifier("opusChatModel") ChatModel opusModel) {
return ChatModelRouter.builder()
// 默认模型
.defaultModel(sonnetModel)
// 按Subagent类型路由
.routeForSubagent("code-analyzer", opusModel)
.routeForSubagent("test-writer", sonnetModel)
.routeForSubagent("doc-generator", haikuModel)
.routeForSubagent("refactor-agent", sonnetModel)
.routeForSubagent("payment-expert", opusModel) // 支付用高级模型
// 按任务特征动态路由
.routeByComplexity(complexity -> {
if (complexity > 0.8) return opusModel;
if (complexity > 0.5) return sonnetModel;
return haikuModel;
})
.build();
}
}
5.3 动态复杂度评估
@Component
public class TaskComplexityEvaluator {
/**
* 评估任务复杂度(0-1)
*/
public double evaluate(String goal, String context) {
double score = 0;
// 因素1:涉及文件数量
int fileCount = countFiles(context);
score += Math.min(fileCount / 20.0, 0.3); // 最多贡献0.3
// 因素2:关键词复杂度
if (goal.contains("架构") || goal.contains("设计")) {
score += 0.2;
}
if (goal.contains("安全") || goal.contains("加密")) {
score += 0.2;
}
if (goal.contains("性能") || goal.contains("优化")) {
score += 0.15;
}
// 因素3:预估代码行数
int estimatedLines = estimateLines(goal);
score += Math.min(estimatedLines / 1000.0, 0.15);
return Math.min(score, 1.0);
}
private int countFiles(String context) {
// 统计context中提到的文件数
return (int) Pattern.compile("\\b\\w+\\.java\\b")
.matcher(context)
.results()
.count();
}
private int estimateLines(String goal) {
// 基于目标描述预估代码量
// 简化实现,实际可用ML模型
return goal.length() * 2; // 粗略估计
}
}
5.4 成本优化策略
@Service
public class CostOptimizedRouter {
private final ChatModelRouter baseRouter;
private final CostTracker costTracker;
/**
* 带预算限制的路由
*/
public ChatModel routeWithBudget(String subagentName,
String goal,
double budgetRemaining) {
// 获取模型成本
Map<String, Double> modelCosts = Map.of(
"haiku", 0.00025, // per 1K tokens
"sonnet", 0.003,
"opus", 0.015
);
// 预估Token消耗
int estimatedTokens = estimateTokens(goal);
// 选择成本合适的模型
if (budgetRemaining < modelCosts.get("haiku") * estimatedTokens / 1000) {
throw new BudgetExceededException("预算不足");
}
// 原本应该用opus,但预算不够时降级
ChatModel preferred = baseRouter.route(subagentName);
String preferredName = getModelName(preferred);
if (modelCosts.get(preferredName) * estimatedTokens / 1000 > budgetRemaining) {
// 降级到更便宜的模型
return findCheaperAlternative(preferredName, budgetRemaining,
estimatedTokens, modelCosts);
}
return preferred;
}
}
六、与A2A和MCP集成
6.1 Subagent与A2A协议
A2A(Agent-to-Agent)协议允许Subagent作为独立服务运行:
配置远程Subagent:
@Bean
public SubagentConfig remotePaymentSubagent() {
return SubagentConfig.builder()
.name("payment-expert-remote")
.description("远程支付系统专家服务")
.model("remote") // 标记为远程
.metadata(Map.of(
"a2a_endpoint", "https://payment-agent.example.com",
"auth_type", "api_key",
"timeout_seconds", "300"
))
.build();
}
A2A客户端适配器:
public class A2ASubagentAdapter implements SubagentExecutor {
private final WebClient webClient;
private final String endpoint;
@Override
public SubagentResult execute(SubagentTask task) {
// 构建A2A请求
A2ATaskRequest a2aRequest = A2ATaskRequest.builder()
.id(UUID.randomUUID().toString())
.goal(task.goal())
.context(task.context())
.build();
// 发送到远程服务
A2ATaskResponse response = webClient.post()
.uri(endpoint + "/a2a/tasks")
.bodyValue(a2aRequest)
.retrieve()
.bodyToMono(A2ATaskResponse.class)
.block(Duration.ofSeconds(300));
// 转换结果
return SubagentResult.builder()
.success(response.status() == A2ATaskStatus.COMPLETED)
.summary(response.result().summary())
.artifacts(response.result().artifacts())
.build();
}
}
6.2 Subagent与MCP协议
MCP(Model Context Protocol)允许Subagent使用MCP Server提供的工具:
@Bean
public SubagentConfig mcpEnabledSubagent() {
return SubagentConfig.builder()
.name("database-expert")
.description("数据库专家,使用MCP工具操作数据库")
.model("sonnet")
.systemPrompt("你是一位数据库专家...")
.enabledTools(List.of(
"mcp:postgres:query", // MCP Postgres工具
"mcp:postgres:schema", // 查看schema
"read_file", "write_file"
))
.build();
}
// MCP工具注册
@Bean
public McpClient postgresMcpClient() {
return McpClient.builder()
.serverUrl("http://mcp-postgres-server:8080")
.toolPrefix("postgres") // 工具前缀
.build();
}
6.3 混合架构示例
七、并行执行与结果聚合
7.1 并行委派
当多个子任务相互独立时,可以并行执行:
@Service
public class ParallelSubagentExecutor {
private final ExecutorService executor = Executors.newFixedThreadPool(4);
private final SubagentRegistry registry;
/**
* 并行执行多个Subagent
*/
public List<SubagentResult> executeParallel(
List<SubagentTask> tasks,
Duration timeout) {
List<CompletableFuture<SubagentResult>> futures = tasks.stream()
.map(task -> CompletableFuture.supplyAsync(
() -> registry.execute(task),
executor
))
.collect(Collectors.toList());
// 等待所有完成
try {
return futures.stream()
.map(f -> f.get(timeout.toMillis(), TimeUnit.MILLISECONDS))
.collect(Collectors.toList());
} catch (TimeoutException e) {
// 超时处理
futures.forEach(f -> f.cancel(true));
throw new SubagentTimeoutException(
"并行执行超时: " + timeout);
}
}
}
7.2 并行执行的错误处理
并行执行时,错误处理比串行更复杂。需要考虑部分成功、部分失败的情况:
@Component
public class FaultTolerantParallelExecutor {
private final ExecutorService executor = Executors.newFixedThreadPool(4);
private final SubagentRegistry registry;
private final int maxRetries = 3;
/**
* 容错并行执行:部分失败不影响其他任务
*/
public ParallelExecutionResult executeWithFaultTolerance(
List<SubagentTask> tasks,
Duration timeout) {
// 使用CompletableFuture处理异常
List<CompletableFuture<TaskResult>> futures = tasks.stream()
.map(task -> CompletableFuture.supplyAsync(() -> executeTask(task), executor)
.exceptionally(ex -> TaskResult.failed(task, ex)))
.collect(Collectors.toList());
// 等待所有完成(包括失败的)
List<TaskResult> results = futures.stream()
.map(f -> {
try {
return f.get(timeout.toMillis(), TimeUnit.MILLISECONDS);
} catch (Exception e) {
return TaskResult.failed(null, e);
}
})
.collect(Collectors.toList());
// 分类结果
List<SubagentResult> successes = results.stream()
.filter(TaskResult::isSuccess)
.map(TaskResult::result)
.collect(Collectors.toList());
List<TaskFailure> failures = results.stream()
.filter(TaskResult::isFailure)
.map(TaskResult::failure)
.collect(Collectors.toList());
return new ParallelExecutionResult(successes, failures);
}
/**
* 带重试的单任务执行
*/
private TaskResult executeTask(SubagentTask task) {
Exception lastException = null;
for (int attempt = 1; attempt <= maxRetries; attempt++) {
try {
SubagentResult result = registry.execute(task);
return TaskResult.success(task, result);
} catch (Exception e) {
lastException = e;
log.warn("Subagent {} execution failed (attempt {}/{}): {}",
task.subagentName(), attempt, maxRetries, e.getMessage());
// 指数退避
if (attempt < maxRetries) {
sleep(Duration.ofSeconds((long) Math.pow(2, attempt)));
}
}
}
return TaskResult.failed(task, lastException);
}
private void sleep(Duration duration) {
try {
Thread.sleep(duration.toMillis());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
/**
* 并行执行结果
*/
public record ParallelExecutionResult(
List<SubagentResult> successes,
List<TaskFailure> failures
) {
public boolean allSucceeded() {
return failures.isEmpty();
}
public double successRate() {
int total = successes.size() + failures.size();
return total > 0 ? (double) successes.size() / total : 0.0;
}
}
/**
* 任务失败记录
*/
public record TaskFailure(
SubagentTask task,
Exception exception,
int attemptCount
) {}
错误处理策略对比:
| 策略 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| Fail-Fast | 任务间强依赖 | 快速发现问题 | 部分失败导致整体失败 |
| Fail-Safe | 任务独立 | 部分失败不影响全局 | 需要额外处理失败任务 |
| Retry | 网络抖动等临时故障 | 提高成功率 | 可能掩盖系统性问题 |
| Circuit Breaker | 远程服务调用 | 防止雪崩 | 增加延迟 |
配置示例:
@Bean
public FaultTolerantParallelExecutor parallelExecutor(SubagentRegistry registry) {
return FaultTolerantParallelExecutor.builder()
.registry(registry)
.threadPoolSize(4)
.maxRetries(3)
.retryBackoff(Duration.ofSeconds(2))
.timeout(Duration.ofMinutes(5))
.failureStrategy(FailureStrategy.PARTIAL_SUCCESS) // 继续执行
.build();
}
7.3 结果聚合策略
public interface ResultAggregator {
String aggregate(List<SubagentResult> results);
}
// 简单拼接聚合器
@Component
public class ConcatAggregator implements ResultAggregator {
@Override
public String aggregate(List<SubagentResult> results) {
return results.stream()
.filter(SubagentResult::success)
.map(SubagentResult::summary)
.collect(Collectors.joining("\n\n---\n\n"));
}
}
// 结构化聚合器
@Component
public class StructuredAggregator implements ResultAggregator {
@Override
public String aggregate(List<SubagentResult> results) {
StringBuilder sb = new StringBuilder();
sb.append("# 并行执行结果汇总\n\n");
for (int i = 0; i < results.size(); i++) {
SubagentResult result = results.get(i);
sb.append(String.format("## 结果 %d: %s\n\n",
i + 1, result.subagentName()));
sb.append(result.summary()).append("\n\n");
if (!result.artifacts().isEmpty()) {
sb.append("### 产出物\n");
for (Artifact artifact : result.artifacts()) {
sb.append("- ").append(artifact.type())
.append(": ").append(artifact.name()).append("\n");
}
sb.append("\n");
}
}
// 统计信息
long successCount = results.stream()
.filter(SubagentResult::success)
.count();
sb.append(String.format("\n**成功率**: %d/%d\n",
successCount, results.size()));
return sb.toString();
}
}
7.3 冲突检测与解决
当多个Subagent修改同一文件时:
@Component
public class ConflictDetector {
public List<Conflict> detectConflicts(List<SubagentResult> results) {
Map<String, List<SubagentResult>> fileModifications = new HashMap<>();
// 收集所有文件修改
for (SubagentResult result : results) {
for (Artifact artifact : result.artifacts()) {
if (artifact.type().equals("file_modification")) {
String filePath = artifact.path();
fileModifications
.computeIfAbsent(filePath, k -> new ArrayList<>())
.add(result);
}
}
}
// 检测冲突
List<Conflict> conflicts = new ArrayList<>();
for (Map.Entry<String, List<SubagentResult>> entry :
fileModifications.entrySet()) {
if (entry.getValue().size() > 1) {
conflicts.add(new Conflict(
entry.getKey(),
entry.getValue().stream()
.map(SubagentResult::subagentName)
.collect(Collectors.toList())
));
}
}
return conflicts;
}
}
// 冲突解决策略
public interface ConflictResolver {
ResolvedModification resolve(Conflict conflict);
}
// 最新优先策略
@Component
public class LatestWinsResolver implements ConflictResolver {
@Override
public ResolvedModification resolve(Conflict conflict) {
// 选择最后完成的Subagent的修改
return conflict.results().stream()
.max(Comparator.comparing(SubagentResult::completedAt))
.map(r -> r.artifacts().stream()
.filter(a -> a.path().equals(conflict.filePath()))
.findFirst()
.orElse(null))
.map(a -> new ResolvedModification(conflict.filePath(), a.content()))
.orElse(null);
}
}
八、最佳实践与踩坑指南
8.1 常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| Subagent递归调用 | Subagent委派给自己 | 配置maxDepth=2防止无限递归 |
| 上下文污染 | Subagent共享上下文 | 确保每个Subagent有独立的ChatMemory |
| Token超限 | 并行返回大量结果 | 使用ResultAggregator压缩输出 |
| 超时失败 | Subagent执行时间过长 | 设置合理的timeout,添加进度回调 |
| 工具不可用 | Subagent缺少必要工具 | 检查enabledTools配置 |
8.2 设计原则
1. 单一职责
每个Subagent应该专注一个明确的领域:
✅ 好:payment-expert、security-auditor、test-writer
❌ 坏:general-helper、code-assistant(职责不清)
2. 适当的粒度
粒度过粗:
- full-stack-developer(太宽泛)
粒度过细:
- java-syntax-fixer
- java-import-organizer
- java-format-helper(太碎片化)
粒度适当:
- java-refactor-expert
- java-test-writer
- java-doc-generator
3. 避免循环依赖
❌ 循环依赖:
Orchestrator → A → B → A(循环)
✅ 有向无环图(DAG):
Orchestrator → A → C
→ B → C
8.3 调试技巧
启用详细日志:
logging:
level:
org.springaicommunity.agent.subagent: DEBUG
追踪Subagent调用链:
@Bean
public SubagentExecutionTracer tracer() {
return SubagentExecutionTracer.builder()
.logToFile(true)
.filePath("logs/subagent-trace.log")
.includeToolCalls(true)
.build();
}
可视化执行图:
@Component
public class SubagentGraphVisualizer {
public String toMermaid(SubagentExecutionGraph graph) {
StringBuilder sb = new StringBuilder();
// 使用字符拼接避免Markdown解析问题
sb.append("`").append("`").append("`mermaid\n");
sb.append("graph TD\n");
for (SubagentNode node : graph.nodes()) {
sb.append(String.format(" %s[%s]\n",
node.id(), node.name()));
}
for (SubagentEdge edge : graph.edges()) {
sb.append(String.format(" %s --> %s\n",
edge.from(), edge.to()));
}
sb.append("`").append("`").append("`\n");
return sb.toString();
}
}
九、总结
Subagent Orchestration的核心价值:
- 专业分工 → 每个Subagent专注擅长领域
- 上下文隔离 → 避免信息过载和污染
- 并行执行 → 提升整体效率
- 可扩展性 → 易于添加新的专业能力
与其他模式的协作:
| 模式 | 与Subagent的关系 |
|---|---|
| Agent Skills | Skill指导何时委派、委派给谁 |
| TodoWriteTool | 大任务拆分为Subagent任务 |
| AskUserQuestionTool | Subagent内部可能需要询问用户 |
| A2A | 远程Subagent通过A2A协议通信 |
| MCP | Subagent使用MCP工具扩展能力 |
| AutoMemoryTools | 保存Subagent偏好和历史结果 |
架构选择指南:
参考资料
- Spring AI Agent Utils - Subagent 文档
- Anthropic - Building Effective Agents
- A2A Protocol Specification
- Model Context Protocol