1. 为什么把代码审查塞进 SKILL.md 里
代码审查这件事,做过的人都懂:同一段代码,老工程师能揪出 SQL 注入和 N+1 查询,新人只能看出缩进没对齐。更麻烦的是输出格式——有人写三百字,有人回一句「LGTM」,你想统计「这个月严重问题占比多少」根本无从下手。
我试过让模型直接审代码,结果三次输出三个样:第一次结构乱得没法看,第二次漏了安全维度,第三次严重问题混在建议里没标出来。问题不在模型能力,在于我们没给它一个稳定的输出契约。
SKILL.md 就是干这个的。它是 Claude Code 里定义 Skill 的入口文件,用 YAML frontmatter 声明元信息,用 Markdown 正文写审查流程和规则。你可以把它理解成给模型的一份「岗位说明书」:审什么、按什么标准分级、报告长什么样,全写死在里面。模型负责灵活判断,模板负责强制结构,两者分离。
这套东西适合谁?适合团队里已经有 Code Review 流程、但被「标准不统一、知识难沉淀、输出太随意」折磨过的开发者。如果你只是偶尔看看自己的代码,用不用 Skill 差别不大;但如果你要横向对比不同 PR 的审查质量,或者想把审查结果喂给 CI 系统做门禁,模板驱动几乎是唯一解。
下面我会给出可复制的 SKILL.md 模板、审查规则清单、触发配置,以及通过 TaoToken 统一 Key 接入的完整步骤。最后用一次真实 diff 验证输出是否命中模板规则。
2. TaoToken 前置:统一 Key 与 API 通道
在写 SKILL.md 之前,得先把模型通道打通。Claude Code 默认走 Anthropic 官方接口,但如果你团队里多人共用、或者想统一管理 Key 和用量,用 TaoToken 做一层 API 网关会省很多事。
TaoToken 在这里的角色是「统一入口」:你拿到一个 Key,配好 Base URL,Claude Code 的所有请求都走这条通道。好处是 Key 不用散落在每个人本地,换模型、看用量、做限额都在一个地方。
2.1 拿 Key 和确认 Base URL
先到控制台创建 API Key。地址是:
https://taotoken.net/console创建完复制 Key,格式类似sk-xxxxxxxx。然后确认 API 端点:
https://taotoken.net/api注意这个地址不带任何查询参数,是纯 API 根路径。Claude Code 需要的 Base URL 就是它。
2.2 在 Claude Code 里配置
Claude Code 读取环境变量来定位 API。你可以在 shell 配置文件里写死,也可以用项目级的.env。我习惯用环境变量,因为切换方便。
export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_API_KEY="sk-你的Key" export ANTHROPIC_MODEL="claude-sonnet-4-20250514"如果你用的是 Claude Code 的 settings 文件,路径通常在~/.claude/settings.json,内容长这样:
{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_API_KEY": "sk-你的Key", "ANTHROPIC_MODEL": "claude-sonnet-4-20250514" } }三件套缺一不可:Base URL 指向 TaoToken,Key 用你创建的,Model ID 写清楚具体版本。Model ID 写错会直接报 404,别问我怎么知道的。
2.3 验证通道是否通
配完先别急着写 Skill,跑一条最小请求确认通道没问题:
curl https://taotoken.net/api/v1/messages \ -H "x-api-key: sk-你的Key" \ -H "anthropic-version: 2023-06-01" \ -H "content-type: application/json" \ -d '{ "model": "claude-sonnet-4-20250514", "max_tokens": 64, "messages": [{"role": "user", "content": "回复 OK"}] }'返回里能看到content字段带文本,就说明通道通了。如果返回 401,检查 Key 有没有复制全;如果返回local proxy failed,检查 Base URL 是不是写成了带路径的地址。
通道通了之后,Skill 的模型调用才有意义。接下来写 SKILL.md。
3. 可复制配置:SKILL.md 模板与触发设置
这一节是核心。我会给出完整的 SKILL.md 模板、references 里的规则清单、以及 Claude Code 的触发配置。所有片段都可以直接复制改。
3.1 目录结构
先看整体结构,四层分离:
7d-code-reviewer/ ├── SKILL.md ├── references/ │ ├── coding-standards.md │ ├── security-checklist.md │ └── review-examples.md ├── templates/ │ └── report-template.md └── scripts/ └── render.mdSKILL.md 是大脑,references 是记忆,templates 是格式,scripts 是渲染说明。职责分离的好处是改格式不用动逻辑,加规则不用动模板。
3.2 SKILL.md 完整模板
--- name: 7d-code-reviewer description: 对指定代码文件或 diff 执行结构化代码审查,输出统一格式的报告。当用户要求审查代码、review PR、检查代码质量时触发。 --- # 代码审查 Skill ## 审查流程 1. 读取目标文件或 diff,识别改动性质(新功能/修 Bug/重构) 2. 按四个维度逐项检查:质量、安全、性能、可维护性 3. 对每个问题分级:严重(必须修复)、中等(建议修复)、轻微(可选改进) 4. 加载 references/ 下对应清单,核对是否遗漏 5. 将结果填入 templates/report-template.md,所有占位符必须填充 ## 审查维度 - 质量:命名清晰度、函数职责单一性、重复代码 - 安全:SQL 注入、XSS、硬编码密钥、越权访问 - 性能:N+1 查询、大循环内 IO、无索引查询 - 可维护性:异常处理、日志、注释、测试覆盖 ## 分级标准 - 严重:可导致数据泄露、服务不可用、资金损失 - 中等:影响性能或可维护性,但不直接导致故障 - 轻微:风格问题、命名建议、可选优化 ## 输出要求 - 必须使用 templates/report-template.md - 所有占位符必须填充,无内容填「无」 - 不得删除模板中的任何章节frontmatter 里name和description是必填。description 要写清楚「什么时候触发」,模型靠它判断是否加载这个 Skill。
3.3 references 规则清单
references/security-checklist.md示例:
# 安全检查清单 ## SQL 注入 - 检查是否使用参数化查询 - 检查是否有字符串拼接 SQL - 检查 ORM 的 raw 查询用法 ## XSS - 检查用户输入是否转义 - 检查 innerHTML 直接赋值 - 检查模板引擎的自动转义是否关闭 ## 密钥泄露 - 检查硬编码的 API Key、密码 - 检查 .env 是否被提交 - 检查日志是否打印敏感字段references/coding-standards.md写团队的命名规范、函数长度上限、注释要求。这些文件只在审查时按需加载,不常驻上下文,省 token。
3.4 触发配置
Claude Code 里触发 Skill 有两种方式。一种是自然语言触发,description 写得好,你说「审查 src/api/user.py」它就会加载。另一种是显式调用:
/7d-code-reviewer 审查 src/api/user.py如果你想在 CI 里自动触发,可以在脚本里调 Claude Code 的 headless 模式:
claude -p "使用 7d-code-reviewer 审查 $(git diff --name-only HEAD~1)" \ --output-format json这样每次 PR 都能自动跑一遍审查,输出 JSON 喂给下游系统。
3.5 模板文件
templates/report-template.md:
# 代码审查报告 ## 评分卡 - 质量:{{quality_score}}/10 - 安全:{{security_score}}/10 - 性能:{{performance_score}}/10 - 可维护性:{{maintainability_score}}/10 - 总分:{{total_score}}/10 ## 问题列表 {{issues}} ## 修复建议 {{suggestions}} ## 优点 {{strengths}}占位符用双花括号,渲染时替换。约定模板里不写 if/else,所有判断在 SKILL.md 里做。
4. 验证请求:用一次真实 diff 跑通审查
配置写完,得用真实代码验证。我拿一段有问题的 Python 代码来跑。
4.1 准备测试代码
# src/api/user.py import sqlite3 def get_user_list(db, keyword): conn = sqlite3.connect(db) cursor = conn.cursor() query = "SELECT * FROM users WHERE name LIKE '%" + keyword + "%'" cursor.execute(query) users = cursor.fetchall() result = [] for user in users: orders = cursor.execute( "SELECT * FROM orders WHERE user_id = ?", (user[0],) ).fetchall() result.append({"user": user, "orders": orders}) return result这段代码有两个明显问题:SQL 字符串拼接(注入风险)、循环内查询(N+1)。
4.2 触发审查
在 Claude Code 里输入:
/7d-code-reviewer 审查 src/api/user.py模型会加载 SKILL.md,按流程读取文件,加载 security-checklist.md 和 coding-standards.md,逐维度检查,最后填模板。
4.3 预期输出
# 代码审查报告 ## 评分卡 - 质量:6/10 - 安全:3/10 - 性能:4/10 - 可维护性:5/10 - 总分:4.5/10 ## 问题列表 ### 严重:SQL 注入风险 位置:get_user_list() 第 7 行 描述:使用字符串拼接构造 SQL,keyword 参数未过滤,可被注入 建议:改用参数化查询 cursor.execute("... LIKE ?", (f"%{keyword}%",)) ### 严重:N+1 查询 位置:get_user_list() 第 11-14 行 描述:循环内逐条查询 orders,用户量增大时性能急剧下降 建议:用 JOIN 一次查出,或先收集 user_id 再批量查询 ## 修复建议 1. 将 SQL 改为参数化查询 2. 将 orders 查询移出循环,改为批量查询 3. 添加异常处理,数据库操作失败时记录日志 ## 优点 - 函数职责相对单一 - 返回值结构清晰4.4 验证要点
检查输出是否命中三条规则:严重问题有没有标「严重」、位置有没有写行号、建议有没有给具体改法。如果三条都中,说明模板约束生效了。如果输出结构乱、漏了评分卡,回去检查 SKILL.md 的「输出要求」章节是不是写清楚了。
5. 常见报错排查
跑不通的时候,对照下面几个真实报错。
5.1 401 Unauthorized
{"error": {"type": "authentication_error", "message": "invalid x-api-key"}}Key 没配对。检查ANTHROPIC_API_KEY是不是完整复制,有没有多余空格。如果用的是 settings.json,确认 JSON 格式没写错,逗号别多别少。
5.2 local proxy failed
Error: local proxy failed to connectBase URL 写错了。确认是https://taotoken.net/api,不要带/v1或/messages后缀。Claude Code 会自己拼路径,你多写一段就 404。
5.3 reading choices 报错
Error: reading 'choices' of undefined这是请求体格式不对。Claude Code 走的是 Anthropic 格式(messages数组),不是 OpenAI 的choices。检查你的 Model ID 是不是写成了 OpenAI 的模型名。Anthropic 模型 ID 形如claude-sonnet-4-20250514。
5.4 OAuth 相关报错
Error: OAuth token expired如果你之前登录过 Anthropic 官方账号,本地可能残留 OAuth 凭证,和 API Key 冲突。清掉~/.claude/下的凭证缓存,或者显式设置ANTHROPIC_API_KEY覆盖。
5.5 Skill 不触发
输入审查指令后模型没加载 Skill。检查 SKILL.md 的description有没有写触发场景关键词。description 太泛(比如只写「代码审查」)模型可能不认,加上「当用户要求审查代码、review PR 时触发」这类明确条件。
5.6 输出缺章节
报告里少了评分卡或优点章节。这是模板占位符没填全。在 SKILL.md 里加一条硬约束:「所有占位符必须填充,无内容填『无』,不得删除模板章节」。模型对显式约束的遵守率明显更高。
6. 接入文档与后续分流
通道和 Skill 都跑通之后,日常用起来就三件事:拿 Key、配 Base URL、写 SKILL.md。Key 和通道管理在控制台,Skill 的写法参考接入文档。
如果你只是想让模型帮你审一段代码,不打算做模板化,直接用模型对话就行,不用折腾 Skill。但如果你要把审查结果归档、对比、喂给 CI,那模板驱动这套值得投入。
长期做编码和 Agent 的话,Coding Plan 更划算,用量和模型切换都在一个面板里管。具体选哪个看你的使用频率:偶尔审一次用按量,天天跑 CI 用套餐。
接入文档里有完整的 API 参数说明和示例,配 Key 遇到问题先翻那里。