本文是《WorkBuddy AI 工作流实战》系列第 3 篇,也是进阶篇。
前两篇解决了两个问题:如何理解 Agent、Skill、Tool,以及如何编写第一个
SKILL.md。这一篇继续向前一步,把单文件 Skill 升级为包含脚本、配置、参考资料和质量检查的工程化工作流,并讨论跨工具分发、MCP 接入与多 Agent 协作。
一、什么时候需要把 Skill 工程化?
第 2 篇创建的doc-to-tasks只有一个SKILL.md。对于“读取内容 → 整理摘要 → 输出待办”这类任务,单文件已经足够。
但有些任务不只是生成文字。例如:
读取当前分支的代码改动,根据团队规范生成 PR 描述和变更日志,并在交付前检查格式是否合格。
这项任务需要:
- 调用 Git 获取真实改动;
- 读取团队 PR 规范;
- 根据配置决定输出目录和语言;
- 生成 PR 描述与变更日志;
- 运行程序检查输出;
- 校验失败时修正并重新检查。
此时,仅靠SKILL.md描述步骤仍然可以工作,但执行逻辑会越来越长,也难以单独测试。更稳妥的做法,是把确定性的操作下沉到脚本,把规则和资料拆到独立文件。
可以采用下面这套推荐结构:
pr-generator/ ├── SKILL.md ├── config.json ├── scripts/ │ ├── collect_diff.py │ └── verify_output.py └── references/ ├── pr-template.md └── team-conventions.md| 组件 | 负责什么 | 是否必需 |
|---|---|---|
SKILL.md | 触发场景、执行步骤、工具选择和完成标准 | 核心文件 |
config.json | 输出目录、语言、模板路径等可调整参数 | 按需添加 |
scripts/ | 获取数据、转换格式、校验结果等确定性操作 | 按需添加 |
references/ | 团队规范、模板和领域资料 | 按需添加 |
这不是所有平台强制规定的“四件套”,而是一种便于维护的工程结构。核心原则是:
需要推理的事情交给 Agent,需要稳定重复的事情交给脚本,需要长期维护的规则放进配置和参考资料。
二、实战案例:从代码改动生成 PR 描述
下面用pr-generator串起完整流程。
1. 先定义完成标准
在写脚本之前,先明确最终产物:
fix: 修复支付回调重复处理 ## 变更点 - 增加支付回调幂等检查 - 补充重复通知测试 ## 验证 - [x] 单元测试通过 - [x] 本地回调测试通过 ## 风险 - 需要观察旧订单数据的兼容情况这个例子的质量要求是:
- 首行必须包含允许的类型标签;
- 必须包含“变更点”和“验证”章节;
- 变更点不能是空内容或“待补充”;
- 输出必须来源于真实改动,不能虚构测试结果。
2. 在SKILL.md中编排流程
--- name: pr-generator description: 根据当前 Git 代码改动生成结构化 PR 描述和变更日志。当用户要求总结分支改动、编写 PR 描述或生成 changelog 时使用。 --- # PR 描述生成器 ## 工作流 1. 确认当前目录是 Git 仓库,并检查工作区状态。 2. 使用 `scripts/collect_diff.py` 获取待描述的代码改动。 3. 阅读 `references/team-conventions.md` 和 PR 模板。 4. 按“标题、变更点、验证、风险”结构生成 PR 描述。 5. 只记录能够从代码、测试结果或用户输入中确认的信息。 6. 将结果保存到配置指定的位置。 7. 使用 `scripts/verify_output.py` 校验输出。 8. 校验失败时根据错误修正,并重新执行校验。 ## 约束 - 不执行提交、推送或创建 PR,除非用户明确要求。 - 不把密钥、令牌、个人信息或无关 diff 写入结果。 - 未实际运行的测试必须标记为“未运行”。 - 无法确认的风险应标记为“待确认”。这里有两个重要设计:
- 生成与发布分离:生成 PR 文案不等于提交代码或创建远程 PR,外部操作应单独确认。
- 事实与推断分离:测试是否通过、风险是否存在,都需要证据;没有证据就明确标记未知。
3. 用脚本实现质量门禁
下面是精简但可以运行的verify_output.py:
frompathlibimportPathimportreimportsys ALLOWED_TYPES="feat|fix|docs|refactor|test|build|chore"REQUIRED_SECTIONS=("变更点","验证")PLACEHOLDERS=("待补充","TODO","TBD")defsection_body(text:str,heading:str)->str:pattern=rf"^##\s+{re.escape(heading)}\s*$\n(.*?)(?=^##\s+|\Z)"match=re.search(pattern,text,flags=re.MULTILINE|re.DOTALL)returnmatch.group(1).strip()ifmatchelse""defvalidate(text:str)->list[str]:errors=[]first_line=text.splitlines()[0].strip()iftext.splitlines()else""ifnotre.match(rf"^({ALLOWED_TYPES})(\(.+?\))?:\s+\S+",first_line):errors.append("标题必须以允许的类型标签开头,例如 fix: 修复登录异常")forheadinginREQUIRED_SECTIONS:body=section_body(text,heading)ifnotbody:errors.append(f"缺少内容完整的“{heading}”章节")elifany(marker.lower()inbody.lower()formarkerinPLACEHOLDERS):errors.append(f"“{heading}”章节仍包含占位内容")returnerrorsdefmain()->int:iflen(sys.argv)!=2:print("用法: python verify_output.py <pr-description.md>")return2path=Path(sys.argv[1])ifnotpath.is_file():print(f"文件不存在:{path}")return2errors=validate(path.read_text(encoding="utf-8"))iferrors:forerrorinerrors:print(f"ERROR:{error}")return1print("校验通过")return0if__name__=="__main__":raiseSystemExit(main())运行方式:
python scripts/verify_output.py output/pr-description.md质量门禁的意义,不是让脚本判断文案“写得好不好”,而是让它检查那些能够明确判断的条件:文件是否存在、章节是否完整、格式是否符合规范、占位符是否清除。
4. 为脚本本身添加测试
既然校验脚本承担“门禁”职责,它本身也需要被验证。至少覆盖三类用例:
| 测试用例 | 预期结果 |
|---|---|
| 合法标题且章节完整 | 返回成功 |
| 缺少“验证”章节 | 返回失败并指出缺失章节 |
“变更点”仍含TODO | 返回失败并指出占位内容 |
这一步经常被忽略。没有测试的门禁脚本,也可能把错误内容放过去。
三、参数怎么管理:明确优先级
当同一个 Skill 被不同项目复用时,输出目录、语言和模板可能不同。可以将默认值放入config.json:
{"output_dir":"docs/pr","language":"zh-CN","template":"references/pr-template.md"}建议采用清晰的覆盖顺序:
用户本次明确要求 > 命令行参数 > 项目配置 > 内置默认值例如,默认输出到docs/pr,但用户本次明确要求写入/tmp/pr.md,就只覆盖本次输出位置,不修改项目配置。
配置设计还要注意:
- 路径应相对于 Skill 或项目根目录解析,不要依赖某台电脑的绝对路径;
- 对配置值进行类型和范围校验;
- 不要把令牌、密码等敏感信息写进可提交的配置文件;
- 缺少可选配置时,应有明确默认行为。
四、跨平台不只是准备.sh和.ps1
原稿把跨平台简化为“同时提供 Shell 和 PowerShell 入口”,但真正的兼容性还包括路径、编码、依赖和命令差异。
更实用的策略是:
- 核心逻辑优先使用跨平台语言:例如 Python 或 Node.js。
- 平台脚本只做薄封装:
.sh和.ps1负责定位运行时并传递参数。 - 使用标准路径 API:避免手工拼接
/或\。 - 固定文本编码:读写文件时显式使用 UTF-8。
- 启动时检查依赖:缺少 Git、Python 或必要包时给出可执行的错误信息。
- 在目标系统上测试:文件看起来兼容,不代表实际运行兼容。
如果团队环境统一,只支持一种平台反而更简单。跨平台是一项真实需求,不是工程成熟度的装饰。
五、一份源如何分发给多个 AI 工具?
不同 AI 工具对 Skill 的目录、文件格式和发现机制可能不同,不能假设把同一个目录软链接过去就一定可用。
更稳妥的方案是维护一个“规范源目录”,再通过安装脚本适配各目标平台:
workflow-library/ ├── skills/ # 唯一维护源 │ └── pr-generator/ ├── adapters/ # 各工具的格式或目录适配 ├── install.py # 安装、更新、检查 └── manifest.json # 版本与目标清单安装脚本可以按环境选择两种策略:
| 策略 | 优点 | 注意事项 |
|---|---|---|
| 软链接 | 源文件更新后立即反映到目标目录 | Windows 权限、容器和部分同步工具可能不支持 |
| 复制安装 | 兼容性更好,目标目录相互隔离 | 更新时需要重新执行安装并防止版本漂移 |
推荐流程是:
读取 manifest → 识别目标工具 → 转换格式或目录 → 安装到目标位置 → 校验文件 → 输出安装报告不要在文章或脚本里硬编码某个工具的目录后就宣称“全平台通用”。目标路径和格式应以对应工具当前版本的官方说明为准,并在安装前检查。
六、MCP 在工作流中负责什么?
MCP(Model Context Protocol,模型上下文协议)用于让兼容的 AI 客户端连接外部工具和数据源,例如代码托管平台、数据库、浏览器或内部服务。
需要分清三层职责:
Skill:描述什么时候调用、按什么顺序调用 Tool / MCP Server:提供具体操作能力 Agent:结合目标和返回结果进行决策例如,PR 工作流可以这样扩展:
读取本地 git diff → 通过代码托管 MCP 查询关联 Issue → 生成 PR 描述 → 本地脚本执行格式校验 → 用户确认后再调用远程工具创建 PR这里有三个边界:
- MCP 服务需要先在客户端正确配置,写一个 Skill 不会自动获得外部权限;
- 能调用工具不代表应该调用,写操作仍要遵循授权和确认规则;
- 外部返回值不一定可信,Agent 仍需验证错误、空结果和权限失败。
因此,MCP 不是“联网开关”,而是标准化工具接入的一种方式。
七、什么时候该创建 Agent?
Skill 适合沉淀一类任务的方法;Agent 适合承担持续决策、需要明确职责边界的角色。
| 需求 | 更适合 Skill | 更适合 Agent |
|---|---|---|
| 固定步骤整理文档 | 是 | 否 |
| 按模板生成 PR 描述 | 是 | 可选 |
| 审查一组跨模块改动并持续追踪问题 | 可提供审查 Skill | 是 |
| 协调测试、审查和发布多个环节 | 可作为能力模块 | 是 |
不要仅仅为了拥有“人格”就创建 Agent。一个 Agent 至少应该明确:
- 它负责解决什么问题;
- 在什么条件下介入;
- 可以使用哪些 Skill 和 Tool;
- 哪些操作必须确认;
- 输出采用什么结构;
- 何时停止并交付。
下面是一个精简的代码审查 Agent 示例。具体 frontmatter 字段和存放目录应以当前客户端支持的格式为准:
--- name: code-reviewer description: 审查代码或 PR 中的正确性、安全性、性能和可维护性问题。当用户明确要求代码审查或合并前检查时使用。 --- # 代码审查 Agent ## 职责 识别会导致错误、行为回归、安全问题或维护成本上升的具体问题。 ## 工作流 1. 理解改动目标和影响范围。 2. 阅读 diff 及必要的关联代码,不只检查单个片段。 3. 运行与风险相匹配的测试或静态检查。 4. 按严重程度排列发现:阻断、重要、建议。 5. 每条发现提供文件位置、触发条件、影响和修改建议。 6. 没有发现问题时明确说明,并列出尚未验证的风险。 ## 约束 - 只报告能够用代码或执行结果支持的问题。 - 不把个人风格偏好描述成缺陷。 - 未经要求不修改代码、不提交、不推送。 - 不编造不存在的文件、API 或测试结果。 ## 输出格式 先列发现,按严重程度排序;然后列开放问题和验证情况;最后给出简短总结。与原稿中“10 年经验”“不留情面”等人格描述相比,职责、证据标准和停止条件更能决定 Agent 是否可靠。
八、如何组建多 Agent 专家团?
多 Agent 的价值不是“角色越多越强”,而是把不同目标、工具权限或上下文边界分开。
以发布流程为例,可以设置三个角色:
代码审查 Agent ─┐ 测试 Agent ─────┼→ 汇总结果 → 人工确认 → 发布 Agent 文档 Agent ─────┘| Agent | 主要输入 | 主要产出 | 不负责什么 |
|---|---|---|---|
| 代码审查 | diff、关联代码、规范 | 按严重程度排列的问题 | 不发布代码 |
| 测试 | 改动范围、测试配置 | 测试结果和失败证据 | 不替测试失败找借口 |
| 文档 | 功能变化、用户影响 | 更新说明和迁移提示 | 不臆造功能行为 |
| 发布 | 已确认的版本与检查结果 | 发布操作及结果记录 | 未确认时不发布 |
多 Agent 协作应补齐四个机制:
- 输入输出契约:上一个 Agent 交付什么,下一个 Agent 才能开始。
- 单一责任边界:避免两个 Agent 同时修改同一文件或重复做同一判断。
- 失败处理:测试失败、工具不可用或信息不足时如何停止和报告。
- 人工确认点:提交、推送、发布和外部通知等操作应明确确认。
如果任务只需一个 Agent 加几个 Skill 就能完成,不要为了“专家团”增加调度成本。
九、数量与 token:不要用简单结论代替测量
Agent 和 Skill 对上下文的影响取决于具体客户端实现:有的只暴露名称和描述,命中后才加载正文;有的会预加载更多元数据;子 Agent 是否使用独立上下文,也因产品和配置而异。
因此,不能笼统地说“安装 100 个 Agent 几乎不耗 token”。更可靠的优化方向是:
- 缩短重复、空泛的角色描述;
- 避免多个 Skill 的
description大面积重叠; - 简单任务不要无意义地派发子 Agent;
- 控制循环次数和工具返回的数据量;
- 对长日志和大文件先筛选,再送入模型;
- 使用客户端提供的上下文或用量信息进行实测。
关注“实际加载了什么、调用了几次、每次返回多少内容”,比只统计 Agent 数量更有意义。
十、从能运行到可维护:一份检查清单
工程化工作流交付前,可以按下面的清单检查:
功能
- 正常输入可以得到预期结果
- 缺少输入时会询问或明确失败
- 不相关请求不会误触发
质量
- 输出格式有明确标准
- 校验失败会阻止交付
- 校验脚本自身有测试
安全
- 不记录或输出敏感信息
- 写文件、提交、推送和发布的边界明确
- 外部操作有必要的授权与确认
可移植性
- 路径没有绑定某台电脑
- 编码和依赖要求明确
- 已在目标系统实际运行
维护
- 配置、脚本和规范职责清晰
- 有版本或更新策略
- 失败信息能够指导排查
这份清单比“文件数量够不够”更能判断一个工作流是否接近生产可用。
总结
从单文件 Skill 走向工程化,可以沿着下面这条路线推进:
单文件 Skill → 引入脚本与质量门禁 → 拆分配置和参考资料 → 适配不同工具与平台 → 接入 MCP 外部能力 → 按职责引入 Agent 协作 → 持续测试和迭代记住四个结论:
- 工程化不是凑齐固定文件,而是分离推理、执行、配置和规范。
- 生成之后必须校验,能够自动判断的条件应交给程序。
- 跨工具分发需要适配层,软链接只是安装策略之一。
- 多 Agent 的核心是职责和契约,不是角色数量和人格包装。
系列收官
《WorkBuddy AI 工作流实战》三篇完成了从概念到工程实践的闭环:
- 第 1 篇:理解 Agent、Skill、Tool 和 Agent Loop;
- 第 2 篇:写出并验证第一个
SKILL.md; - 第 3 篇:加入脚本、质量门禁、跨工具分发、MCP 和 Agent 协作。
下一步不必一次搭建庞大的系统。选择一个经常重复、步骤明确、结果可检查的任务,从单文件 Skill 开始;只有当真实需求出现,再逐步加入脚本、配置和 Agent。
先让流程可用,再让结果可验,最后让系统可维护。