你只搭了半張安全網,卻以為已經完工

讓我們誠實面對:大多數 AI 程式碼流水線目前的真實面貌是什麼。

你用 Cursor 或 Claude Code 產生程式碼。你執行 tsc --noEmit,因為 TypeScript strict mode 能抓出型別不匹配。你執行 ESLint,因為沒人想在拉取請求裡為了分號爭吵。或許你會執行 dependency-cruiser,因為循環匯入很難看。你的測試通過了。你發布了。

然後你以為這就是確定性堆疊。

並不是。這只是個型別與風格堆疊。你防止了無效狀態,並強制執行了匯入邊界,這確實有用。但你完全沒有處理 LLM 剛產生了一個一百八十行的函式,其循環複雜度會讓圖論學者哭泣的事實。你沒發現三個不同的 module 複製了同一個輔助函式,只是變數名稱略有不同。你也沒注意到錯誤處理只有一個 catch (e) { console.log(e) },像個懶散的警衛一樣坐在 promise chain 的最底端。

程式碼編譯通過了。架構很乾淨。但程式碼依然客觀上很爛

這就是缺口。而且這很重要,因為 AI 產生的程式碼特別擅長製造這種垃圾:結構上有效、架構上合規,卻從內部默默腐敗。

遺失的那一層究竟是什麼

想想看,一棟建築通過結構工程師檢查,和住起來舒適,這兩者之間的差別。結構檢查確認的是建築會不會倒塌。它不會檢查淋浴間的排水是否流進廚房水槽。兩者都重要。它們是不同的工作。

你現有的確定性堆疊就是那位結構工程師。它檢查:

  • 型別:這個值以這種形狀存在是否合理?
  • 語法檢查:語法是否遵循基本衛生規範?
  • 架構規則:匯入是否尊重邊界?
  • 測試:理想路徑是否能順利執行而不崩潰?

它不檢查的:

  • 複雜度:這個函式的分支是否多到沒有人類能正確理解?
  • 重複:LLM 是否把同一份邏輯產生在四個地方,只有細微差異?
  • 命名data 算是有意義的變數名稱嗎?還是它只是程式世界裡的聳肩?
  • 錯誤處理:錯誤是真的被處理了,還是只被捕獲然後忽略?
  • 結構:檔案組織是否合理,還是只是個垃圾場?
  • 註解:棘手的地方有解釋嗎?還是下一位開發者需要招魂才能理解?
  • 大小:這個檔案有四百行是因為它需要這麼長,還是因為沒人叫模型停下來?

這些不是審美偏好。複雜度與缺陷密度相關。重複保證了未來的修改會不一致。糟糕的命名增加了每次後續修改的認知負荷。差勁的錯誤處理意味著生產環境故障卻沒有診斷線索。

這方面的研究毫不含糊。我們自己的跨維度分析發現,分層可靠性架構只有在每一層都能抓到前幾層遺漏的缺陷時才有效。如果你的第一層是型別檢查,第二層是測試,但沒人檢查程式碼是否為可維護性災難,那你的堆疊就有個洞。而 AI 產生的程式碼最愛從那個洞掉下去,因為模型非常擅長產生看起來合理的實作,結果卻是活生生的噩夢。

登場:這個名字很嗆的工具

有個工具叫做 fuck-u-code —— 對,真的是這個指令 —— 它做了你流水線中其他工具都沒在做的一件事。它針對十四種語言執行確定性的、基於 AST 的程式碼品質分析,並用實際與真實問題相關的指標,精確告訴你你的程式碼有多爛。

以下是它檢查的項目:

  • 複雜度:循環複雜度與認知複雜度分數。如果函式有十七個分支,它會標記出來。
  • 大小:檔案與函式的行數。產生兩百五十行函式的 LLM,不會因為型別正確就過關。
  • 註解:註解密度與品質。不是因為註解有美德,而是因為沒有解釋的複雜邏輯是維護陷阱。
  • 錯誤處理:錯誤是被捕獲、重新拋出、記錄,還是被默默吞下。
  • 命名:變數與函式名稱品質。datatemphandlerprocess 都過不了關。
  • 重複:跨檔案重複的程式碼區塊。LLM 最愛的把戲:複製貼上加上尋找取代。
  • 結構:檔案組織與 module 內聚性。

它輸出零到一百分的總分。越高越好。它還會輸出每個檔案的「shit-gas index」—— 越高越糟 —— 讓你確切知道哪些檔案需要先處理。分析完全離線執行,透過 tree-sitter AST 解析。你的程式碼永遠不會離開你的機器。在大多數專案上只需不到一秒鐘。

而這點應該會讓你氣自己怎麼沒早點用:它完全免費

工具本身就是這套哲學的體現

fuck-u-code 有趣的地方不只是它檢查什麼。而是它內部的架構方式,因為這個工具本身就是它所屬流水線的完美縮影。

這個工具有兩個指令:

fuck-u-code analyze .          # Deterministic AST analysis. Offline. Fast. Free.
fuck-u-code ai-review . -m gpt-4o   # AI review of the worst-scoring files. API call. Costs tokens.

注意順序。注意預設行為。確定性分析永遠先執行,因為它不需要 API 金鑰、不用花錢,而且每次執行結果不會變。AI 審查是選擇性的第二步,只看分數最差的前 N 個檔案。

這正是你的流水線應該採用的架構。

你不會把每個拉取請求都送給 Greptile 或 Claude Code 做完整的語意審查。那要花錢、耗時間,而且 —— 正如我們在前幾篇文章裡確立的 —— 會產生機率性輸出,連續執行時可能標記也可能沒標記同樣的問題。你先執行確定性閘門。你用完美的可重複性,在毫秒內免費篩掉結構性災難。然後,也只有在那之後,你才把倖存者送去做昂貴的 AI 審查,進行確定性工具做不到的語意、架構與行為分析。

