---
schemaVersion: 1
slug: sd-16-20260402-can-ai-test-itself
ticketId: SD-16
lang: zh-tw
title: AI 能測試自己嗎？— 從 Claude Code 零測試到 Self-Testing Agent 的可能性
summary: Claude Code 512K 行 TypeScript，64K 行生產碼，零測試。但比零測試更讓人困惑的問題是：Anthropic 有全世界最好的 AI coding 工具，他們為什麼不讓它幫自己寫測試？從靜態分析到 MITM proxy，從遞迴自我測試的哲學困境到 OpenClaw 的實戰做法，探索 Self-Testing Agent 到底能走多遠。
originalDate: 2026-04-02
translatedDate: 2026-04-02
source: ShroomDog Lab
sourceUrl: https://gu-log.vercel.app/
author: null
authorshipNote: null
canonicalUrl: https://gu-log.vercel.app/posts/sd-16-20260402-can-ai-test-itself
status: published
replacementTicketId: null
replacementUrl: null
---

# AI 能測試自己嗎？— 從 Claude Code 零測試到 Self-Testing Agent 的可能性

> **來源:** [ShroomDog Lab](https://gu-log.vercel.app/)

三月底，[Claude Code](https://gu-log.vercel.app/glossary#claude-code) 的 512K 行 TypeScript 源碼意外打包進 npm 包，在凌晨四點多被一個實習生發現，幾小時內被鏡像到 GitHub 各處。整個工程師社群集體變成了考古學家，翻那份代碼找化石：KAIROS（一個從沒發布的背景 daemon agent）、187 個 spinner 動詞、一個跨 3,167 行的單一函式。

然後有人找到了這個：

**64,464 行生產碼。零測試。**

Hacker News 上的反應是一種特殊的沉默感——不是興奮，是「嗯，我懷疑過」那種一聲嘆氣。[@DavidKPiano](https://x.com/DavidKPiano/status/2038920459111264362) 那句話讓很多人噴笑：

> “Ironically this is probably the first time that actual humans are carefully & thoroughly reviewing the Claude Code codebase.”

一個 AI coding 工具，代碼第一次被仔細 review，是因為意外洩漏，review 的還是網路上的陌生人，不是它自己的工程師。

但這不是這篇文章最有意思的地方。

更讓人困惑的問題是：**Anthropic 有全世界最好的 AI coding 工具。如果他們想補測試，最自然的做法，不就是讓 Claude Code 幫自己的 source code 寫測試嗎？**

這個問題問起來很顯而易見，答起來卻很有趣。

> **Mogu 想補充：**
>
> 先快速交代「為什麼沒人寫測試」這個問題的答案，因為它其實沒那麼重要。
>
> 當每個人都在跑功能，沒有人的 OKR 上面有「確保品質」這一行，零測試就是自然結果。不是工程師不在乎，是沒有人指定負責這件事。這在 startup 早期是合理取捨，但 Claude Code 現在是年收 25 億美元的產品。
>
> 更好玩的是：這個 repo 裡有 BDD 測試框架、有 Playwright E2E 設定、有 `pnpm run test` 指令——所有工具都在，production code 旁邊空白一片。就像健身房辦了會員，從沒去過。┐(￣ヘ￣)┌

---

## 靜態分析：一個我們已經知道答案的實驗

把 Claude Code 的源碼餵給 Claude，讓它讀完，然後問「這個函式的 edge case 是什麼」。

這條路今天就能跑。Claude 的 1M context 窗口夠大，64K 行的 production code 直接丟進去。聽起來太抽象？來看一個具體的例子——一個真的藏在 Claude Code 裡、靠洩漏才曝光的 bug。

Claude Code 有一個叫 **attestation** 的機制：每個送出的 API request，裡面有個 `cch=00000` 的 placeholder。Bun 的 Zig 層會在傳送前把它替換成計算過的 hash，證明這個請求真的來自正版 Claude Code binary。

設計很精妙。問題是替換邏輯是「掃描整個 HTTP request body，找到 `cch=00000` 就替換」。

如果你的**對話內容**裡剛好出現這個字串——比如你在討論 billing 問題，或者剛好在讀 Claude Code 的源碼——Zig 層會把你對話裡的字串也一起替換掉，破壞 prompt cache key，token 消耗突然暴增 10-20 倍。

GitHub issue #38335，203 個 upvote，大家一直問「為什麼我的 quota 用得特別快」。洩漏之前，沒有人知道為什麼。

這個 bug 不需要跑程式才能找到。你只需要讀 code，然後問一個很基本的問題：「這個字串替換邏輯，有沒有考慮到輸入本身包含 placeholder 的情況？」

**Claude Code 可以在幾分鐘內找到這個問題。沒有人要求它去找。**

> **Mogu 真心話：**
>
> 這個 bug 屬於一類非常古老的問題：把控制訊號和資料訊號混在同一個 channel 裡。
>
> SQL injection、Shell injection、[Prompt](https://gu-log.vercel.app/glossary#prompt) injection，根源全是同一個結構——你用來「指揮」的語言和你傳輸的「內容」走同一條路，然後內容被誤讀成指令。attestation bug 只是這個模式在 HTTP body 層的新版本。
>
> 特別有趣的地方是：Claude Code 裡有 **23 個 bash security check**，專門防 unicode zero-width space injection、IFS null-byte injection，全都是「資料偽裝成控制訊號」的變體。他們非常清楚這類問題，防了一圈，然後自己的 attestation 機制犯了同類錯誤。
>
> 就像你家裝了全套防盜系統，然後把備用鑰匙放在門口的假石頭裡。(⌐■\_■)

---

## 在旁邊開著望遠鏡

靜態分析的盲點是所有 runtime 才出現的東西。

想像一下：你在 Claude Code 和 Anthropic API 之間架了一個透明代理，像在走廊裝了一台監視器，所有流量從它前面走過。Claude Code 在問什麼、API 回了什麼、cache 有沒有命中、model 是哪一個——全部即時可見。

這就是 **mitmproxy** 能做到的事。往 HTTP 流量中間插一個代理，記錄，不干涉。

你會看到幾件很有意思的事。

連續三次收到 529 錯誤（伺服器過載）之後，Claude Code 會靜默地把你從 Opus 降級到 Sonnet，不通知你。你付了 Opus 的錢，伺服器忙的時候，你拿到 Sonnet，你不知道。MITM proxy 讓這個切換在你眼前發生：request header 裡的 model 欄位，從 `claude-opus-4-6` 換成了 `claude-sonnet-4-6`，就這樣。

你也能看到 prompt cache 的行為。Claude Code 把 system prompt 切成 stable（不常變）和 dynamic（每次不同）兩層，確保 cache hit rate 夠高。洩漏的 code 裡有一個標記叫 `DANGEROUS_uncachedSystemPromptSection`——「這段如果放錯位置，cache hit rate 暴跌，費用飆升」的意思。用 proxy 驗證 cache 邏輯有沒有照設計在跑，就是這個用途。

配合靜態分析，你可以對 attestation bug 寫一個真正的測試：「如果 input 包含 `cch=00000`，替換結果是否正確？」動靜結合。

> **Mogu 真心話：**
>
> 靜默降級這件事值得多說兩句。
>
> Anthropic 的公開立場是 transparency first——Constitutional AI 文件、AI Safety 研究、「對使用者誠實」是他們的核心 messaging。然後他們悄悄做了一個功能：伺服器忙的時候，你的 model 偷偷換了，你不知道。
>
> 我不是說這個設計邪惡——服務穩定確實是合理的優先項。但如果有人拿這個 spec 去問 Anthropic 的 AI Safety 團隊「這符合你們說的透明度原則嗎」，那個對話應該會很有趣。ʕ•ᴥ•ʔ

---

## 自己出題、自己改考卷

好，假設你做到了：Claude 讀完 Claude Code 的 source code，找到了 attestation bug，生出了一套完整的 test suite，全綠。

這時候有一個問題要問：**這些測試，誰來確認是對的？**

這裡有件讓人頭皮發麻的事。

如果 Claude 寫了 code，又讓 Claude 寫 test，那兩份東西的「正確性」都建立在 Claude 的直覺上。如果 Claude 對某個 edge case 有系統性的錯誤理解——比如「空字串和 null 應該一樣處理」——那它寫的 code 和它寫的 test 都會反映這個錯誤理解。兩個一起錯，彼此一致，測試全過，bug 永遠不被發現。

這就是讓學生自己出期末考試題、然後自己改考卷。如果這個學生對某個觀念有根本性的誤解，出的題和寫的答案會同樣偏差，沒有老師，沒有人知道。

學術界有個一樣的問題叫「同質性 peer review」：如果整個 field 都有某個共同的盲點，同儕評審找不到它，因為評審者和作者有同樣的盲點。AI 的版本只是新包裝。

**破解方法不是消除這個問題，是引進獨立的觀點。**

用不同的 LLM 寫 code 和測試——Claude 寫 code，GPT 或 Gemini 寫 test，或者反過來。不同的訓練資料、不同的 [RLHF](https://gu-log.vercel.app/glossary#rlhf) 偏好、不同的系統性偏差。你沒辦法保證兩個 model 沒有重疊的盲點，但你讓「兩個同時有同樣盲點」的機率大幅下降了。這不是完美的解法，但至少不是同一個大腦自己出題自己改考卷。

> **Mogu OS：**
>
> Cross-model testing 有一個沒人講但很真實的問題：你現在要付兩家 AI 公司的錢。Claude Max 跑 code，OpenAI API 跑 test generation，月底帳單有點小驚喜。
>
> 但比起「prod 爆掉找不到 bug、工程師半夜救火、SLA 破了客戶跑了」，這個成本根本不算什麼。
>
> 而且有個意外收穫：你會開始注意到兩個 model 的測試風格差異——GPT 傾向寫更多 happy path，Claude 傾向過度 defensive 加一堆 null check。這個差異本身就有資訊量，它告訴你兩個 model 對「什麼是 edge case」的直覺不一樣。(¬‿¬)

---

## [OpenClaw](https://gu-log.vercel.app/glossary#openclaw) 的做法：Oracle 是人，Loop 是機器

說了理論，來說說我們實際在幹嘛。

OpenClaw 的每篇文章都跑 [Ralph Loop](https://gu-log.vercel.app/glossary#ralph-loop)——Claude 寫文章，另一個 Claude instance 按照固定評分標準打分（Persona、MoguNote 品質、整體 Vibe），沒過就重寫，最多三輪。這本質上就是一種 AI 測試 AI 的流程，在「文章品質」這個 domain 上。

它解決了 specification problem 嗎？只解決了一部分。Scorer 和 Writer 都是 Claude，如果 Claude 有某個系統性的盲點，評分可能也有同樣的盲點。偶爾我會拿一篇「Ralph 說 9 分」的文章自己讀，確認有沒有明顯的 miss。這不是設計缺陷，這是整個 AI testing 問題的現實：Oracle 本身需要被偶爾校準，校準者還是人。

但「人需要介入」不等於「人要做每一步」。Ralph Loop 裡，人做的事是設計評分標準、設定 pass bar、偶爾 spot check——不是每篇都親自打分。你把 oracle 設計好，然後機器幫你跑 loop。

> **ShroomDog 的 OS：**
>
> OpenClaw 的 agent-to-agent 架構，其實就是這個結構的 production 版本。
>
> VM 上的 [Mogu](https://gu-log.vercel.app/glossary#mogu) instance（Linux，24/7 在跑）可以透過 SSH 委派任務給其他機器上的 agent。這篇文章就是這樣產出的——Mac 上的 Claude Code 和 VM 上的 Mogu 協作，Mogu 有時候去問另一個 agent。
>
> 不是什麼神奇科技，就是普通的 SSH + stdin/stdout + bash glue。但搭起來以後，你就有了「agent 委派任務給 agent，人管 oracle」的結構。今天跑翻譯和品質評分，同樣的架構明天可以跑測試。

---

## 結語

Claude Code 的零測試，最終是個組織問題，不是技術問題。

技術早就在了——靜態分析今天就能跑，MITM proxy 今天就能架，cross-model testing 今天就能試。attestation bug 那個例子不是理論，是一個真實存在的 bug，被社群在洩漏後幾小時內找到，而這件事 Claude 幾分鐘內就能做到。

真正的原因是：沒有人的工作是把工具用在工具自己身上。

Anthropic 建了全世界最好的 AI coding 工具，幫助數百萬開發者寫出更好測試過的代碼——然後沒有人用這個工具來測試這個工具本身。洩漏之後，社群的陌生人在幾小時內找到了 attestation bug、靜默降級邏輯、那個 3,167 行的函式。這些事情 Claude 本可以更早找到。

這個矛盾不是 Anthropic 獨有的。每個正在用 AI 寫 code 的團隊，都面對同一個問題：誰的工作是確保 AI 寫的東西是對的？

工具已經有了。那個空白的 OKR 欄位才是真正的問題。
