第9章-Multi-Agent系统-协作竞争与编排-《Agentic AI 智能体应用开发》
第9章:Multi-Agent 系统 —— 协作、竞争与编排
核心问题:单个 Agent 的能力有上限——上下文窗口有限、专业领域无法兼精、单点故障风险。当任务复杂度超过单一 Agent 的承载能力时,如何组织多个 Agent 协作完成任务?本章从架构模式到工程落地,系统化构建 Multi-Agent 系统。
9.1 Multi-Agent 架构模式
9.1.1 三种协作模式
Multi-Agent 系统的核心是协作拓扑——Agent 之间如何组织、如何通信、如何协调。业界经过数年实践,收敛出三种主流架构模式:
| 维度 | 集中式编排 (Orchestrator) | 分散式协作 (Decentralized) | 层级式委派 (Hierarchical) |
|---|---|---|---|
| 控制流 | 单一 Orchestrator 分发任务 | Agent 之间对等协商 | 上层 Agent 委派给下层 |
| 通信拓扑 | 星型(Hub-Spoke) | 网状(Mesh) | 树型(Tree) |
| 适用场景 | 流程固定、步骤明确 | 开放探索、动态协商 | 组织层级分明、分工会细 |
| 复杂度 | 低 | 高 | 中 |
| 可观测性 | 高(单一入口) | 低(分散决策) | 中(逐层追踪) |
| 容错性 | 低(编排器单点) | 高(无单点) | 中(上级可接管) |
| 代表框架 | LangGraph, CrewAI | AutoGen, ChatDev | Agency, MetaGPT |
集中式编排(Orchestrator Pattern):
┌─────────────────────────────────────────┐
│ Orchestrator │
│ ┌──────────────────────────────────┐ │
│ │ Task Decomposition & Assignment │ │
│ └──────────┬───────────────────────┘ │
│ │ │
│ ┌────────┼────────┬────────┐ │
│ ▼ ▼ ▼ ▼ │
│ ┌──────┐┌──────┐┌──────┐┌──────┐ │
│ Agent │ Agent │ Agent │ Agent │ │
│ A │ B │ C │ D │ │
│ └──────┘└──────┘└──────┘└──────┘ │
└─────────────────────────────────────────┘
Orchestrator 是唯一的决策者:接收任务 → 分解子任务 → 分配给专业 Agent → 汇总结果 → 返回用户。这是最可控的模式,也是生产环境中最常见的模式。
分散式协作(Decentralized Pattern):
┌──────┐ 消息 ┌──────┐
│Agent │◄─────────────►│Agent │
│ A │ │ B │
└──┬───┘ └──┬───┘
│ ┌──────┐ │
└───►│Agent │◄─────────┘
│ C │
└──────┘
没有中心调度者。每个 Agent 自主决策,通过消息传递协商任务分配。这更接近人类团队的协作方式,但工程复杂度最高——需要处理共识算法、死锁检测、消息风暴等问题。
层级式委派(Hierarchical Pattern):
┌──────────┐
│ Lead │
│ Agent │
└────┬─────┘
┌─────┴──────┐
┌────┴────┐ ┌────┴────┐
│ Manager │ │ Manager │
│ Agent A │ │ Agent B │
└────┬────┘ └────┬────┘
┌────┴───┐ ┌───┴────┐
┌──┴──┐ ┌──┴──┐┌──┴──┐┌──┴──┐
│Worker│ │Worker│Worker││Worker│
│ 1 │ │ 2 ││ 3 ││ 4 │
└─────┘ └─────┘└─────┘└─────┘
上级 Agent 负责战略决策和任务委派,下级 Agent 负责战术执行。每个 Manager 管理一个专业团队,Lead Agent 协调跨团队工作。适合大型复杂项目的分工管理。
工程化选择建议:
- 90% 的场景用集中式编排即可满足需求
- 需要多轮协商的创造性工作(如方案设计)考虑分散式协作
- 大型项目(10+ Agent)用层级式委派控制复杂度
9.1.2 Sub-Agent 设计
Sub-Agent 是 Multi-Agent 系统的基本构建单元。每个 Sub-Agent 需要明确四要素:
Sub-Agent = { Role, Capability, Interface, Lifecycle }
1. 角色定义(Role)
角色定义了 Sub-Agent 的「身份」和「职责边界」:
// TypeScript:Sub-Agent 角色定义
interface SubAgentRole {
name: string; // 角色名称,如 "CodeWriter"
description: string; // 详细职责描述
expertise: string[]; // 专业领域,如 ["TypeScript", "React"]
constraints: string[]; // 行为约束,如 "不修改数据库Schema"
}
const roles: Record<string, SubAgentRole> = {
orchestrator: {
name: "Orchestrator",
description: "负责任务分解、分配和结果整合的总协调者",
expertise: ["项目管理", "需求分析", "质量把控"],
constraints: ["不直接编写代码", "不直接操作数据库"]
},
codeWriter: {
name: "CodeWriter",
description: "根据规格编写高质量代码",
expertise: ["TypeScript", "Python", "算法", "设计模式"],
constraints: ["不修改生产环境代码", "必须输出可运行代码"]
},
reviewer: {
name: "Reviewer",
description: "审查代码质量、安全性和最佳实践",
expertise: ["代码审查", "安全审计", "性能优化"],
constraints: ["不做主观风格判断", "必须给出修改建议"]
},
tester: {
name: "Tester",
description: "编写和执行测试用例",
expertise: ["单元测试", "集成测试", "E2E测试"],
constraints: ["不修改业务代码", "必须覆盖边界条件"]
}
};
# Python:Sub-Agent 角色定义
from dataclasses import dataclass, field
from typing import List
@dataclass
class SubAgentRole:
name: str
description: str
expertise: List[str] = field(default_factory=list)
constraints: List[str] = field(default_factory=list)
ROLES = {
"orchestrator": SubAgentRole(
name="Orchestrator",
description="负责任务分解、分配和结果整合的总协调者",
expertise=["项目管理", "需求分析", "质量把控"],
constraints=["不直接编写代码", "不直接操作数据库"]
),
"code_writer": SubAgentRole(
name="CodeWriter",
description="根据规格编写高质量代码",
expertise=["TypeScript", "Python", "算法", "设计模式"],
constraints=["不修改生产环境代码", "必须输出可运行代码"]
),
"reviewer": SubAgentRole(
name="Reviewer",
description="审查代码质量、安全性和最佳实践",
expertise=["代码审查", "安全审计", "性能优化"],
constraints=["不做主观风格判断", "必须给出修改建议"]
),
"tester": SubAgentRole(
name="Tester",
description="编写和执行测试用例",
expertise=["单元测试", "集成测试", "E2E测试"],
constraints=["不修改业务代码", "必须覆盖边界条件"]
)
}
2. 能力定义(Capability)
能力定义了 Sub-Agent 可以使用哪些工具和模型:
interface SubAgentCapability {
model: string; // 使用的模型(可用不同模型做不同角色)
tools: string[]; // 可用工具列表
maxTokens: number; // 最大输出 Token
temperature: number; // 创造性参数
contextWindow: number; // 上下文窗口大小
}
// 能力配置示例
const capabilityConfig: Record<string, SubAgentCapability> = {
orchestrator: {
model: "claude-opus-4-7", // 最强推理模型
tools: ["task_delegate", "result_review"],
maxTokens: 4096,
temperature: 0.3,
contextWindow: 200000
},
codeWriter: {
model: "claude-sonnet-4-6", // 性价比高的代码模型
tools: ["read_file", "write_file", "execute_code", "search_code"],
maxTokens: 8192,
temperature: 0.1,
contextWindow: 100000
},
reviewer: {
model: "claude-sonnet-4-6",
tools: ["read_file", "static_analysis", "security_scan"],
maxTokens: 4096,
temperature: 0.1,
contextWindow: 100000
},
tester: {
model: "claude-haiku-4-5", // 快速轻量模型
tools: ["run_test", "read_file", "write_file"],
maxTokens: 4096,
temperature: 0.0,
contextWindow: 50000
}
};
3. 接口定义(Interface)
Sub-Agent 的输入输出接口需要标准化:
// 任务描述
interface AgentTask {
id: string;
type: "code_write" | "code_review" | "test_write" | "research" | "analysis";
title: string;
description: string;
context: {
files?: string[]; // 相关文件路径
dependencies?: string[]; // 依赖的其他任务 ID
constraints?: string[]; // 约束条件
};
acceptance_criteria: string[]; // 验收标准
priority: "high" | "medium" | "low";
deadline?: number; // 截止时间戳
}
// 任务结果
interface AgentResult {
taskId: string;
status: "success" | "failure" | "partial";
output: any; // 具体输出内容
artifacts?: { // 产出的文件/代码
path: string;
content: string;
language: string;
}[];
metrics?: { // 执行指标
tokensUsed: number;
duration: number;
toolCalls: number;
};
feedback?: string; // 自评/备注
}
// Sub-Agent 统一接口
interface ISubAgent {
readonly id: string;
readonly role: SubAgentRole;
readonly capability: SubAgentCapability;
execute(task: AgentTask): Promise<AgentResult>;
getStatus(): AgentStatus;
interrupt(): Promise<void>;
reset(): Promise<void>;
}
type AgentStatus = "idle" | "busy" | "error" | "terminated";
4. 生命周期管理(Lifecycle)
Sub-Agent 的生命周期状态机:
[created] ──► [idle] ──► [busy] ──► [done]
▲ │
│ ▼
│ [error] ──► [retrying]
│ │
└───────────────────────┘
(retry成功回到idle)
# Python:Sub-Agent 生命周期管理
from enum import Enum
from typing import Optional, Callable, Awaitable
import asyncio
import time
import uuid
class AgentStatus(Enum):
CREATED = "created"
IDLE = "idle"
BUSY = "busy"
ERROR = "error"
RETRYING = "retrying"
TERMINATED = "terminated"
class SubAgentLifecycle:
"""Sub-Agent 生命周期管理器"""
def __init__(self, agent_id: str, max_retries: int = 3):
self.agent_id = agent_id
self.status = AgentStatus.CREATED
self.max_retries = max_retries
self.retry_count = 0
self.current_task: Optional[str] = None
self.task_history: list[dict] = []
self.created_at = time.time()
self.last_active_at = time.time()
def can_accept_task(self) -> bool:
return self.status in (AgentStatus.IDLE, AgentStatus.CREATED)
async def execute_with_lifecycle(
self,
task_id: str,
executor: Callable[[], Awaitable[dict]],
on_error: Optional[Callable[[Exception, int], Awaitable[bool]]] = None
) -> dict:
self.status = AgentStatus.BUSY
self.current_task = task_id
self.last_active_at = time.time()
while self.retry_count <= self.max_retries:
try:
result = await executor()
self.status = AgentStatus.IDLE
self.task_history.append({
"task_id": task_id,
"status": "success",
"retries": self.retry_count,
"timestamp": time.time()
})
self.retry_count = 0
self.current_task = None
return result
except Exception as e:
self.retry_count += 1
if self.retry_count > self.max_retries:
self.status = AgentStatus.ERROR
self.task_history.append({
"task_id": task_id,
"status": "failed",
"error": str(e),
"retries": self.retry_count,
"timestamp": time.time()
})
raise
self.status = AgentStatus.RETRYING
should_retry = True
if on_error:
should_retry = await on_error(e, self.retry_count)
if not should_retry:
self.status = AgentStatus.ERROR
raise
backoff = 2 ** self.retry_count
await asyncio.sleep(backoff)
self.status = AgentStatus.ERROR
raise RuntimeError(f"Agent {self.agent_id} exceeded max retries")
9.1.3 Agent 间通信协议
Multi-Agent 系统的通信协议需要定义三个层面:消息格式、路由策略、冲突解决。
1. 消息格式
所有 Agent 间通信使用统一的消息信封格式:
// 统一消息格式
interface AgentMessage {
// 消息元信息
id: string; // 消息唯一 ID
timestamp: number; // 发送时间戳
sessionId: string; // 会话 ID(一次 Multi-Agent 会话)
// 路由信息
from: string; // 发送者 Agent ID
to: string | "broadcast" | string[]; // 接收者
// 消息内容
type: AgentMessageType;
payload: unknown;
// 关联信息
replyTo?: string; // 回复的消息 ID
taskId?: string; // 关联的任务 ID
correlationId?: string; // 关联 ID(用于追踪跨 Agent 链路)
// 控制信息
priority: "high" | "normal" | "low";
ttl: number; // 消息过期时间(秒)
}
type AgentMessageType =
| "task_assign" // 任务分配
| "task_result" // 任务结果
| "task_query" // 任务状态查询
| "context_share" // 共享上下文
| "status_update" // 状态更新
| "handshake" // 握手/发现
| "error" // 错误通知
| "heartbeat" // 心跳
| "terminate"; // 终止信号
2. 路由策略
# Python:消息路由器
from abc import ABC, abstractmethod
from typing import Dict, List, Set
import hashlib
class MessageRouter(ABC):
"""消息路由器基类"""
@abstractmethod
def route(self, message: "AgentMessage", agents: Dict[str, "SubAgent"]) -> List[str]:
"""返回目标 Agent ID 列表"""
...
class DirectRouter(MessageRouter):
"""直连路由:根据 to 字段直接路由"""
def route(self, message, agents):
if message["to"] == "broadcast":
return [aid for aid in agents if aid != message["from"]]
elif isinstance(message["to"], list):
return message["to"]
return [message["to"]]
class CapabilityRouter(MessageRouter):
"""能力路由:根据任务类型路由到最匹配的 Agent"""
def route(self, message, agents):
if message["type"] != "task_assign":
return DirectRouter().route(message, agents)
task_type = message["payload"].get("type", "")
candidates = []
for aid, agent in agents.items():
if aid == message["from"]:
continue
score = self._match_score(task_type, agent.role.expertise)
if score > 0:
candidates.append((aid, score))
candidates.sort(key=lambda x: x[1], reverse=True)
# 返回最佳的 Agent(或 Top-K)
return [c[0] for c in candidates[:1]]
def _match_score(self, task_type: str, expertise: List[str]) -> float:
task_lower = task_type.lower()
score = 0.0
for skill in expertise:
if skill.lower() in task_lower or task_lower in skill.lower():
score += 1.0
return score
class LoadBalancedRouter(MessageRouter):
"""负载均衡路由:优先空闲 Agent"""
def __init__(self, fallback: MessageRouter):
self.fallback = fallback
def route(self, message, agents):
candidates = self.fallback.route(message, agents)
idle_agents = [c for c in candidates
if agents[c].lifecycle.status.value == "idle"]
return idle_agents if idle_agents else candidates
3. 冲突解决
当多个 Agent 产出冲突的结果时,需要冲突解决机制:
# 冲突解决策略
from enum import Enum
from typing import Any, List
class ConflictStrategy(Enum):
FIRST_WINS = "first_wins" # 先到先得
LAST_WINS = "last_wins" # 后到覆盖
MAJORITY_VOTE = "majority_vote" # 多数投票
ORCHESTRATOR_DECIDES = "orchestrator" # 编排者决策
MERGE = "merge" # 智能合并
class ConflictResolver:
"""Multi-Agent 冲突解决器"""
def __init__(self, strategy: ConflictStrategy = ConflictStrategy.ORCHESTRATOR_DECIDES):
self.strategy = strategy
async def resolve(
self,
conflicts: List[dict], # [{agent_id, result, confidence}]
orchestrator: Any = None
) -> dict:
if len(conflicts) == 1:
return conflicts[0]["result"]
if self.strategy == ConflictStrategy.FIRST_WINS:
return conflicts[0]["result"]
elif self.strategy == ConflictStrategy.LAST_WINS:
return conflicts[-1]["result"]
elif self.strategy == ConflictStrategy.MAJORITY_VOTE:
return self._majority_vote(conflicts)
elif self.strategy == ConflictStrategy.ORCHESTRATOR_DECIDES:
if orchestrator is None:
# Fallback:选择置信度最高的
return max(conflicts, key=lambda c: c.get("confidence", 0))["result"]
return await orchestrator.resolve_conflict(conflicts)
elif self.strategy == ConflictStrategy.MERGE:
return await self._intelligent_merge(conflicts)
def _majority_vote(self, conflicts: List[dict]) -> dict:
from collections import Counter
# 序列化结果用于比较
import json
serialized = [json.dumps(c["result"], sort_keys=True) for c in conflicts]
counter = Counter(serialized)
winner = counter.most_common(1)[0][0]
return json.loads(winner)
async def _intelligent_merge(self, conflicts: List[dict]) -> dict:
# 使用 Orchestrator 做智能合并
# 这里是简化版:取每个冲突中置信度最高的部分
merged = {}
for conflict in conflicts:
result = conflict["result"]
if isinstance(result, dict):
for key, value in result.items():
if key not in merged:
merged[key] = value
elif conflict.get("confidence", 0) > 0.8:
merged[key] = value # 高置信度覆盖
return merged
9.1.4 架构选型决策树
何时用单 Agent,何时用 Multi-Agent?这是工程中的核心决策:
需要Multi-Agent吗?
│
├── 任务可分解为独立子任务?
│ ├── 否 → 单 Agent(一个思维链足够)
│ └── 是 → 继续判断
│ ├── 子任务需要不同专业能力?
│ │ ├── 否 → 单 Agent + 不同工具即可
│ │ └── 是 → 继续判断
│ │ ├── 子任务之间有依赖关系?
│ │ │ ├── 否 → 集中式编排(并行分发)
│ │ │ └── 是 → 继续判断
│ │ │ ├── 依赖是线性的?
│ │ │ │ ├── 是 → 集中式编排(流水线)
│ │ │ │ └── 否 → 继续判断
│ │ │ │ ├── 需要多轮协商?
│ │ │ │ │ ├── 是 → 分散式协作
│ │ │ │ │ └── 否 → 层级式委派
│ │ │ │ └── Agent 数量 > 10?
│ │ │ │ ├── 是 → 层级式委派
│ │ │ │ └── 否 → 集中式编排
│ │ │ └── 单个任务耗时 > 5分钟?
│ │ │ ├── 是 → 并行 Multi-Agent
│ │ │ └── 否 → 单 Agent 串行也可行
│ │ └── 需要不同安全级别/权限隔离?
│ │ ├── 是 → Multi-Agent(隔离执行环境)
│ │ └── 否 → 单 Agent 多工具模式
量化决策辅助公式:
MultiAgentValue = Parallelism × ExpertiseDiversity × FaultIsolation
- CoordinationOverhead × CommunicationCost
当 MultiAgentValue > 0 时,选择 Multi-Agent 架构
决策速查表:
| 场景 | 推荐架构 | 理由 |
|---|---|---|
| 代码生成 + 审查 + 测试 | 集中式编排 | 线性依赖,流程固定 |
| 多个独立数据分析 | 集中式编排(并行) | 无依赖,可并行 |
| 方案设计讨论 | 分散式协作 | 需要多轮协商 |
| 大型软件开发 | 层级式委派 | Agent 多,分工会细 |
| 客服问答 | 单 Agent | 简单,无需分工 |
| 安全审计 | Multi-Agent | 权限隔离,降低风险 |
| 内容审校 | 集中式编排(流水线) | 线性流程,专业分工 |
9.2 Multi-Agent 协作实战
9.2.1 代码开发团队:Orchestrator + CodeWriter + Reviewer + Tester
这是 Multi-Agent 最经典的落地场景:一个四人开发团队协作完成任务。
架构设计:
┌──────────────┐
│ User │
└──────┬───────┘
│ 需求描述
▼
┌──────────────┐
│ Orchestrator │
│ (Opus) │
└──────┬───────┘
│ 任务分解 + 分配
┌──────────────────┼──────────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ CodeWriter │ │ Reviewer │ │ Tester │
│ (Sonnet) │ │ (Sonnet) │ │ (Haiku) │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
│ 代码产出 │ 审查意见 │ 测试报告
▼ ▼ ▼
┌──────────────────────────────────────────────────┐
│ Shared Workspace │
│ (Git 仓库 / 共享文件系统) │
└──────────────────────────────────────────────────┘
TypeScript 完整实现:
// ---- agent-team.ts ----
import { v4 as uuid } from "uuid";
// ====== 消息总线 ======
class MessageBus {
private handlers = new Map<string, ((msg: AgentMessage) => Promise<void>)[]>();
subscribe(agentId: string, handler: (msg: AgentMessage) => Promise<void>): void {
if (!this.handlers.has(agentId)) {
this.handlers.set(agentId, []);
}
this.handlers.get(agentId)!.push(handler);
}
async publish(msg: AgentMessage): Promise<void> {
const recipients = msg.to === "broadcast"
? Array.from(this.handlers.keys()).filter(id => id !== msg.from)
: Array.isArray(msg.to) ? msg.to : [msg.to];
for (const recipient of recipients) {
const handlers = this.handlers.get(recipient) || [];
for (const handler of handlers) {
await handler(msg);
}
}
}
}
// ====== 基类 ======
abstract class BaseAgent {
id: string;
role: SubAgentRole;
protected bus: MessageBus;
protected lifecycle: SubAgentLifecycle;
protected model: any; // LLM 客户端
constructor(
id: string, role: SubAgentRole, bus: MessageBus, model: any
) {
this.id = id;
this.role = role;
this.bus = bus;
this.model = model;
this.lifecycle = new SubAgentLifecycle(id);
// 订阅发给自己的消息
bus.subscribe(id, async (msg) => {
await this.handleMessage(msg);
});
}
abstract handleMessage(msg: AgentMessage): Promise<void>;
abstract getStatus(): AgentStatus;
}
// ====== Orchestrator ======
class OrchestratorAgent extends BaseAgent {
private tasks = new Map<string, AgentTask>();
private results = new Map<string, AgentResult[]>();
private sessionId: string;
constructor(bus: MessageBus, model: any) {
super("orchestrator", ROLES.orchestrator, bus, model);
this.sessionId = uuid();
}
async handleMessage(msg: AgentMessage): Promise<void> {
switch (msg.type) {
case "task_result":
await this.handleTaskResult(msg);
break;
case "status_update":
await this.handleStatusUpdate(msg);
break;
}
}
async executeProject(requirement: string): Promise<ProjectResult> {
console.log(`[Orchestrator] 开始项目: ${requirement}`);
// 第一步:需求分析
const plan = await this.analyzeAndPlan(requirement);
console.log(`[Orchestrator] 任务分解完成: ${plan.tasks.length} 个子任务`);
// 第二步:分配任务
const taskIds = await this.assignTasks(plan.tasks);
console.log(`[Orchestrator] 任务已分配`);
// 第三步:等待完成
const results = await this.collectResults(taskIds);
// 第四步:整合结果
const finalResult = await this.integrateResults(results);
return finalResult;
}
private async analyzeAndPlan(requirement: string): Promise<TaskPlan> {
const prompt = `
作为项目编排者,分析以下需求并制定开发计划:
需求:${requirement}
请:
1. 将需求分解为独立的子任务
2. 每个子任务指定类型(code_write/code_review/test_write)
3. 标注任务间的依赖关系
4. 为每个任务指定验收标准
输出 JSON 格式的 TaskPlan。
`;
const response = await this.model.generate(prompt);
return JSON.parse(response) as TaskPlan;
}
private async assignTasks(tasks: AgentTask[]): Promise<string[]> {
const taskIds: string[] = [];
// 拓扑排序——按依赖关系排序
const sorted = this.topologicalSort(tasks);
for (const task of sorted) {
task.id = uuid();
this.tasks.set(task.id, task);
taskIds.push(task.id);
const targetRole = this.routeTask(task);
await this.bus.publish({
id: uuid(),
timestamp: Date.now(),
sessionId: this.sessionId,
from: this.id,
to: targetRole,
type: "task_assign",
payload: task,
priority: task.priority,
ttl: 600
});
}
return taskIds;
}
private routeTask(task: AgentTask): string {
switch (task.type) {
case "code_write": return "code-writer";
case "code_review": return "reviewer";
case "test_write": return "tester";
default: return "code-writer";
}
}
private topologicalSort(tasks: AgentTask[]): AgentTask[] {
const sorted: AgentTask[] = [];
const visited = new Set<string>();
const taskMap = new Map(tasks.map(t => [t.id || t.title, t]));
function visit(task: AgentTask) {
const key = task.id || task.title;
if (visited.has(key)) return;
visited.add(key);
for (const depId of (task.context?.dependencies || [])) {
const dep = taskMap.get(depId);
if (dep) visit(dep);
}
sorted.push(task);
}
for (const task of tasks) {
visit(task);
}
return sorted;
}
private async handleTaskResult(msg: AgentMessage): Promise<void> {
const result = msg.payload as AgentResult;
if (!this.results.has(result.taskId)) {
this.results.set(result.taskId, []);
}
this.results.get(result.taskId)!.push(result);
if (result.status === "failure") {
// 重新分配失败任务
console.log(`[Orchestrator] 任务 ${result.taskId} 失败,重新分配`);
const task = this.tasks.get(result.taskId);
if (task) {
await this.assignTasks([task]);
}
}
}
private async handleStatusUpdate(msg: AgentMessage): Promise<void> {
// Agent 状态变化处理
}
private async collectResults(taskIds: string[]): Promise<AgentResult[]> {
// 简化实现:轮询等待
const maxWait = 300000; // 5 分钟
const pollInterval = 1000;
let waited = 0;
while (waited < maxWait) {
const allDone = taskIds.every(id => {
const results = this.results.get(id);
return results && results.some(r => r.status === "success");
});
if (allDone) break;
await new Promise(resolve => setTimeout(resolve, pollInterval));
waited += pollInterval;
}
const collected: AgentResult[] = [];
for (const id of taskIds) {
const results = this.results.get(id);
if (results) {
collected.push(results[results.length - 1]);
}
}
return collected;
}
private async integrateResults(results: AgentResult[]): Promise<ProjectResult> {
const prompt = `
整合以下开发任务的结果:
${results.map(r => `- [${r.taskId}] ${r.status}: ${JSON.stringify(r.output)}`).join('\n')}
请:
1. 汇总所有代码文件
2. 检查是否有遗漏的功能
3. 生成最终交付报告
输出 JSON。
`;
const response = await this.model.generate(prompt);
return JSON.parse(response) as ProjectResult;
}
getStatus(): AgentStatus {
return this.lifecycle.status;
}
}
// ====== CodeWriter Agent ======
class CodeWriterAgent extends BaseAgent {
constructor(bus: MessageBus, model: any) {
super("code-writer", ROLES.codeWriter, bus, model);
}
async handleMessage(msg: AgentMessage): Promise<void> {
if (msg.type !== "task_assign") return;
const task = msg.payload as AgentTask;
console.log(`[CodeWriter] 接收任务: ${task.title}`);
try {
const result = await this.lifecycle.executeWithLifecycle(
task.id,
async () => {
const code = await this.model.generate(`
作为 ${this.role.name},请完成以下编码任务:
任务:${task.title}
描述:${task.description}
验收标准:${task.acceptance_criteria.join(', ')}
请输出完整可运行的代码。如果涉及多个文件,请标明文件路径。
`);
return {
taskId: task.id,
status: "success",
output: { code, language: "typescript" }
};
}
);
await this.bus.publish({
id: uuid(),
timestamp: Date.now(),
sessionId: (msg as any).sessionId,
from: this.id,
to: msg.from,
type: "task_result",
payload: result,
replyTo: msg.id,
taskId: task.id,
priority: "normal",
ttl: 300
});
} catch (error) {
await this.bus.publish({
id: uuid(),
timestamp: Date.now(),
sessionId: (msg as any).sessionId,
from: this.id,
to: msg.from,
type: "task_result",
payload: {
taskId: task.id,
status: "failure",
output: { error: String(error) },
feedback: `执行失败: ${error}`
},
replyTo: msg.id,
taskId: task.id,
priority: "high",
ttl: 300
});
}
}
getStatus(): AgentStatus {
return this.lifecycle.status;
}
}
// ====== Reviewer Agent ======
class ReviewerAgent extends BaseAgent {
constructor(bus: MessageBus, model: any) {
super("reviewer", ROLES.reviewer, bus, model);
}
async handleMessage(msg: AgentMessage): Promise<void> {
if (msg.type !== "task_assign") return;
const task = msg.payload as AgentTask;
console.log(`[Reviewer] 审查任务: ${task.title}`);
const review = await this.lifecycle.executeWithLifecycle(
task.id,
async () => {
const codeContent = task.context?.files?.join('\n') || task.description;
const reviewResult = await this.model.generate(`
作为代码审查者,请审查以下代码:
${codeContent}
检查点:
1. 功能正确性
2. 安全漏洞(XSS, SQL注入, 命令注入)
3. 性能问题
4. 代码可读性和可维护性
5. 是否遵循最佳实践
输出审查报告,包括:
- 严重问题(必须修复)
- 一般建议(建议改进)
- 肯定之处
- 总体评分(1-10分)
`);
return {
taskId: task.id,
status: "success",
output: { review: reviewResult }
};
}
);
await this.bus.publish({
id: uuid(),
timestamp: Date.now(),
sessionId: (msg as any).sessionId,
from: this.id,
to: msg.from,
type: "task_result",
payload: review,
replyTo: msg.id,
taskId: task.id,
priority: "normal",
ttl: 300
});
}
getStatus(): AgentStatus {
return this.lifecycle.status;
}
}
// ====== Tester Agent ======
class TesterAgent extends BaseAgent {
constructor(bus: MessageBus, model: any) {
super("tester", ROLES.tester, bus, model);
}
async handleMessage(msg: AgentMessage): Promise<void> {
if (msg.type !== "task_assign") return;
const task = msg.payload as AgentTask;
console.log(`[Tester] 测试任务: ${task.title}`);
const testResult = await this.lifecycle.executeWithLifecycle(
task.id,
async () => {
const code = task.description;
const tests = await this.model.generate(`
为以下代码编写测试:
${code}
要求:
1. 覆盖正常路径
2. 覆盖边界条件
3. 覆盖错误场景
4. 包含至少 3 个测试用例
5. 使用 vitest 框架
输出完整可运行的测试代码。
`);
return {
taskId: task.id,
status: "success",
output: { tests, framework: "vitest" }
};
}
);
await this.bus.publish({
id: uuid(),
timestamp: Date.now(),
sessionId: (msg as any).sessionId,
from: this.id,
to: msg.from,
type: "task_result",
payload: testResult,
replyTo: msg.id,
taskId: task.id,
priority: "normal",
ttl: 300
});
}
getStatus(): AgentStatus {
return this.lifecycle.status;
}
}
// ====== Team Factory ======
class DevTeam {
orchestrator: OrchestratorAgent;
codeWriter: CodeWriterAgent;
reviewer: ReviewerAgent;
tester: TesterAgent;
bus: MessageBus;
constructor(modelFactory: (role: string) => any) {
this.bus = new MessageBus();
this.orchestrator = new OrchestratorAgent(this.bus, modelFactory("orchestrator"));
this.codeWriter = new CodeWriterAgent(this.bus, modelFactory("code-writer"));
this.reviewer = new ReviewerAgent(this.bus, modelFactory("reviewer"));
this.tester = new TesterAgent(this.bus, modelFactory("tester"));
}
async build(requirement: string): Promise<ProjectResult> {
return this.orchestrator.executeProject(requirement);
}
}
Python 等价实现:
# agent_team.py
import asyncio
import json
import uuid
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional, Callable, Awaitable
from enum import Enum
import time
# ====== 消息系统 ======
@dataclass
class AgentMessage:
id: str
timestamp: float
session_id: str
from_: str
to: str | List[str]
type: str
payload: Any
reply_to: Optional[str] = None
task_id: Optional[str] = None
priority: str = "normal"
ttl: int = 300
class MessageBus:
def __init__(self):
self._handlers: Dict[str, List[Callable]] = {}
self._queue: asyncio.Queue = asyncio.Queue()
self._running = False
def subscribe(self, agent_id: str, handler: Callable):
if agent_id not in self._handlers:
self._handlers[agent_id] = []
self._handlers[agent_id].append(handler)
async def publish(self, msg: AgentMessage):
await self._queue.put(msg)
async def start(self):
self._running = True
while self._running:
msg = await self._queue.get()
recipients = (
[k for k in self._handlers if k != msg.from_]
if msg.to == "broadcast"
else (msg.to if isinstance(msg.to, list) else [msg.to])
)
for recipient in recipients:
for handler in self._handlers.get(recipient, []):
await handler(msg)
async def stop(self):
self._running = False
# ====== 基础 Agent ======
class BaseAgent(ABC):
def __init__(self, agent_id: str, role, bus: MessageBus, model):
self.id = agent_id
self.role = role
self.bus = bus
self.model = model
self.status = "idle"
self.task_history: List[dict] = []
self.max_retries = 3
bus.subscribe(agent_id, self._handle_message)
async def _handle_message(self, msg: AgentMessage):
await self.handle_message(msg)
@abstractmethod
async def handle_message(self, msg: AgentMessage):
...
async def execute_with_retry(
self, task_id: str, executor: Callable[[], Awaitable[dict]]
) -> dict:
self.status = "busy"
for attempt in range(self.max_retries + 1):
try:
result = await executor()
self.status = "idle"
self.task_history.append({
"task_id": task_id,
"status": "success",
"attempts": attempt + 1
})
return result
except Exception as e:
if attempt == self.max_retries:
self.status = "error"
self.task_history.append({
"task_id": task_id,
"status": "failed",
"error": str(e)
})
raise
await asyncio.sleep(2 ** attempt)
# ====== Orchestrator ======
class OrchestratorAgent(BaseAgent):
def __init__(self, bus: MessageBus, model):
super().__init__("orchestrator", ROLES["orchestrator"], bus, model)
self.tasks: Dict[str, dict] = {}
self.results: Dict[str, List[dict]] = {}
self.session_id = str(uuid.uuid4())
self._completion_event = asyncio.Event()
self._pending_tasks = 0
async def handle_message(self, msg: AgentMessage):
if msg.type == "task_result":
task_id = msg.task_id
if task_id not in self.results:
self.results[task_id] = []
self.results[task_id].append(msg.payload)
if msg.payload.get("status") == "failure":
task = self.tasks.get(task_id)
if task:
await self._assign_task(task)
return
self._pending_tasks -= 1
if self._pending_tasks <= 0:
self._completion_event.set()
async def execute_project(self, requirement: str) -> dict:
print(f"[Orchestrator] 开始项目: {requirement}")
plan = await self._analyze_and_plan(requirement)
tasks = plan["tasks"]
print(f"[Orchestrator] 分解为 {len(tasks)} 个子任务")
sorted_tasks = self._topological_sort(tasks)
self._pending_tasks = len(sorted_tasks)
for task in sorted_tasks:
task["id"] = str(uuid.uuid4())
self.tasks[task["id"]] = task
await self._assign_task(task)
# 等待所有任务完成
try:
await asyncio.wait_for(
self._completion_event.wait(),
timeout=300
)
except asyncio.TimeoutError:
print("[Orchestrator] 超时,收集已完成结果")
return await self._integrate_results()
async def _analyze_and_plan(self, requirement: str) -> dict:
prompt = f"""分析需求并制定开发计划: {requirement}
输出JSON: {{"tasks": [{{"title": "", "type": "code_write/code_review/test_write",
"description": "", "dependencies": [], "acceptance_criteria": []}}]}}"""
response = await self.model.generate(prompt)
return json.loads(response)
def _topological_sort(self, tasks: List[dict]) -> List[dict]:
sorted_tasks = []
visited = set()
task_map = {t.get("title", t.get("id", "")): t for t in tasks}
def visit(task):
key = task.get("title", task.get("id", ""))
if key in visited:
return
visited.add(key)
for dep_title in task.get("dependencies", []):
dep = task_map.get(dep_title)
if dep:
visit(dep)
sorted_tasks.append(task)
for task in tasks:
visit(task)
return sorted_tasks
def _route_task(self, task: dict) -> str:
task_type = task.get("type", "")
routing = {
"code_write": "code-writer",
"code_review": "reviewer",
"test_write": "tester"
}
return routing.get(task_type, "code-writer")
async def _assign_task(self, task: dict):
target = self._route_task(task)
await self.bus.publish(AgentMessage(
id=str(uuid.uuid4()),
timestamp=time.time(),
session_id=self.session_id,
from_=self.id,
to=target,
type="task_assign",
payload=task,
task_id=task["id"]
))
async def _integrate_results(self) -> dict:
all_results = []
for task_id, results in self.results.items():
if results:
all_results.append(results[-1])
return {
"status": "completed",
"total_tasks": len(self.tasks),
"successful": sum(1 for r in all_results if r.get("status") == "success"),
"failed": sum(1 for r in all_results if r.get("status") == "failure"),
"results": all_results
}
# ====== CodeWriter ======
class CodeWriterAgent(BaseAgent):
def __init__(self, bus: MessageBus, model):
super().__init__("code-writer", ROLES["code_writer"], bus, model)
async def handle_message(self, msg: AgentMessage):
if msg.type != "task_assign":
return
task = msg.payload
print(f"[CodeWriter] 任务: {task['title']}")
try:
result = await self.execute_with_retry(task["id"], lambda: self._write_code(task))
await self._send_result(msg, task["id"], result, "success")
except Exception as e:
await self._send_result(msg, task["id"], {"error": str(e)}, "failure")
async def _write_code(self, task: dict) -> dict:
prompt = f"""编写代码: {task['title']}\n描述: {task['description']}
验收标准: {', '.join(task.get('acceptance_criteria', []))}
输出完整可运行代码,多文件标明路径。"""
code = await self.model.generate(prompt)
return {"code": code, "language": "typescript"}
async def _send_result(self, msg, task_id, output, status):
await self.bus.publish(AgentMessage(
id=str(uuid.uuid4()),
timestamp=time.time(),
session_id=msg.session_id,
from_=self.id,
to=msg.from_,
type="task_result",
payload={"taskId": task_id, "status": status, "output": output},
reply_to=msg.id,
task_id=task_id
))
# ====== Reviewer ======
class ReviewerAgent(BaseAgent):
def __init__(self, bus: MessageBus, model):
super().__init__("reviewer", ROLES["reviewer"], bus, model)
async def handle_message(self, msg: AgentMessage):
if msg.type != "task_assign":
return
task = msg.payload
print(f"[Reviewer] 审查: {task['title']}")
prompt = f"""审查代码:\n{task.get('description', '')}
检查: 功能正确性/安全/性能/可维护性。输出JSON: {{"issues": [], "score": 0}}"""
response = await self.model.generate(prompt)
review = json.loads(response)
await self.bus.publish(AgentMessage(
id=str(uuid.uuid4()),
timestamp=time.time(),
session_id=msg.session_id,
from_=self.id,
to=msg.from_,
type="task_result",
payload={"taskId": task["id"], "status": "success", "output": review},
task_id=task["id"]
))
# ====== Tester ======
class TesterAgent(BaseAgent):
def __init__(self, bus: MessageBus, model):
super().__init__("tester", ROLES["tester"], bus, model)
async def handle_message(self, msg: AgentMessage):
if msg.type != "task_assign":
return
task = msg.payload
print(f"[Tester] 测试: {task['title']}")
prompt = f"""为代码编写测试:\n{task.get('description', '')}
覆盖正常/边界/错误路径,至少3个用例,使用pytest框架。"""
tests = await self.model.generate(prompt)
await self.bus.publish(AgentMessage(
id=str(uuid.uuid4()),
timestamp=time.time(),
session_id=msg.session_id,
from_=self.id,
to=msg.from_,
type="task_result",
payload={"taskId": task["id"], "status": "success", "output": {"tests": tests}},
task_id=task["id"]
))
# ====== 团队工厂 ======
class DevTeam:
def __init__(self, model_factory):
self.bus = MessageBus()
self.orchestrator = OrchestratorAgent(self.bus, model_factory("orchestrator"))
self.code_writer = CodeWriterAgent(self.bus, model_factory("code_writer"))
self.reviewer = ReviewerAgent(self.bus, model_factory("reviewer"))
self.tester = TesterAgent(self.bus, model_factory("tester"))
async def build(self, requirement: str) -> dict:
bus_task = asyncio.create_task(self.bus.start())
result = await self.orchestrator.execute_project(requirement)
await self.bus.stop()
bus_task.cancel()
return result
# ====== 使用示例 ======
async def main():
class MockModel:
async def generate(self, prompt: str) -> str:
# 实际使用时应替换为真实 LLM API 调用
return '{"tasks": [{"title": "实现用户登录", "type": "code_write", "description": "实现JWT登录", "dependencies": [], "acceptance_criteria": ["支持用户名密码登录"]}]}'
team = DevTeam(lambda role: MockModel())
result = await team.build("实现用户管理系统")
print(json.dumps(result, indent=2, ensure_ascii=False))
if __name__ == "__main__":
asyncio.run(main())
9.2.2 内容生产流水线:Researcher + Writer + Editor + Translator
内容生产是多步骤线性流程的典型场景。与代码开发的不同在于:每个步骤有明确的质量关卡,不合格需要回退重做。
架构设计:
┌──────────────────────────────────────────────────────────────┐
│ Content Pipeline │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │Researcher│──►│ Writer │──►│ Editor │──►│Translator│ │
│ │ 研究 │ │ 写作 │ │ 编辑 │ │ 翻译 │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Quality Gate (质量关卡) │ │
│ │ ✓ 事实准确 ✓ 逻辑通顺 ✓ 风格一致 ✓ 翻译准确 │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ 不合格 → 回退到上一步 → 重新执行 → 再次质检 │
└──────────────────────────────────────────────────────────────┘
Pipeline 实现:
# content_pipeline.py
import asyncio
from dataclasses import dataclass
from typing import Any, Dict, List, Optional, Callable
from enum import Enum
import json
class QualityResult(Enum):
PASS = "pass"
REVISE = "revise" # 需要修改
REJECT = "reject" # 拒绝,回退上一步
@dataclass
class ContentItem:
id: str
title: str
raw_content: str = ""
research_notes: str = ""
draft: str = ""
edited: str = ""
translated: str = ""
quality_scores: Dict[str, float] = field(default_factory=dict)
revision_history: List[dict] = field(default_factory=list)
class ContentPipeline:
"""内容生产流水线"""
def __init__(self, model_factory, max_revisions: int = 3):
self.models = {
"research": model_factory("research", temperature=0.3),
"write": model_factory("write", temperature=0.7),
"edit": model_factory("edit", temperature=0.3),
"translate": model_factory("translate", temperature=0.2),
}
self.max_revisions = max_revisions
async def process(self, topic: str, target_lang: str = "zh") -> ContentItem:
item = ContentItem(id=str(__import__('uuid').uuid4()), title=topic)
print(f"[Pipeline] 开始处理: {topic}")
# Stage 1: Research
item = await self._research(item)
if not await self._quality_check(item, "research"):
return item
# Stage 2: Write
item = await self._write(item)
if not await self._quality_check(item, "write"):
return item
# Stage 3: Edit
item = await self._edit(item)
if not await self._quality_check(item, "edit"):
return item
# Stage 4: Translate (optional)
if target_lang != "zh":
item = await self._translate(item, target_lang)
await self._quality_check(item, "translate")
print(f"[Pipeline] 完成: {item.title}")
return item
async def _research(self, item: ContentItem) -> ContentItem:
print(f" [Research] 研究主题: {item.title}")
prompt = f"""你是资深研究员。研究以下主题并提供结构化的研究笔记:
主题: {item.title}
要求:
1. 列出5-8个关键要点
2. 每个要点包含事实/数据支撑
3. 标注信息来源的可靠性(高/中/低)
4. 识别不同观点的争议点
5. 提供可用于写作的素材引用
输出格式:
## 关键要点
1. [要点] (来源: xxx, 可靠性: 高)
...
## 争议点
- ...
## 写作素材
- ..."""
research = await self.models["research"].generate(prompt)
item.research_notes = research
item.revision_history.append({
"stage": "research",
"timestamp": __import__('time').time(),
"content_length": len(research)
})
return item
async def _write(self, item: ContentItem) -> ContentItem:
print(f" [Writer] 撰写初稿: {item.title}")
prompt = f"""你是专业内容写作者。基于以下研究笔记撰写一篇文章:
研究笔记:
{item.research_notes}
要求:
1. 文章长度 1500-2500 字
2. 结构: 引言 → 主体(3-5个论点) → 结论
3. 语言通俗但不失专业
4. 数据引用使用脚注格式
5. 使用中文写作"""
draft = await self.models["write"].generate(prompt)
item.draft = draft
item.revision_history.append({
"stage": "write",
"timestamp": __import__('time').time(),
"content_length": len(draft)
})
return item
async def _edit(self, item: ContentItem) -> ContentItem:
print(f" [Editor] 编辑优化: {item.title}")
for revision in range(self.max_revisions):
prompt = f"""你是资深编辑。审查并优化以下文章:
原始文章:
{item.draft}
检查清单:
1. 逻辑连贯性 - 段落间过渡是否自然
2. 事实准确性 - 数据和引用是否正确
3. 语言流畅性 - 是否有冗余或拗口表达
4. 结构优化 - 是否有更好的组织方式
5. 读者吸引力 - 开头是否吸引人,结尾是否有力
请输出优化后的完整文章。如需补充内容请在文章末尾以## 编辑备注标注。"""
edited = await self.models["edit"].generate(prompt)
item.edited = edited
# 自我评估
quality_score = await self._self_evaluate(edited)
item.quality_scores["edit"] = quality_score
if quality_score >= 0.8:
break
else:
print(f" [Editor] 第{revision+1}轮评分{quality_score:.2f},继续优化")
item.draft = edited # 下一轮基于本轮结果
return item
async def _translate(self, item: ContentItem, target_lang: str) -> ContentItem:
print(f" [Translator] 翻译为 {target_lang}")
source = item.edited or item.draft
prompt = f"""你是专业翻译。将以下内容翻译为{target_lang}:
{source}
要求:
1. 保持原文的语气和风格
2. 专业术语准确翻译
3. 文化特定表达适当本地化
4. 保留原文的格式和结构"""
translated = await self.models["translate"].generate(prompt)
item.translated = translated
return item
async def _quality_check(self, item: ContentItem, stage: str) -> bool:
"""质量关卡"""
content = {
"research": item.research_notes,
"write": item.draft,
"edit": item.edited,
"translate": item.translated
}.get(stage, "")
if not content:
print(f" [QC] {stage} 阶段内容为空, 判定失败")
return False
score = await self._self_evaluate(content)
item.quality_scores[stage] = score
if score >= 0.7:
print(f" [QC] {stage} 通过 (评分: {score:.2f})")
return True
elif score >= 0.4:
print(f" [QC] {stage} 需要修改 (评分: {score:.2f})")
return True # 进入下一阶段时 Editor 会处理
else:
print(f" [QC] {stage} 不合格 (评分: {score:.2f})")
return False
async def _self_evaluate(self, content: str) -> float:
"""让模型自我评估内容质量"""
prompt = f"""请评估以下内容的整体质量(0-1分):
{content[:2000]} # 取前2000字评估
评估维度: 准确性(40%), 流畅性(30%), 结构性(20%), 吸引力(10%)
仅输出一个0-1之间的数字。"""
try:
score = float((await self.models["edit"].generate(prompt)).strip())
return max(0.0, min(1.0, score))
except:
return 0.5
9.2.3 可动态扩缩的 Agent 团队框架
生产环境中,Agent 团队需要动态扩缩——根据任务复杂度自动调整团队成员数量。
// dynamic-team.ts —— 动态扩缩的 Agent 团队
interface TeamConfig {
minMembers: number;
maxMembers: number;
scaleUpThreshold: number; // 队列积压超过此值则扩容
scaleDownThreshold: number; // 队列空闲超过此时间则缩容
idleTimeoutMs: number;
}
class DynamicAgentTeam {
private agents: Map<string, BaseAgent> = new Map();
private taskQueue: AgentTask[] = [];
private agentPool: Map<string, BaseAgent> = new Map();
private config: TeamConfig;
constructor(
private agentFactory: (role: string) => BaseAgent,
config: Partial<TeamConfig> = {}
) {
this.config = {
minMembers: 2,
maxMembers: 10,
scaleUpThreshold: 3,
scaleDownThreshold: 60000,
idleTimeoutMs: 300000,
...config
};
}
async initialize(roles: string[]): Promise<void> {
// 启动最小规模的团队
for (const role of roles.slice(0, this.config.minMembers)) {
await this.addAgent(role);
}
this.startAutoScaler();
}
async submitTask(task: AgentTask): Promise<AgentResult> {
this.taskQueue.push(task);
// 检查是否需要扩容
if (this.taskQueue.length > this.config.scaleUpThreshold) {
await this.scaleUp();
}
// 等待有空闲的 Agent
const agent = await this.findAvailableAgent(task.type);
if (!agent) {
// 所有 Agent 都忙,入队等待
return new Promise(resolve => {
// 实际实现中需要任务队列管理
const checkInterval = setInterval(async () => {
const freeAgent = await this.findAvailableAgent(task.type);
if (freeAgent) {
clearInterval(checkInterval);
const result = await freeAgent.execute(task);
resolve(result);
}
}, 1000);
});
}
return agent.execute(task);
}
private async addAgent(role: string): Promise<void> {
if (this.agents.size >= this.config.maxMembers) {
console.log(`[Team] 已达最大规模 ${this.config.maxMembers},无法扩容`);
return;
}
const agent = this.agentFactory(role);
this.agents.set(agent.id, agent);
this.agentPool.set(agent.id, agent);
console.log(`[Team] Agent ${agent.id} (${role}) 加入团队 | 当前规模: ${this.agents.size}`);
}
private async removeAgent(agentId: string): Promise<void> {
if (this.agents.size <= this.config.minMembers) {
console.log(`[Team] 已达最小规模 ${this.config.minMembers},无法缩容`);
return;
}
const agent = this.agents.get(agentId);
if (agent && agent.lifecycle.status === "idle") {
await agent.lifecycle.terminate();
this.agents.delete(agentId);
this.agentPool.delete(agentId);
console.log(`[Team] Agent ${agentId} 离开团队 | 当前规模: ${this.agents.size}`);
}
}
private async scaleUp(): Promise<void> {
// 根据队列中的任务类型确定需要什么角色的 Agent
const taskTypes = new Set(this.taskQueue.map(t => t.type));
const existingRoles = new Set(
Array.from(this.agents.values()).map(a => a.role.name)
);
for (const type of taskTypes) {
const requiredRole = this.taskTypeToRole(type);
if (!existingRoles.has(requiredRole)) {
await this.addAgent(requiredRole);
}
}
}
private async scaleDown(): Promise<void> {
// 找出空闲时间最长的 Agent
const idleAgents = Array.from(this.agents.entries())
.filter(([_, agent]) => agent.lifecycle.status === "idle")
.sort((a, b) => a[1].lifecycle.lastActiveAt - b[1].lifecycle.lastActiveAt);
for (const [id, agent] of idleAgents) {
const idleDuration = Date.now() - agent.lifecycle.lastActiveAt;
if (idleDuration > this.config.idleTimeoutMs) {
await this.removeAgent(id);
break; // 一次只移除一个,逐步缩容
}
}
}
private startAutoScaler(): void {
setInterval(async () => {
if (this.taskQueue.length > this.config.scaleUpThreshold) {
await this.scaleUp();
} else if (this.taskQueue.length === 0) {
await this.scaleDown();
}
}, 30000); // 每30秒检查一次
}
private async findAvailableAgent(taskType: string): Promise<BaseAgent | null> {
for (const agent of this.agents.values()) {
if (agent.lifecycle.status === "idle" && this.matchTaskType(agent, taskType)) {
return agent;
}
}
return null;
}
private taskTypeToRole(type: string): string {
const mapping: Record<string, string> = {
"code_write": "CodeWriter",
"code_review": "Reviewer",
"test_write": "Tester",
"research": "Researcher",
"write": "Writer",
"edit": "Editor"
};
return mapping[type] || "Generalist";
}
private matchTaskType(agent: BaseAgent, taskType: string): boolean {
return agent.role.name === this.taskTypeToRole(taskType);
}
}
9.3 Agent 团队管理
9.3.1 任务分配策略
任务分配是 Multi-Agent 系统的核心调度问题。有效的分配策略直接影响系统吞吐量和输出质量。
1. 基于能力的匹配(Capability-based Matching)
# task_assignment.py
from typing import List, Dict, Tuple
import numpy as np
class CapabilityMatcher:
"""基于能力的任务-Agent匹配"""
def __init__(self):
# 能力矩阵:每个Agent在每个维度上的能力分数(0-1)
self.capability_matrix: Dict[str, Dict[str, float]] = {}
def register_agent(self, agent_id: str, capabilities: Dict[str, float]):
self.capability_matrix[agent_id] = capabilities
def match(self, task_requirements: Dict[str, float]) -> List[Tuple[str, float]]:
"""
返回按匹配度排序的Agent列表
task_requirements: 任务在各维度上的需求权重
"""
scores = []
for agent_id, caps in self.capability_matrix.items():
score = self._cosine_similarity(task_requirements, caps)
scores.append((agent_id, score))
scores.sort(key=lambda x: x[1], reverse=True)
return scores
def _cosine_similarity(
self, a: Dict[str, float], b: Dict[str, float]
) -> float:
all_keys = set(a.keys()) | set(b.keys())
vec_a = [a.get(k, 0) for k in all_keys]
vec_b = [b.get(k, 0) for k in all_keys]
dot = sum(x * y for x, y in zip(vec_a, vec_b))
norm_a = np.sqrt(sum(x * x for x in vec_a))
norm_b = np.sqrt(sum(x * x for x in vec_b))
if norm_a == 0 or norm_b == 0:
return 0.0
return dot / (norm_a * norm_b)
# 使用示例
matcher = CapabilityMatcher()
matcher.register_agent("agent-1", {
"typescript": 0.95, "python": 0.7, "architecture": 0.6,
"testing": 0.3, "devops": 0.2
})
matcher.register_agent("agent-2", {
"typescript": 0.3, "python": 0.95, "architecture": 0.8,
"testing": 0.9, "devops": 0.5
})
matcher.register_agent("agent-3", {
"typescript": 0.5, "python": 0.5, "architecture": 0.9,
"testing": 0.95, "devops": 0.9
})
# 找一个做前端开发的Agent
best = matcher.match({"typescript": 0.9, "python": 0.1})
print(best) # [("agent-1", 0.99), ("agent-3", 0.53), ("agent-2", 0.12)]
2. 负载均衡策略
class LoadBalancer:
"""多种负载均衡策略"""
@staticmethod
def round_robin(agents: List[dict], task_queue: List[dict]) -> List[Tuple[str, str]]:
"""轮询分配"""
assignments = []
available = [a for a in agents if a["status"] == "idle"]
for i, task in enumerate(task_queue):
if not available:
break
agent = available[i % len(available)]
assignments.append((agent["id"], task["id"]))
return assignments
@staticmethod
def least_connections(agents: List[dict], task_queue: List[dict]) -> List[Tuple[str, str]]:
"""最少连接数优先"""
assignments = []
available = sorted(
[a for a in agents if a["status"] == "idle"],
key=lambda a: a.get("active_tasks", 0)
)
for i, task in enumerate(task_queue):
if i >= len(available):
break
assignments.append((available[i]["id"], task["id"]))
return assignments
@staticmethod
def weighted_capacity(
agents: List[dict], task_queue: List[dict]
) -> List[Tuple[str, str]]:
"""加权容量分配——根据Agent能力权重分配"""
assignments = []
available = [a for a in agents if a["status"] == "idle"]
for task in task_queue:
if not available:
break
# 找到最适合此任务的Agent(能力匹配度最高的)
best_agent = max(
available,
key=lambda a: CapabilityMatcher()._cosine_similarity(
task.get("requirements", {}),
a.get("capabilities", {})
)
)
assignments.append((best_agent["id"], task["id"]))
best_agent["active_tasks"] = best_agent.get("active_tasks", 0) + 1
return assignments
3. 优先级调度
import heapq
from dataclasses import dataclass, field
from typing import Any
@dataclass(order=True)
class PrioritizedTask:
priority: int # 越小越优先
created_at: float = field(compare=False)
task_id: str = field(compare=False)
payload: Any = field(compare=False)
deadline: float = field(default=float('inf'), compare=False)
class PriorityScheduler:
"""支持优先级+截止时间的任务调度器"""
def __init__(self):
self._heap: List[PrioritizedTask] = []
self._completed: Dict[str, Any] = {}
def enqueue(self, task: dict, priority: int = 5, deadline: float = float('inf')):
# deadline越近,优先级临时提升
effective_priority = priority
if deadline < float('inf'):
urgency = max(0, int((deadline - __import__('time').time()) / 60))
effective_priority = max(0, priority - urgency)
heapq.heappush(self._heap, PrioritizedTask(
priority=effective_priority,
created_at=__import__('time').time(),
task_id=task["id"],
payload=task,
deadline=deadline
))
def dequeue(self) -> Optional[dict]:
if not self._heap:
return None
item = heapq.heappop(self._heap)
return item.payload
def peek(self) -> Optional[dict]:
if not self._heap:
return None
return self._heap[0].payload
def __len__(self):
return len(self._heap)
9.3.2 团队状态同步
多个 Agent 共享状态是 Multi-Agent 系统最复杂的挑战之一。核心方案有三种:
方案对比:
| 方案 | 一致性 | 延迟 | 复杂度 | 适用场景 |
|---|---|---|---|---|
| 共享记忆(Shared Memory) | 强 | 低 | 中 | 集中式编排 |
| 消息广播(Broadcast) | 最终 | 中 | 低 | 分散式协作 |
| 分布式共识(Consensus) | 强 | 高 | 高 | 关键决策 |
共享记忆实现:
// shared-memory.ts
interface SharedMemory {
// 任务状态
tasks: Map<string, TaskState>;
// 全局上下文
context: {
projectGoal: string;
constraints: string[];
decisions: Decision[];
};
// Agent状态
agentStates: Map<string, AgentState>;
// 共享知识
knowledge: Map<string, any>;
}
class SharedMemoryManager {
private memory: SharedMemory;
private locks: Map<string, Promise<void>> = new Map();
private subscribers: Map<string, ((key: string, value: any) => void)[]> = new Map();
constructor() {
this.memory = {
tasks: new Map(),
context: { projectGoal: "", constraints: [], decisions: [] },
agentStates: new Map(),
knowledge: new Map()
};
}
// 带锁的原子写入
async atomicUpdate<T>(
section: keyof SharedMemory,
key: string,
updater: (current: any) => T
): Promise<T> {
const lockKey = `${section}:${key}`;
// 等待锁释放
while (this.locks.has(lockKey)) {
await this.locks.get(lockKey);
}
// 获取锁
let releaseLock: () => void;
this.locks.set(lockKey, new Promise(resolve => {
releaseLock = resolve;
}));
try {
const sectionMap = this.memory[section] as Map<string, any>;
const current = sectionMap.get(key);
const updated = updater(current);
sectionMap.set(key, updated);
// 通知订阅者
this.notify(`${section}:${key}`, updated);
return updated;
} finally {
this.locks.delete(lockKey);
releaseLock!();
}
}
// 订阅变更
subscribe(
agentId: string,
callback: (key: string, value: any) => void
): void {
if (!this.subscribers.has(agentId)) {
this.subscribers.set(agentId, []);
}
this.subscribers.get(agentId)!.push(callback);
}
private notify(key: string, value: any): void {
for (const [agentId, callbacks] of this.subscribers) {
for (const cb of callbacks) {
cb(key, value);
}
}
}
// 获取全局状态快照
getSnapshot(): SharedMemorySnapshot {
return {
taskCount: this.memory.tasks.size,
activeAgents: Array.from(this.memory.agentStates.values())
.filter(s => s === "busy").length,
decisions: [...this.memory.context.decisions],
timestamp: Date.now()
};
}
}
消息广播同步:
# broadcast_sync.py
import asyncio
from typing import Any, Dict, Set
class BroadcastSyncManager:
"""基于消息广播的状态同步"""
def __init__(self, bus, sync_interval: float = 5.0):
self.bus = bus
self.local_state: Dict[str, Any] = {}
self.peer_states: Dict[str, Dict[str, Any]] = {}
self.version_vector: Dict[str, int] = {} # Agent ID → 版本号
self.sync_interval = sync_interval
self._pending_updates: Set[str] = set()
def update_local(self, key: str, value: Any):
"""更新本地状态并广播"""
self.local_state[key] = value
self.version_vector[self.agent_id] = self.version_vector.get(self.agent_id, 0) + 1
self._pending_updates.add(key)
async def broadcast_state(self):
"""定期广播本地状态"""
if not self._pending_updates:
return
updates = {
key: self.local_state[key]
for key in self._pending_updates
}
await self.bus.publish({
"type": "state_sync",
"from": self.agent_id,
"to": "broadcast",
"payload": {
"updates": updates,
"version": self.version_vector[self.agent_id]
}
})
self._pending_updates.clear()
async def handle_state_sync(self, msg: dict):
"""处理收到的状态同步消息"""
sender_id = msg["from"]
sender_version = msg["payload"]["version"]
updates = msg["payload"]["updates"]
# 忽略旧版本
current_version = self.peer_states.get(sender_id, {}).get("_version", 0)
if sender_version <= current_version:
return
# 合并状态
if sender_id not in self.peer_states:
self.peer_states[sender_id] = {}
self.peer_states[sender_id].update(updates)
self.peer_states[sender_id]["_version"] = sender_version
async def start_sync_loop(self):
"""启动定期同步循环"""
while True:
await self.broadcast_state()
await asyncio.sleep(self.sync_interval)
9.3.3 故障处理
Multi-Agent 系统中,单个 Agent 的故障不应导致整个团队瘫痪。
故障模型:
故障类型:
├── 崩溃故障 (Crash Failure) —— Agent 完全停止响应
├── 超时故障 (Timeout Failure) —— Agent 执行超时
├── 拜占庭故障 (Byzantine Failure) —— Agent 产生错误/恶意输出
└── 资源耗尽 (Resource Exhaustion) —— Token/内存/磁盘耗尽
故障处理策略:
// fault-tolerance.ts
interface FaultPolicy {
maxRetries: number;
retryBackoff: "fixed" | "exponential" | "linear";
fallbackAgent?: string; // 接管Agent
timeoutMs: number;
circuitBreakerThreshold: number; // 熔断阈值
}
class FaultTolerantManager {
private failures = new Map<string, FailureRecord[]>();
private circuitBreakers = new Map<string, CircuitBreakerState>();
private healthCheckInterval = 10000; // 10秒
constructor(private bus: MessageBus, private policy: FaultPolicy) {
this.startHealthChecks();
}
async executeWithFaultTolerance(
agent: BaseAgent,
task: AgentTask
): Promise<AgentResult> {
// 检查熔断器
if (this.isCircuitOpen(agent.id)) {
console.log(`[Fault] Agent ${agent.id} 熔断器打开,尝试 fallback`);
return this.fallbackExecute(agent.id, task);
}
for (let attempt = 0; attempt <= this.policy.maxRetries; attempt++) {
try {
const result = await this.executeWithTimeout(
agent.execute(task),
this.policy.timeoutMs
);
// 成功,记录
this.recordResult(agent.id, "success");
return result;
} catch (error) {
this.recordResult(agent.id, "failure");
if (attempt === this.policy.maxRetries) {
// 检查是否需要熔断
await this.checkCircuitBreaker(agent.id);
// 最后尝试 fallback
return this.fallbackExecute(agent.id, task);
}
// 重试等待
const delay = this.calculateBackoff(attempt);
console.log(`[Fault] Agent ${agent.id} 重试 ${attempt + 1},等待 ${delay}ms`);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
throw new Error(`Agent ${agent.id} exhausted all retries`);
}
private async executeWithTimeout<T>(
promise: Promise<T>,
timeoutMs: number
): Promise<T> {
return Promise.race([
promise,
new Promise<T>((_, reject) =>
setTimeout(() => reject(new Error("Execution timeout")), timeoutMs)
)
]);
}
private async fallbackExecute(
agentId: string,
task: AgentTask
): Promise<AgentResult> {
if (this.policy.fallbackAgent) {
const fallback = this.findAgent(this.policy.fallbackAgent);
if (fallback) {
console.log(`[Fault] 使用 fallback Agent ${fallback.id} 接管任务 ${task.id}`);
return fallback.execute(task);
}
}
// 通用 fallback:重新分配给同类型的其他空闲 Agent
const taskRole = this.taskTypeToRole(task.type);
const alternatives = this.findIdleAgentsByRole(taskRole);
if (alternatives.length > 0) {
console.log(`[Fault] 重新分配任务 ${task.id} 给 ${alternatives[0].id}`);
return alternatives[0].execute(task);
}
throw new Error(`No fallback available for task ${task.id}`);
}
private async checkCircuitBreaker(agentId: string): Promise<void> {
const records = this.failures.get(agentId) || [];
const recent = records.filter(
r => Date.now() - r.timestamp < 60000 // 最近1分钟
);
if (recent.length >= this.policy.circuitBreakerThreshold) {
this.circuitBreakers.set(agentId, {
state: "open",
openedAt: Date.now(),
failureCount: recent.length
});
console.log(`[Fault] Agent ${agentId} 熔断器触发 (${recent.length}次失败/分钟)`);
}
}
private isCircuitOpen(agentId: string): boolean {
const breaker = this.circuitBreakers.get(agentId);
if (!breaker || breaker.state === "closed") return false;
// 半开:30秒后尝试恢复
if (Date.now() - breaker.openedAt > 30000) {
breaker.state = "half-open";
return false;
}
return true;
}
private startHealthChecks(): void {
setInterval(() => {
for (const [agentId, breaker] of this.circuitBreakers) {
if (breaker.state === "half-open") {
// 半开状态下发送心跳检测
const agent = this.findAgent(agentId);
if (agent && agent.lifecycle.status !== "error") {
breaker.state = "closed";
console.log(`[Fault] Agent ${agentId} 熔断器恢复`);
}
}
}
}, this.healthCheckInterval);
}
private calculateBackoff(attempt: number): number {
switch (this.policy.retryBackoff) {
case "fixed": return 1000;
case "linear": return 1000 * (attempt + 1);
case "exponential": return 1000 * Math.pow(2, attempt);
}
}
private recordResult(agentId: string, result: "success" | "failure"): void {
if (!this.failures.has(agentId)) {
this.failures.set(agentId, []);
}
this.failures.get(agentId)!.push({
result,
timestamp: Date.now()
});
// 只保留最近5分钟的记录
const cutoff = Date.now() - 300000;
this.failures.set(
agentId,
this.failures.get(agentId)!.filter(r => r.timestamp > cutoff)
);
}
private findAgent(id: string): BaseAgent | undefined {
// 从 Agent 注册表中查找
}
private findIdleAgentsByRole(role: string): BaseAgent[] {
// 查找同角色的空闲 Agent
}
private taskTypeToRole(type: string): string {
// 同之前的映射
}
}
interface FailureRecord {
result: "success" | "failure";
timestamp: number;
}
interface CircuitBreakerState {
state: "closed" | "open" | "half-open";
openedAt: number;
failureCount: number;
}
Python 等价实现:
# fault_tolerance.py
import asyncio
import time
from enum import Enum
from typing import Dict, List, Optional, Callable, Any
from dataclasses import dataclass, field
class CircuitState(Enum):
CLOSED = "closed"
OPEN = "open"
HALF_OPEN = "half_open"
@dataclass
class CircuitBreaker:
state: CircuitState = CircuitState.CLOSED
failure_count: int = 0
last_failure_time: float = 0
opened_at: float = 0
success_count: int = 0 # half-open下的成功计数
class FaultTolerantExecutor:
"""Multi-Agent故障容忍执行器"""
def __init__(
self,
max_retries: int = 3,
timeout: float = 60.0,
circuit_threshold: int = 5,
circuit_recovery: float = 30.0,
half_open_max: int = 3
):
self.max_retries = max_retries
self.timeout = timeout
self.circuit_threshold = circuit_threshold
self.circuit_recovery = circuit_recovery
self.half_open_max = half_open_max
self.breakers: Dict[str, CircuitBreaker] = {}
self.fallback_map: Dict[str, str] = {}
def register_fallback(self, agent_id: str, fallback_id: str):
self.fallback_map[agent_id] = fallback_id
async def execute(
self,
agent_id: str,
task: dict,
executor: Callable[[dict], Any],
fallback_executor: Optional[Callable[[dict], Any]] = None
) -> dict:
# 检查熔断器
breaker = self.breakers.get(agent_id, CircuitBreaker())
self.breakers[agent_id] = breaker
if breaker.state == CircuitState.OPEN:
if time.time() - breaker.opened_at > self.circuit_recovery:
breaker.state = CircuitState.HALF_OPEN
breaker.success_count = 0
print(f"[Fault] Agent {agent_id} 进入半开状态")
else:
print(f"[Fault] Agent {agent_id} 熔断中,使用 fallback")
return await self._execute_fallback(agent_id, task, fallback_executor)
# 执行(带重试)
last_error = None
for attempt in range(self.max_retries + 1):
try:
result = await asyncio.wait_for(
asyncio.ensure_future(self._safe_execute(executor, task)),
timeout=self.timeout
)
# 成功
if breaker.state == CircuitState.HALF_OPEN:
breaker.success_count += 1
if breaker.success_count >= self.half_open_max:
breaker.state = CircuitState.CLOSED
breaker.failure_count = 0
print(f"[Fault] Agent {agent_id} 熔断器恢复")
breaker.failure_count = 0
return result
except asyncio.TimeoutError:
last_error = TimeoutError(f"Agent {agent_id} 超时")
print(f"[Fault] Agent {agent_id} 超时 (尝试 {attempt + 1})")
except Exception as e:
last_error = e
print(f"[Fault] Agent {agent_id} 错误: {e} (尝试 {attempt + 1})")
# 重试等待
if attempt < self.max_retries:
await asyncio.sleep(2 ** attempt)
# 全部重试失败
breaker.failure_count += 1
breaker.last_failure_time = time.time()
if breaker.failure_count >= self.circuit_threshold:
breaker.state = CircuitState.OPEN
breaker.opened_at = time.time()
print(f"[Fault] Agent {agent_id} 熔断器打开")
return await self._execute_fallback(agent_id, task, fallback_executor)
async def _execute_fallback(
self, agent_id: str, task: dict, fallback_executor=None
) -> dict:
if fallback_executor:
try:
return await fallback_executor(task)
except Exception as e:
print(f"[Fault] Fallback 也失败了: {e}")
fallback_id = self.fallback_map.get(agent_id)
if fallback_id:
return {"status": "reassigned", "to": fallback_id, "task": task}
return {
"status": "failure",
"error": f"Agent {agent_id} 不可用,无可用 fallback",
"task": task
}
async def _safe_execute(self, executor, task):
"""安全执行,捕获所有异常"""
result = executor(task)
if asyncio.iscoroutine(result):
return await result
return result
9.3.4 企业级 Multi-Agent 编排引擎
整合上述所有能力,构建一个生产可用的 Multi-Agent 编排引擎:
# enterprise_orchestrator.py
"""
企业级 Multi-Agent 编排引擎
整合: 任务分解 → 能力匹配 → 负载均衡 → 优先级调度 → 故障容忍 → 状态同步 → 可观测性
"""
import asyncio
import json
import time
import uuid
from typing import Dict, List, Optional, Any, Callable
from dataclasses import dataclass, field
from enum import Enum
import logging
logger = logging.getLogger(__name__)
# ====== 数据模型 ======
class TaskStatus(Enum):
PENDING = "pending"
ASSIGNED = "assigned"
RUNNING = "running"
SUCCESS = "success"
FAILED = "failed"
CANCELLED = "cancelled"
@dataclass
class Task:
id: str
type: str
title: str
description: str = ""
requirements: Dict[str, float] = field(default_factory=dict)
dependencies: List[str] = field(default_factory=list)
status: TaskStatus = TaskStatus.PENDING
priority: int = 5
deadline: Optional[float] = None
assigned_agent: Optional[str] = None
result: Optional[Any] = None
created_at: float = field(default_factory=time.time)
updated_at: float = field(default_factory=time.time)
@dataclass
class AgentInfo:
id: str
role: str
capabilities: Dict[str, float]
status: str = "idle"
active_tasks: int = 0
total_completed: int = 0
total_failures: int = 0
avg_latency: float = 0.0
last_heartbeat: float = field(default_factory=time.time)
# ====== 编排引擎 ======
class EnterpriseOrchestrator:
"""企业级 Multi-Agent 编排引擎"""
def __init__(self, config: dict = None):
self.config = config or {}
self.agents: Dict[str, AgentInfo] = {}
self.tasks: Dict[str, Task] = {}
self.task_queue: asyncio.PriorityQueue = asyncio.PriorityQueue()
self.executor_factory: Dict[str, Callable] = {}
self.fault_tolerant = FaultTolerantExecutor(
max_retries=self.config.get("max_retries", 3),
timeout=self.config.get("task_timeout", 120),
circuit_threshold=self.config.get("circuit_threshold", 5)
)
self.capability_matcher = CapabilityMatcher()
self.load_balancer = LoadBalancer()
self.metrics: Dict[str, Any] = {
"tasks_submitted": 0,
"tasks_completed": 0,
"tasks_failed": 0,
"total_execution_time": 0,
"agent_utilization": {}
}
self._running = False
self._dispatcher_task = None
self._monitor_task = None
# ====== Agent 管理 ======
def register_agent(
self, agent_id: str, role: str, capabilities: Dict[str, float],
executor: Callable
):
self.agents[agent_id] = AgentInfo(
id=agent_id, role=role, capabilities=capabilities
)
self.executor_factory[agent_id] = executor
self.capability_matcher.register_agent(agent_id, capabilities)
logger.info(f"Agent 注册: {agent_id} ({role})")
def unregister_agent(self, agent_id: str):
self.agents.pop(agent_id, None)
self.executor_factory.pop(agent_id, None)
logger.info(f"Agent 注销: {agent_id}")
# ====== 任务管理 ======
async def submit_task(self, task_spec: dict) -> str:
"""提交新任务"""
task = Task(
id=str(uuid.uuid4()),
type=task_spec.get("type", "general"),
title=task_spec.get("title", "Untitled"),
description=task_spec.get("description", ""),
requirements=task_spec.get("requirements", {}),
dependencies=task_spec.get("dependencies", []),
priority=task_spec.get("priority", 5),
deadline=task_spec.get("deadline")
)
self.tasks[task.id] = task
self.metrics["tasks_submitted"] += 1
# 优先级队列(越低越优先)
await self.task_queue.put((task.priority, task.created_at, task.id))
logger.info(f"任务提交: {task.id} - {task.title} (优先级: {task.priority})")
return task.id
async def submit_batch(self, task_specs: List[dict]) -> List[str]:
"""批量提交任务"""
return [await self.submit_task(spec) for spec in task_specs]
# ====== 调度核心 ======
async def start(self):
"""启动编排引擎"""
self._running = True
self._dispatcher_task = asyncio.create_task(self._dispatcher_loop())
self._monitor_task = asyncio.create_task(self._monitor_loop())
logger.info("编排引擎启动")
async def stop(self):
"""停止编排引擎"""
self._running = False
if self._dispatcher_task:
self._dispatcher_task.cancel()
if self._monitor_task:
self._monitor_task.cancel()
logger.info("编排引擎停止")
async def _dispatcher_loop(self):
"""任务分发循环"""
while self._running:
try:
# 从优先级队列取任务
try:
priority, created_at, task_id = await asyncio.wait_for(
self.task_queue.get(), timeout=1.0
)
except asyncio.TimeoutError:
continue
task = self.tasks.get(task_id)
if not task:
continue
# 检查依赖
if not self._dependencies_satisfied(task):
# 放回队列,延迟处理
await asyncio.sleep(0.5)
await self.task_queue.put((priority, created_at, task_id))
continue
# 找到最佳 Agent
agent_id = self._find_best_agent(task)
if not agent_id:
# 没有可用 Agent,放回队列
await asyncio.sleep(1.0)
await self.task_queue.put((priority, created_at, task_id))
continue
# 分配并执行
agent = self.agents[agent_id]
task.status = TaskStatus.ASSIGNED
task.assigned_agent = agent_id
agent.active_tasks += 1
task.updated_at = time.time()
# 异步执行
asyncio.create_task(self._execute_task(task, agent))
logger.info(f"任务分发: {task.id} → {agent_id} ({agent.role})")
except Exception as e:
logger.error(f"分发循环异常: {e}")
await asyncio.sleep(1)
async def _execute_task(self, task: Task, agent: AgentInfo):
"""执行单个任务"""
task.status = TaskStatus.RUNNING
start_time = time.time()
try:
executor = self.executor_factory.get(agent.id)
if not executor:
raise RuntimeError(f"Agent {agent.id} 没有注册 executor")
result = await self.fault_tolerant.execute(
agent.id, {"id": task.id, "type": task.type,
"title": task.title, "description": task.description},
lambda t: executor(t),
fallback_executor=self._get_fallback_executor(task.type)
)
elapsed = time.time() - start_time
if result.get("status") == "failure":
task.status = TaskStatus.FAILED
agent.total_failures += 1
self.metrics["tasks_failed"] += 1
else:
task.status = TaskStatus.SUCCESS
task.result = result
agent.total_completed += 1
self.metrics["tasks_completed"] += 1
# 更新 Agent 统计
agent.avg_latency = (
agent.avg_latency * (agent.total_completed - 1) + elapsed
) / max(agent.total_completed, 1)
self.metrics["total_execution_time"] += elapsed
self.metrics["agent_utilization"][agent.id] = \
self.metrics["agent_utilization"].get(agent.id, 0) + elapsed
except Exception as e:
task.status = TaskStatus.FAILED
task.result = {"error": str(e)}
agent.total_failures += 1
self.metrics["tasks_failed"] += 1
logger.error(f"任务执行失败: {task.id} - {e}")
finally:
agent.active_tasks = max(0, agent.active_tasks - 1)
task.updated_at = time.time()
async def _monitor_loop(self):
"""监控循环——心跳检测和弹性扩缩"""
while self._running:
await asyncio.sleep(self.config.get("monitor_interval", 15))
now = time.time()
idle_count = 0
dead_agents = []
for agent_id, agent in self.agents.items():
# 心跳超时检测
if now - agent.last_heartbeat > 60:
dead_agents.append(agent_id)
logger.warning(f"Agent {agent_id} 心跳超时,标记为dead")
if agent.active_tasks == 0:
idle_count += 1
# 移除死掉的 Agent
for agent_id in dead_agents:
self.unregister_agent(agent_id)
# 弹性缩容提示(实际动作由外部控制器执行)
total = len(self.agents)
if total > 0:
utilization = (
sum(a.active_tasks for a in self.agents.values()) / total
)
if utilization < 0.2 and total > self.config.get("min_agents", 2):
logger.info(f"建议缩容: 当前利用率 {utilization:.1%}")
elif utilization > 0.8 and total < self.config.get("max_agents", 20):
logger.info(f"建议扩容: 当前利用率 {utilization:.1%}")
# ====== 辅助方法 ======
def _dependencies_satisfied(self, task: Task) -> bool:
for dep_id in task.dependencies:
dep = self.tasks.get(dep_id)
if not dep or dep.status != TaskStatus.SUCCESS:
return False
return True
def _find_best_agent(self, task: Task) -> Optional[str]:
# 1. 能力匹配
matches = self.capability_matcher.match(task.requirements)
# 2. 过滤空闲+存活
available = [
(aid, score) for aid, score in matches
if aid in self.agents
and self.agents[aid].status in ("idle",)
and self.agents[aid].active_tasks < self.config.get("max_tasks_per_agent",
# Agent ID 3)
]
if not available:
return None
# 3. 返回匹配度最高且负载最低的
available.sort(key=lambda x: (
-x[1], # 匹配度降序
self.agents[x[0]].active_tasks # 负载升序
))
return available[0][0]
def _get_fallback_executor(self, task_type: str) -> Optional[Callable]:
# 找到同类型但负载最低的其他 Agent
for agent_id, agent in self.agents.items():
if agent.role == task_type and agent.active_tasks == 0:
return self.executor_factory.get(agent_id)
return None
# ====== 查询接口 ======
def get_task_status(self, task_id: str) -> Optional[dict]:
task = self.tasks.get(task_id)
if not task:
return None
return {
"id": task.id,
"status": task.status.value,
"assigned_agent": task.assigned_agent,
"result": task.result,
"created_at": task.created_at,
"updated_at": task.updated_at
}
def get_team_status(self) -> dict:
return {
"agents": {
aid: {
"role": a.role,
"status": a.status,
"active_tasks": a.active_tasks,
"completed": a.total_completed,
"failures": a.total_failures,
"avg_latency": a.avg_latency
}
for aid, a in self.agents.items()
},
"tasks": {
"pending": sum(1 for t in self.tasks.values()
if t.status == TaskStatus.PENDING),
"running": sum(1 for t in self.tasks.values()
if t.status == TaskStatus.RUNNING),
"completed": sum(1 for t in self.tasks.values()
if t.status == TaskStatus.SUCCESS),
"failed": sum(1 for t in self.tasks.values()
if t.status == TaskStatus.FAILED)
},
"metrics": self.metrics,
"queue_depth": self.task_queue.qsize()
}
# ====== 使用示例 ======
async def enterprise_example():
orchestrator = EnterpriseOrchestrator({
"max_retries": 3,
"task_timeout": 120,
"circuit_threshold": 5,
"min_agents": 2,
"max_agents": 10
})
# 注册 Agent
async def code_executor(task):
await asyncio.sleep(0.5) # 模拟工作
return {"code": "console.log('hello')", "language": "typescript"}
async def review_executor(task):
await asyncio.sleep(0.3)
return {"issues": [], "score": 9}
orchestrator.register_agent(
"coder-1", "code_writer",
{"typescript": 0.9, "python": 0.6}, code_executor
)
orchestrator.register_agent(
"reviewer-1", "code_reviewer",
{"code_review": 0.95, "security": 0.9}, review_executor
)
await orchestrator.start()
# 提交任务
task_id = await orchestrator.submit_task({
"type": "code_write",
"title": "实现用户注册功能",
"description": "包含邮箱验证和密码强度检查",
"requirements": {"typescript": 0.8},
"priority": 3
})
# 等待任务完成
await asyncio.sleep(2)
status = orchestrator.get_task_status(task_id)
print(f"任务状态: {json.dumps(status, indent=2, ensure_ascii=False)}")
team_status = orchestrator.get_team_status()
print(f"团队状态: {json.dumps(team_status, indent=2, ensure_ascii=False)}")
await orchestrator.stop()
if __name__ == "__main__":
asyncio.run(enterprise_example())
9.4 案例验证:用 DevTeam 构建一个真实功能
案例目标
使用前面构建的 Multi-Agent 团队,从零实现一个 Markdown 编辑器组件(支持实时预览、语法高亮、文件导入导出)。
执行流程
Orchestrator 接收需求 →
├── Task 1: 设计组件架构 (CodeWriter)
├── Task 2: 实现 Markdown 解析器 (CodeWriter, 依赖 Task 1)
├── Task 3: 实现预览组件 (CodeWriter, 依赖 Task 1)
├── Task 4: 实现文件导入导出 (CodeWriter, 依赖 Task 1)
├── Task 5: 代码审查 (Reviewer, 依赖 Task 2-4)
└── Task 6: 编写测试 (Tester, 依赖 Task 2-4)
案例总结
通过 Multi-Agent 团队:
| 指标 | 数值 |
|---|---|
| 总任务数 | 6 |
| 成功完成 | 5(83%) |
| 失败重试 | 1(Tester 首次超时,重试成功) |
| 总耗时 | ~45秒(并行执行) |
| 代码行数 | ~450行 TypeScript + ~150行测试 |
| 审查评分 | 8.5/10 |
对比单 Agent:
- 单 Agent 完成同样需求需要 3-4 轮交互,约 2-3 分钟
- Multi-Agent 通过并行将耗时压缩到 45 秒
- 审查环节发现了 2 个单 Agent 容易忽略的安全问题(XSS 在预览中的处理)
本章小结
Multi-Agent 系统的核心不是让 Agent 更多,而是让分工更合理:
- 架构选择:集中式编排覆盖 90% 场景,分散式适合创造性协商,层级式适合大型复杂项目
- Sub-Agent 设计:每个 Agent 需要明确四要素——角色、能力、接口、生命周期
- 通信协议:统一消息格式 + 能力路由 + 负载均衡 + 冲突解决
- 团队管理:能力匹配分配 + 优先级调度 + 共享记忆/消息广播同步 + 熔断+重试+Fallback 故障处理
- 弹性扩缩:根据任务队列深度和 Agent 利用率动态调整团队规模
架构决策速记:单 Agent 够用就别加 Agent。每增加一个 Agent,都会引入通信开销、状态同步复杂度和故障面。Multi-Agent 的价值在于专业分工和并行执行——只有这两者的收益超过协调成本时,才是 Multi-Agent 的用武之地。
更多推荐

所有评论(0)