一、为什么需要多 Agent 协作
单一 Agent 的能力存在天花板:一个 Agent 很难同时精通数据分析、代码编写、安全审查等多个领域。多 Agent 系统通过分工协作实现 1+1 > 2 的效果。
1.1 单 Agent vs 多 Agent
| 维度 | 单 Agent | 多 Agent |
|---|---|---|
| 专业度 | 通用能力 | 各 Agent 专注特定领域 |
| 容错性 | 单点故障 | 互相校验 |
| 并行度 | 串行处理 | 可并行执行子任务 |
| 复杂度 | 实现简单 | 需处理 Agent 间通信 |
| 成本 | 较低 | 较高(多模型调用) |
二、多 Agent 协作模式
2.1 主管-下属模式(Manager-Worker)
┌─────────────┐
│ 主管 Agent │ ← 任务分解、结果汇总
├─────────────┤
│ ┌───┐ ┌───┐ │
│ │ A │ │ B │ │ ← 各下属 Agent 专注执行
│ └───┘ └───┘ │
└─────────────┘class ManagerAgent:
"""主管 Agent:负责任务分解和结果整合"""
def __init__(self, llm, workers: Dict[str, 'WorkerAgent']):
self.llm = llm
self.workers = workers
def execute(self, task: str) -> str:
# 1. 分解任务
subtasks = self._decompose(task)
# 2. 分配子任务
results = {}
for worker_name, subtask in subtasks.items():
worker = self.workers.get(worker_name)
if worker:
results[worker_name] = worker.execute(subtask)
# 3. 整合结果
return self._synthesize(results)
def _decompose(self, task: str) -> Dict[str, str]:
"""将任务分解为子任务分配给各 Worker"""
response = self.llm.chat(
f"将以下任务分解,返回 JSON 格式:\n"
f"{{\"worker_A\": \"子任务描述\", \"worker_B\": ...}}\n"
f"可用 Worker: {list(self.workers.keys())}\n"
f"任务:{task}"
)
return json.loads(response)2.2 辩论模式(Debate)
多个 Agent 从不同角度分析同一问题,互相辩论:
class DebateTeam:
"""辩论模式:多角度分析"""
def __init__(self, agents: List[Agent], moderator: Agent):
self.agents = agents
self.moderator = moderator
def debate(self, question: str, rounds: int = 3) -> str:
opinions = []
# 第一轮:各自发表观点
for agent in self.agents:
opinions.append({
"agent": agent.name,
"view": agent.analyze(question)
})
# 后续轮次:互相反驳和完善
for round_num in range(1, rounds):
for i, agent in enumerate(self.agents):
others_views = [
o["view"] for j, o in enumerate(opinions)
if j != i and len(o["view"]) > 0
]
rebuttal = agent.rebuttal(question, others_views)
opinions[i]["view"] += f"\n[反驳] {rebuttal}"
# 主持人总结
return self.moderator.summarize(question, opinions)2.3 流水线模式(Pipeline)
任务按阶段依次由不同 Agent 处理:
Agent A(分析) → Agent B(设计) → Agent C(实现) → Agent D(测试)class PipelineOrchestrator:
"""流水线编排"""
def __init__(self, stages: List[Tuple[str, Agent]]):
self.stages = stages
def execute(self, input_data: Any) -> Any:
current = input_data
for stage_name, agent in self.stages:
print(f"▶️ 阶段: {stage_name}")
current = agent.process(current)
if self._validate_output(stage_name, current):
continue
else:
print(f"⚠️ {stage_name} 输出验证失败,重新执行")
current = agent.process(current)
return current三、Agent 间通信协议
3.1 结构化消息格式
@dataclass
class AgentMessage:
"""Agent 间通信消息"""
sender: str
receiver: str
msg_type: str # "request" | "response" | "broadcast"
content: Any
metadata: Dict = field(default_factory=dict)
timestamp: float = field(default_factory=time.time)
msg_id: str = field(default_factory=lambda: str(uuid.uuid4()))3.2 消息总线模式
class MessageBus:
"""消息总线:解耦 Agent 间通信"""
def __init__(self):
self.subscribers: Dict[str, List[Callable]] = {}
self.message_history: List[AgentMessage] = []
def subscribe(self, agent_name: str, callback: Callable):
if agent_name not in self.subscribers:
self.subscribers[agent_name] = []
self.subscribers[agent_name].append(callback)
def publish(self, message: AgentMessage):
self.message_history.append(message)
# 投递到指定接收者
if message.receiver in self.subscribers:
for cb in self.subscribers[message.receiver]:
cb(message)
# 广播
if message.msg_type == "broadcast":
for agent_name, callbacks in self.subscribers.items():
if agent_name != message.sender:
for cb in callbacks:
cb(message)四、安全防护
4.1 Agent 安全风险矩阵
| 风险类型 | 描述 | 严重程度 |
|---|---|---|
| 提示注入 | 用户输入劫持 Agent 行为 | 🔴 严重 |
| 工具滥用 | Agent 频繁调用高成本工具 | 🟡 中等 |
| 数据泄露 | 敏感信息被写入记忆或输出 | 🔴 严重 |
| 权限提升 | Agent 执行越权操作 | 🔴 严重 |
| 循环失控 | Agent 陷入无限执行循环 | 🟡 中等 |
4.2 防护措施实现
class SafeAgent:
"""带安全防护的 Agent 基类"""
def __init__(self):
self.tool_budget = 100 # 每次任务的工具调用预算
self.tool_calls = 0
self.start_time = None
def execute_tool(self, tool_name: str, **kwargs):
# 1. 成本控制
self.tool_calls += 1
if self.tool_calls > self.tool_budget:
raise BudgetExceeded("工具调用超预算")
# 2. 超时控制
if time.time() - self.start_time > 300: # 5 分钟
raise TimeoutError("任务执行超时")
# 3. 输入过滤
for key, value in kwargs.items():
if isinstance(value, str) and is_sql_injection(value):
raise SecurityError(f"检测到 SQL 注入: {key}")
if isinstance(value, str) and is_prompt_injection(value):
raise SecurityError(f"检测到提示注入: {key}")
# 4. 输出脱敏
result = self._call_tool(tool_name, **kwargs)
return self._sanitize_output(result)
def _sanitize_output(self, output: str) -> str:
"""脱敏处理"""
# 替换疑似敏感信息
output = re.sub(r'\b\d{17}[\dXx]\b', '***', output) # 身份证
output = re.sub(r'1[3-9]\d{9}', '***', output) # 手机号
output = re.sub(r'AKID[a-zA-Z0-9]{20,}', '***', output) # 密钥
return output4.3 人类介入(Human-in-the-Loop)
class HumanApproval:
"""高危操作的人工审批"""
RISKY_OPERATIONS = [
"delete_resource", "modify_permissions",
"execute_shell", "transfer_funds"
]
def execute_with_approval(self, tool_name: str, tool_args: Dict):
if tool_name in self.RISKY_OPERATIONS:
# 暂停等待人工审批
approval = self._request_approval(tool_name, tool_args)
if not approval:
return {"error": "操作被人工拒绝"}
return self.tools[tool_name](**tool_args)五、生产环境部署
5.1 系统架构
┌─────────┐ ┌──────────┐ ┌──────────┐
│ 客户端 │───▶│ API 网关 │───▶│ 任务队列 │
└─────────┘ └──────────┘ └──────────┘
│
┌─────────▼─────────┐
│ Agent 工作节点池 │
│ ┌───┐ ┌───┐ ┌───┐ │
│ │ A │ │ B │ │ C │ │
│ └───┘ └───┘ └───┘ │
└─────────┬─────────┘
│
┌───────────────┼───────────────┐
│ │ │
┌─────▼───┐ ┌──────▼────┐ ┌─────▼───┐
│ 向量 DB │ │ 工具 API │ │ 监控 │
└─────────┘ └───────────┘ └─────────┘5.2 关键部署配置
# agent_config.yaml
agent:
max_concurrent_tasks: 10
task_timeout: 300 # 秒
retry_policy:
max_retries: 3
backoff_base: 2
rate_limits:
llm_calls: 100 # 每分钟
tool_calls: 50 # 每分钟
monitoring:
metrics:
- response_time
- token_usage
- tool_success_rate
- agent_error_rate
logging:
level: INFO
retention_days: 30
sensitive_fields:
- api_key
- password
- token5.3 监控指标
import prometheus_client as prom
# 定义指标
agent_requests = prom.Counter(
'agent_requests_total',
'Agent 请求总数',
['agent_name', 'status']
)
agent_latency = prom.Histogram(
'agent_task_duration_seconds',
'任务执行耗时分布',
['agent_name'],
buckets=[1, 5, 10, 30, 60, 120, 300]
)
token_usage = prom.Counter(
'agent_token_usage_total',
'Token 消耗总数',
['model', 'type'] # type: input/output
)
tool_calls = prom.Counter(
'agent_tool_calls_total',
'工具调用次数',
['tool_name', 'status']
)六、成本优化
6.1 成本构成
| 成本项 | 占比 | 优化策略 |
|---|---|---|
| LLM API 调用 | 60-80% | 模型蒸馏、缓存、降级 |
| 向量数据库 | 10-20% | 索引优化、分级存储 |
| 工具 API | 10-20% | 本地缓存、批量请求 |
| 基础设施 | 5-10% | 弹性伸缩、按需付费 |
6.2 Token 优化策略
class CostOptimizer:
"""Token 成本优化"""
def __init__(self, llm):
self.cache = {} # 结果缓存
def optimize_messages(self, messages: List) -> List:
"""优化消息上下文:丢弃冗余"""
optimized = [messages[0]] # 保留 system prompt
# 只保留最近的 N 轮对话
recent = messages[1:]
if len(recent) > 10:
summary = self._summarize_mid(messages[:len(messages)-10])
optimized.append(summary)
optimized.extend(recent[-10:])
else:
optimized.extend(recent)
return optimized
def cached_completion(self, messages: List) -> str:
"""带缓存的 LLM 调用"""
cache_key = hashlib.md256(
json.dumps(messages, sort_keys=True).encode()
).hexdigest()
if cache_key in self.cache:
return self.cache[cache_key]
response = self.llm.chat(messages)
self.cache[cache_key] = response
return response七、总结
从开发到生产部署,构建可靠的 Agent 系统需要关注:
- 协作模式:根据场景选择主管-下属、辩论或流水线模式
- 安全防护:提示注入防护、敏感数据脱敏、人工审批
- 可观测性:完善的监控指标和日志系统
- 成本控制:缓存策略、模型降级、优化上下文长度
AI Agent 正在从实验室走向生产,掌握这些工程实践,是构建可靠 Agent 系统的关键。
📖 本系列完结:从基础概念到生产部署,共 6 篇文章,涵盖了 AI Agent 开发的完整知识体系。