DeepAgents+MCP+Skills+A2A:多智能体设计稿转代码实战指南
1. 先把这个项目全景图说清楚:四套技术各管哪一段
1.1 一个真实的需求:从设计稿到可运行代码
我接手过一个内部工具项目:设计师在蓝湖和Figma里面把页面改完,前端开发照着视觉稿手动切图、翻译样式、写组件,一个中等复杂度的页面往往要一两天。产品经理问我,能不能让AI直接"看懂"设计稿,再把代码骨架搭出来,中间最好还能自动调用设计系统里的规范、自动检查落地的还原度。
放在一年前,这是个很棘手的问题。单靠一个大模型去读设计稿,得到的只是"描述",不是可执行的工作流。现在这个问题有了相对完整的技术答案,就是我标题里写的那套组合: DeepAgents做编排,MCP去接外部工具和数据,Skills充当可复用的经验包,A2A解决模型和智能体之间的通信 。这四样东西各管一段,拼起来就是一整套可落地的"多智能体全流程"。
这篇文章不是官方文档的翻译,是我把这两年在多智能体项目里的踩坑、调通、跑崩、又调通的过程,连同对协议和框架的理解,一次性整理成"21章完整版"之外的另一种完整版——不讲目录,讲为什么这么做、实际跑起来是什么感受。
1.2 MCP、A2A、Skills、DeepAgents各自的定位
很多朋友一上来就被四个名词劝退了,其实它们解决的完全是不同层面的问题。
先说 MCP(Model Context Protocol) 。它是模型和外部工具之间的"插座协议"。没有MCP的时候,你想让AI调用一个内部API,要么自己写胶水代码,要么把API封装成prompt暴力塞进去。有了MCP,工具按标准协议暴露能力,模型客户端按标准方式调用,插上就能用。我把它理解成 AI世界的USB-C接口 。
再看 Skills 。如果你把模型当成一个聪明但没经验的新人,MCP给他的是"工具箱",Skills给他的就是"老师傅的操作手册"。一个Skill通常是一组带说明文件、步骤定义、参考案例的指令包,告诉模型"遇到这类任务时,按这套方法论执行"。它不像MCP那样直接调用函数,而是提供一种可复用的"做事方式"。
然后是 A2A(Agent-to-Agent) 。这是让不同智能体互相通信的协议。MCP解决的是"AI调用工具",A2A解决的是"AI调用AI"。当一个任务需要规划、编码、测试、UI还原多个角色协作时,它们之间怎么打招呼、怎么派活、怎么回报结果,就是A2A负责的事。
最后是 DeepAgents 。它是一个具体的开发框架,帮你把前面三样东西组装成一个可运行的多智能体应用。你可以把它理解成整条流水线的中控台,负责调度任务、管理上下文、把Skills挂到合适的节点、把MCP工具暴露给子智能体、甚至通过A2A去和其他Agent服务对话。
1.3 整条链路是怎么串起来的
用我实际做的"设计稿到代码流程"来串一遍就清楚了。
需求进来后,DeepAgents里的规划节点先分析任务,拆成"读取设计稿规范、提取页面结构、生成前端代码骨架、检查还原度"四个子任务。第一个子任务通过Figma MCP把设计稿的图层、颜色、标注读出来;第二个子任务把数据交给一个挂了"前端编码Skills"的编码智能体;第三个子任务再调MCP把生成代码推给本地脚手架工具;如果这个过程涉及另一个独立的Agent服务,比如一个专门做视觉校验的微服务,那双方就通过A2A协议来通信,主智能体下发校验请求,视觉校验Agent回传差异报告。
所以说白了: Skills给智能体内功,MCP给智能体手脚,A2A让智能体之间有共同语言,DeepAgents把这一切编排成一条跑得通的生产线 。这篇文章后面会按这条逻辑线展开,我会尽量讲清楚每个环节的"为什么",而不只是堆API。
2. MCP:先把手能伸到的地方铺开
2.1 MCP到底在解决什么问题
聊MCP之前,我先说一个很多团队反复踩的坑:在项目初期,把"工具调用"直接写死在大模型的system prompt里。前端调用后端接口,人肉维护一份长长的手册,模型用的时候从里面"猜"参数。结果手册和实际接口一旦不同步,模型要么瞎编工具名,要么参数格式不对,调试起来非常痛苦。
MCP的核心价值就是把"工具发现"和"工具调用"标准化。一个MCP Server会通过标准接口暴露三样东西: Tools(工具) 、 Resources(资源) 、 Prompts(提示模板) 。客户端连上这个Server之后,可以自动拿到工具清单、按标准格式发起调用、读取资源内容,根本不用预先知道对方内部是怎么实现的。数据格式基于 JSON-RPC 2.0 ,传输层支持 stdio (本机进程间通信)和 HTTP+SSE (远程服务通信)等模式。
我举个例子你就明白它多省事。我们的设计稿存在Figma上,Figma官方出了MCP Server。以前想让AI读设计稿,得先导出PNG、再写图像识别脚本、再把识别结果转成AI能理解的文本。现在直接让DeepAgents连接Figma MCP,AI自己就能发出"get_figma_file_styles""get_figma_file_layout"这类调用,拿到的还是结构化数据,比如颜色变量、字体、坐标、组件实例。
需要注意的是,MCP并非只能对接云端SaaS。我见过有人给本地股票软件做MCP Server,把本地K线数据和选股结果暴露成工具;还有人给CATIA、NXOpen这类工业设计软件包了一层MCP,模型可以直接调用CAD软件的建模接口。这说明MCP的价值不止在互联网工具,它同样适合企业内部系统、专业软件和本地数据源。
2.2 手写一个MCP Server示例:本地项目仓库分析
理论讲再多,不如写一个能跑通的Server。下面这个示例用Python实现,目标是暴露一个"本地项目仓库结构分析"工具。它背后的能力很普通——就是把目录结构和文件行数统计出来——但关键是它用MCP协议把自己变成了AI可调用的标准化工具。
import os
from mcp.server import Server
from mcp.server.stdio import run_server
from mcp.types import Tool, TextContent
app = Server("repo-analyzer")
@app.list_tools()
async def list_tools():
return [
Tool(
name="repo_summary",
description="分析本地代码仓库,返回目录树、总文件数和总行数",
inputSchema={
"type": "object",
"properties": {
"root_path": {"type": "string", "description": "仓库绝对路径"}
},
"required": ["root_path"]
}
)
]
@app.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "repo_summary":
root_path = arguments["root_path"]
total_files = 0
total_lines = 0
tree_lines = []
for dirpath, dirnames, filenames in os.walk(root_path):
depth = dirpath.replace(root_path, "").count(os.sep)
indent = " " * depth
tree_lines.append(f"{indent}{os.path.basename(dirpath)}/")
for f in filenames:
total_files += 1
fp = os.path.join(dirpath, f)
try:
with open(fp, "r", encoding="utf-8", errors="ignore") as fh:
total_lines += len(fh.readlines())
except Exception:
pass
result = "\n".join(tree_lines[:200])
return [TextContent(type="text", text=(
f"目录树(前200行):\n{result}\n"
f"总文件数:{total_files},总行数:{total_lines}"
))]
if __name__ == "__main__":
run_server(app)
这个Server跑起来之后,支持MCP的客户端(比如DeepAgents、Claude Desktop、Cursor)可以直接发现它。我刚开始写MCP Server时也犯过一个错误:以为Tools越多越好,把几十个接口全暴露出去。实际上MCP工具描述如果不够精确,模型会选错工具,反而降低成功率。工具少而精,描述里写清楚"什么时候用、参数是什么单位、返回什么结构",才是真正的工程经验。
2.3 主流MCP生态盘点:从Figma到蓝湖再到安全测试工具
给团队选型时,MCP生态是否成熟是我最看重的指标。现在的情况是"热门工具基本都有了官方或社区维护的MCP Server"。
- 设计协作类 :Figma官方MCP支持读取设计稿、图层、样式;国内的设计协作平台蓝湖也推出了对应的MCP,可用于获取设计标注、设计提案。前端拿设计稿生成代码是当前最典型的场景。
- 开发工具类 :Cursor内置了MCP支持,可以接入本地文件操作、代码搜索、Git操作等服务;Codex的MCP可以用来执行命令行任务;还有像Context7这类"文档MCP",把第三方库的官方文档结构化,AI能在编码时动态查询最新API。
- 安全与测试类 :Burp Suite和Yakit都有配套的MCP Server,可以让AI直接操作流量、发送测试请求、分析告警。做AI辅助安全测试的团队现在省掉了大量脚本开发,直接让模型通过MCP来编排测试工具。
- 专业软件类 :CAD领域有CATIA、NXOpen的MCP方案,虽然还比较早期,但方向很明确——AI本身不擅长计算几何,但通过MCP调用专业建模内核的参数化接口,就能完成复杂的模型生成任务。
- 金融数据类 :有人给通达信这类股票软件做了本地数据MCP,这样模型可以直接读本地行情数据,而不是靠大模型的记忆去"编造"数字。
我的建议是:新项目接入某个外部能力前,先去MCP生态里搜一遍,能直接用现成的Server就不自己写。但凡是核心链路依赖的工具,一定要自己审计Server代码或自己写,因为第三方Server的稳定性、权限边界、返回质量参差不齐。我给你一个排查口诀: 先看Server的返回是不是严格的JSON-RPC格式,再看工具描述是否精准,最后看有没有对网络和文件系统的访问限制 。
3. Skills:给智能体装上传经编过的经验
3.1 Skills和MCP的边界:什么时候用Skill,什么时候用MCP
这可能是新手最容易混淆的一对概念。网上有张很火的对比图:MCP是"给AI一双手",Skills是"给AI一套肌肉记忆"。这个类比不算精确,但方向是对的。
我自己的判断标准很简单: 如果一项能力需要通过调用外部函数才能完成,选MCP;如果一项能力是"模型应该怎么做、按什么思考路径、参考什么规范",选Skills 。
举个例子。我在项目里给前端编码智能体挂了一个"前端开发Skills",里面包含的不只是"写代码"这个动作,还有:拿到设计稿后先分析风格变量,再搭组件树,再写样式,每一步都有检查清单。这套东西不是外部工具,不需要调用函数,但它能让模型的输出更稳定。相比之下,获取设计稿标注这件事就必须用Figma MCP,因为那是外部数据源。
如果一个能力介于两者之间怎么选?我给的补充判断是:看"是否需要模型利用外部实时状态"。需要就MCP,纯教模型"怎么做"就Skill。比如说"从Git提交记录里生成今日工作总结",需要读Git状态,应该做成MCP工具;而"写commit message时遵循Conventional Commits规范"属于做事方式,做成Skill更合适。
有一类"数学建模Skills""数模Skills"在国内社区很火,本质上就是把建模大赛这类任务的方法论沉淀成Skill:赛题分析、指标选择、模型选型、论文排版,每个环节都有对应的提示词模板和检查项。这也是Skills的正确用法——它承载的是"经验"和"流程",不是"接口"。
3.2 一个Skill到底长什么样
我以自己常用的"结构图Skills"为例拆解一下。这个Skill的作用是让AI在画架构图之前,先做信息架构梳理,然后产出Mermaid或PlantUML代码。它的目录结构基本上长这样:
structure-diagram-skill/
SKILL.md
examples/
ecommerce.md
event-driven.md
references/
mermaid-cheatsheet.md
SKILL.md是核心,里面有一段YAML格式的前置元信息,然后再用自然语言描述任务目标、可用的工具、执行步骤和质量标准。简化后大概是这样:
---
name: structure-diagram-skill
description: 根据需求描述生成架构图或结构图时使用,防止AI直接乱画
---
# 结构图生成流程
1. 先从需求中提取实体清单和关系清单
2. 确认关系类型(依赖、聚合、组合、单向/双向)
3. 将实体与关系映射到图表语法
4. 检查是否有孤立节点、循环依赖
5. 最后输出图表代码和简短说明
## 注意事项
- 如果没有明确说明,优先使用 Mermaid 语法
- 实体名使用 PascalCase,关系名使用小写短语
- 不生成超出需求范围的假设性模块
## 参考示例
- 见 examples/ecommerce.md(电商订单流)
- 见 examples/event-driven.md(事件驱动架构)
你可能会问:这个Skill和直接把"注意事项"写在system prompt里有什么区别?区别在于Skills是 结构化、可积累、可复用 的。你可以把几十个这样的Skill放到Skills目录里,智能体启动时按任务类型动态加载,而不是在一个巨大的prompt里全部塞满。Prompt会越写越乱,Skill却可以像乐高一样灵活组合。
3.3 Skills Harness和Superpowers带来的启发
社区里关于"Skills Harness"的讨论不少,我研究之后的理解是:Harness指的是"技能运行环境",它决定了技能怎么被发现、怎么加载、怎么和模型交互。有的实现是文件夹扫描,有的是在模型启动时按任务描述在向量库里搜出最相关的几个Skill,再动态注入上下文。好的Harness设计会做三件事: 技能路由(按任务选技能)、技能隔离(不同技能间的上下文不污染)、技能链(一个技能触发另一个技能) 。
Superpowers这个项目给了我不少启发。它的思路是把"技能"做得非常细:不只一个大而全的"写代码技能",而是按场景拆成"调试技能""重构技能""写测试技能""解释遗留代码技能"。一个模型在编码任务里可能同时加载两三个技能,任务不同,技能组合完全不同。这不是形式上的花活,而是工程上真实提升了成功率——因为每个技能里的提示词上下文更聚焦,模型不容易"精神污染"。
我在实际项目里测试过,同样是用DeepAgents做任务分解,挂不挂Skills,对复杂任务的输出稳定性影响非常明显。不挂Skills时,子智能体经常"自由发挥",步骤混乱;挂了Skills之后,子智能体会按Skill里定义的步骤顺序走,即使模型版本换了,输出质量也能保持稳定。这也是我把Skills视为"多智能体系统的宪法"的原因——宪法管住的是流程,而不是具体某句话怎么写。
4. A2A:让智能体之间说同一种语言
4.1 A2A与MCP的分工
如果团队里只有一个Agent,MCP加Skills基本就够用了。但多智能体场景下,最头疼的问题不是单个Agent笨,而是它们之间"讲不通"。你有你的工具,我有我的状态,你交付的东西我不知道怎么读取,怎么办?
A2A(Agent-to-Agent) 就是为了解决这个"讲不通"而生的。它把每个Agent视为一个服务,Agent之间通过标准消息互相发现、通信、传递任务。你可以把它理解成HTTP之于Web那样:不需要知道对方用什么语言写的、部署在哪台机器上,只要双方遵守同样的请求响应格式就能对话。
MCP和A2A经常被放在一起对比,很多初学者会以为它们是对手方案。其实分工很清楚: MCP是Agent的"手",A2A是Agent的"嘴" 。MCP管的是Agent如何调用工具和系统;A2A管的是Agent如何与其他Agent打交道。一个Agent完全可以既通过MCP调用外部工具,又通过A2A把任务委托给另一个Agent。
我常打的比方是:MCP像是"厨房里的厨具"——统一的炊具接口,什么锅都能放上灶台;A2A像是"餐厅和后厨之间的传菜窗口"——传的是什么菜、怎么报单、怎么确认出餐,这些规则大家都得认。
4.2 Agent Card从0.3到1.0:协议演进中最关键的变化
A2A协议从0.3版本演进到1.0版本的过程中,最值得关注的是 Agent Card从"格式化名片"变成了"协议级的能力声明" 。0.3版本里,Agent Card已经定义了Agent的名字、描述、URL、版本号,还定义了一组skills数组——每个skill描述这个Agent能做哪个具体任务。当时的问题是,卡片信息太"薄",缺乏对交互模式的约束,两个Agent即使都实现了协议,仍容易在"任务类型是否匹配""卡片宣告的技能与运行时能力是否一致"上出偏差。
1.0版本做了几个关键收紧,我挑最重要的三点说:
第一,Agent Card里的skills字段被进一步结构化 。每个skill从简单的"名称+描述"升级为包含操作参数说明、输入输出结构和处理能力的声明。这非常像把"JSON Schema"内嵌到了卡片里。一个Agent拿到另一方的卡片后,不只是知道"哦他能处理前端重构",还能知道"他需要我传design_tokens和page_structure这两种结构,输出的是React组件代码"。
第二,任务对象(Task)的生命周期被明确 。A2A中Agent之间的对话以Task为单位,每个Task有id、status、artifact(产出的成果物)、message(消息记录)。1.0版本强调Task的最终状态必须是"completed""canceled""failed"这类明确终态,避免两边因为"我以为你还在算"导致死等。
第三,能力协商机制更完善 。1.0版本的AgentCard可以让Agent声明自己支持的能力配置,比如是否支持长时任务回调、是否支持流式消息、是否支持客户端发起的重试。这让处于不同部署环境(内网/公网、离线/在线)的Agent可以彼此协商出一个双方都接受的通信方式。
一个完整的1.0版本Agent Card示例大概长这样:
{
"identifier": "ui-review-agent",
"displayName": "UI还原度审查Agent",
"description": "接收设计稿数据和前端代码,返回视觉还原差异报告",
"url": "https://agent.example.com/a2a",
"version": "1.0.0",
"capabilities": {
"streaming": false,
"pushNotifications": true
},
"skills": [
{
"id": "visual-diff",
"name": "视觉差异检测",
"description": "用于比较设计稿和实现稿在颜色、间距、字体上的差异",
"inputModes": ["application/json"],
"outputModes": ["application/json"]
}
],
"security": {
"authentication": {
"schemes": ["bearer"],
"credentials": "required"
}
}
}
从0.3到1.0,最核心的变化是"卡片"从给人看的宣传页,变成了机器能解析、能决策的契约。
4.3 一个可落地的A2A交互流程
纸上谈兵没意思,我拿一个实际用过的场景演示A2A的交互流程。假设主Agent是"项目规划Agent"(我们叫它Planner),子Agent是"前端编码Agent"(叫它Coder),它们分布运行在两个不同的服务进程里。
第一步,Planner通过A2A协议向Coder发送一个Task,Task的payload里明确写了输入和期望输出:
{
"jsonrpc": "2.0",
"method": "tasks/send",
"params": {
"id": "task-001",
"message": {
"role": "user",
"parts": [
{
"text": "请根据design-payload.json生成前端页面骨架"
}
]
}
}
}
第二步,Coder收到Task后,先不回完成,而是返回一个pending状态,然后异步处理。处理过程中,它会调用自己的MCP工具拉取设计稿数据、查组件库,再按前端Skills里的规范写代码。完成后,通过
tasks/complete
方法回传结果:
{
"jsonrpc": "2.0",
"method": "tasks/state",
"params": {
"id": "task-001",
"status": "completed",
"artifacts": [
{
"name": "generated-code.zip",
"metadata": {
"files": 23,
"language": "tsx",
"framework": "react"
}
}
]
}
}
第三步,Planner解析artifacts,如果发现还有后续任务,比如"把代码交给视觉审查Agent",就再走一遍同样的流程。整个过程里,每个消息都必须是标准化的,不能有双方私下约定的"暗号"。这就是A2A最大的价值: 它把Agent网络从一个单体应用变成了可扩展的开放生态 。
我在实际落地时的体会是,协议本身不复杂,但"Agent给的承诺要能兑现"很重要。1.0版本之所以加强Agent Card,就是希望大家在真正通信前,先把能力边界说清楚。如果你把不存在的能力写进Agent Card,另一方按契约来请求,你返回不了预期结构,整个信任体系就崩了。
5. DeepAgents:把上面的东西编排成真正的项目
5.1 DeepAgents的工程化形态和核心设计
DeepAgents给我的第一印象是:它不像传统"调用大模型API"的脚本那么单薄,而是一个真正 以Agent为第一公民 的开发框架。它对多模态输入、交互式运行的支持,让人觉得它更像一个"Agent IDE"而不只是一个SDK。
我使用之后把它的核心设计归纳成三点:
第一,以任务中心化的方式组织Agent生命周期 。框架会维护一套历史记录系统,记录每个错误修复动作、交互失败模式、子步骤的完整过程。任务从"创建"到"完成"有明确的状态流转,这跟A2A协议的Task模型是天然对齐的。你可以查看每个子Agent干了什么、产出是什么、失败了之后试过哪条新路径。
第二,支持多模态交互 。它不只处理文本,还能直接处理图像、文档截图等输入。我在设计稿还原场景里,直接把Figma导出的视觉稿截图喂进去,让规划Agent先"看图说话",把页面结构提取成文本描述,再把描述交给编码Agent。这条链路没有DeepAgents的多模态支持时,完全走不通。
第三,Skills和MCP合并接入 。DeepAgents支持在任务规划阶段就把Skills和MCP工具纳入考虑。你可以直接告诉框架"给编码Agent挂上'前端开发Skills',同时把Figma MCP提供的工具暴露给它",框架会把这些配置应用到运行时的智能体上下文里。
5.2 用DeepAgents写一个多智能体协作流程示例
下面是一段简化版的伪配置和代码,展示我如何在DeepAgents里定义Agent角色、挂载Skill、连接MCP:
from deepagents import DeepAgent, Skill, MCPToolRegistry
repo_analyzer = MCPToolRegistry.connect("repo-analyzer")
figma_tools = MCPToolRegistry.connect("figma-server")
planner = DeepAgent(
name="planner",
role="项目规划",
instructions="分析需求并拆解为可执行任务",
)
coder = DeepAgent(
name="coder",
role="前端编码",
instructions="按前端工程规范实现页面代码",
skills=[Skill.load("frontend-development")],
tools=[repo_analyzer.tool("read_project_config")]
)
design_specialist = DeepAgent(
name="design-specialist",
role="视觉还原",
instructions="读取设计稿,提取样式变量和布局结构",
tools=[figma_tools.tool("get_figma_styles")],
)
# 多智能体协作:planner 拆解任务后派发给其他 Agent
result = planner.delegate(
task="把Figma页面转为React/Tailwind代码",
assigns={
"design-analysis": design_specialist,
"code-generation": coder,
}
)
注意几个细节:
MCPToolRegistry.connect
会把MCP Server暴露的工具做一层"鉴权+超时"包装,避免子Agent乱调工具;
Skill.load
会在Agent启动时把选中的Skill加载进上下文,而不是等到运行时再临时注入。
这里有一个容易被忽略的工程决策: 为什么要让design-specialist负责提取样式,而不是让coder直接连Figma MCP? 原因是我希望"读设计稿"和"写代码"两件事有清晰的上下文边界。设计稿数据很杂,如果直接全部塞给coder,它既要处理视觉信息又要写代码,容易分心;先由design-specialist提取出精简的样式token和布局树,再传给coder,后者只需专注代码生成,成功率明显更高。
5.3 编排层要重点设计的状态管理
多智能体系统里,"状态管理"是最容易失控的部分。我见过很多项目,Agent之间靠来回传递超大JSON报文维持状态,跑几轮之后上下文爆掉、关键信息丢失、子Agent开始互相覆盖对方的产出。
我的经验是,在编排层必须明确三条状态规则:
第一,子Agent之间不共享非必要上下文 。每个子Agent只拿到完成本任务必需的输入,输出也只保留关键产物。比如design-specialist输出的是"样式变量+布局树"而不是一份5000行的Figma原始JSON。在DeepAgents这类框架里,你要显式设计每个Agent的"输入契约"和"产出契约"。
第二,任务状态必须持久化 。不能只把状态放在内存里,因为任何一个Agent超时挂掉,整个任务链都会断。我一般会把Task状态同步到Redis或者数据库,记录"哪个Agent负责、当前阶段、已完成产物地址"。
第三,要有全局回滚点 。多智能体协作难免出错,出错后如果只能从零开始,成本太高。我会在每个关键节点生成一个"阶段快照",比如"设计稿解析完成""代码骨架生成完成",出错时从最近的成功快照继续。这个思路和数据库的checkpoint机制很像。
6. 端到端实战复盘:从设计稿到代码骨架的完整流水线
6.1 项目结构和任务拆解
前面讲了不少原理,现在完整复盘一遍我实际搭过的流水线。任务很明确:输入一个Figma/蓝湖设计稿,输出一份可运行的React+Tailwind页面骨架。
我把整条流水线拆成五个阶段:
| 阶段 | 负责Agent | 主要工具 | 产出物 |
|---|---|---|---|
| 需求解析 | Planner | DeepAgents规划上下文 | 任务清单、页面清单 |
| 设计稿分析 | Design Specialist | Figma MCP / 蓝湖 MCP | 样式token、布局树、组件标注 |
| 代码生成 | Coder | 前端开发Skills、仓库工具 | React组件、Tailwind样式 |
| 静态检查 | Reviewer | 项目配置MCP、Lint工具 | 差异报告、错误修正建议 |
| 人工确认 | 全局唯一 | 不需要 | 最终合并请求 |
为什么把"静态检查"单独作为一个Agent而不是让Coder自己检查自己?因为让写代码的Agent检查自己写的代码,等于让考生自己判卷,除非有非常严格的checklist,否则基本都是"我检查过了,没问题"。独立Reviewer角色的存在价值,一方面是隔离上下文,另一方面是"审视者"的立场会让它更容易发现问题。
6.2 核心串联代码
在这个流水线里,最重要的串联逻辑是"产出物如何在Agent之间传递"。我用的核心代码逻辑如下:
from deepagents import DeepAgent, Skill, MCPToolRegistry
# 1. 连接外部工具
figma = MCPToolRegistry.connect("figma-server")
project_loader = MCPToolRegistry.connect("project-loader")
# 2. 定义三个核心Agent
design_specialist = DeepAgent(
name="design-specialist",
role="视觉解析",
tools=[figma.tool("get_figma_file")],
instructions="分析设计稿,返回样式变量、布局树和组件列表",
)
coder = DeepAgent(
name="coder",
role="前端编码",
skills=[Skill.load("frontend-development"), Skill.load("tailwind-patterns")],
tools=[project_loader.tool("create_component")],
instructions="严格按照输入的结构化设计信息生成React组件",
)
reviewer = DeepAgent(
name="reviewer",
role="代码审查",
tools=[project_loader.tool("lint_project")],
instructions="调用lint工具检查代码问题,列出所有差异点,不要直接修改代码",
)
# 3. 编排主流程
planner = DeepAgent(
name="planner",
role="编排调度",
instructions="把设计稿转代码任务串联起来,发现问题及时回滚",
)
# 实际执行:解析设计稿 -> 生成代码 -> 审查修正
design_report = design_specialist.run("读取design payload并输出结构化的JSON")
code_deliverable = coder.run(
f"基于以下设计报告生成代码: {design_report}"
)
review_report = reviewer.run(f"检查以下代码并返回报告: {code_deliverable}")
# 4. 如果Reviewer发现问题,循环回去让Coder修改
if not review_report.is_clean():
for issue in review_report.issues:
coder.run(f"修复如下问题,不要引入新问题: {issue.description}")
这段代码看着简单,实际运行中花了我最多时间调试的不是Agent本身,而是"Reviewer提的问题Coder改不动"的死循环。后来我用两个手段解决:一是Reviewer的报告必须结构化,问题必须带着"文件路径+行号+建议修改",不能只给一句"代码质量不佳";二是每个Agent的修改有次数上限,超过上限就交给人工处理,避免无限死循环。
6.3 运行实测和经验总结
用一套真实页面跑完整条流水线之后,我记录了几个关键数字:设计稿标注的样式提取成功率在95%以上,偶尔失败是因为Figma里用了非标准的文本样式;生成代码的初次通过率大概在70%左右,剩下30%需要Reviewer指出后一轮修改就能解决;真正的死循环占比不到5%,基本都是"视觉差异主观性太强"导致的。
这组数据背后藏着一个经验: 设计稿转代码这件事,"还原度"的评判标准先得定义清楚 。我在项目里给Reviewer明确列了检查优先级:第一是样式token与设计稿一致(颜色、字号、间距不能错),第二是布局层级正确(父子组件嵌套关系不能乱),第三才是视觉细节(阴影、圆角、渐变这类主观项)。这个优先级排序让Reviewer的输出稳定了很多。
再分享一个看起来小但对成功率影响极大的细节:给Figma MCP的token配置必须处理超时问题。Figma大文件动辄几百MB,MCP调用一次可能两三分钟。如果不做超时控制和任务分段,Client那边早就断开了,任务直接失败。我的做法是先调用Figma的"文件树"接口拿到页面结构,再按页面一个一个拉取图层数据,最后统一汇总,而不是一口气读全量文件。
另一个心得是: "生成代码"这一步的Skills质量直接决定项目的天花板 。我给Coder挂的"前端开发Skills"里不仅有通用规则,还有团队自己的编码规范、组件库使用文档、甚至是几个"反面案例"。这些内容让模型在生成代码时就不是"会写JS的人"而是"熟悉我们团队规范的前端"。
7. 踩坑记录和可复用的优化建议
7.1 MCP调用超时与并发控制
多智能体系统里最典型的故障就是MCP调用超时。我总结下来,超时原因通常不是网络慢,而是 模型不知道这个工具会慢 。MCP工具列表在模型眼里是一视同仁的"函数",模型以为调用两个工具的时间差不多,结果连续串行调用了好几个Figma大文件接口,整个任务链卡死。
我的优化方案有三条,按性价比排序:第一,给MCP Server端做"任务超时上限+进度回调",让客户端知道当前任务在跑,没挂;第二,在工具描述里显式写明"本工具耗时可能超过60秒,请在使用时……",让模型提前有预期;第三,在编排层做并发控制,不要同时给子Agent暴露太多MCP工具,否则模型会乱。
7.2 技能命中率低的问题:从"塞规则"到"写意图"
有段时间我一直在往Skills里堆规则,觉得规则越多模型越不会犯错。结果事与愿违,SKILL.md越来越长,模型反而"看不到重点"了,输出质量下降。
后来我把一堆规则改成了"意图+决策树"的结构。每个Skill的description里写清楚" 什么情况下用这个Skill ",而不是"这个Skill包含……"。比如我把"frontend-development"的description从"包含React编码规范、组件设计模式、Tailwind最佳实践"改成"当你需要根据设计稿生成React页面代码时使用,尤其是从Figma/蓝湖输出转代码"。这一改,模型按需加载Skill的准确率提高了不少。
这个经验契合了Skills Harness的设计原则: 技能路由靠的是"意图匹配"而不是"关键词匹配" 。你写Skills的description时,要从"这个技能能做什么"切换到"在什么任务场景下应该用我"。
7.3 关于"预测多智能体交互的世界模型"这类进阶话题
最近社区里开始讨论"能预测多智能体交互的世界模型"这类方向,我也关注了一段时间。它的思路是:用一个大模型去模拟"如果Agent A采取动作X,Agent B会如何反应",从而预判多智能体交互的结果,减少试错成本。虽然现在还比较早期,但它指向一个趋势:多智能体系统不能只靠"现场调度",最好能在行动前做一些推演。
我个人的看法是,实战项目里可以先从"规则加轻量预测"做起,不必等一个完美世界模型。比如我在流水线里预设了一些"已知坏模式":Coder生成的组件名和现有项目冲突、Reviewer和Coder对某个视觉规范理解不一致、MCP工具在某个特殊目录下报错。这些坏模式被沉淀成规则后,Planner在派发任务前会先检查输入是否命中坏模式,命中就预先调整,避免执行期才发现问题。这些规则用久了,其实就是一个"轻量世界模型"的雏形。
最后再分享一个工具选型的建议:不要被框架名迷惑,也不要一上来就想改造框架。先用DeepAgents套现成的MCP生态和Skills体系,把一条端到端流程跑通,再去考虑自研编排器或者引入更复杂的A2A网络。分布式系统里,先让流程跑起来比架构好要重要得多;架构是在跑的过程中长出来的,不是一开始设计出来的。希望这篇文章能帮你少走几步弯路。
更多推荐
所有评论(0)