最近经常有朋友问我,现在做 AI 应用到底应该往哪个方向使劲。我的建议一直很明确:别再研究“怎么调一个更好用的聊天机器人”了,真正有价值的是多智能体集群——让多个各有所长的 Agent 分工协作,去完成一个单 Agent 干不了或者干不好的复杂任务。但真要上手,你会发现概念一大堆:MCP、A2A、Skills、编排框架…… 每个词单独看都懂,合在一起就懵了。我最近啃完一门叫《DeepAgents+MCP+A2A+Skills 超级多智能体》的慕课,可以说把这套体系完整跑通了一遍。这篇就把我的理解、实操过程、还有踩过的坑完整记录下来,适合已经会调 API、想往多 Agent 架构方向进阶的开发者参考。
1. 为什么单 Agent 不够用了,集群才是答案
先聊一个很多人没想透的问题:我们为什么非要搞什么“多智能体集群”?一个 Agent 把所有事包圆了不行吗?我刚开始也是这么想的,直到自己在项目里撞了几次墙,才彻底明白单 Agent 模式的天花板在哪。
第一个痛点是上下文窗口的物理限制。你让一个 Agent 既要写代码、又要查文档、还要做行业分析,它就得同时塞下系统提示词、工具定义、行业背景资料、对话历史。上下文窗口就这么大,塞的东西越多,模型注意力就越分散,推理质量肉眼可见地下降。到后面它甚至会把工具调用参数都写错,纯粹是“脑子不够用了”。
第二个痛点是工具数量的爆炸。做正经项目,少说也要接十几个外部工具:搜索、数据库、文件读写、代码执行、消息推送。如果把这些工具全部塞给同一个 Agent,光是工具描述就能吃掉几千 token,而且模型在几十个工具里做选择时,误选率非常高。我实测过,超过二十个工具之后,工具调用正确率开始明显下滑,超过三十个就基本没法看了。
第三个痛点是职责混乱。单 Agent 模式里,所有能力混在一个 Prompt 里,想给某一块能力单独加规则、调参数、换模型,都会牵一发动全身。比如我想给“内容审校”这个环节单独加大模型剂量、加强校验规则,结果发现它和“资料搜集”共用一套 Prompt,根本没法独立调整。
这时候你再看多智能体架构,思路就完全不一样了。它的核心理念就像一个公司团队:每个 Agent 是专精某类工作的员工,它们各自维护自己的上下文、工具集和任务记忆,通过明确的协议互相协作。这样每个 Agent 的上下文都很干净,工具列表短而精,模型选择也可以“因岗设人”。 这门课把多智能体体系拆成了四个核心拼图,我给你们捋一下各自扮演的角色。DeepAgents 是编排层,相当于整个团队的总导演,负责拆解任务、调度 Agent、汇总结果、管理状态。MCP 是“工具接入层”,解决 Agent 怎么安全、标准化地调用外部工具和数据的问题。A2A 是“Agent 之间的通信协议”,解决不同的 Agent 之间怎么互相开口说话、派活儿的问题。Skills 是“能力封装层”,把可复用的领域技能打包成一个个技能包,让 Agent 按需加载、快速上岗。
| 组件 | 核心角色 | 解决的痛点 | 一句话类比 |
|---|---|---|---|
| DeepAgents | 编排调度 | 任务拆解、流程控制、状态管理 | 总导演 |
| MCP | 工具与数据接入 | 统一外部工具/数据接口 | 通用插线板 |
| A2A | 智能体间通信 | Agent 之间的发现、协商、协作 | 团队通信协议 |
| Skills | 领域能力封装 | 可复用任务知识与流程沉淀 | 工作手卡 |
这套组合拳的价值在于:MCP 让每个 Agent 能平等地“使用工具”,A2A 让 Agent 能互相“协作”,Skills 让 Agent 能快速“掌握技能”,DeepAgents 则把所有环节编排成一条可监控、可回滚、可审计的业务流。四个拼图各管一摊,但最终咬合成一个完整体系。
2. MCP、A2A、Skills 到底解决什么问题
2.1 MCP:把工具接入做成标准插座
先说说目前最火、也最容易被误会的 MCP。好多人以为 MCP 是个什么新框架或者新模型,其实它本质上是一套协议,全称是 Model Context Protocol,模型上下文协议。它解决的是“Agent 怎么和外部工具、数据源打交道”的问题。
你可以把 MCP 理解成电子设备里的 USB-C 接口。以前的充电线五花八门,每个设备一个口,换设备就得换线。MCP 做的事情就是把这个口统一了:只要工具方实现了 MCP Server,任何支持 MCP 的客户端(Claude Desktop、各种 Agent 框架、你自研的大模型应用)都能直接插上就用,不需要为每个工具单独写一套适配器。
MCP 的架构很简洁,就是客户端-服务器模式。Agent 侧是 MCP Client,工具侧是 MCP Server,两者通过 JSON-RPC 2.0 通信,传输方式有 stdio 和 HTTP 两种。核心接口就那几个:initialize做握手,tools/list列出可用工具,tools/call调用具体工具,还有resources/list暴露数据资源。我给你们看一个最简的 MCP Server 长什么样,用 Node.js 几行就能撑起来。
import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; const server = new Server( { name: 'demo-tools', version: '1.0.0' }, { capabilities: { tools: {} } } ); server.setRequestHandler({ method: 'tools/list' }, async () => { return { tools: [{ name: 'search_posts', description: '按关键词搜索技术博客文章,返回标题、链接和摘要', inputSchema: { type: 'object', properties: { keyword: { type: 'string' } }, required: ['keyword'] } }] }; }); server.setRequestHandler({ method: 'tools/call' }, async (request) => { const args = request.params.arguments ?? {}; // 这里实现真正的搜索逻辑,可能是调数据库或第三方 API return { content: [{ type: 'text', text: JSON.stringify(searchPosts(args.keyword)) }] }; }); const transport = new StdioServerTransport(); await server.connect(transport);这里最值得说的是描述信息的重要性。description写得好不好,直接影响模型能不能正确选用这个工具。我不能写“搜索功能”这种泛泛的描述,必须写清楚工具“在什么场景下使用”“输入参数是什么含义”“返回什么结构”。我踩过的坑就是早期描述写得太随意,模型经常在该调工具的时候不调,或者把参数传错。后来把描述改成了“在用户想找技术资料或博客文章时使用,按关键词搜索,返回结构化列表”,命中率立刻上来了。
2.2 A2A:让 Agent 之间用标准协议对话
MCP 解决的是 Agent 调用工具,但 Agent 要调用另一个 Agent 的能力怎么办?这就是 A2A(Agent-to-Agent)协议出场的地方。它是 Google 在 2025 年推动的开放协议,目标就是让不同厂商、不同框架的 Agent 之间能互相发现、互相通信、协同完成复杂任务。
这里特别容易混淆:MCP 和 A2A 的定位完全不同。MCP 是“Agent 使用工具”的协议,工具本身没有主动性,它只是被调用。A2A 是“Agent 和 Agent 对话”的协议,对方是个自主运行的智能体,它会自己理解任务、自己决定怎么做、做完给你交付结果。一句话总结:MCP 是你在指挥工具,A2A 是你给同事派活,同事自己想办法把事做成。
A2A 的核心概念也不复杂,你可以对照着公司协作场景来理解。Agent Card就是每个 Agent 的“简历”或“服务公告”,写明它擅长什么、能接受什么样的任务、支持哪些调用方式,放在/.well-known/agent.json上供别人发现。Task就是一项待办任务,状态流转有明确规定(比如 submitted、working、input-required、completed、failed)。Message是 Agent 之间传递消息的载体,里面包含一个Part数组,Part 可以是纯文本、文件、结构化数据。Artifact是任务执行过程中或结束时的产物,相当于交付物。
我用一个课程里的案例来具象化。假设发布 Agent 对外暴露了一份 Agent Card,写着“我可以接收文章 Markdown 内容,负责格式化排版并推送到指定平台”。内容生成 Agent 发现自己需要发布能力时,就会向发布 Agent 发送一个task/send请求,里面带上文章内容。发布 Agent 收到后创建 Task,返回任务 ID。之后两边通过task/get查询状态,任务完成后通过task/reply把最终的发布链接作为 Artifact 交回来。
A2A 本质上是个 JSON-RPC 2.0 over HTTP 的协议,消息格式都是标准 JSON。好处是生态里任何一个“会说 A2A 话”的 Agent 都能互相协作,不会因为框架不同就变成信息孤岛。
2.3 Skills:把“领域能力”打包成技能卡
第三个核心概念是 Skills。MCP 管的是外部工具,A2A 管的是 Agent 间通信,而 Skills 管的是“给 Agent 内置一组可复用的领域工作流”。它最早是从 Claude 的 Agent Skills 规范里火起来的,后来被大量框架借鉴,现在基本成了 Agent 能力封装的默认形态。
我把 Skills 理解成“武功秘籍”:它不是一个被直接调用的函数,而是一套包含触发条件、操作步骤、经验技巧、注意事项的文档 + 辅助资源包。当模型判断当前任务匹配了这个 Skill,它就会把 Skill 的内容加载进上下文,按里面的步骤逐步执行。
一个标准 Skills 包通常长这样:
my-skills/ ├── research-writer/ │ ├── SKILL.md │ └── templates/ │ └── article-template.mdSKILL.md 是核心,头部是 YAML 格式的元信息,正文是执行这个技能的具体指导。给你看一个实际可用的例子:
--- name: technical_article_writer description: 面向技术博客的深度文章撰写技能。适用于需要把一个技术主题整理成结构清晰、含代码示例、含踩坑经验的文章场景。不适用于新闻快讯或短文案。 --- # 技术文章撰写技能 ## 适用场景 - 用户提供主题,需要输出一篇完整的技术文章 - 需要包含背景、原理说明、实操步骤、常见问题 ## 执行步骤 1. 先分析主题,输出文章大纲,大纲必须包含:引言、核心概念拆解、实操过程、问题排查、经验总结 2. 根据大纲查找必要资料,确保技术细节准确 3. 按大纲逐节写作,每节至少 300 字,代码示例必须标注语言类型 4. 完成后自查:是否有 AI 套路化表达、是否有未解释的术语、代码是否可运行 ## 输出格式 - 文章标题 + Markdown 正文 - 每个代码块标注语言 - 重点术语用加粗标记 ## 质量检查清单 - [ ] 每个 H2 段落超过 500 字 - [ ] 包含至少 4 个 H2 章节 - [ ] 文中无“随着...的发展”等套话这里最关键的是要把“什么时候该用这个 Skill”写清楚,以及“执行时要遵循什么流程”。模型拿到一份 Skill 后,靠的就是这段话去判断启不启用它。我见过很多糟糕的 Skills 写法,Description 写“这是写文章的 Skill”,结果模型遇到任何写作任务都拿它来用,包括写两句朋友圈文案,效果自然一塌糊涂。好的 Description 要写清楚触发场景、排除场景、预期效果。
MCP Tool 和 Skill 的区别也要说透。MCP Tool 是一个独立的、可被调用的外部能力,比如“查天气”“发邮件”。Skill 是一整套“怎么完成任务”的流程知识,中途可能自己去调 MCP Tool,也可能不动工具纯粹靠 Prompt 规则。打个比方:Tool 是工具箱里的电钻,Skill 是“如何安全高效地装一个书架”的指导手册。手册可能会让你用电钻,但电钻本身不知道装书架的事。
2.4 三者的分工与边界
现在把三者的边界彻底捋清楚。MCP、A2A、Skills 不是替代关系,而是三个不同维度上的协议,分别解决 Agent 生态里的“四肢”“口舌”和“大脑经验”。
| 维度 | MCP | A2A | Skills |
|---|---|---|---|
| 通信方向 | Agent → 工具/数据源 | Agent ↔ Agent | Agent → 自身知识/流程 |
| 复用单位 | 外部工具能力 | 智能体服务 | 任务处理流程 |
| 典型载体 | 工具与服务端 | 服务端 + Agent Card | 目录 + SKILL.md |
| 协议/格式 | JSON-RPC 2.0(stdio/HTTP) | JSON-RPC 2.0 over HTTP | 文档 + 脚本 + 资源 |
| 类比 | 通用插线板 | 同事沟通 | 员工手册 |
| 核心问题 | 怎么调用外部能力 | 怎么找到并委托另一个 Agent | 怎么让 Agent 掌握领域任务 |
在 DeepAgents 这套编排体系里,三者是协同工作的:编排层先拆解任务,判断“这一步需要查资料”,于是通过 MCP 调搜索工具;判断“这一步需要写深度文章”,于是加载对应的 Skills;判断“这一步需要专业审校”,于是通过 A2A 把任务派给另一台机器上的审校 Agent。整套流程对用户而言就是一个整体,只是内部在有序分工。
3. 构建一套可编排的多智能体集群
学完概念,我觉得还得动手把课里的核心案例完整跑一遍,才能真正把四个东西串起来。这节课的案例是一个“技术内容创作 + 审校 + 发布”的集群,我照着搭了一遍,很有代表性——既有工具调用又有技能加载,还涉及跨 Agent 协作。接下来我用这个案例,完整走一遍实操流程。
3.1 先解决“工具底座”:写一个 MCP Server
第一步是搭工具底座。这个集群里内容 Agent 需要搜索技术文章、获取参考文档,这些属于“外部数据访问”,统一通过 MCP Server 暴露。
我实现了一个简单的 MCP Server,同时提供了两个能力:search_articles工具和get_documentation资源。search_articles用来按关键词搜文章,get_documentation用来按文档名拉取内部技术手册。这样做的核心好处是:两个 Agent(内容生成 Agent 和审校 Agent)可以共用同一个 Server,不需要各自对接数据源。如果你有多个 MCP Server,在一个配置里列出来就行:
{ "mcpServers": { "content-search": { "command": "node", "args": ["/path/to/content-search-server/index.js"], "env": { "SEARCH_API_KEY": "xxx" } }, "code-exec": { "command": "python", "args": ["/path/to/code-exec-server/main.py"] } } }整个集群里所有 Agent 的配置都指向同一份 MCP 配置文件,这就是“一个底座供全体使用”。实训里特别强调了一点:MCP Server 内部不要写业务逻辑,它只负责“把外部能力以标准接口暴露出来”,真正“怎么用这些能力做决策”是 Agent 和编排层的事。刚开始我经常把大量判断逻辑塞进 Server 里,结果就是 Server 越写越重,还得自己维护一堆状态,后来全部挪出去,清爽多了。
3.2 再写“技能卡”:定义两个核心 Skills
工具底座有了,接下来给内容 Agent 和审校 Agent 各配一个技能卡。内容 Agent 需要写作技能,审校 Agent 需要技术审校技能。
我定义了technical_article_writer和technical_reviewer两个 Skills。technical_article_writer的内容就是上面贴过的那份 SKILL.md,核心是让模型按“大纲→资料→逐节写作→自查”的流程走。technical_reviewer则是另一套逻辑:
--- name: technical_reviewer description: 技术文章质量评审技能。适用于对已有文章进行专业审查,从准确性、结构完整性、代码可执行性、表达简洁度四个维度打分并给出修改意见。不适用于风格润色。 --- # 技术审校技能 ## 审校维度 1. 技术准确性:断言是否准确、参数是否误导、代码是否能运行 2. 结构完整性:是否有清晰标题层级、结论是否自然 3. 表达质量:是否存在空话套话、是否有未解释的缩写 4. 实用价值:是否包含可复现的步骤和可操作的建议 ## 输出格式 - 总评分(0-100) - 分维度评分 + 具体问题 - 修改意见列表(按严重程度排序) ## 红线检查 - 拒绝含糊表述,要求给出明确建议 - 不重写文章,只输出问题和修改建议写 Skill 的时候我最大的心得是:步骤要写到“一个实习生看了也能照做”的程度。很多人写 Skill 就是几句抽象描述,比如“认真负责地完成写作”,模型拿到后根本不知道具体怎么做。真正有用的 Skill 是流程清单 + 检查清单,模型照着执行,输出质量立刻稳定很多。
3.3 用 A2A 把发布 Agent 暴露出去
内容生成和审校搞定了,接下来是发布环节。发布 Agent 在这套集群里是独立的服务,通过 A2A 协议对外提供能力。我给它配了 Agent Card:
{ "@context": "https://json-ld.org/contexts/person.jsonld", "identifier": "publisher-agent-v1", "name": "Technical Content Publisher", "description": "接收文章 Markdown,负责格式标准化并发布到内容平台", "url": "http://localhost:4120/", "capabilities": { "skills": ["markdown_formatting", "publishing"], "inputModes": ["text/markdown", "application/json"], "outputModes": ["text/plain", "application/json"] } }然后在服务根路径下放/.well-known/agent.json,指向这份 Card。我实现的核心处理逻辑是处理task/send请求:
from flask import Flask, request, jsonify app = Flask(__name__) # 存储任务状态 tasks = {} @app.post("/task/send") def task_send(): body = request.get_json() task_id = generate_task_id() tasks[task_id] = {"status": "working", "result": None} message = body["params"]["message"] # 从 message 中拿到文章 markdown,开始处理 process_async(task_id, message) return jsonify({"result": {"id": task_id, "status": {"state": "working"}}}) @app.post("/task/get") def task_get(): body = request.get_json() task_id = body["params"]["id"] return jsonify({"result": tasks.get(task_id)})从代码里能看到 A2A 的交互本质:调用方发来一个任务,接收方创建 Task 并立即返回状态,调用方轮询task/get获取结果。发布 Agent 在后台异步处理格式化、排版、推送,做完了把结果写进任务状态。这套异步机制很重要,因为 Agent 处理任务往往耗时较长,同步等待会卡死调用方。
3.4 在编排层串起完整流程
前面三块都是“零件”,现在把它们装进 DeepAgents 这个“总装车间”。编排层要做的事情有三件:拆解任务、调度 Agent、管理状态。
我在这门课的实践中用了一个类似工作流的描述方式来定义集群的运行逻辑,核心思路是这样的:
# 伪代码:编排层的工作流定义 workflow = create_pipeline("technical_content_pipeline") @workflow.step("generate") def generate_content(topic): writer = get_agent("content_writer") return writer.run( skill="technical_article_writer", mcp_servers=["content-search"], input={"topic": topic} ) @workflow.step("review") def review_content(article): reviewer = get_agent("technical_reviewer") result = reviewer.run( skill="technical_reviewer", input={"article": article} ) if result.score >= 80: return {"status": "approved", "article": article} else: return {"status": "rejected", "comments": result.comments, "article": article} @workflow.step("publish") def publish_content(article): publisher = get_agent("publisher") return publisher.request_a2a( target="http://localhost:4120", task="publish_article", payload={"markdown": article} )这里最关键的设计是状态管理。课程里用了明确的“任务生命周期”模型,每个任务都有清晰状态:pending → running → approved/rejected/completed/failed。为什么重要?因为多 Agent 集群里,任务不会永远一条直线走下去,它会被打回、会被挂起、会失败。比如审校 Agent 给文章打了 60 分,编排层就要把任务送回生成 Agent 修改,形成“创作→审校→打回→再创作→再审校”的循环。没有状态机管理,这种循环很快就乱套了。
我在这门课的实践中尤其体会到一个点:编排层的“路由规则”要外置,不要写死在代码里。分数阈值、重试次数、回退动作这些都应该是可配置的。我最早是写死的,后来业务方说“审校分数从 80 分改成 75 分吧”,我就得改代码重新部署。改成配置之后,改阈值就像改个 JSON 一样简单。
3.5 在本地跑起来的完整核对清单
把一个集群从零跑通,我整理了一份核对清单,照着走能省大量排查时间:
- 先单独启动每个 MCP Server,用 MCP Inspector 或 curl 验证
tools/list能返回预期工具列表。 - 单独测试每个 Agent:直接给它一个任务,确认它能在无集群环境下独立完成。
- 用
/.well-known/agent.json验证发布 Agent 的 Agent Card 可被公网访问。 - 在编排层把 Agent 逐个注册进来,每注册一个就跑一次最小化任务。
- 最后才把完整流水线串起来,先跑一个“短任务”验证链路,再跑真实完整任务。
我犯过的最大错误就是跳过前面的单独测试,直接把整套集群启动,结果排错时根本不知道问题出在 MCP 工具、Skill 定义还是 A2A 调用上。现在我的铁律是:先单点后链路,先简单后完整。
4. 常见问题与排查技巧实录
实操过程中遇到问题太正常了,这门课里也花了不少篇幅讲排错。我把几个高频问题和排查思路整理成一张速查表,都是我实际踩过的:
| 问题现象 | 可能原因 | 排查/解决方法 |
|---|---|---|
| MCP 工具列表为空 | Server 进程没启动 / JSON-RPC 握手失败 | 用 MCP Inspector 单独连接,看 initialize 是否成功 |
| 模型死活不调用某个 Tool | Description 写得太含糊 / 场景不匹配 | 把触发场景讲透,写明“什么时候用/什么时候不用” |
| 模型不按 Skill 执行 | Skill 描述与任务不匹配 / Skill 名太宽泛 | 缩小触发条件,增加排除场景,步骤写具体 |
| A2A 握手失败 | Agent Card 缺失 / URL 配置错误 | 浏览器直接访问 /.well-known/agent.json 验证 |
| A2A 任务卡在 working | 接收方异步逻辑挂了 | 检查接收方日志,手动模拟 task/send 请求 |
| 集群上下文爆炸 | 中间产物全堆在内存 | 用结构化中间态,只传摘要和关键字段 |
| 任务漂移(答非所问) | 任务目标在链路中被稀释 | 每个任务带上原始目标字段,Agent 执行前先复核 |
4.1 MCP 连接不上、工具不显示
这是最常见的问题。我最早遇到的场景是:配置好 MCP Server,Agent 里却看不到任何工具。排查后发现是 stdio 模式下 Server 启动失败,但错误被吞掉了,日志里什么都没留下。所以第一件事永远是先用 MCP Inspector 这种独立调试工具单独连一次,工具能列出来再谈后面的事。
还有一类问题是工具名冲突。多个 MCP Server 可能暴露了同名工具,比如搜索类工具都叫search,模型调用时就会二选一甚至报错。我的做法是在服务端把名字改成带业务前缀的,比如content_search_posts、code_search,这样既语义清晰,也从根上规避了冲突。
4.2 模型就是不调用我写的 Skill
这个问题比工具不调用更隐蔽。Skill 不像 MCP Tool 在请求时自动暴露给模型,它通常需要 Agent 框架按描述去判断“要不要加载”。如果 Description 写得太泛,模型会觉得“这个技能适用于所有写作任务”,结果遇到什么任务都加载一遍;或者反过来,写得太窄,模型永远触发不了。
我的经验是:描述里必须写清楚“触发场景 + 排除场景 + 预期收益”。比如我的technical_reviewer如果只写“审校文章”,模型就不会在遇到“文章内容很烂”时主动加载,但如果写了“对已有文章从准确性、结构、代码可执行性四个维度打分并给出修改意见”,模型的触发准确率就高很多。另外 Skill 文件命名也要控制好,不要叫通用词比如writer,最好带上场景,就是technical_article_writer这种。
4.3 A2A 握手失败、消息格式报错
A2A 的坑主要集中在协议细节上。我遇到过一次:Agent Card 配好了,但对方 Agent 总是报 404。排查发现是/.well-known/agent.json放错了目录,放在了根目录但卡没走/.well-known路径。A2A 的规范里,Agent Card 必须要放在/.well-known/这个标准路径下,这是约定俗成的,不是你想放哪就放哪。
另外task/send的请求体和返回体必须严格遵循协议结构,多一个字段少一个字段都可能导致对方解析失败。我建议直接把规范里的 JSON 示例拷过来改,不要自己重新发明一个“看起来更顺眼”的结构。曾经我图省事把params层去掉了,结果对方 Agent 直接报“Missing required field: params”。
4.4 编排时上下文爆炸与任务漂移
集群跑起来之后,最大的隐形敌人是上下文爆炸。多 Agent 协作时,中间产物和日志会疯狂累积。我碰到过:内容 Agent 产出一篇 5000 字的文章,审校 Agent 又加了 2000 字的批注,修改后的文章又变成 6000 字,结果下一次审校 Agent 的上下文里塞进了一万字的历史文本,模型开始胡言乱语。
解决办法是“中间产物瘦身”。编排层在传递过程中只保留关键字段:当前版本的文章、最新一轮审校意见、任务原始目标,而不是把全链路的所有历史对话都堆给下一环。这里要特别注意,“原始目标”字段必须贯串始终。否则链路长了之后,下游 Agent 只看到上游的摘要,最后做出来的东西跟原始需求完全偏离。我经历过一次:用户要一篇“MCP 协议入门”的文章,传了几手之后,发布 Agent 拿到的东西变成了“MCP Server 源码分析”,主题都跑偏了。加了原始目标字段就没再出现过这种情况。
4.5 安全与权限:Agent 集群最容易翻车的地方
这一点是课程里反复强调、也是我一度忽略的:多智能体集群的安全模型比单 Agent 复杂得多。单 Agent 只有一个决策点、一套权限,集群里却是多个 Agent、多套工具、多条通信链路,任何一个环节被攻破都可能产生连锁反应。
我总结了几条必须遵守的底线。第一,最小权限原则:每个 Agent 只拥有完成自身任务所需的权限,内容 Agent 能读搜索但不能写数据库,发布 Agent 能推送内容但不能删数据。第二,人工审批节点:对高风险操作(比如真实发布、删除数据、发起支付)在中间插入人工确认步骤,这在 A2A 上就是约定“任务流转到 high-risk 状态时必须等待人工确认”。第三,输入注入防护:Agent 从外部拿到的内容可能夹带恶意指令,比如某篇文档里写了“忽略之前所有指令”,绝不能盲目执行。我的做法是在编排层加一层“内容清洗”,剥离可疑指令后再传给下一环节。
课程最后还专门讲了一个点:要分清“数据通道”和“控制通道”。A2A 通信里,消息正文是数据通道,任务状态流转是控制通道。恶意内容应该最多停留在数据通道,永远不能让它通过控制通道改变集群的行为逻辑。
5. 这门课后我的体会与扩展建议
整套跑下来,我最深的感受是:多智能体集群的复杂度不是靠“多堆几个 Agent”堆出来的,而是靠“把每个 Agent 的边界划清楚”长出来的。好架构的标志是,每个 Agent 都小得能让人一眼看懂“它是干什么的、能调用什么、不能调用什么”,而不是一个万能大脑被塞满所有可能。
我自己踩过几次坑之后,现在再做 Agent 项目,会先问自己三个问题:这个任务真的需要多个 Agent 吗?如果需要拆分,拆分的依据是“工具集不同”还是“职责不同”?Agent 之间是通过 MCP、A2A 还是 Skills 交互?想清楚这三个问题,架构基本就不会跑偏。课程的案例给了三条很有价值的扩展方向。一个是把 Agent 记忆系统接入编排层,让 Agent 能记住历史任务中的偏好和结论。另一个是把事件驱动机制加进去,让外部事件(比如新文章发布、新 issue 创建)直接触发集群里的 Agent 开始工作,而不是每次都由用户手动发起任务。还有一个是增加观测与回放能力,记录每个 Agent 的完整决策轨迹。
最后分享一个非常实用的小技巧:在本地调试这套集群时,别一头扎进代码里打日志,先用一个“最小复现”的方式把链路缩短——临时把审校 Agent 的阈值调到最低、把发布 Agent 变成一个打印结果的假服务,先验证链路通不通。链路通了,再恢复真实逻辑。这一步省了我几百刀 API 费用,也把排错时间压缩了一半。希望这篇能帮你在多智能体这条路上少踩几个坑。