ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Prompt、Skill、MCP与SubAgent:Coding Agent四层架构解析

Prompt、Skill、MCP与SubAgent:Coding Agent四层架构解析

最近连续好几个做 Coding Agent 的朋友都在问同一个问题:Skills 和 MCP 到底什么关系?有个团队内部甚至为此吵了起来,一派说 MCP 是 Skills 的下一代,另一派说 Skills 是 MCP 的封装壳。我每次都得从 Prompt 讲起,一路讲到 SubAgent,才能把话说清楚。之所以这么费劲,是因为这四个词在社区里被并列讨论得太久了,大家默认它们是同一层的东西,可以互相替代。可真到工程落地的时候你会发现,它们根本不在一个维度上。

这篇文章我不打算只丢一张对比表就完事。我会先把四个东西各自的定位用一句话钉死,再讲清楚两两之间真正的边界,然后给一个完整的真实场景选型(PR 审查助手),最后附上我整理的一套最小可运行源码。适合两类人看:一类是正在搭 Coding Agent、被这几个词绕晕的开发者;另一类是已经在用其中某个方案、想知道另外几个能不能一起用进来的朋友。文档只会告诉你"是什么",很少告诉你"为什么这么分层"以及"实际项目里怎么组合",后面这块才是踩坑最多的地方。

1. 先想明白一点:这四个词不在同一层,别直接对比

无论哪个框架、哪篇文档,只要把这四个词并列出来,就已经在制造误解了。因为其中两个是"规范/实体",一个是"内容",还有一个是"架构模式"。硬要放在天平上比谁替代谁,注定比不出结果。

1.1 Prompt 是地基,也是唯一"内容层"的东西

Prompt 说白了就是塞进模型上下文窗口的那段文本:系统提示词、用户消息、few-shot 示例,全是 Prompt。它的本质是"告诉模型此时此刻应该怎么想、怎么做"。这是所有 Agent 行为的起点,没有它,模型只是一坨参数矩阵,什么也干不了。

所以你会发现一个很有意思的事实:后面讲的 Skill、MCP、SubAgent,最终都会以某种形式变成"Prompt"的一部分——Skill 被加载后是加进上下文的指令;MCP 工具的描述会写进工具列表让模型看到;SubAgent 更是自带一整条系统提示词。这个"万变不离其宗"的规律,是整篇文章最重要的一根线。

1.2 Skill 是能力封装包,面向"复用"设计

Skill 是把一段可复用的指令打包成文件:文件名、描述、触发条件、指令正文,可能还附带脚本。它的核心价值在于按需加载和复用——不在上下文里躺着占位置,等需要时(通常是描述匹配命中)才被塞进去。

举个很普通的例子:你们团队有一套代码审查规范,两千字。如果你把它写成 Prompt 硬塞进系统提示词,那每一轮对话都要为这两千字付钱;但如果把它做成一个 Skill,平时它根本不出现在上下文里,只在用户真的要求"审查代码"时才会被加载进来。这一进一出,省掉的可能是一整条链路的 token 开销。

1.3 MCP 是连接协议,面向"互通"设计

MCP(Model Context Protocol,模型上下文协议)解决的是 Agent 和外部工具之间"怎么接"的问题。它定义了一套标准接口:工具是什么、参数长什么样、结果怎么返回。只要两边都遵循这套协议,任何 Agent 客户端都能接任何 MCP 服务端,就像任何设备都能插同一个标准的充电口。

所以 MCP 不是"能力本身",它是"能力的插座"。同一个 MCP 服务端,可以同时服务多个不同的 Agent,也可以被同一套系统反复复用。它不关心你的 Agent 怎么思考,只负责把外部世界的操作安全、标准地递到你面前。

1.4 SubAgent 是运行模式,面向"编排"设计

SubAgent 不是一种"绑定"在 Agent 上的能力,而是一个架构模式:主 Agent 觉得当前任务太杂,就新建一个独立运行的 Agent 实例,给它独立的上下文、独立的系统提示词、甚至独立的工具集,让它专注解决某一块,然后把结果交回主 Agent。

这个模式是"包含"关系,而不是"平级"关系。一个 SubAgent 可以加载自己的 Skill,也可以通过 MCP 客户端调用工具,它的一切行为同样由 Prompt 驱动。你甚至可以把主 Agent 也理解成一个"特殊的 SubAgent"——只是它多了一个调度其他 Agent 的权限。

1.5 一个不太正经但好用的记忆锚点

