開源AI 安全Prompt Injectionlessons-learned

12 次提交、0 次合併:我在開源 AI 安全社群學到的事

· 12 分鐘閱讀
目錄
  1. 大撒網
  2. 為什麼全部失敗
  3. 錯誤一:用同一把鑰匙開所有的門
  4. 錯誤二:做好了再問
  5. 錯誤三:跟錯人
  6. 錯誤四:工具本身不夠格
  7. 轉折
  8. 先讀 code,再寫 code
  9. 同時打磨工具
  10. 正確回覆那個紅隊測試框架
  11. 第一個 Merge
  12. 目前的狀態
  13. 給正在被拒的人
  14. 這篇文章會更新

我們做了一個 LLM prompt 防禦掃描器:prompt-defense-audit。掃描系統提示詞,用純 regex 偵測 12 種攻擊向量是否有防禦。不用 LLM、不用 API、5 毫秒跑完。

背後有實際資料:從 4 個公開資料集掃了 1,646 個正式環境系統提示,發現 97.8% 沒有間接注入防禦,平均分數 36/100。

我們覺得這個研究有價值,決定貢獻回開源社群。

然後花了兩週學到一個痛苦的教訓。


大撒網

我們向 12 個開源專案提交了 PR 或 Issue:

專案 類型 結果
一個大型 LLM 紅隊測試框架(7,500⭐) PR 被關閉
Cisco AI Defense skill-scanner Issue #81 被關閉
OWASP LLM Top 10 PR #816 無回應
Anthropic cookbook PR #502 無回應
Microsoft agent-governance-toolkit Issue #821 後來有回應
Microsoft presidio Issue #1933 無回應
awesome-llm-security PR #134 無回應
awesome-ai-tools PR #1031 無回應
Awesome-Prompt-Engineering PR #91 無回應
agent-audit Issue #5 無回應
一個 LLM 護欄框架 Issue #1764 無回應

12 個提交。0 個合併。2 個直接被關。9 個沒人理。


為什麼全部失敗

回頭看,原因很明確。

錯誤一:用同一把鑰匙開所有的門

我們把同一套 YAML 格式的「防禦姿態 pattern」提交給不同的專案。每個專案都有自己的架構、自己的程式語言、自己的 plugin 格式。我們完全沒有去理解。

那個紅隊測試框架是 Python 寫的,核心概念是 Probe(產生攻擊)和 Detector(評估回應),用 class 繼承、有 detect() method、要跑 pytest。

我們提交了 6 個 YAML 檔案。

維護者的回覆很直接:這個 PR 完全沒有試著遵循該專案的使用方式與程式碼規範,因此婉拒。

他說得對。我們提交了一份規格書,但他們要的是可以跑的 Python 模組。

錯誤二:做好了再問

那個專案的創建者其實有在 issue 裡問我們一個問題:

"Can you give references to the principles behind the defense assessment approach & quantification method?"

我們沒有回答這個問題,就直接開了 PR。

這等於跳過了「取得共識」的步驟。在開源社群,這是大忌。你應該先在 issue 裡討論方向、確認架構適配,拿到某種程度的認可,然後再寫 code。

「做好了再問」在開源社群不是效率,是傲慢。

錯誤三:跟錯人

在那個專案的 issue 討論中,一位獨立研究者(不是該專案的維護者)很熱情地回應,說「go ahead and open that PR against community_modules/contrib/」。

我們照做了。但那個目錄結構是他自己 repo 的,不是該專案的。他沒有 merge 權限。

教訓:確認你在跟誰對話。熱情 ≠ 權限。

錯誤四:工具本身不夠格

當維護者點進我們的 prompt-defense-audit repo,他們看到:

  • 3 顆星
  • 3 個 commits
  • 0 個 CI/CD
  • 0 個 test framework(只有一個手寫 assert 的檔案)
  • 沒有 CONTRIBUTING.md
  • 沒有 SECURITY.md:一個安全工具,沒有安全政策

這看起來像是一個週末的 side project,不像是一個值得整合進企業級工具的函式庫。


轉折

Cisco AI Defense 的 skill-scanner 拒絕了我們的 issue,但維護者 vineethsai7 說了一句關鍵的話:

"I don't think this is part of the scope of skill-scanner. If you think the MCP specific ones can fit in the MCP scanner, please open a PR there!"

他把我們導向了 mcp-scanner。

這次我們換了方式。

先讀 code,再寫 code

我們花時間讀透了 mcp-scanner 的架構:它的 threat detection 模組怎麼寫、test 怎麼跑、Python code style 是什麼。然後用他們的語言寫了一個 Prompt Defense Analyzer,不是用我們自己的 YAML 格式。

同時打磨工具

我們把 prompt-defense-audit 從玩具升級到專業:

  • 手寫 assert → Vitest,84 個測試,100% coverage
  • 沒有 CI → GitHub Actions,Node 20/22 matrix,badge 亮綠燈
  • 沒有文件 → CONTRIBUTING.md、SECURITY.md、CHANGELOG.md、issue templates
  • 3 個 commits → 有 release notes 的 v1.3.0

正確回覆那個紅隊測試框架

回到那個專案的 issue,我們回答了創建者的方法論問題:

  • 附上學術引用(Greshake et al. 2023 間接注入、Schulhoff et al. 2023 注入分類學、OWASP LLM Top 10)
  • 承認 PR 架構錯誤
  • 提出兩個用 Python probe/detector 重做的方向
  • 明確說「我想先取得共識再寫 code」

