资讯动态

从SKILL.md到脚本:如何把安全审计做成AI Agent技能包

发布时间:2026/9/23 5:12:14 来源:尧图企业网站定制
最近半年AI Agent 圈子里最火的一个词就是 skill。Claude、Codex、OpenCode 这些工具先后都加入了 skill 机制GitHub 上也冒出来一堆技能库里面全是别人写好的 SKILL.md。说实话一开始我并不太理解这玩意和普通的 prompt 工程有多大区别直到我亲手把一个高频重复的工作——安全审计做成了一个叫 security-audit-skill 的技能包才真正明白 skill 这个抽象层解决的是什么问题。这篇文章就把我整个设计和实现过程拆开来讲包括为什么安全审计适合做成 skill、SKILL.md 到底应该怎么写、配套脚本怎么组织以及在本地跑通一次完整审计流程时需要避开的那些坑。如果你正在研究 agent skill、想给 Codex 或 Claude 装一个能用的技能包或者单纯想看看安全审计这类专业任务怎么被结构化地交给 AI这篇都适合你。1. 动手前先搞懂Skill、Agent、插件到底差在哪1.1 什么是AI Skill它解决的问题是什么Skill技能在 AI Agent 体系里指的是一个可以被 Agent 按需加载的结构化知识包。以 Claude 定义的格式为例一个 skill 就是一个目录里面最主要的是一份 SKILL.md 文件文件开头的 YAML 段声明了技能名称和适用场景正文则是给模型看的操作指引。目录里还可以放脚本、参考文档、示例模板等辅助资源。很多第一次接触的人把 skill 当成一个高级 prompt这个理解不算错但不够准确。Prompt 是静态的、每次对话都要跟着上下文一起走skill 是动态的、按需加载的更像一个可以被 Agent 随时查阅的任务手册。我做个生活化类比可能更好理解Agent 本身像一个实习生底子不错什么都懂一点但拿到具体任务时不知道该按什么流程走。Skill 就是给这个实习生的一张任务卡片上面写着任务目标、操作流程、注意事项、对应工具在哪里、哪些情况可以自己判断、哪些情况必须停下来上报。Agent 看到任务后先看自己的工具盒里有没有匹配的 skill 卡片有就按卡片上的流程干活。没有 skill 的 Agent 也不是不能干活但每次都要靠用户把流程讲一遍过程漫长、结果不可控遇到复杂任务还容易丢三落四。之所以需要这个抽象层是因为原始模型不适合塞进去太多程序性知识。你可以在 system prompt 里写剧本文案、写角色设定但如果要写一百段怎么做事的流程prompt 会变得冗长、互相干扰、且每次对话都要消耗 token。Skill 是懒加载的平时占用的上下文几乎为零触发时才被完整读入。这有点像程序里的虚拟内存用到了才换页。而且 skill 支持用脚本扩展能力这是普通 prompt 完全做不到的。一个写好的 skill 可以在不同项目、不同用户之间复用团队协作时可以把最佳实践沉淀下来不用每次从零开始教模型。1.2 Skill、Agent、插件的边界这个热词下面翻车的问题特别多网上不少人在问skill和agent的区别是什么我梳理一下我自己的理解。Agent 是一个完整执行体它有记忆、能规划、能调用工具、能做多轮任务拆解它是干活的人。工具或插件是一个具体的外部能力接口比如能搜索网页能执行 Shell 命令能读某个数据库它是 Agent 的手脚。Skill 则是流程和知识的封装描述的是某个专业领域的工作应该怎么做它可以引用工具但自己不直接执行它是 Agent 的作业指导书。一个容易混的点skill 和工具都能被 agent 调用但工具回答的是我能做什么动作skill 回答的是这件事应该按什么步骤做成什么样。打个比方工具是一把螺丝刀skill 是一本用它拆装设备的维修手册。理想情况下skill 内部会指导 agent 在合适节点调用工具完成整个工作流。所以你不能说学了 skill 就没必要学工具两者是不同层级的东西。很多平台现在把 agent、skill、tool 三者打通但也因为概念层叠导致刚上手的人分不清看到一个目录里有 SKILL.md 又有 tool 配置就以为这是同一个东西其实前者描述流程后者提供能力。我在设计 security-audit-skill 的过程中最大的体会是先分清流程和能力再动手。安全审计的流程是固定的这适合归入 skill而具体扫文件、跑命令、读仓库这些是能力适合做成工具或脚本。skill 负责指挥工具负责执行Agent 负责调度这样分工清晰后代码写起来也顺。1.3 为什么安全审计特别适合做成Skill我选安全审计来做第一个 skill不是拍脑袋。安全审计这类任务的特性是流程高度标准化拿到一个项目第一件事看依赖清单第二件事扫硬编码密钥第三件事检查配置项第四件事看历史提交里的敏感信息这个流程可复用性极强。判断标准相对明确密钥格式、端口配置、数据库连接串有没有暴露这些都是规则化的检查项适合让模型按清单执行。结果表达需要结构审计结果若只是丢一段聊天文本别人没法跟踪如果按严重程度分级、按文件定位、给修复建议输出质量立刻就不一样。而且这类工作对人的经验依赖重资深安全工程师的很多检查套路确实值得沉淀成一份可执行的作业指导书。反观一些不适合做 skill 的任务比如开放式头脑风暴流程不固定、判断标准模糊硬做成 skill 反而会限制模型的灵活性。安全审计恰好是反例有明确输入、有固定流程、有分级输出是非常标准的技能化场景。再加上现在代码仓库越来越大依赖越来越多靠人眼一行行看根本看不过来手动审计很容易漏。安全审计 skill 的价值就是把这些重复劳动自动化、流程化让人把精力放到真正需要判断力的地方。2. security-audit-skill的整体设计从场景拆解到目录结构2.1 这个Skill要解决什么问题在设计之前我先明确了这个 skill 的边界。首先它面向的审计范围是代码仓库级别的安全基线检查包括几个大项依赖组件版本风险、硬编码密钥与敏感信息、常见危险函数、错误配置文件、数据库连接和外部服务地址泄露。其次是历史提交记录中的敏感信息回扫这个在传统审计里经常被漏掉但其实特别重要因为密钥一旦提交进 git 历史删当前文件是没用的历史记录里还能翻出来。同时我给自己划了几条不做的边界不做渗透测试那是另一套方法论涉及运行环境、网络链路、权限绕过流程完全不同硬塞进来会污染 skill 的指令不改代码skill 只负责报告发现是否修复由人决定自动化修代码的风险太高宁可先收敛在检测层不做在线漏洞库的实时查询考虑到很多执行环境是离线内网这个 skill 的检测逻辑要尽量本地可用不依赖外部 API。边界划清楚之后很多东西就好设计了。一个 skill 最怕的就是贪大什么都能干什么都干不深那种技能包最后往往变成了一个什么都做不好的大杂烩。我还想清楚了一个问题这个 skill 面向的用户是谁。我定位的是开发者自检、团队上线前检查、以及安全工程师的辅助工具。所以输出格式上我不能只写发现了一个问题而要给出文件位置、风险等级、简要依据、修复建议方便直接转给对应负责人。这个思路也影响了后面的报告模板设计。2.2 目录结构与文件规划我最终采用的目录结构如下为了阅读方便省略了部分文件security-audit-skill/ ├── SKILL.md # 技能主文件声明操作指引 ├── scripts/ │ ├── scan_secrets.py # 敏感信息扫描 │ ├── scan_dependencies.py # 依赖组件风险检查 │ ├── scan_configs.py # 配置基线检查 │ └── utils.py # 公共函数 ├── reference/ │ ├── high_risk_patterns.md # 高风险模式清单 │ ├── config_checks.md # 配置检查基线 │ └── output_format.md # 输出格式规范 └── templates/ ├── audit_report.md # 审计报告模板 └── remediations.md # 修复建议速查这里有两个关键点。第一SKILL.md 必须放在根目录文件名必须是 SKILL.md平台靠这个约定来识别技能包第二scripts 目录和 reference 目录这种命名不是随手取的Claude、Codex 这些平台的 skill 规范中代码和参考文档约定放在这两个位置agent 在读取 skill 时会对这些目录给一定权重。你如果用了自定义目录名大多数平台也不是不能用但最好按约定来省得平台升级后出现兼容问题。模板目录里的 audit_report.md 是我比较得意的一点。很多人写 skill 只关注怎么让模型执行操作忽略了最后输出长什么样。但实际使用中报告格式直接决定了这份审计结果能不能被团队接受。所以我专门做了一份 Markdown 模板包含风险等级、文件定位、问题描述、修复建议、复测状态这几个字段并要求 agent 严格按模板输出。这样每次审计出来的结果都是同一套格式方便汇总、对比和跟踪。2.3 SKILL.md的YAML头部设计SKILL.md 的开头是 YAML frontmatter这部分是技能的门面直接决定 agent 在什么场景下会想起加载这个技能。我的头部是这样写的--- name: security-audit-skill description: 对代码仓库执行安全基线审计检查依赖风险、硬编码密钥、敏感信息泄露、危险配置项和历史提交敏感信息适用于代码评审、上线前检查、供应链安全自查。 ---description 是我反复打磨过的地方。刚开始我写的是Perform security audit for code repositories后来发现太宽泛。遇到一个任务时agent 是拿用户请求和你写的 description 做语义匹配的desc 越贴近实际触发场景命中率越高。所以我加上了依赖风险、硬编码密钥、敏感信息泄露、危险配置项、历史提交敏感信息这些具体词并补充了适用于代码评审、上线前检查这类场景短语。实测下来触发准确率明显提升。另外建议在 description 里同时保留一句英文很多平台对英文描述的语义匹配更稳定中英混写能提高跨平台兼容性。YAML 头的其他字段我没有写成复杂的格式。name 就是技能名description 是触发词这两个是核心。有些平台的 skill 规范还支持 allowed-tools、version、author 这些字段但我测试下来过度填写这些字段并不会带来明显的触发率提升反而可能因为格式错误导致整个 frontmatter 解析失败。所以我坚持能用就行的原则只保留 name 和 description。3. 核心实现让AI真的会做安全审计3.1 SKILL.md指令部分怎么写YAML 头部之后就是主体指令。这里要提醒一句SKILL.md 本质上是给模型读的不是给程序读的所以不需要写一堆 if/else 式的伪代码。更好用的是分步骤的模糊指令 边界说明 示例。我的主体指令大概分五段角色与目标、执行步骤、触发脚本的条件、结果决策规则、输出规范。角色与目标这一段我说明 agent 此时扮演的是资深安全审计工程师目标是给出可执行的安全基线检查报告。执行步骤列出五个阶段的检查流程并说明每阶段需要调用哪个脚本。触发脚本的条件是关键比如仓库存在 package.json、requirements.txt 等文件时才运行依赖扫描存在 .env、config 类文件时才扫描配置基线避免它在不合适的项目里乱跑脚本。结果决策规则允许 agent 对脚本输出做二次判断比如某个高置信度误报可以主动降级但必须在报告中说明理由。输出规范强制要求按模板输出包括风险等级、文件路径、行号、原因、修复建议。写指令时最容易犯的错是把所有细节全写进去。SKILL.md 不是文档库它是工作流骨架。真正的大段细节清单应该放到 reference 目录里让 agent 在执行到对应阶段时再去读取。这样既能保证指令简洁聚焦又能让模型在需要时获取详细参照。我实测对比过把 200 行规则全塞进 SKILL.md 后agent 反而更容易在长上下文中丢失关键约束精简成五段核心指令后执行质量和指令遵循度反而提升了。尽量用肯定句描述期望行为比如执行时优先扫描 src 目录而不是不要忽略 src 目录后者很容易被模型理解成质量差一点的 src 目录可以不管。3.2 配套脚本密钥泄露扫描这是整个 skill 里最核心的脚本。它的任务是在仓库里找出疑似硬编码密钥、令牌、数据库连接串。核心思路是正则匹配加熵值检测双层过滤。我知道正则会有很高的误报率所以脚本必须做两层判断先按特征正则匹配再用熵值判断字符串的随机程度最后过滤掉明显的示例代码和测试数据。#!/usr/bin/env python3 scan_secrets.py - 扫描仓库中的硬编码密钥与敏感信息 import re import os import math import argparse import pathlib # 常见高敏感关键词 KEY_PATTERNS { aws_access_key: r(?i)(AKIA[0-9A-Z]{16}), private_key: r-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----, github_token: r(?i)(gh[pousr]_[0-9A-Za-z]{36,}), generic_secret: r(?i)(api[_-]?key|secret|token|password|passwd)\s*[:]\s*[\][^\]{8,}[\], } EXCLUDE_DIRS {.git, node_modules, venv, .venv, dist, build, __pycache__} def shannon_entropy(s: str) - float: 计算字符串香农熵用于衡量随机度 if not s: return 0.0 freq {} for ch in s: freq[ch] freq.get(ch, 0) 1 length len(s) return -sum((count / length) * math.log2(count / length) for count in freq.values()) def scan_file(file_path: pathlib.Path) - list: results [] try: content file_path.read_text(encodingutf-8, errorsignore) except Exception: return results for name, pattern in KEY_PATTERNS.items(): for match in re.finditer(pattern, content): matched match.group(0) # 过滤明显的示例数据 if any(token in matched for token in [example, your_, xxxx, test]): continue line_no content[:match.start()].count(\n) 1 # 计算匹配串的熵低于阈值判定为普通变量名 entropy shannon_entropy(matched) if entropy 3.0 or name in (aws_access_key, private_key): results.append({ rule: name, file: str(file_path), line: line_no, match: matched[:40] (... if len(matched) 40 else ), entropy: round(entropy, 2), }) return results def main(): parser argparse.ArgumentParser(descriptionScan secrets in repository) parser.add_argument(path, nargs?, default., helprepository root path) args parser.parse_args() base pathlib.Path(args.path).resolve() findings [] for dirpath, dirnames, filenames in os.walk(base): dirs dirnames[:] for d in dirs: if d in EXCLUDE_DIRS: dirnames.remove(d) for filename in filenames: file_path pathlib.Path(dirpath) / filename findings.extend(scan_file(file_path)) for idx, f in enumerate(findings, 1): print(f[{idx}] {f[rule]} | {f[file]}:{f[line]} | {f[match]} | entropy{f[entropy]}) print(f\n总计发现疑似敏感信息 {len(findings)} 处) if __name__ __main__: main()熵值阈值的选型我踩过坑。开始设的是 3.5结果很多真实的 AWS Key 反而因为长度相近被判成低熵漏掉了后来又调到 3.0配合规则的固定前缀比如 AKIA、ghp_这些才平衡。这里想强调的是不要把熵值当成万能药更靠谱的思路是强特征前缀 长度检查熵值只做辅助过滤这就是代码里为什么对 aws_access_key 和 private_key 不要求熵值的原因。还有一个容易被忽略的问题git 历史里的敏感信息用普通文件扫描扫不出来所以我又加了一个模式让模型在 SKILL.md 里把 git log 的检查单独作为一阶段流程配合 git log -p 的输出喂给扫描逻辑。3.3 配套脚本依赖与配置检查依赖扫描脚本我做得比较轻核心是从 package.json、requirements.txt、pom.xml 这类文件里提取组件名和版本号再跟一个内置的风险版本清单比对。风险版本清单我维护在 reference/ 目录的 high_risk_patterns.md 里脚本只负责解析提取行为判断交给模型去读那份清单。这样设计的好处是依赖清单本身是数据脚本不承担语义判断更新规则时不用改代码改 markdown 文件就行维护成本低很多。配置检查脚本的核心逻辑则是盯几个高频高危配置数据库地址是否写死并出现在代码中、开启调试模式的后端服务、缺少认证的暴露接口等。这类检查很依赖上下文脚本只能做第一层发现可疑项最终判断还是应该交给模型结合项目场景去打分所以我给模型设置了明确的决策规则如果仓库是纯前端项目出现 DEBUGTrue 这种配置就不该列为高危最多提一句建议确认。同样的逻辑也适用于端口扫描一个本地开发文档里写了 3306 端口和一个生产配置文件里出现 0.0.0.0:3306风险等级完全不同这些判断必须由模型在理解了仓库用途之后做。这里还有一个细节依赖扫描不要只扫生产依赖开发依赖里的漏洞同样值得关注尤其那些有 CLI 入口的构建工具一旦被攻破影响面非常大。所以脚本提取依赖时会把 dependencies 和 devDependencies 都收进来但在报告里区分标注让模型判断要不要单独提升风险等级。这种细粒度的控制既体现了 skill 的价值也减少了无意义的告警噪音。3.4 参考文档与白名单策略reference/ 目录下的 high_risk_patterns.md 我维护了一份常见的高风险模式清单条目包括CVE 公告里反复出现的组件风险版本、常见密钥格式的样例、危险函数调用模式如直接拼接 SQL 字符串、使用不安全的反序列化接口、把日志打到公共目录。每个条目我都附带了一小段解释告诉模型为什么这是风险、判定时注意什么而不是只丢一个关键词清单。因为模型拿去直接用如果不知道背后的原理很容易把白名单里的正常代码误报。白名单策略也是不得不做的。任何安全扫描工具都有误报agent 在审计一个项目时如果总把测试代码里的 fake_key 报成高危报告的可信度会迅速下降。我的方案是在 SKILL.md 里写明白测试目录、mock 文件、fixtures 目录默认低优先级除非匹配到强特征比如真实私钥块否则不报。项目根目录的 .auditignore 文件可以用来忽略指定目录或文件。这个机制参考了 .gitignore 的思路实现成本很低但实际使用体验提升很大。白名单的维护同样有风险。如果我告诉模型测试目录可以忽略它可能为了省事把所有测试目录都忽略掉。所以我在 SKILL.md 里给了一条限制忽略前必须确认该目录下没有包含看起来像真实数据的文件如果测试文件里出现真实数据库地址或生产环境凭据必须报高危。这条约束一加误报缓解了盲区也堵住了。4. 实操全流程安装、调用与效果验证4.1 在Claude Code里安装使用在 Claude Code 中使用 skill 的流程很简单把 security-audit-skill 这个目录放到 ~/.claude/skills/ 目录下新版客户端也可以放到项目里的 .claude/skills/然后重新启动会话。启动后可以直接说对当前项目做一次安全审计Claude 会自动匹配到描述里的场景词加载 skill然后按照 SKILL.md 里的步骤执行。我特别注意了一下加载路径的优先级项目内 .claude/skills/ 会覆盖用户级 ~/.claude/skills/ 下的同名 skill。所以如果团队想统一安全审计规范推荐把 skill 直接放进项目仓库的 .claude/skills/ 里跟着代码一起走版本。这样每个开发者拉下代码后不需要额外安装审计标准也是统一的。个人自用的话放在用户级目录就好但要注意同名覆盖问题不同项目可能需要不同版本的审计规则这时项目级目录更合适。安装之后最好先跑一个冒烟测试找个已知有问题的仓库或者自己造一个带几个故意漏洞的测试项目跑一遍看 skill 能不能正常触发、脚本能不能正常执行、输出是不是符合预期。这一步非常关键很多 skill 的问题不是写的时候暴露的而是放到真实环境里才出现比如某个目录权限不够、某个脚本路径写死、某些文件编码解析失败。先把可控环境跑通再去审计真实项目会少很多排查的心智负担。4.2 在Codex、OpenCode等工具中使用这半年 Codex、OpenCode 都跟进了 skill 机制。Codex 的 skills 目录约定是项目下的 .codex/skills/OpenCode 也有自己的插件目录。大多数平台识别的都是同一个目录格式SKILL.md scripts 等。所以这份 security-audit-skill 基本可以做到一次编写、多平台复用。需要注意的差异主要是触发方式和文件读取权重。举个例子Codex 在解析描述时可能对中文描述的支持不如英文稳定所以我实际上在 SKILL.md 的 description 里同时放了一段英文描述。遇到中文描述匹配不上的问题加英文描述是成本最低的解决方式。OpenCode 的 skill 加载机制则更强调用户显式选择所以我在测试时发现它更稳定但少了一点自动触发的惊喜感。两者各有用处显式加载适合强制流程自动触发适合日常低门槛使用。如果你是在 CI 流水线里跑审计我建议优先用显式加载的方案确定性强、不容易误触发其他文件。跨平台复用时scripts 脚本的路径也要注意。有些平台执行脚本时的工作目录是项目根目录有些则是 skill 所在目录如果代码里用相对路径引用 reference 文件很容易出现找不到文件的问题。我的对策是在脚本里统一用file推导绝对路径这样不管从哪个目录被调用都能正确定位资源文件。这个问题不亲手试一次很难提前想到但我写下来之后后面复制到任何平台都少踩一次坑。4.3 实测效果与输出示例我在一个测试仓库上跑了一遍完整流程仓库结构是普通的 Node 后端项目故意埋了三处隐患一处 .env 文件里的数据库连接串、一处代码里写死的 GitHub Token、一处 package.json 里引用了过时版本。最终输出是从审计报告模板生成的核心结构大概是## 安全审计报告 ### 高严重度 1. 位置: .env:3 | 类型: 数据库连接串明文 发现: postgres://admin:secret123db.example.com:5432/prod 建议: 改用环境变量注入吊销并轮换该凭据 2. 位置: src/config.js:27 | 类型: GitHub Token 硬编码 发现: ghp_********已打码 建议: 立刻吊销该 token迁移到 CI 密钥管理服务 ### 中严重度 3. 位置: package.json:19 | 类型: 依赖版本过旧 发现: lodash4.17.19 存在已知漏洞 建议: 升级至 4.17.21 及以上 ### 低严重度 4. 位置: test/fixtures/api_key.txt | 类型: 疑似测试密钥 发现: 疑似 mock 数据已忽略 建议: 无需处理但请确认该文件不包含真实数据这个输出最大的好处是可以直接交差。风险等级清楚、定位到行、修复建议具体省掉了很多整理时间。我数了一下整个审计从发起请求到拿到报告大概不到三分钟其中大部分时间花在了脚本扫描和模型读取参考文档上。如果是人工审计光是翻完整个仓库的依赖清单和配置目录就要接近这个时间。当然skill 不是万能的它做的更多是把该看的都看一遍真正的安全思路和业务判断还是需要人来把关。5. 常见问题与排查技巧实录5.1 SKILL.md没有被识别这个坑我踩得很早。写好了 skill目录结构也放对了但对 Agent 说做一次安全审计完全没有反应。排查下来的原因是我在 SKILL.md 文件末尾写了一段无关的 memo破坏了 frontmatter 的解析Agent 整个把文件当成了普通 markdown 读技能自然没有激活。所以如果你的 skill 突然不生效第一步就是检查 SKILL.md 开头的 YAML 部分有没有多余字符、有没有把 description 写错缩进。另外还有几个容易被忽略的检查点目录名是否以 skill 结尾其实不影响识别关键是 SKILL.md 必须放在目录根下文件编码建议 UTF-8BOM 头在某些平台会引发读取异常多语言 description 中如果冒号后跟了中文某些解析器可能把整行截断我建议冒号后加空格再写内容。这类问题属于配置格式问题而不是skill 内容问题排查时要先分清是哪一类不然很容易在指令内容上反复折腾浪费时间。5.2 脚本执行权限与环境问题scripts 目录下的 Python 脚本经常遇到权限问题。在 macOS 和 Linux 上如果脚本没有执行权限Agent 调用时可能直接报 permission denied。我的处理方式是安装后先跑一遍 chmod x scripts/*.py或者在 SKILL.md 里写明执行脚本时使用 python3 scripts/xxx.py而不是 ./scripts/xxx.py后者其实更稳妥因为很多环境里系统将来可能换了 Python 解释器路径。我最后选了后者因为 skill 在团队里分发时不可能要求每个人都手动去 chmod。还有一类问题是依赖。scan_secrets.py 我只用了标准库这是有意为之。如果你在 skill 里引入了 requests、numpy 这类第三方库在离线的审计环境里装不上整个 skill 就废了。安全审计技能的使用场景经常是别人的生产代码仓库你没有权限也不应该往环境里装一堆依赖。所以能用标准库解决的问题坚决不引第三方库。这个原则也适用于配置检查脚本我全部用标准库和文件解析实现任何有 Python3 的环境都能直接跑零依赖才是技能包该有的姿态。5.3 误报与白名单策略调整即便做了熵值过滤误报依然存在。最常见的误报是把中文拼音变量名、Hash 值、JWT 片段当成密钥。JWT 的头部和签名部分都符合高熵特征很容易让正则误判。我的对策是把 JWT 的格式单独列出一条规则但不直接报高危而是提示疑似 JWT请确认是否应出现在源码中把最终判断交给模型的语义理解。这样既不会漏掉真实风险又不会因为一堆假阳性让使用者对报告失去信任。白名单的维护也要小心。.auditignore 文件不能随意加目录否则审计就有了盲区。我个人的建议是白名单只用于放行的理由必须写清楚比如virtualenv 目录第三方依赖无需审计。测试目录不要默认全部忽略因为测试代码里常出现真实测试数据库的地址和测试账号密码这些也是敏感信息。如果你发现某个白名单规则导致了真实风险被忽略要尽快把规则收紧否则这个 skill 的可靠性会大打折扣。5.4 不同平台的行为差异不同平台对 skill 的支持程度不完全一样表现出的问题也千奇百怪。在我测试过的工具里Claude Code 对长指令的遵循度最好基本能严格按 SKILL.md 里的五步走完Codex 有时候会跳步比如直接跑脚本不看 reference 文档导致判断结果缺乏细节OpenCode 的加载最稳定但触发机制更偏手动。因此你需要根据主要使用的平台对 skill 做一定程度的适配。针对跳步问题我后来在 SKILL.md 的指令里加了一句话每完成一个阶段把发现追加到一份中间结果文件最后统一汇总输出。这样即便 agent 在推理过程中走神至少中间结果文件还在报告质量不会崩得太厉害。这种方法实际上是借鉴了工程里的 checkpoint 思想用在控制 agent 行为上意外地好用。还有一点同一份 skill 在不同平台上的运行开销不一样。description 太长会导致每次对话都被加载浪费上下文窗口。我最后把 description 控制在一百多字足够触发又不至于太重。5.5 问题速查表为了便于参考我把调试过程中遇到的高频问题整理成一张速查表现象可能原因解决方式skill 完全没被触发SKILL.md 文件名或位置错误、YAML frontmatter 解析失败确认文件名和目录位置检查开头的 YAML 头格式触发了但不按流程执行SKILL.md 指令过长、关键步骤被淹没精简指令把细节移到 reference 目录脚本执行报错权限不足或依赖缺失用 python3 显式调用优先使用标准库输出里大量误报白名单策略过松、正则过于宽泛提高熵值阈值、补充 .auditignore 规则跨平台表现差异大description 匹配不稳定、脚本路径写死中英双语 description、脚本统一用绝对路径审计结果缺少细节模型跳过了 reference 文档在 SKILL.md 中增加中间结果 checkpoint看到表格里这些问题你会发现大部分都不是 skill 原理有多难而是工程细节堆出来的。写 skill 有点像写测试用例你要不断地给模型设定条件、给脚本加边界、给输出加规范最终让它在一个相对可控的范围内稳定输出。这个打磨过程比一开始写 SKILL.md 花的时间多得多但最后的价值也高得多。回头看这个 security-audit-skill 最让我受益的其实不是省了多少时间而是它逼我把安全审计的流程重新梳理了一遍。以前我接一个仓库习惯随手凭经验看文件夹里逛到哪看到哪经常漏东西写 SKILL.md 的过程等于把自己的经验强制成一个固定流程每次运行都在同一个检查框架下漏检就少了。后来我给 skill 加新规则的时候也会顺手把 reference 里的高风险清单更新一遍等于是把个人经验变成了团队资产。如果让我给正在研究 skill 的朋友一个建议不要一上来就写一个万能大技能找一个你最熟悉、重复次数最多、流程最固定的任务把它做成第一个 skill。做完一次你对skill 到底该怎么写的理解会比看十篇文档都深。后续如果想扩展可以考虑把审计结果自动同步到工单系统或者接入 CI 的上线检查流程那又是另一个故事了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价