从 “security-audit” 这个技能点说起:最近我把安全审计这件事,从一份改不完的检查清单,重构成了一整套可复用的 AI Skill 包。说白了就是把我平时做代码审查、配置核查、依赖排查的那套思路,沉淀成了一份 Agent 能直接读懂、按步骤执行、还会主动停下来向我确认的动作手册。这个包我起名就叫security-audit-skill,核心不是为了炫技,而是解决一个很实际的问题:安全审计这类“知识密集 + 流程固定 + 产出标准化”的活,太适合交给 Skill 来干了。
这篇文章我准备完整拆一下我的设计思路、目录结构、每个审计环节怎么落地,以及我在真实项目里踩过的坑。不管你是刚接触 AI 编程助手、想给自己的 Agent 装个“安全大脑”,还是单纯好奇 Skill 这种新形态到底能干什么,这篇都值得你对照着抄作业。
1. 为什么是“Skill”:安全审计的 Know-How 密度刚好合适
聊具体方案之前,我想先把 Skill 到底是什么讲清楚。最近热词榜上 Skill 相关的讨论特别多,但你去看 Claude 的 Skill、Codex 的 Skill、opencode 的 Skill 甚至 Spring AI 的 Skill,它们的底层逻辑都是同一件事:把某个领域的专业知识和工作流程,以结构化文档 + 步骤脚本的形式,注入到 Agent 的上下文里,让它能按照你预设的方法论去干活。
1.1 Skill 不是脚本,也不是 Agent
很多人会问,Skill 和 Agent 到底什么区别?我的理解是:Agent 是能自主决策的“员工”,Skill 是这位员工手里的“作业指导书(SOP)”。Agent 负责调度、分解任务、调用工具,而 Skill 告诉你“安全审计到底该怎么一步步做”。
你可以把 Skill 理解成“可复用的领域方法论”:它不像插件那样硬编码在系统里,而是以自然语言 + 少量脚本的形式存在,Agent 在需要时加载它,然后照着里面的流程去执行。这意味着你可以今天用一个 Skill 做安全审计,明天换个 Skill 做数学建模,后天再换一个做会议纪要。它们彼此独立,互相不污染。
1.2 安全审计为什么适合做成 Skill
不是所有任务都适合封装成 Skill 的,但安全审计几乎是教科书级别的合适场景。原因有三:
- 流程高度标准化:安全审计虽然专业,但它的骨架是固定的。配置核查要看哪些文件、依赖扫描要跑哪些命令、代码审查要盯哪些缺陷模式、报告要输出什么格式,这些都是多年沉淀下来的共识,完全可以写成步骤。
- 知识密度高、细节多:审计的关键不在于“跑一个扫描器”,而在于“知道要查什么、查到之后怎么判断”。比如一个配置项是
AllowEncodedSlashes,它不是简单地“开或关”,你得知道在什么场景下开才是合理的。这种“判断力”恰恰是 Skill 能承载的,因为 SKILL.md 里可以写下所有判断条件和经验规则。 - 产出格式固定:安全审计的产出是一份结构化报告,包含发现项、风险等级、修复建议。这个格式非常适合用模板约束 Agent,只要在 Skill 里定义了报告模板,它每次输出的结构就不会跑偏。
所以我的结论是:Skill 最适合的场景,是那种“专家能讲清楚规则,但执行起来重复且繁琐”的工作。安全审计不是机械地扫一遍,而是规则 + 判断 + 报告的组合,刚好是 Skill 的主场。
2. 从零搭建 security-audit-skill 的目录与元信息
一个合格的 Skill 包,首先得有一个清晰的目录结构和一份能“指挥”Agent 的 SKILL.md。这一节我把我的目录设计和元信息写法完整放出来,供你直接照搬。
2.1 目录结构与 SKILL.md 骨架
我的security-audit-skill长这样:
security-audit-skill/ ├── SKILL.md ├── assets/ │ ├── report-template.md │ ├── finding-categories.md │ └── severity-matrix.md ├── scripts/ │ ├── scan-deps.sh │ ├── check-config.sh │ └── summarize-report.py └── references/ ├── owasp-top10.md ├── cwe-list.md └── secure-headers.md核心是SKILL.md,它决定了 Agent 拿到这个 Skill 后“先干嘛、后干嘛、哪些不能干”。我的写法是“Frontmatter(元信息)+ 流程正文”的结构,开头用 YAML 声明基础信息,后面用自然语言描述执行流程。
--- name: security-audit description: 面向 Web 应用与云上基础架构的安全审计。适合在代码审查、上线前检查、依赖风险排查等场景使用。能自动完成配置核查、依赖扫描、常见漏洞模式识别,并输出标准化审计报告。 version: 1.2.0 author: your-name tags: security, audit, code-review, dependency-check triggers: 安全审计、安全检查、security audit、帮我看看安全、上线前检查、依赖风险 dependencies: - bash - python3 - docker - trivy - semgrep --- # Security Audit 技能说明 本技能用于执行分层安全审计,覆盖四个层级: 1. 基础设施层:云平台与容器配置核查 2. 依赖层:第三方组件漏洞扫描 3. 代码层:源码级缺陷模式识别 4. 报告层:审计结果汇总与修复建议 执行时,遵循以下核心原则: - 每一步必须先收集原始信息,再下结论,不允许凭空猜测。 - 发现高严重度问题时,立即暂停流程并向用户确认,不要自行继续。 - 所有输出必须遵循 assets/report-template.md 模板。为什么要在triggers里写那么多触发词?因为 Skill 在 Agent 里是通过“意图识别”被调起来的,触发词越丰富,Agent 在听到“帮我看看这个项目安不安全”或“上线前帮我查一圈”时,越能准确唤起这个技能。这个点很多人会忽略,但实际用起来差别很大。
2.2 步骤编排:让 Agent 知道“先做什么,后做什么”
有了元信息之后,最关键的是在 SKILL.md 正文里把执行步骤写清楚。我的编排逻辑是“收集-分析-验证-报告”四段式:
- 第 1 步:收集审计范围。明确这次要审什么。是只审代码,还是连部署配置一起审?是单服务还是整个微服务集群?范围没定清楚,后面所有工作都是白做。我在这一步要求 Agent 先列出所有需要审计的文件、服务和配置项清单,并让我确认。
- 第 2 步:执行配置核查。对暴露面比较大的配置项进行检查,比如容器是否以 root 运行、云安全组是否全开放、数据库是否开启了公网访问、Web 服务器是否泄露了版本号等。这一步依赖
scripts/check-config.sh做自动扫描。 - 第 3 步:执行依赖扫描。用 OWASP Dependency-Check 或 Trivy 扫描项目依赖,找出有已知 CVE 的组件。这里尤其要注意生产环境依赖和开发环境依赖的区别,开发依赖的高危漏洞影响面通常要小一些。
- 第 4 步:执行代码层审计。这一步我会让 Agent 用 semgrep 跑一遍规则集,再结合人工经验对高风险模式做二次判断。
- 第 5 步:汇总报告并给出修复优先级。把所有发现项汇总成一张风险矩阵,按严重程度排序,每一条都写清楚“问题在哪、为什么是问题、怎么修”。
这样的编排逻辑在于:风险识别要有层次感。你不能上来就钻到代码里抠某个函数的边界问题,而应该先在外围把容易发现的问题扫干净(配置、依赖),再往核心走(代码逻辑),最后统一出报告。这样做的好处是,Agent 不会因为沉浸在某个局部细节里,而漏掉更全局性的风险。
3. 审计流程的核心环节拆解
有了流程骨架之后,我来说说每个环节具体怎么落地。这一节是实战部分,我会给出我在每个环节里的具体操作、判断标准和产出样例。
3.1 基础设施层:配置核查的要点
基础设施层核查的核心理念是“缩小攻击面”。我在scripts/check-config.sh里内置了一批高频高风险配置项的检查,包括但不限于:
| 检查项 | 风险说明 | 通过标准 |
|---|---|---|
| 容器是否以 root 运行 | root 权限容器被攻破后,等同于宿主机沦陷 | 非 root 用户运行 |
| 安全组/防火墙是否全开放 | 端口全开等于直接暴露在公网 | 仅放行业务所需端口 |
| 数据库公网访问 | 数据库暴露在公网上,容易被暴力破解 | 仅内网访问 |
| Web 服务版本信息泄露 | 版本号泄露方便攻击者匹配已知漏洞 | 隐藏版本号 |
| 敏感环境变量 | 密钥、Token 写在环境变量且被日志打印 | 密钥集中管理,禁止输出日志 |
这个脚本逻辑不复杂,核心是“扫描 + 输出 JSON”,方便后续报告阶段解析。我举个判断的例子:如果发现容器以 root 运行,风险等级直接评 High;但如果这是运维团队有意的选择,且已经通过 Linux capabilities 做了降权,我会在报告里备注“需人工确认是否接受该风险”而不是一刀切否定。
这一段的实操心得是:Agent 做配置核查很容易走极端,要么把一切非默认配置都当成风险,要么对严重的风险过于宽容。你必须先在 Skill 里给它明确的判断标准和阈值,尤其要写清楚“哪些情况是例外”。否则最后出来的报告就是一堆噪音,失去了可执行性。
3.2 依赖层:漏洞扫描与分级判断
依赖扫描是我认为 Skill 化收益最大的一步。传统流程是:拉一份依赖清单,去 NVD 或 OSV 查漏洞,再人工判断哪些漏洞真正影响当前项目。这套流程极其繁琐,完全适合让 Agent 执行。
我用的思路是:先导出依赖清单(Python 项目用pip freeze,Node 项目用npm list --json,Java 项目用mvn dependency:tree),再喂给 Trivy 或 OSV-Scanner 做比对,最后让 Agent 输出一张“漏洞影响矩阵”。关键是最后一步的人工判断环节,我会要求 Agent 对每个高危漏洞回答三个问题:
- 这个漏洞影响的组件,是直接依赖还是间接依赖?间接依赖的话,影响链路是什么?
- 这个漏洞公开披露的利用条件是什么?我们当前的使用方式是否满足?
- 是否有官方修复版本?升级会不会引入兼容性问题?
这三个问题本质上是让 Agent 从“报漏洞”升级到“判断风险”。同样一个 CVE,如果是开发环境的测试工具,风险可以接受;如果是生产环境核心模块,就必须马上处理。没有这个判断层,依赖扫描就只是罗列一个长长的清单,没有实际决策价值。
我在实际项目里用这个流程帮团队定位过一个典型的“间接依赖漏洞”:某个工具库依赖了一个老版本的 XML 解析器,这个解析器有已知的 XXE 漏洞。直接升级解析器会破坏工具库的兼容性,最终方案是等工具库官方升级并临时在调用层做输入过滤。这种判断在传统扫描工具里根本做不了,但有了 Skill 的推理能力,它能把“依赖关系 + 漏洞信息 + 业务形态”串在一起分析。
3.3 代码层:常见漏洞模式的自动化识别
代码层的审计是安全审计里最难自动化的一部分,因为优秀的代码审计不仅依赖规则,更依赖上下文理解。但代码审计适用的常见漏洞模式还是可以自动化识别的。业界有比较成熟的 SAST 工具和规则集,比如 semgrep、CodeQL、gosec、bandit 等。
我的做法是把 semgrep 作为第一道筛子,把以下这些高危模式作为必须检查的规则:
- SQL 注入:字符串拼接 SQL 语句
- 命令注入:把用户输入拼接到 shell 命令里
- 路径穿越:使用用户输入拼接文件路径
- 反序列化漏洞:直接反序列化不可信数据
- 硬编码密钥:代码里写死密码、Token、AK/SK
- SSRF:将用户输入的 URL 直接作为服务端请求地址
第二道筛子是让 Agent 逐个读这些规则的命中结果,结合上下文判断是真阳性还是误报。这个环节我给 Agent 的命令是“不要放过任何一个可疑点,但也不要冤枉任何一段正常业务代码”。比如一个 semgrep 命中“使用字符串拼接 SQL”,但代码里拼接的其实是用户 ID 且已被类型强转为整数,那这个发现项的风险等级就应该降为 Low 或直接标记为误报。
在这部分我最想强调的是:代码审计的产出不是“找到一堆 bug”,而是“给开发团队一个能直接照着改的清单”。所以每个代码层的发现项,我都会要求在报告模板里写明文件路径、代码行号、触发方式说明和一个修复示例。
4. 工程落地的关键参数与执行细节
把 Skill 做出来只是第一步,真正让它好用,还得在工程细节上下功夫。我这一节分享几个直接影响效果和成本的参数选择。
4.1 把审计拆成阶段,避免上下文窗口爆掉
AI Agent 的上下文窗口是有限的资源。安全审计这种任务,天然就特别容易产生大量上下文:依赖清单可能几百上千行,扫描结果可能几万个 token,代码文件可能一次性被读入好几十个。如果不做阶段拆分,还没跑到审计报告环节,上下文可能就满了。
我的解决方案是“分阶段注入”:
- 第一阶段只注入依赖清单摘要,不是全量输出,而是只列出“有高危漏洞的组件 + 版本号”;
- 第二阶段按需读取源码,只有命中规则的代码片段才被完整读入,不是把整个项目目录全部塞给 Agent;
- 第三阶段对单个发现项做专门分析,一次只处理一个漏洞,而不是一次性让 Agent 分析全部结果。
在实际操作里,我会要求 Agent 在处理依赖扫描结果时,统一输出成“组件名 | 版本 | 风险等级 | 漏洞数”的表格,只有高危项才展开细节。这样能用最少的 token 传递最多的信息。
4.2 控制审计粒度和 Token 成本
Token 成本是很多人初用 AI Agent 做专业任务最容易忽略的点。安全审计这种重活,一次深度审计消耗的 token 可能远远超出预期。我分享一下我的成本控制思路:
| 策略 | 具体做法 | 预期效果 |
|---|---|---|
| 缩小审计范围 | 只审最新变更的代码,不做全量审计 | Token 消耗降低 50% 以上 |
| 使用摘要代替原文 | 依赖清单、配置文件只传递关键字段 | 上下文占用减少 60% |
| 限制重复扫描 | 已在远程 CI 做过的检查不重复执行 | 避免无效计算 |
| 设置输出上限 | 报告只输出高、中、低三类发现,不罗列全部扫描记录 | 报告可读性大幅提升 |
特别想提醒的一点是:不要一上来就让 Agent “全面审计”,而是让它“按模块审计”。分模块跑,每轮结束保存中间结果,最后再汇总。这样既能控制单次任务的复杂度,又能在中间环节插入人工确认,发现跑偏可以及时纠正。
4.3 Skill 的版本管理与迭代经验
Skill 不是写一次就完事的,它必须持续迭代。尤其是安全领域,新的威胁模式不断出现,判断准则也要持续更新。我在security-audit-skill里维护了一个CHANGELOG.md,每次迭代都会记录“新增了哪个检查项、为什么加、影响的版本是什么”。
比如我最初只检查了 Dockerfile 的 USER 指令,后来发现实际部署里不少服务是通过 Kubernetes 的securityContext来限制权限的,于是就在配置核查里新增了 K8s SecurityContext 的检查项。再比如,之前只关注 NPM 依赖,后来前端项目开始用 pnpm,我又补充了对 pnpm-lock.yaml 的解析支持。
在版本约定上,我遵守一个原则:修改判断准则时,必须同时更新版本号。小改动(比如新增一条检查规则)用 minor 版本,大的流程变更(比如新增一个审计层级)用 major 版本。这样你在团队里分发 Skill 时,别人才能知道自己的本地副本是不是过期了。
5. 踩坑记录与复用心得
任何实操类的东西,真正有价值的部分都在坑里。我把这段时间使用security-audit-skill遇到的典型问题整理成了一个速查表,每个点都是真实踩过之后才总结出来的。
5.1 典型坑点速查表
| 问题 | 现象 | 解决思路 |
|---|---|---|
| Agent 高估风险 | 把所有偏离默认配置的项都标成 High,报告全是高危 | 在 Skill 里写入“例外场景”判断规则,标明哪些情况可降级 |
| 扫描命令执行失败 | 项目是 monorepo 结构,根目录跑依赖扫描时解析不到子项目 | 在 Skill 流程首步加入“项目结构识别”,自动定位子项目目录 |
| 误报过多 | semgrep 规则命中大量非安全问题,把真正的问题淹没了 | 在 Skill 里维护“白名单模式”,将业务专用的自定义函数加入白名单 |
| 上下文爆掉 | 审计到一半开始忘记前面的结论,报告质量明显下降 | 强制分阶段注入,每阶段只携带当前必要的上下文 |
| AI 产生幻觉 | 报告里编造了不存在的文件路径和漏洞 | 在 Skill 里强调“未在收集阶段获取的信息,不允许写入报告”;每一条发现项必须关联实际扫描证据 |
这里面最值得展开的是 AI 的自信问题。有一次审计一个 Node.js 项目,我在报告里发现 Agent “自动脑补”了一个文件路径,甚至断言那个文件里有 SQL 注入。但实际上那个文件在这个分支里根本不存在——它是从另一个分支“记忆”过来的。从那以后,我在 SKILL.md 里强制加了这样一条规则:
所有发现项必须包含可回溯的证据。代码层发现项必须附带文件路径、代码行号和代码片段;配置层发现项必须附带配置文件的原始键值。无法提供证据的发现项一律不允许出现在报告中。
这条规则写好之后,报告质量有了质的提升。它相当于堵住了大模型“自由发挥”的下限。
5.2 复用的经验:一个 Skill 出去,团队都能用
最后我想聊聊复用。初始我把这个 Skill 做成给个人用,后来发现团队里其他成员也在用,而且不同成员的需求差别很大。开发同学希望它能输出“直接可以照着改的修复建议”,运维同学希望它偏重配置核查和部署安全,测试同学则更关心越权、逻辑漏洞这类问题。
所以我又给security-audit-skill加了一个“审计模式”参数:
- 审计模式: full:全流程审计,适合上线前或季度巡检。
- 审计模式: dep-only:只做依赖扫描,适合日常依赖变更检查。
- 审计模式: code-only:只做代码审计,适合代码评审阶段。
- 审计模式: config-only:只做配置核查,适合部署前检查。
这个设计让同一个 Skill 能服务多类场景。日常开发用 dep-only 就够了,上线前跑 full,中间夹几次 code-only 做代码评审辅助。每一个模式都复用同一套目录、同一套报告模板,只是在流程上做了裁剪。
对我来说,把这个项目做成 Skill 最大的收获不是“AI 帮我干了很多活”,而是把一个原本存在人脑里的、口口相传的安全审计方法,变成了一种所有人能共享、能迭代、能复制的能力资产。后续我还在琢磨怎么把漏洞情报的新规则自动同步进 Skill,以及怎么让多个 Skill 之间可以互相调用,比如审计发现某个依赖有问题时,自动唤起“依赖升级”Skill 评估升级方案。
如果你也在折腾自己的 Skill,我的建议是:别贪大,先挑一个你自己最熟、流程最固定的工作开始封装。把你怎么判断、怎么决策、怎么出报告的细节全部写进去,跑通一遍之后再加复杂度。这个思路,比看一百篇 Skill 简介都管用。