然後等。


第一個 Merge

Cisco mcp-scanner PR #146,從開 PR 到合併:51 分鐘。

說實話,這不是一個高難度的技術成就。mcp-scanner 是新專案,積極吸收貢獻,門檻相對低。我們的 PR 是純新增(955 行新增、0 行刪除),不碰現有 code,reviewer 沒什麼要擔心的。

但它代表一件事:我們學會了用對方的語言說話。


目前的狀態

專案 狀態
Cisco mcp-scanner 已合併 ✅
大型 LLM 紅隊測試框架 等待維護者回覆。方向對了,結果未知
Microsoft agent-governance-toolkit 有正面互動,維護者提出合作方向
其餘 9 個 靜置

2026 年 9 月 26 日補註: 上表是撰文當時的狀態。Microsoft agent-governance-toolkit 的 PR #854 已於 2026 年 4 月 8 日合併。這支 PR 放了什麼(12 個攻擊向量的偵測邏輯、58 個測試)、為什麼投給這個專案,寫在從零到幫微軟寫 Code 的四個月紀錄。它從開 issue 提案、被維護者主動指派到合併的經過,連同 Cisco 那次 51 分鐘合併,則記在Cisco 在 51 分鐘內 merge 我的 PR。截至 2026 年 9 月 26 日,我們累計有 31 個 PR 合併進 15 個組織的上游專案(不含 awesome 清單收錄)。

一個 merge 不算成功。但零個 merge 到一個 merge 之間的距離,比一個到十個還遠。


給正在被拒的人

如果你也在嘗試貢獻開源 AI 安全專案,這是我們付了學費換來的經驗:

1. 先在 issue 討論,等有共識再寫 code。

大多數被拒的 PR 不是因為 code 不好,是因為方向沒對齊。一個 issue 裡的三句話討論,可以省你一週的工作。

2. 用對方的語言寫。

如果專案用 Python,你就用 Python。如果他們有自己的 base class,你就繼承那個 base class。不要發明自己的格式然後期望別人來適應你。

3. 你的工具要配得上你的野心。

如果你要向有大企業支持的專案提交貢獻,你的 repo 不能長得像一個週末專案。CI、測試、文件、安全政策:這些不是裝飾,是維護者判斷你是否可靠的信號。

4. 被拒不是終點,是資訊。

「不在我們的 scope」→ 表示你要找對的 repo。 「沒有整合我們的架構」→ 表示你要讀他們的 code。 「可以提供方法論引用嗎?」→ 表示他們有興趣,但需要你證明嚴謹度。

每一次拒絕都在告訴你下一步該往哪走。

5. 確認你在跟誰說話。

熱情的回覆 ≠ merge 權限。看清楚對方是 maintainer、contributor、還是路人。


這篇文章會更新

這個故事還沒結束。如果對方的維護者接受我們的方向,我們會用 Python 寫一個正式的 probe/detector 模組,那會是一個真正的技術挑戰。如果被拒,我們也會寫出來。

開源貢獻不是英雄故事,是反覆碰壁然後學會轉彎的過程。


本文作者是 Ultra Lab 團隊,我們做 AI 安全工具。prompt-defense-audit 是 MIT 開源,歡迎貢獻。

常見問題

開源專案的 PR 為什麼會被拒絕?

大多數被拒的 PR 不是因為 code 不好,而是方向沒對齊。我們 12 次提交全部失敗的原因有四個:用自己的 YAML 格式提交,沒有遵循對方的架構、程式語言與 plugin 格式;沒有回答創建者的問題就直接開 PR;把非維護者的熱情回覆當成權限;自己的 repo 缺少 CI、測試框架和 SECURITY.md,看起來像週末的 side project。

貢獻開源專案,要先開 issue 討論還是直接發 PR?

先在 issue 討論,等有共識再寫 code:先討論方向、確認架構適配,拿到某種程度的認可,然後再寫。在開源社群,「做好了再問」不是效率,是傲慢。一個 issue 裡的三句話討論,可以省你一週的工作。

PR 或 issue 被開源維護者拒絕後該怎麼辦?

被拒不是終點,是資訊。「不在我們的 scope」表示你要找對的 repo;「沒有整合我們的架構」表示你要讀他們的 code;「可以提供方法論引用嗎?」表示他們有興趣,但需要你證明嚴謹度。我們的第一個 merge 就來自一次拒絕:Cisco skill-scanner 的維護者拒絕我們的 issue 時,把我們導向 mcp-scanner,後來 PR #146 從開 PR 到合併花了 51 分鐘。

開源維護者怎麼判斷外部貢獻者可不可靠?

CI、測試、文件、安全政策不是裝飾,是維護者判斷你是否可靠的信號。維護者點進我們的 prompt-defense-audit 時,只看到 3 顆星、3 個 commits、沒有 CI、沒有 SECURITY.md。後來我們改用 Vitest(84 個測試、100% coverage)、加上 GitHub Actions,並補齊 CONTRIBUTING.md、SECURITY.md 與 CHANGELOG.md。

每週 AI 自動化實戰筆記

不廢話,只有能直接用的東西。Prompt 模板、自動化 SOP、技術拆解。

加入一人公司實驗室

免費資源包、每日建造日誌、可以對話的 AI Agent。一群用 AI 武裝自己的獨立開發者社群。

想自己動手試試?

UltraProbe 免費、免註冊,掃一次網站就知道 Google 與 AI 找不找得到你。