📌本讲摘要· 学完前 32 讲、你已经掌握了 CLAUDE.md、SubAgent、Skills、Hooks、MCP、Agent SDK、Plugins、Rules、性能优化、安全治理 10 大机制。本讲把它们全部串起来、带你从 0 到 1 构建一个生产可用的自动化 PR 审查 Agent:每条 PR 自动跑 lint、单测、安全扫描、风格检查、变更摘要、并把结果以评论形式贴回 PR。这个项目不复杂、但它会用上你学过的每一项能力、是一个合格的毕业作品。
1. 项目选题:为什么选自动化 PR 审查 Agent
毕业项目的选题有三个标准:
- 真实场景:能跑在真实代码上、不是玩具 demo
- 够综合:能覆盖 80% 以上的课程知识点
- 可扩展:留出 3-5 个优化点、后续可以持续迭代
自动化 PR 审查 Agent 完美命中三条——
- 真实场景:几乎每个团队都需要、GitHub/GitLab 上 90% 的 PR 都需要 code review
- 够综合:CLAUDE.md 装项目约定、Skills 装具体审查能力、SubAgent 分工、Hooks 拦截危险操作、MCP 连 GitHub、Agent SDK 跑 CI、Rules 写团队规范、安全治理做密钥保护
- 可扩展:第一版只跑 lint+单测、后续可加安全扫描、依赖审计、PR 描述生成、自动合入等
| 对比维度 | 传统 CI lint | PR 审查 Bot(SaaS) | 本项目(Claude Code Agent) |
|---|---|---|---|
| 规则定制 | YAML、改完要 push | 受限于平台 | CLAUDE.md + Skills、本地即改即用 |
| 理解力 | 只能匹配 pattern | AI 驱动但黑盒 | AI 驱动 + 全链路可观测 |
| 成本 | 免费 | 按 seat 收费 | 按 token 收费、本地零边际 |
| 可扩展 | 写脚本 | 受限 | 新增一个 Skill 即可 |
| 数据安全 | 数据在 CI 跑 | 数据传给 SaaS | 数据在自己机器/自家 CI |
2. 架构设计:五件套 + MCP + Agent SDK
整体架构分四层、从底向上是:数据层(本地文件系统 + Git)、能力层(Skills + SubAgent)、编排层(主 Agent + Hooks)、对接层(MCP 连 GitHub + Agent SDK 跑 CI)。
🏗️ PR 审查 Agent · 整体架构
这套架构用到了课程里的 10 大机制:CLAUDE.md(第 3 讲)、SubAgent(第 4-9 讲)、Skills(第 10-16 讲)、Hooks(第 17-18 讲)、MCP(第 19 讲)、Tools(第 20 讲)、Headless/CI(第 21 讲)、Rules(第 22 讲)、Agent SDK(第 23-24 讲)、Plugins(第 25 讲)、外加性能(第 31 讲)与安全(第 32 讲)两条横切线。
⚠️坑 1· 上来就堆功能——第一版只做 diff 摘要 + lint + 单测三件事、跑通后再加安全和风格。一次性做完所有 4 个 SubAgent、出 bug 排查会非常痛苦。
3. Skills 设计:5 个具体 Skill 的内容与触发
实战代码块 1 — CLAUDE.md 完整内容。这是项目根目录的 CLAUDE.md、把团队约定写进 Agent 的开机记忆。
# CLAUDE.md · PR 审查 Agent ## 项目目标 每条 PR 提交后,自动审查代码质量、安全、风格,并以评论形式发回 PR。 ## 技术栈 - 后端:Node.js 20 + TypeScript 5 - 测试:Vitest - Lint:ESLint + Prettier - 安全扫描:Semgrep + npm audit - GitHub 集成:GitHub MCP - CI:GitHub Actions ## 约定 - 所有 PR 必须通过 4 项审查:lint / test / security / style - 审查结果用 markdown 评论,分四节呈现 - 高危问题(blocker)必须阻断合并 - 风格问题(nit)只提示不阻断 - 用 opus 跑主审查,haiku 跑 lint/style,sonnet 跑 test/security ## 工作流 1. GitHub webhook 触发 CI 2. Agent SDK 启动主 Agent,加载本 CLAUDE.md 3. 主 Agent 读 PR diff,拆 4 路并行调用子代理 4. 子代理结果汇总,主 Agent 写 markdown 评论 5. 通过 GitHub MCP 发评论 6. 如果有 blocker,标记 PR 为 "changes requested" ## 关键文件 - .claude/skills/ · 5 个具体 Skill - .claude/agents/ · 4 个子代理配置 - .claude/hooks/ · PII 脱敏 + 审计日志 - .claude/settings.json · 权限配置实战代码块 2 — 5 个 Skill 的 SKILL.md 索引。每个 Skill 独立放在.claude/skills/<name>/SKILL.md。
# .claude/skills/<skill-name>/SKILL.md # 5 个 Skill 共用以下结构,只列 name + description + 关键 prompt 片段 --- ### Skill 1 · lint-check name: lint-check description: 跑 ESLint 检查,把错误按文件+行号整理。触发:lint, eslint, code style, 代码风格。 model: haiku tools: [Bash, Read] --- 执行 `pnpm run lint` 并解析输出,返回结构化错误列表: {file, line, column, severity, message, rule} ### Skill 2 · test-runner name: test-runner description: 跑 Vitest,定位失败用例。触发:test, unit test, 单测, 跑测试。 model: sonnet tools: [Bash, Read] --- 执行 `pnpm test --reporter=json`,解析 JSON,返回: {suite, test, status, error, duration_ms} ### Skill 3 · security-scan name: security-scan description: 跑 Semgrep + npm audit,识别高危依赖。触发:security, 漏洞, CVE, 危险依赖。 model: sonnet tools: [Bash, Read] --- 依次执行: 1. `semgrep --config=auto src/` 2. `npm audit --json` 合并结果,按 severity 排序,返回: {tool, rule_id, file, line, severity, message, fix} ### Skill 4 · style-review name: style-review description: 检查命名、注释、复杂度。触发:style, naming, 命名, 注释, 复杂度。 model: haiku tools: [Read, Grep] --- 读 PR diff,检查: - 命名是否符合项目 camelCase/PascalCase 约定 - 函数是否 > 50 行 / 圈复杂度 > 10 - 注释是否覆盖"为什么"而不只是"做了什么" 返回: {file, line, issue, severity: "nit"|"suggestion"} ### Skill 5 · pr-summarizer name: pr-summarizer description: 生成 PR 描述 / 变更摘要。触发:PR description, 变更摘要, summarize。 model: haiku tools: [Read, Grep] --- 读 PR diff + commit messages,生成: - 一句话变更摘要 - 受影响文件清单(按目录分组) - 风险点标注(是否改 db schema / 公共 API) 返回 markdown 格式,可直接贴 PR description5 个 Skill 都用渐进式披露:不调用就不加载正文、只占用 description 的 50 词左右。模型选型上、lint 和 style 用 haiku(简单模式匹配),test 和 security 用 sonnet(需要理解失败原因),pr-summarizer 用 haiku(纯摘要任务)。
⚠️坑 2· 5 个 Skill 都用 opus——简单任务烧钱、大材小用。Skill 选模型要看任务复杂度、不要全用最贵。
4. SubAgent 编排:主代理 + 4 个子代理的分工
实战代码块 3 — 主代理 + 4 子代理编排。这是 Agent SDK 调主 Agent 的入口、主 Agent 内部再用 Task tool 并行调度 4 个子代理。
// scripts/run-pr-review.ts// Agent SDK 入口,在 GitHub Actions 里被调用import{query,ClaudeCodeOptions}from"@anthropic-ai/claude-code";constoptions:ClaudeCodeOptions={model:"opus",systemPrompt:{type:"preset",preset:"claude_code",append:(awaitimport("fs").readFileSync("./CLAUDE.md","utf-8")},allowedTools:["Bash","Read","Grep","Task"],mcpServers:{"github":{command:"npx",args:["-y","@modelcontextprotocol/server-github"],env:{GITHUB_TOKEN:process.env.GITHUB_TOKEN!}}}};constprompt=`请审查 PR #${process.env.PR_NUMBER},仓库${process.env.REPO}。 步骤: 1. 用 GitHub MCP 读 PR diff 2. 并行调用 4 个子代理: - lint-check(用 lint-check skill) - test-runner(用 test-runner skill) - security-scan(用 security-scan skill) - style-review(用 style-review skill) 3. 把 4 个子代理结果汇总 4. 用 pr-summarizer skill 生成 PR 摘要 5. 用 GitHub MCP 写评论到 PR 返回的最终结果应是 markdown 评论正文。`;constresult=awaitquery({prompt,options});// 把评论发回 PR(主 Agent 自己用 MCP 写)console.log(result.text);主 Agent 用 opus(因为要做整体决策:优先级、风险点、是否阻断)、子代理用 haiku/sonnet(并行执行、每路独立上下文、互不干扰)。注意 systemPrompt 用append而不是override——保留 Claude Code 默认行为、只追加项目级约定。
| Agent | 模型 | 工具 | 职责 | 预计 Token |
|---|---|---|---|---|
| 主 Agent | opus | Bash, Read, Grep, Task, GitHub MCP | 读 diff、并行调度、汇总、写评论 | ~8K |
| lint-check | haiku | Bash, Read | 解析 lint 输出、结构化错误 | ~2K |
| test-runner | sonnet | Bash, Read | 跑单测、定位失败 | ~4K |
| security-scan | sonnet | Bash, Read | 跑 Semgrep + npm audit | ~5K |
| style-review | haiku | Read, Grep | 命名/注释/复杂度 | ~2K |
| pr-summarizer | haiku | Read, Grep | 生成 PR 摘要 | ~2K |
单次 PR 审查总成本约 23K Token,4 个子代理并行跑、主 Agent 只承担 ~8K。比起一个 opus Agent 一把梭、成本能省 50-60%。
⚠️坑 3· 主 Agent 自己读完整 diff 再调度子代理——diff 可能 5000+ 行、主 Agent 一旦读完、上下文就爆了。正确做法:主 Agent 用
git diff --stat先看文件清单、再让 4 个子代理各自读自己负责的部分。
5. Hooks 编排:PreToolUse / PostToolUse / Stop 三层钩子
实战代码块 4 — 三层 Hook 配置 + 监控 dashboard。这是.claude/settings.json的 hooks 段。
{"hooks":{"PreToolUse":[{"matcher":"Bash","hooks":[{"type":"command","command":".claude/hooks/pii-guard.sh"},{"type":"command","command":".claude/hooks/permission-check.sh"}]}],"PostToolUse":[{"matcher":"*","hooks":[{"type":"command","command":".claude/hooks/audit-log.sh"}]}],"Stop":[{"matcher":"*","hooks":[{"type":"command","command":".claude/hooks/usage-stats.sh"},{"type":"command","command":".claude/hooks/alert-on-blocker.sh"}]}]}}四类 Hook 各司其职:
- pii-guard:PreToolUse 拦截含 PII 的命令(参考第 32 讲)
- permission-check:PreToolUse 二次校验、防止 Skill 绕过 settings.json 权限
- audit-log:PostToolUse 记录每次工具调用、落 JSON Lines(参考第 32 讲)
- usage-stats:Stop 时统计本次会话的 token 用量、推到 Prometheus
- alert-on-blocker:Stop 时检查主 Agent 输出、如果包含 “blocker” 关键词、发 Slack 告警
Hook 配合 Skill 配合 SubAgent 配合 MCP、组成完整的输入拦截 → 执行编排 → 输出审计闭环。
6. 部署与运营:从灰度到全量 + 监控 + 迭代
项目上线分四阶段:
- 阶段 1 · 自己玩(1 周):本地手跑 10 个 PR、验证基本流程
- 阶段 2 · 小范围灰度(2 周):3 个志愿者项目接入、只读不写评论、人工对照审查结果
- 阶段 3 · 写评论灰度(2 周):Agent 开始发评论、但加 [Bot-Alpha] 前缀、方便识别
- 阶段 4 · 全量上线:去掉前缀、正式开放所有项目
监控三件套:
- 成功率:Agent 跑完任务的占比(目标 > 95%)
- 误报率:Agent 报的 blocker 被人工 review 驳回的比例(目标 < 10%)
- 用户满意度:PR 作者对评论的 👍 / 👎(目标 > 80%)
迭代方向:
- 加PR 描述自动生成(已部分实现、pr-summarizer 可扩展)
- 加依赖更新自动 PR(用 npm outdated + 自动开 PR)
- 加自动合入(所有审查通过 + 2 个 approve → 自动 merge)
- 加复盘学习(用第 31 讲 /compact 的对话历史、定期复盘误报、反哺 prompt)
⚠️坑 4· 第一版就追求 100% 准确率、跑了 2 周没结果——Agent 审查的 ROI 在减少人工重复劳动、不是取代人类判断。先做 60 分、再迭代到 80 分、最后才是 95 分。
7. 毕业寄语 + 下一步行动
33 讲到这里就结束了。回头看、Claude Code 工程化的核心不是会用工具、而是:
- 把约定写进 CLAUDE.md、让 Agent 启动就懂你的项目
- 把能力封装成 Skill、让复杂操作可复用、可降本
- 把职责拆给 SubAgent、让并行 + 隔离成为本能
- 把横切挂到 Hook、让权限、审计、计费自动跑
- 把外部接进 MCP、让 Agent 的能力不被工具数量限制
- 把生产自动化用 SDK、让 Agent 真正能跑在 CI 里
- 把安全当持续运营,12 道关持续过、Playbook 持续演练
下一步行动清单(给完成 33 讲的你):
- 选一个你正在做的项目、用本讲的方法搭一个 PR 审查 Agent、跑通第一版
- 把你 5 个最常用的 prompt 抽成 Skill、放进
.claude/skills/ - 把团队的 review checklist 写成 Rules、扔进
.claude/CLAUDE.md - 把 Claude Code 接进 CI(参考第 21 讲)、跑 Headless 模式
- 订阅官方更新:docs.claude.com/claude-code + huangjia2019/claude-code-engineering
- 持续读 shanraisshan/claude-code-best-practice、跟进全功能地图
课程毕业、工程化之路才刚开始。祝你的 Agent 们跑得稳、跑得省、跑得久。
8. 一句话备忘
🎉 毕业快乐。下一个项目、交给 Agent 们去做吧。