从零实现grill-me风格代码审查Skill:Claude Code与Agent技能开发实战

📅 发布时间:2026/8/30 10:05:17
从零实现grill-me风格代码审查Skill:Claude Code与Agent技能开发实战 最近在折腾 Claude Code 与各类 Agent 工具时发现不少开发者都在讨论/grill-me这种特殊风格的 Skill。简单说它不再是“帮 AI 补充背景资料”而是设计成一套追问机制让 AI 反过来不断向你提尖锐问题帮助你审视方案缺陷、代码边界和业务风险。这种思路很值得借鉴所以我把 Skill 的基础知识、编写规范和实战落地方式整理成一篇系统教程并结合/grill-me的设计理念实现一个简化版“代码审问者”Skill。无论你是刚接触 Skill 的新人还是已经在用 Claude Code / Codex 的进阶玩家这篇文章都能让你少走弯路。1. Skill 是什么一套让 AI 独立执行任务的“技能包”1.1 从提示词工程到技能封装的演进在传统提示词工程里我们需要在每次对话里反复粘贴系统提示、示例和约束条件。这种方式不仅容易超出上下文长度还会因为提示词不稳定导致 AI 输出飘忽不定。Skill技能本质上是把“某类任务所需的知识、指令、模板和脚本”封装成独立文件AI 在识别到对应任务时自动加载并使用这些文件。从这个角度看Skill 解决的问题非常明确让复杂任务的处理流程可复用、可分享、可版本管理。比如你可以把“Spring Boot 项目代码审查规范”写成一个 Skill之后每次在项目里执行审查时AI 会自动按规范检查、输出结构化报告而不是你临时手写一段提示词。1.2/grill-me风格的启发/grill-me是近期社区讨论度较高的一类 Skill 设计模式核心思想是“让 AI 主动审问你”。普通文档型 Skill 是 AI 按照流程执行而 grill-me 风格强调AI 针对你的方案提出尖锐问题、列出反方观点、逼你补全逻辑漏洞。这种设计非常适合以下场景技术方案评审前先用 AI 做一轮“灵魂拷问”。代码功能开发前让 AI 分析需求中的边界条件和异常分支。系统设计答辩准备提前暴露自己没考虑的故障场景。你可以把它理解成一个“自动化的技术评审委员会”。AI 不再只是工具人而是一个带批判性思维的协作伙伴。1.3 适用读者与学习收益本文内容适合三类读者刚开始接触 Claude Code、Codex、Cursor 等 AI Agent 工具的开发者想弄明白 Skill 的安装路径、目录结构和写法。已经在使用现成 Skill但想定制一个属于自己的审查、追问型 Skill 的进阶玩家。团队内部想沉淀一套统一开发规范、代码审查标准或运维流程的负责人。读完本文后你能掌握Skill 的标准目录结构与SKILL.md写法。如何设计带参数、带脚本的 Skill。如何实现一个简化版/grill-me风格的代码审查 Skill。如何排查 Skill 不生效、上下文过长、权限不足等高频问题。2. Skill 核心机制拆解SKILL.md 与工作目录2.1 最核心的SKILL.md文件Skill 的入口通常是SKILL.md它采用 Markdown 格式但带有 YAML frontmatter元数据区。一个最小化的 Skill 结构如下my-skill/ └── SKILL.mdSKILL.md里有两个区域YAML 头部定义name、description其中description会被 Agent 用来判断何时触发这个 Skill。Markdown 正文定义具体的执行步骤、规则、示例和注意事项。你可以把SKILL.md想象成“工作手册”Agent 读取它之后按手册执行任务。手册写得好不好直接决定 Skill 的智能程度。2.2 description 是 Skill 的“触发开关”在实际使用中很多新手踩过同一个坑Skill 无法自动触发原因就是description写得太宽泛或太抽象。比如下面这种描述就很不友好description: 帮助用户审查代码。它没有说明“在什么场景下使用”“输入是什么”“输出是什么”。更好的写法是description: 当用户要求进行代码审查、寻找潜在缺陷、检查安全风险和性能问题时使用本 Skill 来分析代码并输出结构化审查报告。用户可能提到“review code”“代码审查”“帮我看下这段代码”等短语。这样写的好处是Agent 在匹配用户意图时能更准确地命中。如果你的 Skill 是手动触发的也可以不依赖 description 的自动匹配而是通过命令或显式路径加载。2.3 辅助脚本文件可以放在 Skill 目录内SKILL.md只是入口。实际工程中我们经常需要把 Python 脚本、JSON 模板、配置文件等放在 Skill 目录下。例如code-review-skill/ ├── SKILL.md ├── scripts/ │ ├── review.py │ └── analyze.py └── templates/ └── review-report.mdSKILL.md中可以直接写“运行python scripts/review.py file来对指定文件进行静态分析”Agent 会按指示调用脚本。这给 Skill 带来了非常强的扩展能力——它不只是文字指令还能驱动真实工具执行检测、生成报告、分析数据。2.4 Skill 与 MCP 的关系很多读者会混淆 Skill 和 MCPModel Context Protocol模型上下文协议。两者确实有交集但定位不同对比项SkillMCP核心定位任务执行流程与知识封装模型与外部工具、数据源之间的标准化协议文件形式SKILL.md加辅助文件服务端与客户端配置通常是 JSON-RPC 通信使用方式按任务自动/手动加载通过协议调用外部工具、数据库、API典型场景代码审查、文档生成、Prompt 流程查询数据库、调用公司内部 API、读文件系统可以这么理解Skill 偏“流程和提示词”MCP 偏“工具连接和数据获取”。很多复杂场景会把两者结合例如 Skill 规定审查流程MCP 负责从代码库、SonarQube 接口拉取真实数据。但初学者最好先把 Skill 本身写好不要一上来就混用两层概念。3. 环境准备与版本说明3.1 运行环境要实现和运行本文的 Skill你需要一个支持 Skill 机制的 AI Agent 客户端。目前市面上的主流方案包括Claude CodeAnthropic 官方 CLI 工具CodexOpenAI 的 CLI / IDE 集成方案Cursor 的 Rules 与自定义指令机制OpenClaw 等社区项目版本更新比较快本文无法保证某个固定版本仍然兼容但核心思路是通用的大部分支持自定义 Agent 技能的软件最终都依赖“目录 Markdown 指令 辅助脚本”的组合。如果你使用的是 Claude CodeSkill 一般会放在项目的.claude/skills/目录下或用户级全局目录下.claude/skills/ └── code-review-skill/ └── SKILL.md如果是 Codex路径和配置可能不同建议以官方文档为准。这里重点不是死记路径而是理解“将 SKILL.md 放入 Agent 能扫描到的技能目录并以名称调用”。3.2 编写工具写SKILL.md只需要任意文本编辑器比如 VS Code、Vim甚至系统自带记事本。如果你想运行辅助脚本还需要一个可用的 Python 或 Node.js 环境。版本建议如下但仍需按实际环境调整Python 3.9 及以上 Node.js 18 及以上如果脚本用 Node 编写没有固定版本要求的关键在于SKILL.md是纯文本规则文件不依赖特定编译器只有辅助脚本才依赖运行时环境。3.3 示例项目结构为了统一演示本文会围绕一个“代码审查审问者”项目展开。最终目录如下grill-review-skill/ ├── SKILL.md ├── prompts/ │ ├── initial.md │ └── round2.md └── scripts/ └── collect_context.py我们会在后续章节逐步填充这些文件。4. 从零实现一个最小 Skill先跑通过程4.1 创建目录和SKILL.md第一步在任何你喜欢的位置创建目录mkdir first-skill cd first-skill mkdir prompts scripts然后创建SKILL.md内容如下--- name: first-skill description: 当用户要求演示一个最简单的 Skill或想了解 Skill 的基本结构与执行流程时使用本 Skill。 --- # 第一个 Skill 这是一个演示型 Skill。 ## 执行步骤 1. 向用户说明 Skill 的概念。 2. 展示当前目录的 SKILL.md 文件结构。 3. 输出一句欢迎语。 4. 询问用户是否要继续编写更复杂的 Skill。这段内容虽然简单但它已经具备完整 Skill 的特征有元信息、有执行步骤、有输出要求。4.2 将 Skill 放到可识别目录以 Claude Code 为例把first-skill整个目录复制到项目的.claude/skills/下mkdir -p .claude/skills cp -r first-skill .claude/skills/此时结构为.claude/skills/first-skill/ └── SKILL.md如果你的 Agent 工具已经运行通常需要重启会话或执行一次目录刷新命令不同工具命令不同。然后你可以直接询问“加载 first-skill给我演示一下它的功能。”如果 Agent 正确读取了SKILL.md它会按其中的步骤返回内容。4.3 验证是否生效判断 Skill 是否生效可以从两个角度看运行时是否主动使用了SKILL.md中定义的流程。输出中是否体现了第一步、第二步、第三步的指令。如果没有生效优先检查目录名称的大小写是否正确。SKILL.md 是否以 UTF-8 编码保存。frontmatter 中name是否与目录名一致。Agent 的版本是否支持自动扫描该目录。4.4 最小 Skill 的局限刚才的最小 Skill 只能演示概念距离真正实用还很远。因为它没有交互环节、没有外部数据输入、没有生成具体报告。所以我们进入下一节用/grill-me风格把它改造成一个真正能用的“审问者” Skill。5. 实战实现一个 /grill-me 风格代码审问 Skill5.1 设计思路我们做一个名为grill-review的 Skill。它的核心工作流程如下用户提供一段代码或一个技术方案。Skill 不直接给结论而是先输出一系列尖锐问题。用户回答后Skill 根据回答补充更深入的问题。累积三轮问答后Skill 整理出一份“方案风险清单”。这其实就是/grill-me风格的简化实现通过递归追问来逼出盲点。为了让它更通用我们把问题主题限定为“代码审查 方案评审”因为这是开发者最常用的场景。5.2 目录结构与文件内容完整目录如下grill-review-skill/ ├── SKILL.md ├── prompts/ │ ├── initial.md │ └── followup.md └── scripts/ └── collect_context.pySKILL.md这个文件是整个 Skill 的调度中心。它负责定义触发条件、执行流程和输出格式。--- name: grill-review description: 当用户要求对代码、技术方案、系统设计进行批判性审查或希望被反复追问、找出方案中的漏洞时使用本 Skill。用户可能提到“grill me”“审问我的方案”“帮我找出风险”“代码审查”“方案评审”等场景。 --- # 代码审问者Grill Review ## 角色定位 你是一个资深技术评审人风格直接、犀利但不恶意。你的目标是找出方案中的逻辑漏洞、边界问题、安全隐患与可维护性风险。 ## 执行流程 ### 第一轮需求澄清 1. 请求用户提供代码片段或方案描述。 2. 如果用户已提供内容提炼出 3 到 5 个关键假设。 3. 向用户提问每个问题必须包含“为什么”或“如果……会怎样”。 ### 第二轮边界探测 1. 根据用户回答找出上轮回答中仍然模糊的点。 2. 重点追问异常分支、性能瓶颈、数据一致性、权限安全、外部依赖故障。 3. 每轮提问数量不超过 5 个避免问题过载。 ### 第三轮风险汇总 1. 将用户所有回答整理为“已确认结论”。 2. 将仍然无法回答的问题整理为“待确认风险”。 3. 输出一个包含风险等级高/中/低的清单。 ## 输出格式 当完成三轮交流后使用以下结构输出 markdown ## 方案风险清单 ### 已确认结论 - ... ### 待确认风险 | 风险点 | 等级 | 说明 | | --- | --- | --- | | ... | 高/中/低 | ... | ### 建议行动 - ...注意事项不要代替用户做决定你的任务是让用户自己意识到问题。不要重复称赞用户的方案除非它是真正严谨的设计。如果用户在某一轮回答“不知道”不要直接跳过请换一种更简单的问法重新追问。#### prompts/initial.md 这是一个备用提示词文件当 SKILL.md 的主指令不够时可以引导 Agent 生成更有攻击性的审查问题 markdown 你正在进入第一轮审查。 用户给出了一个技术方案说明。你需要从以下维度生成问题 1. 这个方案的不可变假设是什么如果假设不成立会发生什么 2. 方案的失败模式有哪些哪些故障会导致数据丢失或资金损失 3. 方案里有没有“最终一定会发生”的定时炸弹 4. 上线后如何运维监控指标是什么 5. 如果系统在凌晨 3 点崩溃值班人员能在 10 分钟内定位问题吗这个文件的价值在于它可以被SKILL.md引用也可以被有心人单独提取作为 prompt 片段复用结构上更清晰。scripts/collect_context.py为了让 Skill 不纯靠“嘴问”我们可以增加一个辅助脚本。这个脚本不是必须的但能展示 Skill 结合脚本能力后的威力。#!/usr/bin/env python3 # 文件路径grill-review-skill/scripts/collect_context.py import os import re import sys def count_imports(code: str) - int: 统计代码中的 import 语句数量用于判断依赖复杂度。 lines code.splitlines() imports [line for line in lines if re.match(r\s*(import|from)\s, line)] return len(imports) def detect_long_functions(code: str, max_lines: int 60) - list: 扫描代码中行数超过阈值的函数用于提示可维护性风险。 lines code.splitlines() function_start None function_name result [] for idx, line in enumerate(lines): match re.match(r\s*def\s(\w)\s*\(, line) if match: if function_start is not None and idx - function_start max_lines: result.append((function_name, idx - function_start)) function_start idx function_name match.group(1) if function_start is not None and len(lines) - function_start max_lines: result.append((function_name, len(lines) - function_start)) return result def calculate_todo_count(code: str) - int: 统计 TODO/FIXME 注释数量。 return len(re.findall(r(TODO|FIXME), code)) def main(): if len(sys.argv) 2: print(Usage: python collect_context.py file_path) sys.exit(1) file_path sys.argv[1] if not os.path.exists(file_path): print(fError: file {file_path} not found) sys.exit(1) with open(file_path, r, encodingutf-8, errorsignore) as f: code f.read() report { file: file_path, lines: len(code.splitlines()), import_count: count_imports(code), todos: calculate_todo_count(code), long_functions: detect_long_functions(code), } print( Code Context Report ) print(fFile: {report[file]}) print(fLines: {report[lines]}) print(fImport statements: {report[import_count]}) print(fTODO/FIXME count: {report[todos]}) if report[long_functions]: print(Long functions (more than 60 lines):) for name, length in report[long_functions]: print(f - {name}: {length} lines) else: print(No long functions detected.) print( End Report ) if __name__ __main__: main()这个脚本会读取一个 Python 文件统计行数、import 数量、TODO 注释以及超过 60 行的“长函数”。在SKILL.md的流程中我们可以让 Agent 先运行脚本收集上下文再结合上下文提出问题。5.3 让 SKILL.md 调用脚本上面的SKILL.md还可以写得更有执行力。比如在第二轮流程中插入脚本调用提示### 第二轮边界探测 1. 询问用户代码文件路径。 2. 如果路径提供运行指令python scripts/collect_context.py 文件路径 3. 根据脚本输出中的 import 数量、TODO 数量和长函数数量生成针对性问题。这样 Skill 就从“纯问答”升级成了“代码分析 提问”。这也是很多社区高级 Skill 的标准姿势用脚本承担机械性统计工作用 AI 承担逻辑推理和批判性提问。5.4 运行与验证流程假设用户写了一个文件demo.pyimport os import random def process(data): # TODO: 处理 data 为空时的逻辑 result [] for i in range(100): if random.random() 0.5: result.append(i) return result def save_to_disk(content, path): with open(path, w) as f: f.write(content) def main(): data [1, 2, 3] output process(data) save_to_disk(str(output), output.txt) if __name__ __main__: main()在 Agent 会话中你使用grill-reviewSkill并附上demo.py路径。Agent 会按流程先跑脚本python scripts/collect_context.py demo.py预期输出 Code Context Report File: demo.py Lines: 24 Import statements: 2 TODO/FIXME count: 1 Long functions (more than 60 lines): - process: 100 lines End Report 注意这里的函数长度统计是示例输出实际行数取决于process内部代码。脚本会把超过 60 行的函数输出为长函数。基于这个上下文Agent 会展开追问比如process函数为什么这么长有没有拆分成多个小函数的计划save_to_disk没有处理目录不存在、磁盘满、文件占用等异常如果写入失败会怎样random.random() 0.5这个边界条件在业务上是否合理是否存在“永远不满足”或“几乎永远满足”的风险这种问题风格就是/grill-me的核心不直接给修复方案而是先让开发者自己意识到问题。5.5 结果说明三轮问答结束后Agent 会生成一份方案风险清单。假设用户都回答了最终输出会像这样## 方案风险清单 ### 已确认结论 - 用户确认 process 函数确实承担了过滤和聚合两种职责。 - 用户确认 save_to_disk 缺少异常处理。 - 用户知道 TODO 注释对应的空数据场景尚未实现。 ### 待确认风险 | 风险点 | 等级 | 说明 | | --- | --- | --- | | 空数据输入 | 高 | process 对空列表的处理逻辑缺失 | | 写盘异常 | 中 | 未处理磁盘满、权限不足等异常 | | 随机逻辑不可测试 | 中 | random 导致输出不稳定难以做单元测试 | ### 建议行动 - 为 process 增加空列表分支。 - 在 save_to_disk 中增加 try/except 与日志记录。 - 将 random.random() 抽取为可注入依赖便于测试。到这里grill-reviewSkill 就完成了一次完整工作循环。它既展示了 Skill 的自动流程能力也展示了/grill-me风格与普通代码审查的最大区别用户不是拿到一份现成的“建议列表”而是通过与 AI 的问答自己把方案缺陷一步步暴露出来。6. 进阶技巧如何让 Skill 更“聪明”6.1 参数的灵活使用在SKILL.md中你可以定义占位符让 Agent 在执行时替换为真实内容。比如## 输入 用户需要提供一个代码文件路径{{file_path}}Agent 会从对话中提取file_path并将其填入后续指令。这种方式比让 AI 自己猜测路径更可靠。6.2 多轮状态记录/grill-me风格依赖多轮对话。为了让 Agent 不丢失上下文最好在SKILL.md中显式要求它记录状态## 状态跟踪 在每一轮提问结束后维护一个临时要点列表下一轮提问前先复述上一轮已经确认的要点。复述时不允许添加用户未确认的信息。这能有效避免多轮对话后期Agent 遗忘用户早前回答过的问题。6.3 与 MCP 工具联动如果你想在审查中获取真实代码仓库数据比如 Git 提交历史、SonarQube 扫描结果可以考虑增加 MCP 工具。此时 Skill 负责编排流程MCP 负责数据接入。一个典型链路是Agent 通过 MCP 获取代码文件的静态扫描结果。Skill 读取扫描结果。基于扫描结果生成审问问题。不过这里要提醒MCP 配置相对复杂涉及服务端地址、权限等。建议先把 Skill 本身跑顺再考虑接入外部数据源。6.4 多文件 Skill 的组织要点实用 Skill 往往包含多个文件。组织时要注意SKILL.md始终放在根目录并保持文件名严格为SKILL.md。脚本统一放scripts/不要和SKILL.md混放。模板统一放templates/。文档或示例可以放examples/。自定义目录名和文件路径要在SKILL.md中写清楚减少 Agent 猜测成本。7. 常见问题与排查思路在实际使用 Skill 的过程中下面几个问题出现频率最高。问题现象常见原因解决思路Skill 不自动触发description描述不精准或包含太多泛化词重写 description加入用户可能说的关键词和触发场景Agent 找不到 Skill目录位置错误或目录名与name不一致检查是否存在.claude/skills/skill-name/SKILL.md确保目录名一致SKILL.md 指令没被遵循文件编码不是 UTF-8或 frontmatter 格式错误用文本编辑器另存为 UTF-8检查 YAML 缩进脚本无法运行Python 环境缺少依赖或脚本路径写错在SKILL.md中写绝对路径或相对路径先手动运行脚本验证多轮问答上下文丢失没有状态记录机制在 SKILL.md 中要求 Agent 每轮先复述已确认要点输出格式混乱未在 SKILL.md 中定义输出模板增加“输出格式”章节给出 Markdown 模板Skill 与 MCP 工具冲突同时多个工具抢着处理用户请求在 Skill 描述中明确“任务归属”避免职责重叠排查时建议按“先手动后自动”的顺序先把 Skill 目录复制到正确位置然后手动打开SKILL.md检查 YAML再用命令行跑辅助脚本最后才在 Agent 会话中测试触发。8. 最佳实践与工程建议8.1 命名与描述规范Skill 的name建议使用小写字母加连字符例如grill-review、code-analyzer。避免使用空格和中文。description要有“触发关键词 任务边界 输出要求”这是决定自动触发准确率的最关键因素。8.2 版本管理只要涉及多文件、多种脚本就建议用 Git 管理。目录结构建议skills/ └── grill-review/ ├── SKILL.md ├── scripts/ └── tests/在SKILL.md的 frontmatter 中可以增加version字段--- name: grill-review version: 0.1.0 description: ... ---方便团队追踪变化。8.3 权限与安全边界如果 Skill 的脚本会读取文件、调用 API 或执行命令务必要有安全边界只允许读取用户显式指定的路径。脚本中不要硬编码密钥。对用户输入的文件路径做合法性校验防止路径穿越。删除、覆盖文件等高危操作必须经过用户二次确认。这一点特别重要。Skill 的运行主体是 AI Agent如果你的脚本里写了rm -rf或drop table一旦触发条件判断失误后果会很严重。8.4 测试策略给 Skill 写测试听起来很麻烦但反而是工程化最重要的环节。你至少要做三类测试触发测试输入不同语料确认description是否能准确匹配。流程测试给 Agent 一个样例输入看它是否按SKILL.md的步骤执行。脚本测试对scripts/下的 Python 脚本写单元测试确保输出格式稳定。脚本测试示例# 文件路径grill-review-skill/tests/test_collect_context.py import sys import os sys.path.insert(0, os.path.join(os.path.dirname(__file__), .., scripts)) from collect_context import count_imports, calculate_todo_count def test_count_imports(): code import os\nimport sys\n assert count_imports(code) 2 def test_calculate_todo_count(): code # TODO: fix this\n# FIXME: too slow\n assert calculate_todo_count(code) 2运行测试python -m pytest tests/通过测试后Skill 的基础质量就有了保障。8.5 从“能用”到“好用”的演进路径一个 Skill 的成熟通常经过三个阶段第一阶段只有SKILL.md能按流程输出。第二阶段加入脚本能做简单统计和文件处理。第三阶段加入模板、多轮状态管理、外部 MCP 联动。建议初学者不要一开始就设计一个大而全的 Skill而是先做一个能跑的 MVP再逐步补充脚本和联动能力。就像本文中的grill-review先完成“提问-回答-汇总”循环再考虑接入数据库查询、CI 扫描等能力。8.6 关注社区生态Skill 的生态还在快速演进。Claude Code、Codex 和其他 Agent 工具对 Skill 的支持方式各不相同社区里也已经出现了不少值得参考的 Skill 库。你可以关注官方文档、GitHub 上高星项目也可以直接搜索“skill 推荐”“skill 库”等关键词看看别人是如何组织SKILL.md的。但记住别人的 Skill 可以借鉴在框架和思路上不要直接复制后不经过验证就用于生产环境。9. 结语与下一步关于 Skill 你一定还想知道它到底能跑多复杂的任务会不会被大模型能力限制实际上Skill 机制的本质是把“任务流程”和“模型推理”分层流程、脚本、模板是确定性的工程模型推理是不可确定性的智力部分。我们编写 Skill 时核心工作就是把流程设计得足够清晰把所有确定性内容都固化成文件留给模型发挥的空间就只剩推理和表达。这样 AI 的输出质量会稳定很多。下一步建议你先动手写一个最简单的属于你自己的 Skill不追求功能完整哪怕只是让 Agent 按固定模板输出一段日报都能帮你快速理解加载机制、目录路径和触发逻辑。等你熟练之后再逐步加入辅助脚本、多轮状态、MCP 联动。一个人项目中的一个小 Skill也许只是你的一次实验却很可能成为团队后续规范化的起点。动手试一试你会比只看文章的其他人早一步掌握这套 AI 技能开发能力。