把四个东西放到餐厅场景里:Prompt 是你对厨师说的每一句话;Skill 是厨师手边的 SOP 手册,遇事翻开照做;MCP 是后厨所有电器统一的插座标准,什么牌子都能插;SubAgent 是你临时雇来的配菜师傅,他也有自己的手册和工具,干活独立,做完把成果端给你。

为了方便对照,我把它们放在一张表里:

概念本质抽象层级典型用途
Prompt发给模型的指令文本内容层控制模型行为、设定角色、传递任务
Skill可复用的能力封装包能力层按需加载团队规范、工作流、审查规则
MCP工具连接的开放协议连接层对接代码托管平台、数据库、浏览器等外部系统
SubAgent独立运行的子任务执行进程编排层并行审查、上下文隔离、专业化分工

提示:下次再有人问"Skill 是不是 MCP 的下一代",就把这张表拿给他看。一个管"做什么",一个管"怎么接",完全没有可比性。

2. Prompt 与 Skill:一次性指令和可复用能力包的分界线

很多人觉得 Skill 就是"结构化一点的 Prompt",这个说法只对了一半。Skill 里确实装着 Prompt 文本,但 Skill 多出来的东西,是 Prompt 根本给不了的。

2.1 长时间挂在大上下文里的 Prompt,其实很贵

先说 Prompt 的隐藏成本。我们把一套完整代码审查规范写进系统提示词,看起来没问题,但它有个致命缺陷:无论模型当前在处理什么任务,这段规范都在上下文里。每一轮对话、每一次工具调用、每一次模型思考,都要重新处理这两到三千 token 的文本。

我做过一次粗略估算。一个中等活跃的 Coding Agent 会话,一天可能来回几百轮;假设上下文里常年挂着 2,500 token 的规范,一天额外消耗可能就是几十万 token。更麻烦的是,这些规范还会"抢注意力"——模型在处理一个"帮我写个 README"的任务时,还要同时 hold 着"审查代码要注意 SQL 注入"这类高优先级指令,反而容易答非所问。

2.2 Skill 多出来的三样东西:按需加载、文件化、可执行

Skill 的第一个差异是按需加载。它平时躺在磁盘上,只有描述匹配到用户意图时才被注入上下文。这就解决了"常年占位"的问题。

第二个差异是文件化。Prompt 活在对话里,是一次性的;Skill 活在仓库里,可以被版本管理、被团队评审、被跨项目复制。审查规范从 A 项目复制到 B 项目,Prompt 时代你得重新粘一遍,Skill 时代直接引用同一个文件。

第三个差异是我认为最关键的:可执行。Prompt 只能说"你可以检查一下代码复杂度",Skill 的配套脚本可以直接调起复杂度计算工具,把结果贴进上下文让模型判断。前者是让模型"看着办",后者是让模型"基于真实数据做决策"。

2.3 什么样的情况该从 Prompt 升级到 Skill

如果你的 Agent 出现下面任一种情况,就该考虑把某段 Prompt 抽成 Skill:

  • 同一段指令在多个项目、多个子任务里反复出现;
  • 这段指令超过了大约 2,000 token,而且有条件分支,像"如果变更涉及鉴权接口,则需要额外检查"这种;
  • 指令里出现了"需要真实计算结果"的诉求,而不只是要求模型脑补;
  • 指令需要多人维护、定期更新。

反过来,如果只是一次性任务,比如"帮我润色这段注释",老老实实写 Prompt 就行,别为了炫技硬造一个 Skill 文件。

2.4 常见误区:把 Skill 当成万能 Prompt 收纳箱

有些人把所有的规则全塞进一个"超级 Skill"里,结果触发时一加载又是几千 token。Skill 的灵魂是"按需",意味着粒度要适中。我会把 code-review 拆成 security-review、perf-review、style-review 三个小 Skill,而不是一个大而全的"审查总纲"。这也正好为后面 SubAgent 的分工埋了个伏笔。评判标准很简单:如果在一次任务里,两个 Skill 总是成对出现、且其中一份明显只在特定子环节有用,那就说明粒度拆大了。

3. MCP:它解决的是连接问题,不是能力定义问题

如果说 Skill 是在"怎么教"这件事上做了升级,那 MCP 就是在"怎么接"这件事上立了规矩。

3.1 没有 MCP 之前,工具接入的混乱账