fuck-u-code 從字面上在內部實作了這個架構。analyze 指令是你的第一層品質濾網。ai-review 指令是你的第二層語意深度分析。這個工具就是它自身所實現原則的示範。

經濟論點幾乎讓人憤怒

讓我們花點時間談談錢,因為這正是產業現狀讓人真正惱火的地方。

AI 程式碼審查平台按拉取請求或審查程式碼行數收費。費用不算巨大 —— 大概每個拉取請求一兩塊美金 —— 但終究不是零,而且會隨著團隊速度而增加。如果你用 AI 產生程式碼,你的速度比過去更快,這意味著你的審查成本也比過去更高。

與此同時,fuck-u-code 會在不到一秒鐘內分析你的整個 codebase,橫跨十四種語言,而且完全不收費。它會標記出真正有問題的那百分之二十檔案。它會產生 JSON 或 Markdown 報告供你的持續整合流程使用。如果平均分數低於你設定的閾值,它會讓建置失敗。

如果你在每個 PR 都執行 AI 審查,卻沒有先設置確定性品質閘門,那你等於是在花 API token 去發現某個函式太複雜。這就像聘請結構工程師來告訴你家裡很髒。工程師當然有這個資格,但你在浪費他的時間和你的錢。

經濟上理性的流水線是:

  1. AI 產生程式碼
  2. 型別檢查、語法檢查與架構規則(你現有的堆疊)
  3. fuck-u-code analyze(遺失的品質閘門 —— 零元、不到一秒)
  4. AI 審查(Greptile 等 —— 但只針對通過第三步的檔案,或只在第三步標記出有趣模式時)

這不是理論。這是算術。確定性閘門抓出確定性工具設計來解決的問題類別。AI 審查抓出需要語意理解才能解決的問題類別。每個工具都做自己擅長的事。沒人會為了結構衛生而浪費 token。

MCP 整合:為工作流程而生,不是事後拼湊

如果你認真看待 AI 輔助開發,還有一個細節很重要。

fuck-u-code 內建 MCP server。如果你使用 Claude Code、Cursor 或任何其他支援 MCP 的工具,你可以直接從你的 agent 呼叫 fuck-u-code analyze。agent 不需要知道 AST 解析或循環複雜度是什麼。它呼叫一個工具。工具回傳結構化報告。agent 根據報告採取行動。

這很重要,因為它閉合了迴路。產生程式碼的同一個 AI,現在可以收到關於該程式碼品質的確定性回饋,而且是以它能理解並採取行動的格式。agent 可以看到 src/auth/login.ts 的 shit-gas index 是一百分之八十七,然後在任何人看到這個 PR 之前就決定 refactor。

我們之前在文章中寫過,持續整合是讓規格驅動開發成真的 enforcement 層。MCP 整合意味著 fuck-u-code 不只是個持續整合閘門。它是個agent 可存取的品質預言機,生成流水線可以即時查詢它。

實際加入它長什麼樣子

你不需要遷移計畫。你只需要五分鐘。

npm install -g eff-u-code
fuck-u-code analyze .              # See your current scores
fuck-u-code config init            # Generate .fuckucoderc.json

設定你的閾值。選擇最低總分。選擇每個檔案可接受的最大 shit-gas index。把它加進你的 pre-commit hooks:

# .husky/pre-commit
fuck-u-code analyze . --format json --output quality-report.json

或加進持續整合:

# .github/workflows/quality.yml
- name: Code Quality Gate
  run: |
    npm install -g eff-u-code
    fuck-u-code analyze . --format markdown -o quality.md
    # Parse the JSON and fail if overall score < threshold

權重可以調整。如果你的團隊更在乎複雜度而非註解,就在 .fuckucoderc.json 中調整指標權重。如果你想排除測試檔案,使用 --exclude。如果你想看前二十個最差檔案而非預設的十個,使用 -t 20

然後,當你篩掉了結構性災難,再把有趣的檔案送去做 AI 審查:

fuck-u-code ai-review . -m gpt-4o -t 5   # Review only the 5 worst files

這就是流水線。產生。型別檢查。品質閘門。審查倖存者。發布。

誠實的結論

我不會假裝 fuck-u-code 能解決你 codebase 裡的所有問題。它抓不出競態條件。它不會告訴你你的驗證邏輯有微妙的計時攻擊。它無法取代 property-based testing、mutation testing、形式驗證,或我們在前幾篇文章裡談過的任何其他層級。

它會做的是抓出那些無聊、可預測、昂貴,但目前沒人在抓的問題。它會告訴你 AI 產生的 API 處理程式長達三百行而且沒有錯誤處理。它會告訴你三個不同的服務複製了同一份驗證邏輯。它會告訴你一半的變數都叫做 dataresult,而你應該為此感到慚愧。

這些不是邊緣案例。這是沒有品質回饋迴路的快速程式碼生成流水線的預設輸出。LLM 不會累,但也不會不好意思。它產生爛程式碼的自信,跟產生好程式碼時一模一樣,而你現有的確定性堆疊會讓它通過,因為你的堆疊設計來檢查的是有效性,不是品質。

有效性和品質是不同的東西。兩者你都需要。

fuck-u-code 不是完整的答案。它是這個具體問題的答案:「最便宜、最快速、最具確定性的方式,阻止 AI 產生的結構性垃圾進入程式碼審查,是什麼?」

答案是:解析 AST、評分指標、讓建置失敗,然後叫模型重試。

它不花錢。只需不到一秒鐘。而且它補上了你安全堆疊中一個你可能根本不知道存在的洞。