一、 开场:一次让我怀疑人生的”三个和尚”事件
大家好,我是老金。
今天这篇文章,源于一次让我怀疑人生的项目经历。
上个月,我们团队接了一个企业级 AI Agent 项目。
需求听起来很简单:做一个智能客服系统。
我觉得这玩意儿小 case,三下五除二就搭了一个 Multi-Agent 系统:
- 1 个主 Agent(负责接待)
- 3 个子 Agent(分别负责订单查询、技术支持、投诉处理)
- 1 个路由 Agent(负责分发任务)
架构图一画,自我感觉良好:
“你看,主 Agent 接待,然后根据用户意图分发给子 Agent,各司其职,井井有条!”
结果呢?
上线第一天,系统就炸了。
用户投诉:
- “我说要退货,它让我等了两分钟,然后告诉我去联系人工”
- “我问技术问题,它让我找技术支持 Agent;我问技术支持 Agent,它又让我找主 Agent”
- “三个 Agent 在那互相推诿,场面极其混乱”
那天晚上,我坐在电脑前,看着满屏的报错日志,整个人是懵的。
“三个和尚没水喝”的事情,竟然发生在了我的 Multi-Agent 系统里。
这个教训让我意识到:
Multi-Agent 不是”多写几个 Agent 就完事了”,而是一门需要专门学习的”协作艺术”。
今天这篇文章,我就把那次踩坑后学到的的东西,全部分享出来。
内容包括:
- Multi-Agent 的核心挑战是什么?
- MCP 协议是什么?为什么它能解决协作问题?
- 如何在 OpenClaw 中配置 MCP 协议?
- 实战案例:搭建一个多 Agent 协作系统
- 常见问题与解决方案
如果你正在做 Multi-Agent 项目,这篇文章可能会救你的命。
二、 Multi-Agent 的核心挑战:不是”多”,而是”乱”
在讲 MCP 协议之前,我想先聊聊 Multi-Agent 最大的痛点:
不是 Agent 越多越强,而是 Agent 越多越乱。
2.1 我踩过的三个大坑
先说说我那次项目踩的坑。
坑一:上下文丢失
用户先跟主 Agent 聊了几句,然后被转发给技术支持 Agent。
技术支持 Agent 完全不知道前面聊了什么,只能让用户再说一遍。
用户心态崩了:“我都说第三遍了,你们到底有没有人听我说话?”
坑二:任务重复执行
主 Agent 判断用户要退货,转发给退货 Agent。
退货 Agent 开始处理,转发过程中,主 Agent 又判定用户需要售后服务,又发了一遍请求。
同一个退货流程,跑了两次。
系统资源炸了:“你在教我做事?”
坑三:循环调用
用户问了一个订单问题。
主 Agent 转发给订单 Agent。
订单 Agent 说”这个我处理不了”,转发回主 Agent。
主 Agent 想了想,转发给了技术支持 Agent。
技术支持 Agent 说”这也我处理不了”,又转发回主 Agent。
主 Agent 陷入死循环,直到触发超时保护。
用户等了 30 秒,得到一个”服务超时”的提示。
2.2 问题的根源
这三个坑,其实指向同一个根源:
Agent 之间没有”协作规范”。
每个 Agent 都是独立思考的个体,它们:
- 不知道其他 Agent 在做什么
- 不知道上下文怎么传递
- 不知道什么情况该找谁
- 不知道任务完成后要通知谁
就像一支没有通讯设备的军队,各自为战,不乱才怪。
2.3 解决方案:协议与规范
要解决 Multi-Agent 的协作问题,需要三样东西:
- MCP 协议(Model Context Protocol):定义 Agent 之间怎么传递信息
- 协作流程规范:定义 Agent 之间怎么分工协作
- 共享记忆机制:定义上下文怎么共享
下面我一个个讲。
三、 MCP 协议详解:Agent 之间的”普通话”
MCP(Model Context Protocol,模型上下文协议)是 Anthropic 提出的一个开放协议。
它的作用,用一句话说清楚:
MCP 是 Agent 之间的”普通话”——让不同的 Agent 能够互相理解、正确协作。
在 MCP 出现之前,每个系统都有自己的 Agent 通信方式:
- 我的系统用 JSON 传递消息
- 你的系统用 XML 传递消息
- 他的系统用自定义格式传递消息
大家”语言不通”,根本没法协作。
MCP 的出现,就是为了解决这个”语言障碍”问题。
3.1 MCP 的核心概念
MCP 有三个核心概念:
概念一:Host(宿主)
Host 是 MCP 协议的入口,负责:
- 接收用户请求
- 协调各个 Agent 的工作
- 维护全局上下文
在 OpenClaw 中,OpenClaw 本身就是 Host。
概念二:Client(客户端)
Client 是连接到 Host 的 Agent。
每个 Agent 都是一个 Client,它们:
- 向 Host 注册自己的能力
- 接收 Host 的任务分配
- 向 Host 汇报执行结果
概念三:Resource(资源)
Resource 是 Agent 可以访问的资源。
包括:
- 文件系统
- 数据库
- API 接口
- 其他 Agent 的能力
Resource 需要通过 MCP 协议注册、发现和使用。
3.2 MCP 的工作流程
一个典型的 MCP 工作流程是这样的:
用户 → Host(OpenClaw)→ 解析意图 → 选择 Agent
↓
Agent(Client)接收任务 → 执行 → 返回结果
↓
Host 汇总结果 → 返回给用户
在这个流程中,MCP 协议规定了:
- Host 怎么发现 Agent 的能力?(注册机制)
- 任务怎么分发给 Agent?(分发机制)
- 结果怎么返回?(回调机制)
- 上下文怎么传递?(上下文机制)
3.3 MCP vs 自定义协议
有人可能会问:
“我自己写一个通信协议不行吗?为什么要用 MCP?”
我的回答是:
“行,但你是在重复造轮子。”
对比一下:
| 维度 | MCP 协议 | 自定义协议 |
|---|---|---|
| 标准化 | 行业标准,大家都能理解 | 只有你自己能用 |
| 扩展性 | 开箱即用,插件丰富 | 每次加功能都要重写 |
| 维护成本 | Anthropic 维护,你只管用 | 你自己维护,累死 |
| 社区支持 | 大量现成的 MCP Server | 什么都没有 |
一句话:能用标准协议,就别自己造轮子。
四、 OpenClaw 中配置 MCP 协议
理论讲完了,下面讲实战。
如何在 OpenClaw 中配置 MCP 协议?
4.1 启用 MCP 功能
默认情况下,MCP 功能是启用的。
如果你需要自定义配置,编辑 config.yaml:
# config.yaml
mcp:
enabled: true
host: "0.0.0.0"
port: 18789
客户端配置
clients:
-
name: "agent-support"
type: "mcp"
url: "http://localhost:8001"
-
name: "agent-order"
type: "mcp"
url: "http://localhost:8002"
-
name: "agent-complaint"
type: "mcp"
url: "http://localhost:8003"
4.2 配置文件示例
下面是一个完整的 MCP 配置文件示例:
# config/mcp/servers.yaml
servers:
客服 Agent
support-agent:
command: "python"
args: ["-m", "mcp_server_support"]
env:
API_KEY: ${OPENCLAW_API_KEY}
capabilities:
- "text-generation"
- "sentiment-analysis"
订单 Agent
order-agent:
command: "python"
args: ["-m", "mcp_server_order"]
env:
API_KEY: ${OPENCLAW_API_KEY}
capabilities:
- "order-query"
- "refund-processing"
投诉 Agent
complaint-agent:
command: "python"
args: ["-m", "mcp_server_complaint"]
env:
API_KEY: ${OPENCLAW_API_KEY}
capabilities:
- "complaint-handling"
- "escalation"
连接配置
connection:
timeout: 30
retries: 3
heartbeat_interval: 10
4.3 配置 Agent 之间的协作规则
除了 MCP 协议,你还需要配置 Agent 之间的协作规则:
# config/collaboration/routing.yaml
routing:
主 Agent 配置
main_agent:
name: "agent-main"
capabilities:
- "intent-classification"
- "task-routing"
路由规则
rules:
-
pattern: "退货|退款|取消订单"
agent: "order-agent"
priority: 1
-
pattern: "技术问题|报错|无法登录"
agent: "support-agent"
priority: 1
-
pattern: "投诉|不满|差评|经理"
agent: "complaint-agent"
priority: 1
-
pattern: "人工|人工客服|人工服务"
agent: "agent-main" # 不转发,直接转人工
action: "escalate"
兜底规则
fallback:
agent: "agent-main"
message: "抱歉,我暂时无法处理您的问题,已为您转接人工客服。"
4.4 配置上下文共享
上下文丢失是最常见的问题之一。
在 OpenClaw 中,你可以通过 Memory 模块配置上下文共享:
# config/memory/shared_context.yamlshared_memory: enabled: true
存储类型
storage: type: "redis" # 推荐用 Redis,生产环境
type: "memory" # 仅开发环境使用
上下文配置
context:
保留最近 10 轮对话
max_history: 10 # 每个对话的最大 Token 数 max_tokens: 16000 # 保留哪些类型的上下文 include: - "user_intent" - "conversation_history" - "task_progress" - "agent_results"自动清理配置
cleanup:
7 天无活动的对话自动清理
inactive_days: 7 # 每次清理保留 100 条 keep_count: 100配置完成后,每个 Agent 都可以通过 MCP 协议访问共享上下文:
from openclaw.mcp import MCPClient创建客户端
client = MCPClient("support-agent")
获取共享上下文
context = await client.get_shared_context( conversation_id="conv_12345", include=["conversation_history", "user_intent"] )
在 Agent 中使用上下文
response = await agent.generate( prompt=context.get_prompt(), history=context.get_history() )
五、 实战案例:搭建一个智能客服多 Agent 系统
理论讲完了,下面用一个完整的实战案例来演示:
如何用 OpenClaw + MCP 协议搭建一个智能客服系统?
5.1 系统架构
这个客服系统包含:
- 主 Agent(agent-main):负责接待、意图识别、任务分发
- 技术支持 Agent(agent-support):负责处理技术问题
- 订单 Agent(agent-order):负责处理订单相关问题
- 投诉 Agent(agent-complaint):负责处理投诉和升级
- 共享 Memory:存储对话历史和上下文
5.2 目录结构
my-customer-service/ ├── config/ │ ├── config.yaml # 主配置 │ ├── mcp/ │ │ ├── servers.yaml # MCP 服务器配置 │ │ └── collaboration.yaml # 协作规则配置 │ └── memory/ │ └── shared_context.yaml # 上下文共享配置 │ ├── agents/ │ ├── main_agent.py # 主 Agent │ ├── support_agent.py # 技术支持 Agent │ ├── order_agent.py # 订单 Agent │ └── complaint_agent.py # 投诉 Agent │ ├── skills/ │ ├── intent_classifier.py # 意图分类 Skill │ ├── order_processor.py # 订单处理 Skill │ ├── tech_support.py # 技术支持 Skill │ └── complaint_handler.py # 投诉处理 Skill │ └── docker-compose.yml # 部署配置5.3 主 Agent 实现
主 Agent 是整个系统的入口,负责接待和分发:
# agents/main_agent.pyclass MainAgent: def init(self, config): self.mcp_client = MCPClient("agent-main") self.intent_classifier = IntentClassifier() self.router = TaskRouter(config["routing"])
async def handle_message(self, message: str, conversation_id: str): """处理用户消息""" # 1. 获取共享上下文 context = await self.mcp_client.get_shared_context( conversation_id, include=["conversation_history", "user_intent"] ) # 2. 意图识别 intent = await self.intent_classifier.classify( message, context.get_history() ) # 3. 保存用户意图到共享上下文 await self.mcp_client.update_shared_context( conversation_id, {"user_intent": intent} ) # 4. 任务分发 target_agent = self.router.route(intent, message) # 5. 转发任务(通过 MCP) result = await self.mcp_client.send_task( target_agent, { "original_message": message, "conversation_id": conversation_id, "context": context.to_dict() } ) # 6. 更新共享上下文 await self.mcp_client.update_shared_context( conversation_id, { "task_progress": result.status, "last_agent": target_agent, "last_result": result.summary } ) return result.response5.4 子 Agent 实现
以技术支持 Agent 为例:
# agents/support_agent.pyclass SupportAgent: def init(self, config): self.mcp_client = MCPClient("agent-support") self.tech_support_skill = TechSupportSkill()
async def handle_task(self, task: dict): """处理技术支持任务""" message = task["original_message"] conversation_id = task["conversation_id"] context_data = task["context"] # 1. 获取共享上下文 context = await self.mcp_client.get_shared_context( conversation_id, include=["conversation_history", "user_intent"] ) # 2. 诊断问题 diagnosis = await self.tech_support_skill.diagnose( message, context.get_history() ) # 3. 生成解决方案 if diagnosis.can_resolve: solution = await self.tech_support_skill.resolve( diagnosis.solution_id, context=context.get_all() ) response = solution.response else: # 无法处理,返回升级请求 response = await self.escalate( conversation_id, diagnosis.reason ) # 4. 更新任务状态 await self.mcp_client.update_task_status( task_id=task["task_id"], status="completed", result=response ) return response async def escalate(self, conversation_id: str, reason: str): """升级到投诉 Agent""" # 发送升级请求到共享上下文 await self.mcp_client.update_shared_context( conversation_id, { "escalation": { "reason": reason, "from_agent": "support-agent", "to_agent": "complaint-agent", "timestamp": datetime.now().isoformat() } } ) return "很抱歉,这个问题我暂时无法解决,已为您转接高级客服。"5.5 部署配置
使用 Docker Compose 部署:
# docker-compose.ymlversion: '3.8'
services: openclaw: image: openclaw/openclaw:latest ports:
- "18789:18789" volumes:
- ./config:/app/config
- ./agents:/app/agents
- ./skills:/app/skills environment:
- MCP_ENABLED=true
- REDIS_URL=redis://redis:6379 depends_on:
- redis restart: unless-stopped
redis: image: redis:7-alpine volumes:
- redis_data:/data restart: unless-stopped
volumes: redis_data:
六、 常见问题与解决方案
最后,聊聊 Multi-Agent 实践中常见的问题。
6.1 问题一:Agent 响应慢
症状:用户发消息,要等 5-10 秒才有回复
原因:
- MCP 协议有额外的网络开销
- 多个 Agent 串行执行,耗时累加
- 共享 Memory 读取延迟
解决方案:
# 1. 启用并行执行 async def handle_message(self, message: str, conversation_id: str): # 意图识别和上下文获取并行 intent, context = await asyncio.gather( self.intent_classifier.classify(message), self.mcp_client.get_shared_context(conversation_id) ) # ...2. 优化 Memory 配置
memory: cache: enabled: true ttl: 300 # 5 秒缓存
6.2 问题二:Agent 之间循环调用
症状:Agent A 调用 Agent B,Agent B 又调用 Agent A,死循环
解决方案:
# 配置调用链限制 collaboration: max_hops: 3 # 最多转发 3 次 prevent_loops: true记录调用链
chain: enabled: true max_length: 5
6.3 问题三:上下文爆炸
症状:对话历史越来越长,Token 超出限制
解决方案:
# 自动摘要压缩 memory: compression: enabled: true trigger_tokens: 8000 # 超过 8000 Token 时压缩 summary_prompt: | 请用 200 字总结以下对话历史: {{conversation_history}}6.4 问题四:某个 Agent 挂了,整个系统不可用
症状:子 Agent 重启期间,所有相关请求都失败
解决方案:
# 配置降级策略 fallback: # 当 support-agent 不可用时 support-agent: - agent: "main-agent" # 回退到主 Agent message: "技术支持暂时不可用,请稍后再试"当 order-agent 不可用时
order-agent:
- agent: "main-agent" message: "订单服务暂时不可用,请访问官网自助查询"
七、 写在最后:Multi-Agent 是一门将”复杂性”变成”战斗力”的艺术
这篇文章,我写了差不多 6000 字。
从踩坑经历,到 MCP 协议原理,再到实战案例和常见问题。
但比起这些技术细节,我想说的核心观点是:
Multi-Agent 不是银弹,不是 Agent 越多越强。
它是一门将”复杂性”变成”战斗力”的艺术。
用好了,它能让你的系统分工明确、高效协作。
用不好,它会让你的系统变成”三个和尚没水喝”的灾难现场。
“让对的 Agent,做对的事。”
这是我学到的最重要的一课。
与你共勉。
我是技术老金,我们下期见!
📌 相关文章推荐