我早期搭过一个内部 Agent,需要接三个外部系统:代码托管平台、内部数据库、浏览器自动化。当时每个系统都要单独写一个连接器,而且连接器的写法跟 Agent 的实现强耦合——换一个 Agent 框架,三个连接器全部重写。这就是经典的 N×M 问题:N 个工具 × M 个 Agent,每个组合都要单独开发。

MCP 把这道题解成了 N+M:工具方实现一个 MCP 服务端,任何支持 MCP 客户端的 Agent 拿去就能用。它是一个 JSON-RPC 2.0 协议,支持 stdio 和 HTTP 传输,服务端会暴露三类对象:工具(可调用的函数)、资源(可读的数据)、提示词模板(可复用的 Prompt)。

3.2 Skill 与 MCP 的真正边界:一个管"怎么做",一个管"怎么接"

经常有人把 Skill 和 MCP 放在一起比较,因为它们看起来都像"给 Agent 加能力"。但边界其实很清楚:

  • Skill 定义的是"内部工作流":触发这个 Skill 后,Agent 应该按什么步骤走、遵循什么规则;
  • MCP 定义的是"外部接口契约":某个操作叫什么名字、传什么参数、返回什么结构。

两者是协作关系,不是替代关系。一个 Skill 的内部步骤,完全可以写着"调用 MCP 工具 fetch_pr_diff 获取变更内容"。Skill 提供的是判断逻辑和流程约束,MCP 提供的是真正能把活干完的手。

我在实际项目里的经验是:凡是"团队独有的规则、流程、判断标准",优先做成 Skill;凡是"要和外部系统打交道、且将来可能给多个 Agent 复用"的,优先做成 MCP。一个偏内部,一个偏外部,方向完全不同。

3.3 什么能力适合做成 MCP Server

判断标准其实就三条:

  • 有没有标准的对外接口?有,比如代码托管平台的 REST API,就适合包一个 MCP;
  • 是不是多个项目、多个 Agent 都要用?是,就值得做成通用的;
  • 有没有状态和资源需要管理?有,比如数据库连接、浏览器会话,MCP 可以在服务端管理,而不是把状态塞进模型上下文。

反过来,如果一个能力只是某团队内部的一次性流程,没有任何外部系统交互,那做成 MCP 纯属浪费——用 Skill 就够了。

4. SubAgent:它是编排层,不是功能层

聊完三个"静态"的东西,该聊那个最容易被误解的 SubAgent 了。它不是一个可以"绑定"的功能,而是一种组织架构。

4.1 工具调用和 SubAgent,完全是两回事

很多初学者以为 SubAgent 就是"Agent 调用一个更复杂的工具"。差远了。工具调用是同步的——主 Agent 的上下文里发起一个函数,结果传回同一个上下文,所有中间过程都在主上下文里展开。SubAgent 则是"主 Agent 开了一个子进程":它有独立的上下文窗口、独立的系统提示词、独立的工具列表、独立的循环步数上限。

这个区别带来一个直接后果:主 Agent 不会被子 Agent 的中间过程污染。拿 PR 审查举例,主 Agent 只需要知道"安全审查结果:3 个高危项、2 个中危项",而不需要关心安全审查 Agent 内部是怎么读 diff、怎么翻文档的。子 Agent 那几千步思考,永远不会出现在主对话里。

4.2 SubAgent 的三个核心价值:隔离、并行、专业化

隔离前面说了,再补一个反面案例。我曾经在主上下文里连续做三种审查——安全、性能、风格,差一点把上下文撑爆。三套审查规范加一份 5,000 行的 diff,主上下文很快就逼近长度限制,后面审查质量直线下降。后来拆成三个 SubAgent,每个只拿自己需要的规则和 diff 片段,主上下文始终保持在一个轻量状态。

并行也容易理解:安全、性能、风格三个审查互不依赖,天然是并行任务。三个 SubAgent 同时跑,整体耗时从串行的十几分钟压缩到三四分钟,具体取决于模型服务的并发能力。

专业化则是另一个角度:SubAgent 可以配不同的模型、不同的温度、不同的工具集。安全审查想用更严谨的模型,风格审查想用快而便宜的模型。这在主 Agent 里很难做到,在 SubAgent 层是小菜一碟。

4.3 SubAgent 与其他三者的组合关系

理清这一层,四个词就全部串起来了:

  1. 主 Agent 收到任务后,命中某个 Skill(比如 pr-review),Skill 给出流程定义;
  2. 流程里要求调用 MCP 工具获取外部数据(比如 diff 文本);
  3. 主 Agent 决定派三个 SubAgent 分工,每个 SubAgent 的 Prompt 由主 Agent 生成,通常来自子 Skill 的加载;
  4. 每个 SubAgent 内部又可以有自己的 MCP 工具调用和循环;
  5. 最后,结果以文本或结构化对象的形式返回主 Agent,由主 Agent 汇总。

