Skill:從越權(quán)漏洞到CI/CD集成)
去年我在維護(hù)一個(gè)內(nèi)部服務(wù)時(shí)代碼評(píng)審階段發(fā)現(xiàn)支付回調(diào)接口埋著一個(gè)越權(quán)漏洞。更尷尬的是這段有問(wèn)題的代碼是AI編程助手生成的它能秒級(jí)寫(xiě)完業(yè)務(wù)邏輯卻完全沒(méi)意識(shí)到自己在處理敏感資源時(shí)需要校驗(yàn)歸屬權(quán)。從那天起我開(kāi)始琢磨一件事能不能把安全審計(jì)的能力做成一整套Agent隨時(shí)可調(diào)用的“技能包”讓AI不光會(huì)寫(xiě)代碼還能在寫(xiě)之前、寫(xiě)之后主動(dòng)幫我把安全隱患篩一遍。于是就有了security-audit-skill這個(gè)項(xiàng)目。這篇文章會(huì)把整個(gè)過(guò)程完整攤開(kāi)來(lái)講Skill在Agent生態(tài)里到底是什么、為什么安全審計(jì)特別適合做成Skill、一個(gè)可用的security-audit-skill內(nèi)部結(jié)構(gòu)長(zhǎng)什么樣、我是怎么在本地倉(cāng)庫(kù)和CI流水線里實(shí)測(cè)的以及中途踩過(guò)的誤報(bào)、漏報(bào)、上下文丟失這些坑。如果你正在用Codex、Claude、OpenCode這類(lèi)工具寫(xiě)代碼又不想把安全問(wèn)題全部押在事后人工評(píng)審上這篇內(nèi)容應(yīng)該能幫你少走不少?gòu)澛贰?. security-audit-skill到底在解決什么問(wèn)題1.1 代碼安全審計(jì)的痛點(diǎn)與現(xiàn)有工具的邊界代碼安全審計(jì)這件事傳統(tǒng)上基本靠三類(lèi)手段靜態(tài)分析工具SAST、依賴(lài)漏洞掃描、人工代碼評(píng)審。SAST類(lèi)工具像Semgrep、CodeQL、SonarQube優(yōu)點(diǎn)是規(guī)則嚴(yán)謹(jǐn)、覆蓋廣但問(wèn)題是誤報(bào)率不低而且很多規(guī)則只能抓“特征”抓不住業(yè)務(wù)流程里的邏輯漏洞。比如前面說(shuō)的越權(quán)問(wèn)題工具能看到你調(diào)用了getOrderById但它不知道這個(gè)訂單是不是屬于當(dāng)前登錄用戶(hù)這種上下文只能靠人去判斷。人工評(píng)審倒是能理解業(yè)務(wù)邏輯但成本高、周期長(zhǎng)而且在小團(tuán)隊(duì)里往往被壓縮成“上線前走個(gè)過(guò)場(chǎng)”。依賴(lài)漏洞掃描解決的是供應(yīng)鏈問(wèn)題對(duì)自研代碼的邏輯缺陷基本無(wú)能為力。你會(huì)發(fā)現(xiàn)傳統(tǒng)工具鏈在“靜態(tài)特征檢測(cè)”和“業(yè)務(wù)邏輯理解”之間存在一條明顯的空檔而大模型恰好擅長(zhǎng)理解意圖和上下文。這就是我決定把安全審計(jì)做成Agent Skill的出發(fā)點(diǎn)把SAST的規(guī)則嚴(yán)謹(jǐn)性和LLM的上下文理解能力結(jié)合起來(lái)。1.2 為什么是Skill而不是Plugin或者Agent熱詞區(qū)里有人在問(wèn)“skill和agent的區(qū)別”這確實(shí)是很多人剛接觸這個(gè)概念時(shí)最容易混淆的地方。我的理解直接說(shuō)Agent是一個(gè)能做決策、能循環(huán)執(zhí)行任務(wù)的“操作者”Skill是給這個(gè)操作者預(yù)裝的“能力包”。Agent負(fù)責(zé)拆解任務(wù)、調(diào)用工具、編排步驟Skill負(fù)責(zé)告訴Agent“面對(duì)某類(lèi)問(wèn)題時(shí)你有一整套成熟的應(yīng)對(duì)流程可以按這個(gè)來(lái)”。如果你把這個(gè)能力做成插件它會(huì)偏向于提供一個(gè)具體的函數(shù)或接口調(diào)用方得自己決定什么時(shí)候用、怎么用主動(dòng)權(quán)在調(diào)用方手里。但做成Skill主動(dòng)權(quán)在Agent手里當(dāng)它發(fā)現(xiàn)當(dāng)前任務(wù)涉及安全檢查時(shí)會(huì)自動(dòng)加載對(duì)應(yīng)流程。Plugin是“你叫它它才動(dòng)”Skill是“Agent根據(jù)任務(wù)上下文主動(dòng)想到用它”。至于把它做成一整個(gè)獨(dú)立的Agent那就太重了——安全審計(jì)通常只是研發(fā)流程的一個(gè)環(huán)節(jié)做成Agent反而難以和現(xiàn)有的Codex、Claude Code、OpenCode工作流無(wú)縫銜接。所以security-audit-skill的定位很清晰它不是替代人類(lèi)安全工程師的獨(dú)立系統(tǒng)而是給AI編程助手裝上的一套“安全審查工作記憶”。代碼寫(xiě)完了或者準(zhǔn)備提交了Agent能自覺(jué)進(jìn)入審計(jì)模式把可疑點(diǎn)一處處列出來(lái)給你看。2. 拆解Skill的運(yùn)行機(jī)制Agent怎么“學(xué)會(huì)”做安全審計(jì)2.1 Skill的核心組成SKILL.md與腳本資產(chǎn)的協(xié)作關(guān)系我在GitHub上參考過(guò)不少Skill項(xiàng)目也自己翻過(guò)一批skill技能庫(kù)發(fā)現(xiàn)一個(gè)靠譜的Skill基本都由兩大部分構(gòu)成面向Agent的指令文件和面向具體任務(wù)的腳本資產(chǎn)。指令文件通常叫SKILL.md它的作用不是給人讀的文檔而是給LLM的“工作手冊(cè)”。腳本資產(chǎn)則是實(shí)際干活的代碼比如掃描器、規(guī)則文件、報(bào)告模板。這兩者的關(guān)系我打個(gè)比方SKILL.md是帶班組長(zhǎng)的工作指令告訴Agent“這次任務(wù)的流程分幾步、每步有什么標(biāo)準(zhǔn)、遇到什么情況要停下來(lái)”腳本資產(chǎn)是工具箱里的扳手和螺絲刀Agent按指令判斷該擰哪個(gè)螺絲時(shí)就抽出對(duì)應(yīng)工具去執(zhí)行。沒(méi)有SKILL.mdAgent不知道什么時(shí)候該用這批腳本沒(méi)有腳本資產(chǎn)Agent只能靠自己的知識(shí)硬寫(xiě)規(guī)則質(zhì)量完全不可控。我見(jiàn)過(guò)一些人寫(xiě)的SkillSKILL.md只有三五行“你是一個(gè)安全審計(jì)專(zhuān)家”沒(méi)有任何流程和約束實(shí)際用下來(lái)Agent基本不會(huì)觸發(fā)偶爾觸發(fā)了也只是泛泛而談給不出具體文件和行號(hào)。真正好用的SkillSKILL.md一定要寫(xiě)得像SOP標(biāo)準(zhǔn)作業(yè)程序一樣明確。2.2 觸發(fā)與編排讓審計(jì)動(dòng)作在合適的時(shí)機(jī)自動(dòng)出現(xiàn)Skill能不能被Agent自動(dòng)想起來(lái)關(guān)鍵在SKILL.md里怎么描述觸發(fā)條件。這部分的寫(xiě)法直接決定你的Skill是“救命工具”還是“擺設(shè)”。我在多次實(shí)測(cè)后總結(jié)出一條經(jīng)驗(yàn)觸發(fā)條件描述要覆蓋“任務(wù)類(lèi)型”和“信號(hào)詞”兩層。任務(wù)類(lèi)型層是告訴Agent“這類(lèi)任務(wù)你應(yīng)該用我”比如“代碼審查”“安全審計(jì)”“上線前檢查”“提交前自查”。信號(hào)詞層是更細(xì)的提示比如“SQL查詢(xún)”“用戶(hù)輸入”“鑒權(quán)”“Token”“加密”“依賴(lài)”“日志脫敏”等等。當(dāng)用戶(hù)對(duì)Agent說(shuō)“幫我review一下這個(gè)改動(dòng)”Agent看到“review”這個(gè)詞再結(jié)合當(dāng)前改動(dòng)的代碼涉及用戶(hù)輸入拼接查詢(xún)就會(huì)主動(dòng)聯(lián)想到該加載security-audit-skill。編排層同樣重要。Skill一旦被激活A(yù)gent不能上來(lái)就亂掃一通得有步驟。我在SKILL.md里明確規(guī)定了執(zhí)行順序先收集項(xiàng)目結(jié)構(gòu)和變更文件列表再做靜態(tài)規(guī)則掃描然后讓模型對(duì)掃描結(jié)果做上下文研判最后輸出結(jié)構(gòu)化報(bào)告。這個(gè)順序一旦固定下來(lái)審計(jì)結(jié)果的可復(fù)現(xiàn)性會(huì)大幅提升。我剛開(kāi)始沒(méi)寫(xiě)執(zhí)行順序結(jié)果Agent每次跑的流程都不一樣有時(shí)候先分析業(yè)務(wù)邏輯有時(shí)候先掃依賴(lài)文件報(bào)告格式五花八門(mén)根本無(wú)法橫向?qū)Ρ取?. 手寫(xiě)一個(gè)可復(fù)現(xiàn)的security-audit-skill結(jié)構(gòu)3.1 目錄骨架與核心清單如果只是想要一個(gè)能跑的Skill不需要搞得很復(fù)雜。我的第一個(gè)可用版本包含一個(gè)目錄、三個(gè)文件結(jié)構(gòu)如下security-audit-skill/ ├── SKILL.md └── scripts/ ├── audit_rules.json ├── scan.py └── report_template.mdSKILL.md是Agent的行為指導(dǎo)告訴它什么場(chǎng)景下激活、按什么流程審計(jì)、需要注意哪些約束比如“不要在沒(méi)有證據(jù)的情況下斷言漏洞必須給出文件路徑和行號(hào)”。audit_rules.json是靜態(tài)規(guī)則的集合把常見(jiàn)高危模式按類(lèi)別組織好Agent可以加載它做初步篩查。scan.py是一個(gè)輕量腳本負(fù)責(zé)做兩類(lèi)事情一是列出倉(cāng)庫(kù)里的關(guān)鍵文件清單二是調(diào)用規(guī)則文件跑一輪正則和AST風(fēng)格的模式匹配把可疑代碼段定位到文件和行號(hào)。report_template.md是輸出的標(biāo)準(zhǔn)模板保證每次審計(jì)報(bào)告格式一致方便后續(xù)處理和歸檔。這個(gè)結(jié)構(gòu)理論上可以跑在任何支持Skill機(jī)制的Agent上。我實(shí)際測(cè)試過(guò)Codex和OpenCode也有人在Claude Code里裝過(guò)類(lèi)似的兼容性整體沒(méi)問(wèn)題。核心思路就是不要讓Agent自己從零編一套審計(jì)流程而是把所有流程和規(guī)則固化下來(lái)Agent只需要按圖索驥。3.2 檢測(cè)規(guī)則怎么寫(xiě)才不被Agent忽略規(guī)則文件是security-audit-skill的靈魂。寫(xiě)得不好Agent加載了也不當(dāng)回事。我第一版規(guī)則只有一張簡(jiǎn)單的關(guān)鍵詞列表比如“password”“token”“select”結(jié)果Agent掃描的時(shí)候把所有帶這些詞的代碼全標(biāo)紅了報(bào)告完全沒(méi)法看。后來(lái)我改成了結(jié)構(gòu)化規(guī)則每一條包含規(guī)則ID、風(fēng)險(xiǎn)類(lèi)別、嚴(yán)重級(jí)別、匹配模式、上下文判斷要點(diǎn)、修復(fù)建議。這里貼一個(gè)我實(shí)際在用的例子{ rule_id: AUDIT-SQLI-001, category: injection, severity: critical, patterns: [ executeQuery, executeUpdate, rawQuery, $query, \\$qb-expr() ], context_hints: [ 判斷拼接進(jìn)SQL的字符串是否來(lái)自HTTP請(qǐng)求參數(shù), 檢查是否使用了預(yù)編譯語(yǔ)句如果沒(méi)有判定為可疑, 如果SQL片段里有直接拼接的變量名必須標(biāo)記出來(lái) ], recommendation: 使用參數(shù)化查詢(xún)或預(yù)編譯語(yǔ)句禁止直接拼接SQL }關(guān)鍵點(diǎn)在于context_hints這一段。我的做法是腳本掃描出候選位置后把這一段的代碼片段連同context_hints一起交給LLM。Agent讀到“來(lái)自HTTP請(qǐng)求參數(shù)”“是否預(yù)編譯”這兩個(gè)提示就能基于上下文做出判斷而不是機(jī)械地見(jiàn)executeQuery就報(bào)警。這樣一套組合拳下來(lái)誤報(bào)率明顯下降報(bào)告里能說(shuō)出“為什么可疑”而不只是“這里有這個(gè)函數(shù)”。還有一點(diǎn)值得強(qiáng)調(diào)規(guī)則描述里必須明確“什么時(shí)候不要報(bào)”。比如很多代碼里寫(xiě)日志時(shí)會(huì)打印用戶(hù)郵箱這不算敏感信息泄露但如果打印的是身份證號(hào)、支付賬號(hào)就要標(biāo)記為中等風(fēng)險(xiǎn)。LLM需要這些邊界才能做出準(zhǔn)確判斷別讓它猜。3.3 輸出報(bào)告格式設(shè)計(jì)審計(jì)報(bào)告格式是我調(diào)整次數(shù)最多的部分。一開(kāi)始Agent自己生成markdown報(bào)告結(jié)構(gòu)還算清晰但不同輪次跑出來(lái)的字段名不統(tǒng)一有的寫(xiě)“嚴(yán)重級(jí)別”有的寫(xiě)“風(fēng)險(xiǎn)等級(jí)”對(duì)接到后續(xù)工單系統(tǒng)時(shí)很麻煩。后來(lái)我干脆用模板把它定死報(bào)告必須包含以下區(qū)塊審計(jì)概覽項(xiàng)目名、審計(jì)時(shí)間、掃描文件總數(shù)、問(wèn)題總數(shù)、按嚴(yán)重級(jí)別分布嚴(yán)重/高/中/低問(wèn)題列表每條包含問(wèn)題ID、風(fēng)險(xiǎn)類(lèi)型、嚴(yán)重級(jí)別、文件路徑、行號(hào)、問(wèn)題描述、上下文證據(jù)、修復(fù)建議未發(fā)現(xiàn)問(wèn)題的重點(diǎn)區(qū)域按SKILL.md里的關(guān)鍵詞清單列出哪些高風(fēng)險(xiǎn)區(qū)域已經(jīng)排查過(guò)且未發(fā)現(xiàn)問(wèn)題方便評(píng)審人知道Agent確實(shí)覆蓋了哪些范圍補(bǔ)充觀察Agent在上下文研判中發(fā)現(xiàn)但不完全確定的問(wèn)題單獨(dú)放一個(gè)“低置信度提示”避免混入正式問(wèn)題造成干擾報(bào)告格式定死之后還有一個(gè)額外的好處你可以寫(xiě)一個(gè)后續(xù)任務(wù)讓Agent把報(bào)告內(nèi)容自動(dòng)填到某個(gè)表格或者Issue模板里字段能一一對(duì)應(yīng)上。安全團(tuán)隊(duì)跟進(jìn)問(wèn)題的時(shí)候不用再?gòu)囊欢紊⑽睦锸謩?dòng)提煉信息。4. 實(shí)測(cè)鏈路從本地代碼倉(cāng)庫(kù)到審計(jì)報(bào)告4.1 環(huán)境準(zhǔn)備與Skill裝載我先說(shuō)明一下測(cè)試環(huán)境機(jī)器是MacBook Pro安裝了Codex的CLI版本同時(shí)也用OpenCode跑過(guò)一遍兩個(gè)環(huán)境下的表現(xiàn)基本一致。Skill的裝載方式不同工具略有差異但原理相同——把Skill目錄放在Agent能掃描到的配置路徑中或者用支持的命令手動(dòng)裝載。以Codex為例你可以在配置里指定skill目錄也可以直接在會(huì)話中用命令加載某個(gè)skill。這里有一個(gè)新手特別容易踩的坑裝完Skill之后一定要開(kāi)一個(gè)新會(huì)話驗(yàn)證Agent能否正確識(shí)別。Agent的上下文是會(huì)話級(jí)的你在舊會(huì)話里裝好的Skill舊會(huì)話可能不會(huì)主動(dòng)刷新加載容易誤以為“Skill壞了”。我一般會(huì)在裝完后問(wèn)一句“你現(xiàn)在有哪些可用的skill分別適用什么場(chǎng)景”讓Agent復(fù)述一遍確認(rèn)它真的讀到了SKILL.md里的內(nèi)容而不是我還停留在理想狀態(tài)。4.2 完整執(zhí)行過(guò)程與結(jié)果解讀我用一個(gè)模擬了常見(jiàn)漏洞的測(cè)試倉(cāng)庫(kù)來(lái)做演示。倉(cāng)庫(kù)是Python寫(xiě)的一個(gè)Flask應(yīng)用含一個(gè)登錄接口、一個(gè)訂單查詢(xún)接口、一個(gè)數(shù)據(jù)庫(kù)訪問(wèn)模塊。我在里面人為埋了幾個(gè)典型問(wèn)題登錄接口里SQL拼接、訂單查詢(xún)接口沒(méi)校驗(yàn)用戶(hù)歸屬、日志里打印了明文密碼字段、requirements.txt里出現(xiàn)了一個(gè)存在已知漏洞的舊版本庫(kù)。實(shí)際執(zhí)行時(shí)我讓Agent“review這個(gè)項(xiàng)目的代碼重點(diǎn)關(guān)注安全問(wèn)題”。Agent成功加載了security-audit-skill然后按SKILL.md流程先掃描文件清單隨后調(diào)用scan.py跑規(guī)則找到可疑位置再結(jié)合上下文逐條研判。最后產(chǎn)出的報(bào)告里四個(gè)問(wèn)題全部命中并且SQL注入那條被標(biāo)成了嚴(yán)重級(jí)別越權(quán)那條標(biāo)為高日志脫敏問(wèn)題標(biāo)為中依賴(lài)漏洞標(biāo)為高。文件路徑、行號(hào)、修復(fù)建議全部對(duì)得上。有個(gè)細(xì)節(jié)讓我印象很深A(yù)gent在研判越權(quán)問(wèn)題時(shí)自己去看了一眼這個(gè)接口路由有沒(méi)有裝飾器做登錄校驗(yàn)發(fā)現(xiàn)只有登錄校驗(yàn)沒(méi)有歸屬校驗(yàn)然后在報(bào)告里寫(xiě)了一條“雖然接口要求登錄但并未校驗(yàn)訂單歸屬存在IDOR風(fēng)險(xiǎn)”。這說(shuō)明只要上下文給得足LLM是真的能理解邏輯漏洞而這恰恰是傳統(tǒng)SAST工具最難啃的部分。4.3 誤報(bào)、漏報(bào)與上下文丟失的應(yīng)對(duì)實(shí)測(cè)中不可能全是順利的。我遇到的第一類(lèi)問(wèn)題是誤報(bào)典型場(chǎng)景是測(cè)試代碼里大量使用Mock數(shù)據(jù)字符串里包含“select * from users”這種SQL片段但其實(shí)是測(cè)試用例不是真實(shí)查詢(xún)。剛開(kāi)始Agent會(huì)把這些標(biāo)成“疑似SQL注入”。后來(lái)我在SKILL.md里加了一條約束“如果可疑代碼位于test/、tests/、mock/、fixtures/目錄應(yīng)降級(jí)為觀察項(xiàng)不計(jì)入正式問(wèn)題列表?!闭`報(bào)率一下降了七成。第二類(lèi)問(wèn)題是漏報(bào)多發(fā)生在代碼文件特別多的時(shí)候。Agent受上下文窗口限制可能只仔細(xì)看了前幾個(gè)文件后面的文件草草帶過(guò)。我后來(lái)在SKILL.md里明確要求“先掃描項(xiàng)目結(jié)構(gòu)如果文件數(shù)量超過(guò)20個(gè)必須分批審計(jì)每一批都要在報(bào)告中記錄覆蓋狀態(tài)?!蓖瑫r(shí)要求scan.py輸出一份完整文件清單Agent審計(jì)完一批勾選一批避免遺漏。第三類(lèi)也是最有代表性的問(wèn)題上下文丟失。有一次在一個(gè)大型Java項(xiàng)目里跑Agent分析到一半突然忘了自己加載過(guò)security-audit-skill開(kāi)始用普通“代碼解釋”模式跟我聊天報(bào)告格式完全走樣。排查了半天發(fā)現(xiàn)是因?yàn)镾KILL.md太長(zhǎng)Agent讀到后面注意力被其他任務(wù)占用了。解決辦法是把SKILL.md精簡(jiǎn)到核心SOP把冗長(zhǎng)的規(guī)則細(xì)節(jié)全部挪到audit_rules.json和scripts里讓SKILL.md只承擔(dān)“流程指揮”的角色。這個(gè)調(diào)整之后上下文丟失的情況明顯減少。5. 從“能用”到“好用”的進(jìn)階經(jīng)驗(yàn)5.1 讓審計(jì)規(guī)則可配置化跑到第二周我開(kāi)始不滿(mǎn)足于固定的內(nèi)置規(guī)則。不同項(xiàng)目的風(fēng)險(xiǎn)側(cè)重點(diǎn)差別很大給支付系統(tǒng)做審計(jì)重點(diǎn)看金額計(jì)算、冪等性、回調(diào)驗(yàn)簽給內(nèi)容社區(qū)做審計(jì)重點(diǎn)看XSS、用戶(hù)生成內(nèi)容的展示轉(zhuǎn)義給內(nèi)部管理系統(tǒng)做審計(jì)重點(diǎn)看越權(quán)和敏感數(shù)據(jù)查詢(xún)。由于每個(gè)項(xiàng)目的代碼風(fēng)格和業(yè)務(wù)形態(tài)不一樣固定規(guī)則很難滿(mǎn)足所有場(chǎng)景。我的做法是引入一個(gè)audit_profile.json配置層允許按項(xiàng)目覆蓋規(guī)則。每個(gè)項(xiàng)目根目錄下放一個(gè)審計(jì)配置文件里面可以指定啟用哪些規(guī)則類(lèi)別、額外添加哪些關(guān)鍵詞模式、忽略哪些目錄。scan.py在運(yùn)行時(shí)先讀取項(xiàng)目配置再疊加內(nèi)置規(guī)則形成一份“項(xiàng)目專(zhuān)屬規(guī)則集”。SKILL.md里也寫(xiě)了一段如果發(fā)現(xiàn)項(xiàng)目根目錄有audit_profile.json優(yōu)先使用它覆蓋默認(rèn)規(guī)則。這樣做的收益很直接不同團(tuán)隊(duì)可以直接共享同一個(gè)Skill但每個(gè)項(xiàng)目有自己的審計(jì)策略。規(guī)則集不再是僵死的而是隨項(xiàng)目演進(jìn)的資產(chǎn)。有同事問(wèn)我這算不算把Skill變成配置驅(qū)動(dòng)的框架我說(shuō)對(duì)這個(gè)階段你已經(jīng)不是在“寫(xiě)死規(guī)則”了而是在建設(shè)一套組織級(jí)的安全審計(jì)基線。5.2 和CI/CD流水線的結(jié)合本地跑通之后我很快意識(shí)到真正發(fā)揮價(jià)值的地方是CI流水線。人的自覺(jué)性不可靠但流水線不會(huì)偷懶。我的做法是寫(xiě)了一個(gè)小的命令行入口能讓Agent在離線環(huán)境下對(duì)指定代碼變更集運(yùn)行審計(jì)。注意CI環(huán)境一般沒(méi)有交互式會(huì)話所以命令行入口必須支持非交互模式接收一個(gè)diff或提交范圍輸出報(bào)告文件。實(shí)際流水線里我是這樣接的在Pull Request觸發(fā)后CI執(zhí)行一次“新增或變更文件的增量審計(jì)”把報(bào)告上傳到GitHub Action的artifact如果有嚴(yán)重級(jí)別的問(wèn)題直接讓CI標(biāo)記為失敗阻止合并。最開(kāi)始團(tuán)隊(duì)成員擔(dān)心誤報(bào)會(huì)拖慢合并速度于是我加了一個(gè)“細(xì)微閾值”配置只有嚴(yán)重和高等級(jí)問(wèn)題才阻斷流水線中低等級(jí)問(wèn)題只出現(xiàn)在報(bào)告里提醒開(kāi)發(fā)者處理。這樣既守住了底線又不至于讓AI審計(jì)變成開(kāi)發(fā)流程的瓶頸。這套流程跑了一個(gè)多月最直觀的效果是人工評(píng)審時(shí)不再需要花時(shí)間找低級(jí)的注入問(wèn)題可以把注意力放到業(yè)務(wù)邏輯和架構(gòu)合理性上。AI審計(jì)把“下限”兜住了人工評(píng)審專(zhuān)注“上限”的優(yōu)化。5.3 我踩過(guò)的坑與最終建議最后集中說(shuō)幾個(gè)踩過(guò)的坑。第一個(gè)坑是Skill里塞了太多領(lǐng)域知識(shí)導(dǎo)致SKILL.md巨長(zhǎng)Agent加載后占用大量上下文窗口反而沒(méi)空間去看代碼了?,F(xiàn)在我的原則是SKILL.md控制在兩百行以?xún)?nèi)領(lǐng)域知識(shí)放到腳本或參考資料里需要的時(shí)候再按需讀取。這就像你給新員工發(fā)手冊(cè)手冊(cè)目錄寫(xiě)清楚就行別把整本手冊(cè)背下來(lái)。第二個(gè)坑是規(guī)則誤傷業(yè)務(wù)特例。比如有些項(xiàng)目會(huì)把日志加密密鑰放在配置文件里掃描器看到“key ...”就報(bào)警但人家這是有意的設(shè)計(jì)。應(yīng)對(duì)方法是在audit_rules.json里支持“白名單模式”允許項(xiàng)目聲明哪些路徑、哪些變量名是已知可接受的掃描時(shí)直接跳過(guò)。這能顯著減少團(tuán)隊(duì)對(duì)AI審計(jì)的“狼來(lái)了”疲勞。第三個(gè)坑也是最玄學(xué)的就是Agent模型的版本差異。同一個(gè)Skill在不同模型版本下表現(xiàn)波動(dòng)很大有時(shí)候突然像換了一個(gè)人規(guī)則執(zhí)行得七零八落。我能給的建議是把SKILL.md里的關(guān)鍵指令寫(xiě)得更“笨”一些比如“遇到關(guān)鍵字的文件必須逐個(gè)列出文件名和行號(hào)不得只寫(xiě)文件名”這種傻瓜式指令在任何模型下都不容易被忽略。另外重要的審計(jì)結(jié)論一定要有腳本輸出的結(jié)構(gòu)化數(shù)據(jù)作為支撐不能只靠模型“覺(jué)得有問(wèn)題”。最后一個(gè)建議別指望Skill是銀彈。它能把安全審計(jì)的覆蓋面擴(kuò)大、讓普通開(kāi)發(fā)者也能獲得接近專(zhuān)業(yè)審計(jì)師的初篩能力但替換不了專(zhuān)業(yè)安全人員對(duì)復(fù)雜業(yè)務(wù)風(fēng)險(xiǎn)的設(shè)計(jì)判斷。我現(xiàn)在的用法是“AI做初篩人做復(fù)核”兩者組合安全效率提升明顯風(fēng)險(xiǎn)也控得住。如果你也在搭自己的Agent工作流建議不要把Skill定義成“檢查者”而是定義成“輔助你思考的搭檔”那才是它真正發(fā)光的地方。