尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

AI Agent技能化实战:从零封装一个安全审计Skill

发布时间:2026/9/24 23:28:55

资讯中心
01
ARTICLE

AI Agent技能化实战:从零封装一个安全审计Skill

AI Agent技能化实战:从零封装一个安全审计Skill
1. 为什么安全审计需要“技能化”1.1 安全审计的痛点不是扫描器不够而是流程太碎先交代一下背景。最近我在负责一个后端代码仓库的安全审计工作前后折腾了两周最大的感受不是扫描工具不够强而是整个审计流程碎得让人头疼。一般的安全审计大概包括这么几件事先要把项目依赖拉出来对照漏洞库查一遍然后跑静态代码扫描看有没有SQL注入、命令注入、敏感信息硬编码这类问题还要顺带检查一下配置文件有没有把密码写死、密钥有没有被提交到仓库里最后把所有结果整理成一份能交给开发团队去修的报告。每件事都有对应的现成工具比如依赖检查用trivy静态扫描用semgrep密钥检测用gitleaks。但工具之间的协作完全靠人工。跑完一个工具拿到一堆输出你还得手工去过滤误报、判断真伪、归类优先级然后把这些结论翻译成开发团队能看懂的修复建议。传统做法是写一堆shell脚本把这些命令串起来但脚本的问题是“死”的。它不知道当前仓库是什么语言、什么框架、有没有历史遗留问题需要排除也不会根据扫描结果动态调整后续动作。说白了脚本只能机械执行不能“想”。1.2 skill与agent的分工skill是“会做的事情”agent是“调度的脑”后来我接触到AI编程助手里的skill机制思路一下子打开了。这里的skill不是传统意义上的“技能树”而是给AI Agent用的、结构化封装好的能力模块里面通常包含说明文档、脚本、规则模板和示例输出。Agent可以在需要的时候自动加载这个skill按照skill里定义的流程去执行任务。很多人分不清skill和agent的区别我打个比方。Agent像一个项目的负责人它负责理解你的需求、拆解任务、调度资源、检查结果。Skill则像是负责人手下的施工班组操作手册里面清楚写了“遇到什么情况该用什么工具、按什么顺序执行、输出什么格式”。没有skill的Agent就像一个很聪明但没有任何工地经验的实习生你让它去检查脚手架安全它能跟你聊一堆安全理论但不知道实际该看哪里、量什么、记录什么。反过来说如果把安全审计的完整方法论固化成一个skillAgent就能按手册干活先收集依赖再跑静态扫描然后查密钥泄露最后汇总出报告。整个过程Agent负责调度和判断skill负责提供专业能力。1.3 为什么选security-audit作为第一个skill我之所以把security-audit作为第一个吃螃蟹的项目有三个原因。第一安全审计的流程边界很清晰。从输入一个代码仓库到输出一份审计报告中间每一步做什么都是约定俗成的非常适合固化成标准流程。相比如“做个新功能”这种开放性问题“审一遍这个仓库的安全性”是有限边界任务模型和skill都不容易跑偏。第二这个领域已经有大量成熟的命令行工具。trivy、semgrep、gitleaks、bandit这些工具输出稳定、文档齐全skill里只需要封装调用逻辑和结果解析逻辑不需要从零造轮子。第三安全问题天然适合大模型做二次分析。扫描器擅长“发现异常”但不擅长“判断这是不是一个真问题”。比如semgrep报了一个“可能存在的SQL注入”到底能不能被实际利用需要结合上下文判断。大模型恰好擅长这种推理。scan器负责筛模型负责断skill负责把两者串起来这个组合非常舒服。一句话总结我的思路把安全审计专家的执行流程和判断标准封装成Agent能读懂、能调用、能复用的技能包。2. security-audit-skill的核心设计2.1 skill的目录结构别小看文件摆放这件事Skill的目录结构是第一个要设计好的东西。我见过不少人写的skill功能逻辑没问题但目录乱成一锅粥Agent根本不知道先读哪个文件后跑哪个脚本。结构化、命名清晰是skill能被正确加载的前提。我用的目录结构如下security-audit/ ├── SKILL.md ├── scripts/ │ ├── audit_sast.py │ ├── audit_secrets.py │ ├── collect_deps.py │ └── report_builder.py ├── rules/ │ ├── custom_sast_rules.yaml │ └── audit_policy.json └── templates/ └── report_template.md几个关键点说明一下。SKILL.md是整个skill的入口和说明书Agent会优先读取这个文件来理解skill的用途和调用方式。scripts目录放所有可执行脚本每个脚本职责单一比如collect_deps.py只负责收集依赖清单audit_sast.py只负责跑静态扫描。rules目录放自定义规则和策略配置我自己加的semgrep规则会放在这里和工具默认规则区分开。templates目录放报告模板保证每次输出的审计报告结构一致这个对有报告洁癖的人来说很解压。目录结构设计的一个核心原则是让Agent在看到SKILL.md之后不需要问人就能知道“下一步执行哪个脚本”。所以脚本命名要直观不要出现a.py、b.py这种只有自己能看懂的命名。2.2 SKILL.md怎么组织让大模型知道什么时候该用、怎么用SKILL.md不是给人类看的开发文档而是给大模型看的“使用说明书”。这两者的写法有本质区别。人类文档追求严谨完整模型说明书追求“意图匹配清晰调用链明确”。我的SKILL.md结构大致是# Security Audit Skill ## 适用场景 - 对代码仓库进行安全审计包括依赖漏洞、代码缺陷、密钥泄露等 - 适用语言Python、JavaScript、TypeScript、Java、Go - 不适用的场景不负责修复代码漏洞只负责发现与建议 ## 依赖工具 - trivy依赖漏洞扫描 - semgrep静态代码分析 - gitleaks密钥泄露检测 - 需要提前安装并确保在PATH中可用 ## 审计流程 1. 先运行 scripts/collect_deps.py 收集依赖清单 2. 再运行 scripts/audit_sast.py 执行静态代码扫描 3. 然后运行 scripts/audit_secrets.py 检查密钥泄露 4. 最后运行 scripts/report_builder.py 汇总生成审计报告 ## 注意事项 - 所有脚本默认在仓库根目录执行绝对不要扫描node_modules或.venv目录 - 扫描结果会输出为JSON文件存放在 .audit-cache/ 目录下 - 如果已有前一天的结果缓存审计脚本会跳过未修改的文件增量模式 - 输出报告必须包含修复建议禁止只报问题不给方案注意看这个文件里有几个关键信息适用场景什么时候该用、依赖工具需要什么环境、审计流程怎么执行、注意事项有什么坑。这些内容的顺序和权重很有讲究。适用场景一定要写得具体不然会出现“用户问一处代码注释的黑客段子Agent也想去跑安全审计”这种尴尬情况。我一开始就是因为在SKILL.md里没写清楚适用场景结果Agent在我让它处理任何代码问题时都先跑一遍安全扫描简直灾难。注意事项是给模型划红线。比如规定不要扫描依赖目录否则一次审计能给你扫出几千个第三方库漏洞报告根本没法看。增量模式也很重要不然每次全量扫描仓库大了之后一次审计要跑十几分钟。2.3 规则与策略把经验固化成代码Skill除了流程还要把安全专家的判断经验固化下来。这部分我放在rules目录里。拿semgrep来说官方规则库很全但很多规则在你的项目里根本不适用。比如一个内部管理后台项目不太可能受到公开互联网攻击很多关于SSRF的规则实际威胁等级就偏低。所以我没有直接全量启用所有规则而是基于项目自身情况挑了一批高危规则再自己补几条针对性的自定义规则。我写了一个自定义规则文件截取一段Python相关的rules: - id: python-eval-usage patterns: - pattern: eval($ARG) message: 检测到eval()动态执行代码请确认参数来源。如果参数来自用户输入存在代码注入风险建议改用ast.literal_eval替代。 languages: - python severity: WARNING你可能觉得这条规则很简单但它很实用。eval()在Python里一直是个危险函数安全审计时看到就要重点确认。用semgrep规则把这类问题自动抓出来比我以前用grep搜eval再一个个看上下文要高效得多。还有安全策略配置文件audit_policy.json用来定义审计的优先级和阈值{ severity_weights: { critical: 10, high: 7, medium: 4, low: 1 }, threshold: 15, block_on: [critical, high], ignore_paths: [tests/, docs/, examples/] }这个文件的作用是给后面的流程决策用的。比如阈值设在15如果一次审计累计的高危问题超过这个数脚本就会在报告开头加上一句“本次扫描发现问题过多建议暂停发版优先处理安全问题”。这些都是把专家经验固化成机器可执行的策略。2.4 脚本层的设计稳定、可解释、容错脚本是skill的手脚。设计脚本时我最看重三个词稳定、可解释、容错。稳定是指脚本在仓库根目录下执行时不管目标是Python项目还是Node项目都能正常工作。实现方式是所有脚本内部先做一次项目类型检测根据包管理器的不同走不同分支。可解释是指脚本的输出必须是结构化的最好全程使用JSON。为什么因为Agent读JSON比读大段日志效率高得多。一个脚本的输出如果是“扫描发现3个高危问题具体如下”这种自然语言模型还要再解析一遍容易出错。JSON直接给模型它一眼就能看懂每个字段的含义。容错是指脚本不能因为某个小异常就崩掉。比如gitleaks报错说当前仓库没初始化git脚本不会直接退出而是记录一条warning然后继续跑semgrep。我把这个容错逻辑放到了脚本的核心循环里任何一步失败都只影响当前步骤不影响整体审计流程。results {} try: results[deps] run_dependency_scan() except Exception as e: results[deps] {error: str(e), issues: []} try: results[sast] run_sast_scan() except Exception as e: results[sast] {error: str(e), issues: []} try: results[secrets] run_secrets_scan() except Exception as e: results[secrets] {error: str(e), issues: []}虽然代码看起来很简单但这几个try-except是防止“一处报错全盘崩溃”的关键。很多时候安全审计跑在别人的仓库上你永远不知道会遇到什么奇葩环境容错设计能救命。3. 实操落地从零写一个能用的security-audit-skill3.1 环境准备工具不在多够用就行先说环境依赖。因为skill的核心是调用外部命令行工具所以先把工具装齐。# Python生态用来跑脚本逻辑 sudo apt-get install -y python3-pip # 依赖漏洞扫描器 sudo apt-get install -y trivy # 静态代码分析工具 python3 -m pip install semgrep # 密钥泄露检测工具 sudo apt-get install -y gitleaks # JSON处理工具脚本内部会用到 sudo apt-get install -y jq安装完之后验证一下工具是否都在PATH里which trivy semgrep gitleaks jq如果每个命令都返回了路径说明环境就绪。这里有个小提醒semgrep的版本迭代很快规则写法有细微差别建议在虚拟环境里安装别直接装到系统Python里不然以后升级容易把系统环境搞乱。3.2 编写SKILL.md内容样例我复制一份当时项目里实际用的SKILL.md你可以直接参考这个结构来写自己的版本# Security Audit Skill ## 适用场景 这个skill用于对代码仓库进行安全审计。它会检查依赖漏洞、静态代码缺陷、密钥泄露三类问题并根据发现的问题生成带修复建议的审计报告。 ## 触发条件 - 用户要求“安全审计”或“安全检查”或“security audit” - 用户提到“扫描一下代码有没有漏洞”“检查依赖是否安全”等类似表达 - 注意如果用户只是想了解安全审计的概念而不是要求实际扫一个仓库不要使用本skill ## 依赖工具 trivy、semgrep、gitleaks、python3、jq工具缺失时先提示安装再执行 ## 使用流程 1. 确认当前目录是仓库根目录 2. 执行 python3 scripts/collect_deps.py 收集依赖 3. 执行 python3 scripts/audit_sast.py 执行静态代码扫描 4. 执行 python3 scripts/audit_secrets.py 执行密钥泄露扫描 5. 执行 python3 scripts/report_builder.py 汇总生成报告 6. 把报告内容呈现给用户重点说明高危及以上问题 ## 输出要求 - 必须包含问题描述、文件位置、危险等级、修复建议 - 如果没有发现问题也要明确说明“未发现明显风险” - 报告生成后按照严重程度从高到低排序呈现 ## 注意事项 - 不要扫描 node_modules、.venv、vendor 等第三方目录 - 扫描过程中如果某个工具失败不要停止继续跑其他工具 - 不要把原始扫描日志全部贴给用户先汇总再展示 - 缓存目录 .audit-cache/ 属于临时文件报告生成后可以清理注意这里面的触发条件写了两层什么时候“应该用”什么时候“不应该用”。这是很多skill作者容易忽略的。光是“用什么”不够还要让模型知道“别乱用”。3.3 核心脚本的调用链脚本调用链这块我直接说明每个脚本的核心逻辑方便你照着实现。collect_deps.py的逻辑是先检测仓库里存在哪个包管理文件。如果发现requirements.txt就用trivy的requirements模式扫描Python依赖如果发现package-lock.json就用trivy的node模式如果发现go.mod就走gomod模式。然后输出一个JSON文件记录每个依赖的版本和已知漏洞。audit_sast.py的逻辑是调用semgrep加载初始规则集加上rules/custom_sast_rules.yaml里的自定义规则扫描当前目录下的代码文件。扫描完成后解析semgrep输出的JSON过滤掉ignore_paths中配置的目录把剩余问题汇总成结构化列表。audit_secrets.py的逻辑是用gitleaks的dir模式扫描整个仓库检测是否有密钥、密码、token等敏感信息被硬编码在代码里。检测到结果后脚本会做一步去重和排除处理比如排除测试文件中的假密钥。report_builder.py的逻辑是读取前三个脚本生成的JSON结果按严重程度排序套用report_template.md模板生成最终的Markdown报告。报告里每一条问题都给出了文件路径、行号、问题描述和修复建议。整个调用链设计成四个脚本串行而不是一个大脚本一次性做完所有事。好处是每一步的输出都是中间产物可缓存、可复查、可单独调试。如果semgrep扫描结果有问题你只需要重跑audit_sast.py不用把前面依赖扫描也重新跑一遍。3.4 在AI编程助手中注册与调用Skill写好之后怎么让Agent识别到它不同工具的配置方式不一样但大方向是统一的把skill目录放到指定的配置目录然后在对话中触发。以我用的环境为例在配置文件里注册skill目录指向我本地的security-audit/目录。注册成功后对话中只要提到类似“对当前项目做一次安全审计”Agent就会主动读取SKILL.md按流程开始执行。调用效果大概是这样的Agent先调用collect_deps.py我看到终端开始跑trivy扫描然后接着跑semgrep输出的问题列表会实时显示最后gitleaks扫描完毕Agent把汇总报告呈现在我面前。整个流程大概两三分钟比我手动逐个跑工具再自己写报告快了不止一个量级。有一个使用上的小技巧如果你只想让Agent审某个子目录可以直接说“只审计api/目录不审计前端代码”。因为SKILL.md里的ignore_paths是全局配置线程粒度的控制需要用自然语言约束Agent会结合你的要求调整semgrep的扫描路径参数。3.5 输出示例与人工复核一份合格的审计报告长什么样我截取一个实际跑出来的片段给你感受一下# 安全审计报告 扫描目标/data/projects/order-service 扫描时间2025-01-12 14:32:05 ## 高危问题 ### SQL注入风险 - 文件src/repository/order.py:78 - 问题描述使用f-string拼接SQL查询语句参数直接嵌入SQL存在注入风险 - 修复建议使用ORM参数化查询或使用?占位符禁止直接拼接字符串 ### 敏感密钥泄露 - 文件config/production.yaml:23 - 问题描述检测到疑似阿里云AccessKey Secret格式匹配 - 修复建议立即吊销该密钥改用环境变量或密钥管理服务存储报告呈现的时候Agent还会做一道人工复核的工序它会把semgrep报出的问题里那些明显误报先过滤掉比如一个测试文件里故意写的“eval”示例实际上根本没有外部输入Agent会在报告里备注“该问题疑似误报原因测试代码无用户输入路径”。这一步是纯脚本做不到的也是为什么skill要跟大模型配合而不是纯靠脚本跑的原因。4. 常见问题与排查实录4.1 skill没有被Agent识别这是最常见的坑。我把skill目录放在指定配置目录下之后一开始怎么触发都不生效Agent对我的“安全审计”请求完全无感只跟我聊安全概念不调用任何脚本。排查了一圈发现是两个原因造成的。第一目录名不对。我把目录命名成了security_audit下划线但Agent只会识别连字符格式的skill目录名。改回security-audit之后马上就被识别了。第二SKILL.md开头没写好。我一开始写的是“This document describes...”Agent读了之后把它当普通文档没有识别成skill定义。后来改成“# Security Audit Skill”这种明确的标题格式问题解决。如果你也遇到类似情况优先检查这两点大概率能解决。4.2 误报太多报告没法看用semgrep默认规则集扫一个中型项目第一次生成的报告有300多个问题其中大部分是低危和中危真正需要立即处理的高危问题其实只有十几个。误报多的时候不要轻易把规则集去掉那样会把真正的问题也漏了。我建议的做法是先跑一次全量扫描把结果保存一份然后不看低危问题只看高危和严重的问题。同时针对那些频繁误报的规则在audit_policy.json的ignore_paths里加上对应目录或者直接在semgrep的自定义规则配置里把某条规则标记为disabled。另外要做baseline。第一次审计时把所有存量问题标记为“已知问题”后续审计只关注新增问题。这个逻辑我在SKILL.md里通过缓存目录实现了增量模式跑起来之后报告的噪声一下子少了很多。4.3 上下文被撑爆Agent处理不过来还有一个很实际的问题扫描出来的原始结果可能是几千行JSON如果Agent把所有内容都塞进上下文窗口会直接把对话撑爆。Agent的处理能力再强给它几千个问题它也只能走马观花。我在report_builder.py的脚本里做了摘要逻辑如果某个类型的问题超过20条只输出前5条明细然后加一行“该类型另有N条类似问题已汇总为附件”。这样Agent拿到的上下文是浓缩过的既能看到问题全貌又不会淹没在海量细节里。这个优化做完之后生成报告的速度明显快了Agent的回复质量也更高因为它能把精力放在分析高危问题上而不是花时间逐条阅读几千条低危提示。4.4 扫描太慢跑一次要等很久我第一个版本是全量扫描一个代码量中等的仓库跑下来需要十几分钟简直不能忍。排查发现瓶颈在trivy每次都要重新拉取漏洞数据库而且还连带扫描了所有依赖目录。优化方案有三个我都用上了。第一给trivy配置数据库缓存路径不让它每次都下载。第二扫描前先用collect_deps.py生成依赖清单然后直接指定trivy只扫描这个清单文件不扫整个目录。第三把增量扫描的逻辑打开基于git的mtime判断哪些文件改过没改过的直接跳过。三个优化叠加一次审计从十几分钟降到了两分钟左右基本可用了。优化项做法效果数据库缓存设置TRIVY_CACHE_DIR持久化漏洞库减少重复下载依赖清单扫描先收集依赖清单再喂给trivy减少无关扫描增量模式只扫变更文件大幅缩短全量时间4.5 自定义规则逻辑正确但semgrep不执行写自定义规则的时候遇到过一个诡异问题规则文件语法检查通过但semgrep就是一条都匹配不到。后来发现是规则文件里的languages字段写错了。我写的是python但那个仓库其实是Python 3项目semgrep期望的语言标识是python没问题真正的问题是YAML文件里有一个字段值包含了未转义的双引号导致规则被静默跳过。排查方法先用semgrep --validate规则文件检查有没有报错再单独用一条极简规则测试确认semgrep能正常匹配最后再逐步调试复杂规则。别嫌麻烦这种问题排查起来比你想的更耗时间。5. 进阶把这个skill做成团队标准审计流水线5.1 与CI/CD结合审计自动化Skill在本地能用起来之后更大的价值是推进到CI/CD流水线里让每次代码提交自动跑安全审计。我用GitHub Actions做了一个示例配置核心逻辑是代码推送到main分支或提交Pull Request时自动检出代码安装工具跑security-audit skill把结果作为PR评论发布。name: Security Audit on: pull_request: branches: [ main ] jobs: audit: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - name: Install tools run: | pip install semgrep apt-get update apt-get install -y gitleaks trivy jq - name: Run security audit skill run: | python3 scripts/collect_deps.py python3 scripts/audit_sast.py python3 scripts/audit_secrets.py python3 scripts/report_builder.py - name: Post report to PR run: | cat .audit-cache/report.md $GITHUB_STEP_SUMMARY配合前面提到的baseline机制增量扫描在CI场景特别重要。没有baseline的话一个老仓库每次PR都会被历史问题刷屏开发人员很快会对审计报告免疫流水线就形同虚设了。5.2 多Agent协作场景审计与修复的闭环Skill封装的不只是“扫描”这一件事更是一个完整的协作协议。在我们的团队里我把审计流程做成了两个Agent协作的模式。安全Agent持有security-audit-skill负责扫描和出报告开发Agent负责根据报告修复代码。两个Agent之间通过“问题清单文件”协作安全Agent输出的每个issue都带了一个唯一的编号修复时按编号追踪。这个做法的好处是审计报告不只是一份记录而是一份可执行的任务清单。开发Agent拿到报告后可以针对高危问题逐条修复修完再跑一遍同一份skill看对应编号的问题是否消失。整个流程形成了一个闭环而不是单向的一次性审计。要做到这一点skill里的report_builder.py会在每个issue后面增加一个“验证命令”字段告诉Agent修复后怎么验证。比如SQL注入那条验证命令就是“重新执行semgrep确认该告警消失”。5.3 后续扩展思路从代码审计到全面安全检查目前这个security-audit-skill覆盖了依赖漏洞、静态代码缺陷和密钥泄露三个维度这已经覆盖了绝大多数应用层安全问题。但还是可以继续扩展我有几个已经验证可行的方向。一个是容器镜像扫描。如果你的服务是容器化部署可以在skill里增加一个镜像扫描步骤用trivy的image模式直接扫镜像文件把基础镜像的漏洞也纳入审计范围。一个是IaC配置审计用tfsec或checkov扫描Terraform、CloudFormation这类基础设施代码检查是否有暴露高风险端口、开启了公共访问权限之类的配置问题。还有一个方向是规则库的持续更新。目前skill里的自定义规则是我手动维护的semgrep的社区规则库也在持续更新我设置了一个每周任务自动拉取最新规则跟自定义规则合并后再跑一遍离线测试确保规则更新不会导致大量误报。这些功能都做完之后这个skill就不再只是一个工具脚本集合而是一个小型的团队安全基础设施了。最后分享一点自己的体会安全审计这个事以前总让人觉得是专家才能干的活。我做了这个skill之后最大的感受是专家经验可以被结构化和工具化然后在Agent的调度下发挥出规模化的价值。锦上添花的是当你把规则、策略、流程都固化下来之后团队的审计水平会明显向最好的那一次审计对齐而不是每次依赖不同人的经验发挥。如果你也想做一个类似的skill我的建议是不要一开始就追求大而全。先从一个最简单的SKILL.md配一个脚本开始跑通“Agent识别skill-调用脚本-输出报告”这条链路然后再逐步加规则、加工具、加增量优化。步子大了容易扯到蛋先小步快跑把一个垂直场景做到极致比做一个什么都沾一点但什么都不精的“全家桶”实用得多。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。