4.4 别把 SubAgent 当成万能药

SubAgent 不是免费的:它需要时间启动、会消耗独立上下文配额、还可能引入结果格式不一致的问题。如果任务本来一个工具调用就能解决,没必要拆出一个完整子进程;如果任务是高度耦合的,硬拆反而会丢上下文。

我的判断原则很简单:要不要上 SubAgent,就看任务是否同时满足"可独立拆分""涉及大量中间上下文""需要多视角对比"。缺一条,都建议先留在主流程里解决。

5. 真实场景:一个 PR 审查助手的完整选型与落地链路

纸上谈兵聊了四层概念,下面看一个具体的例子——我最近在内部搭的 PR 审查助手。

5.1 需求是什么

团队代码都托管在一个代码托管平台上,希望有个 Coding Agent 能在 PR 提交后自动做三件事:安全审查(找注入、越权、硬编码密钥)、性能审查(找 N+1 查询、大循环里的 IO)、风格审查(对照团队规范)。审查结果要能发回 PR 评论区。

需求听起来很普通,但它刚好把四个概念全用上了,是天然的对照实验。

5.2 为什么这样选型:每一层选择的理由

先说 MCP。代码托管平台是一个外部系统,有公开 API,且我们不止一个项目要用这个连接能力。所以第一件事是写一个"代码托管平台 MCP Server",暴露 fetch_pr_diff 和 comment_on_pr 两个工具。这个 Server 写好之后,任何 Agent 都能复用它,这是典型的"接口标准化"收益。

再说 Skill。团队的审查规范是文本性质的、团队独有的,而且会不断演进。它不应该写死在哪个 Agent 的代码里,于是我们把三套审查规则分别做成 security-review、perf-review、style-review 三个 Skill 文件。平时不加载,审查时按需注入。

最后说 SubAgent。三套审查规则差异极大、关联性很弱,而且审查过程会产生大量中间分析(每套规则对每段 diff 的分析结果),如果全放在主上下文中,上下文会被迅速撑爆。所以我们让主 Agent 并行派三个 SubAgent,各自加载对应 Skill、对着 diff 独立工作。

至于 Prompt,它永远是底层:主 Agent 的编排逻辑靠系统提示词实现,SubAgent 的初始化 Prompt 也是生成出来的。它像胶水一样粘住其他三层。

5.3 单个 PR 的完整执行链路

流程大概是:

  1. 用户对主 Agent 说:"审查一下 PR #42";
  2. 主 Agent 的系统提示词里定义了审查编排流程,同时按描述匹配加载 pr-review Skill;
  3. Skill 指令要求先调用 MCP 工具 fetch_pr_diff 拉取 diff——这一步把外部数据拉进主上下文,只有一份 diff,体积可控;
  4. 主 Agent 拆分任务:创建 security-review、perf-review、style-review 三个 SubAgent;
  5. 每个 SubAgent 初始化时,加载自己对应的 Skill 指令,拿到 diff 文本,然后独立运行若干轮,调用必要的 MCP 工具之后输出结构化结论;
  6. 主 Agent 等待全部 SubAgent 返回,按严重程度去重、合并、排序,生成一份统一报告;
  7. 最后调用 MCP 工具 comment_on_pr 把报告发到 PR 评论区。

第三步有一个设计细节值得说:diff 由主 Agent 统一拉取,而不是每个 SubAgent 各自拉取。因为拉取操作本身有频率限制,让三个 SubAgent 轮询同一个接口既慢又容易触发限流。主 Agent 拉完之后切成片段传给子 Agent,是更工程化的做法。

5.4 踩过的坑:把三套规则全部塞进主 Prompt 的后果

这项目一开始不是这么设计的。第一版我图省事,把三套审查规则直接拼进主 Agent 的系统提示词,审查流程也在同一个上下文里顺序执行。结果遇到大型 PR 就出问题:5,000 行 diff 加上三套规则,主上下文很快就逼近上限,模型开始"忘记"后面的规则,审查质量肉眼可见地下滑;而且安全审查的中间分析会把大量无关内容带进对话历史,彻底稀释注意力。

后来改成 SubAgent 分工后才想明白:审查这种任务,天然适合"上下文隔离 + 并行",主 Agent 只做调度和汇总。改造完以后,同一个大 PR 的审查耗时大概是原来的三分之一,上下文占用峰值降了六到八倍。

6. 源码级参考:一套最小可运行的组合实现

下面给你看一个能直接跑起来的骨架。它不依赖任何重型框架,核心逻辑就三个部分:Skill 文件、MCP Server、SubAgent 调度器。接上真实的模型 API 就能当脚手架用。

6.1 目录结构

pr-review-demo/ ├── skills/ │ ├── pr-review/SKILL.md │ ├── security-review/SKILL.md │ ├── perf-review/SKILL.md │ └── style-review/SKILL.md ├── mcp_server.py ├── subagent.py └── main.py

6.2 Skill 文件长什么样

以 pr-review 这个编排 Skill 为例:

--- name: pr-review description: 从安全、性能、风格三个维度审查一个 PR。 when: 用户提到"审查 PR"、"code review"或给出 PR 编号时 --- # PR Review 编排流程 当本 Skill 被加载时,按以下步骤执行: 1. 确定仓库名与 PR 编号。 2. 调用 MCP 工具 fetch_pr_diff 获取 diff 原文。 3. 并行创建三个 SubAgent:security-review / perf-review / style-review。 4. 将 diff 按文件切块分发给各 SubAgent。 5. 汇总三份结论,按严重程度排序、去重。 6. 调用 MCP 工具 comment_on_pr 提交报告。

安全审查 Skill 长这样:

--- name: security-review description: 分析 diff 中的注入、越权、硬编码密钥等安全问题。 --- 你对传入的 diff 做安全审查。逐文件检查: - SQL 注入:是否拼接外部输入到 SQL/查询语句。 - 命令注入:是否拼接外部输入到命令行执行。 - 越权:新增接口是否缺失权限校验。 - 硬编码密钥:是否出现 token、密码、AK/SK 字面量。 输出格式: ## 风险等级:高/中/低 ### 文件路径:行号 - 问题描述 - 修复建议

这里的关键是 frontmatter 里的 description 字段。加载器靠它来判断"什么场景该加载哪个 Skill",所以描述必须写得能命中用户意图,而不是写"用于审查"这种废话。

6.3 MCP Server 的最小实现

MCP 官方 Python SDK 提供了声明式的接口,写起来非常直白。核心是暴露两个工具:拉取 diff 和提交评论。

# mcp_server.py from mcp.server.fastmcp import FastMCP mcp = FastMCP("code-host-tools") @mcp.tool() def fetch_pr_diff(pr_number: int, repo: str) -> str: """从代码托管平台拉取指定 PR 的 diff 文本。""" import requests url = f"https://git.example.com/api/v1/repos/{repo}/pulls/{pr_number}" headers = {"Authorization": f"Bearer {TOKEN}"} r = requests.get(url, headers=headers) r.raise_for_status() detail = r.json() diff_url = detail.get("diff_url") return requests.get(diff_url, headers=headers).text @mcp.tool() def comment_on_pr(pr_number: int, repo: str, body: str) -> bool: """把审查结论作为评论提交到 PR 页面。""" import requests url = f"https://git.example.com/api/v1/repos/{repo}/issues/{pr_number}/comments" r = requests.post(url, json={"body": body}, headers={"Authorization": f"Bearer {TOKEN}"}) return r.status_code == 201 if __name__ == "__main__": mcp.run()

这段代码里的核心是函数签名和 docstring。MCP 的协议层会自动把函数名转成工具名、把参数转成 JSON Schema、把 docstring 转成工具描述——模型就是靠这些描述来决定"要不要调用、传什么参数"的。所以 docstring 一定要写清楚,别偷懒。

进程启动后,这个 Server 会通过 stdio 等待 MCP 客户端连接。你可以直接把它交给任何懂 MCP 的 Agent 去接,不需要为每个 Agent 重写一遍。

6.4 SubAgent 的最小实现

SubAgent 的核心是一个带独立上下文的 agent loop:

# subagent.py class SubAgent: def __init__(self, name, system_prompt, tools, max_steps=12): self.name = name self.system_prompt = system_prompt self.tools = tools # dict: 工具名 -> 可调用函数 self.max_steps = max_steps self.messages = [{"role": "system", "content": system_prompt}] def run(self, task: str) -> str: self.messages.append({"role": "user", "content": task}) for _ in range(self.max_steps): resp = llm_call(self.messages, tools=list(self.tools)) self.messages.append( {"role": "assistant", "content": resp["content"]} ) if not resp.get("tool_calls"): return resp["content"] for call in resp["tool_calls"]: fn = self.tools[call["name"]] result = fn(**call["arguments"]) self.messages.append({ "role": "tool", "tool_call_id": call["id"], "content": str(result), }) return "达到最大步数,任务未完成"

注意几个细节:

  • llm_call 这里泛指你的模型调用入口,可以在里面处理流式输出、错误重试;
  • messages 是子 Agent 私有的,主 Agent 的 message 列表永远看不到它的内部历史;
  • max_steps 是硬上限,防止某个子 Agent 陷入死循环烧钱。

6.5 主流程:加载 Skill、启动 MCP、派子 Agent、汇总

下面这段伪码省掉了 MCP 客户端的握手细节,只保留编排骨架,方便你对着结构理解:

# main.py import asyncio SKILL_DIR = "skills" def load_skill(name: str) -> str: path = f"{SKILL_DIR}/{name}/SKILL.md" with open(path) as f: return f.read() def retrieve_skills(user_msg: str) -> list[str]: # 简化版:用关键词触发。真实实现建议用 embedding 检索。 table = { "pr-review": ["审查", "review", "PR"], "security-review": ["安全", "注入", "密钥"], "perf-review": ["性能", "慢", "N+1"], "style-review": ["风格", "规范", "format"], } hit = [] for skill, keywords in table.items(): if any(kw in user_msg for kw in keywords): hit.append(skill) return hit async def main(): # 1. 连接 MCP Server(std::stdio 启动子进程,握手细节省略) # available 是工具名 -> 可调用函数的映射 async with _mcp_session() as session: available = await collect_mcp_tools(session) # 2. 主 Agent 编排 user_msg = "请审查 PR #42" active_skills = retrieve_skills(user_msg) orchestration = "\n\n".join(load_skill(s) for s in active_skills) main_prompt = f"{MAIN_SYSTEM_PROMPT}\n\n{orchestration}" diff = await session.call_tool( "fetch_pr_diff", {"pr_number": 42, "repo": "demo"}, ) # 3. 根据 pr-review Skill 的指令派三个 SubAgent sub_specs = ["security-review", "perf-review", "style-review"] agents = [ SubAgent(spec, load_skill(spec), available) for spec in sub_specs ] # 4. 并行执行(实际并行要考虑限流和失败重试) results = await asyncio.gather( *[asyncio.to_thread(a.run, str(diff)) for a in agents] ) # 5. 汇总并写入 PR report = merge_results(*results) await session.call_tool("comment_on_pr", { "pr_number": 42, "repo": "demo", "body": report, })

这段代码省掉了不少模型调用细节和连接细节,但骨架和真实项目是一致的:MCP 把外部能力接进来,Skill 提供流程与规则,SubAgent 负责隔离式并行执行,Prompt 在每一层做驱动。你把这几个文件拆开、各自精化,就是一个可以上线的雏形。

6.6 这套 Demo 的局限和扩展方向

先说局限。第一,Skill 触发用的是关键词表,真实场景里用户表达千奇百怪,建议换成向量检索或者让模型自己做路由判断。第二,MCP Server 用的 stdio 传输只适合本地进程,多机部署要换 HTTP 传输。第三,SubAgent 的并行没有做熔断和失败重试,真实环境里某个子 Agent 崩了,主流程最好能降级处理。

扩展方向也顺手列一下:你可以给 SubAgent 加上"结果校验器",让它在返回前自检格式;也可以把"加载 Skill 再派 SubAgent"的流程抽成一个通用编排框架,让不同的 Skill 定义不同的子分工策略。到这一步,你手里的就不再是 Demo,而是一个有血肉的小型 Agent 平台了。

最后说个我自己的设计心法。现在每接到一个 Coding Agent 的能力设计,我都会先画一张"上下文带宽图":主 Agent 的上下文里到底要常驻什么、按需加载什么、哪些内容应该隔离到子 Agent 里去。画完这张图,用哪个方案基本就自动出来了。某个能力要跟外部系统打交道、且将来会被多个项目复用,那它基本该做成 MCP;一套团队独有的判断规则或流程,那它该是一个 Skill;任务链条长、中间上下文多,那它该被拆成 SubAgent;而 Prompt 永远是兜底的那个——它是唯一不需要额外基础设施的东西,也是一切抽象的第一层地基。把这四个层级想清楚了,再看任何 Agent 架构文档,基本不会被名词绕晕。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进