智能體軟體工程 #4|當 Agent 寫完程式碼,誰來說「可以合併」?

系列文章:


圖片

在這個系列的前兩篇中,我們分別拆解了兩個問題:當 Agent 每天可以產出幾十個 PR 時,傳統的 Code Review 流程會崩潰(#2);當多個 Agent 並發工作時,Git 的心智模型會成為瓶頸(#3)。

這兩個問題指向同一個更根本的空白:在 Agent 完成編碼之後、程式碼合併到主分支之前,缺少一個確定性的、機器可執行的品質門檻。

傳統流程中,這個門檻是人類 reviewer。他打開 PR,讀幾百行 diff,在腦子裡模擬程式碼行為,判斷「這段程式碼對不對」,然後點擊 Approve。這個過程依賴人的經驗、注意力和時間,這三種在 Agent 時代都是不可擴充套件的資源。

CI 測試是機器門檻,但它只檢查「已有的測試是否通過」,不檢查「Agent 的實作是否滿足了這次任務的意圖」。一個 Agent 可以讓所有已有測試通過,但實作了一個完全錯誤的功能。因為沒有人告訴 CI「這次任務的意圖是什麼」。

這就是 agent-spec 要解決的問題。

agent-spec 不是一個「更好的 Code Review 工具」,它是一個不同的典範。它把審查的物件從程式碼變成了合約,把審查的時間點從編碼之後移到了編碼之前,把驗證的執行者從人變成了機器。

一、審查點的位移

agent-spec[1] 的核心理念可以用一句話概括:把人類的審查點從「程式碼寫完之後」移到「程式碼寫之前」。

傳統流程中,人類注意力的分配大致是這樣的:

寫 Issue (10%) → Agent 編碼 (0%) → 讀程式碼 diff (80%) → 點 Approve (10%)

80% 的人類時間花在「讀程式碼 diff」上,這是一個低效的活動。Reviewer 在 diff 中尋找的東西本質上是兩類:**「Agent 有沒有做對」**(功能正確性)和 「Agent 有沒有做了不該做的事」 (越權行為)。前者需要理解業務意圖,後者需要理解程式碼邊界。兩者都隱含在 Issue 的自然語言描述中,沒有被形式化。

agent-spec 把這個分配變成:

寫 Contract (60%) → Agent 編碼 (0%) → 看 explain 摘要 (30%) → 點 Approve (10%)

人類的主要工作從「讀程式碼」變成了「寫 Contract」。用結構化的方式定義任務的意圖、技術決策、檔案邊界和驗收標準。這是一個更高價值的活動:你在定義「什麼是對的」,而不是在程式碼 diff 中猜測「這是不是對的」。

程式碼寫完之後,人類看到的不再是幾百行 diff,而是一個 Contract 級別的執行摘要:Contract 定義了什麼意圖?Agent 修改了哪些檔案?是否在允許範圍內?綁定的測試是否全部通過?如果這些都是「是」,approve 就是一個 5 秒鐘的操作。

二、Task Contract:控制面的四要素

agent-spec 的核心抽象是 Task Contract 。一個結構化的任務規格,包含四個要素。

第一要素:Intent(意圖)

不是一個模糊的 Issue 標題,而是一段聚焦的說明。這個任務要做什麼、為什麼做、在什麼上下文中做。意圖給 Agent 提供方向感,也讓 reviewer 在最後判斷「Contract 定義是否正確」時有據可依。

## Intent
Add a user registration endpoint to the existing auth module.
New users register with email + password; a verification email
is sent on success. This is the first step of the user system.

第二要素:Decisions(已定決策)

已經確定的技術選擇。不是「建議」或「考慮」,而是不可商量的決定。Agent 照著做,不需要自己選技術方案。這消除了 Agent 最容易產生偏差的環節:技術選型。

## Decisions
- Route: POST /api/v1/auth/register
- Password hash: bcrypt, cost factor = 12
- Verification token: crypto.randomUUID(), stored in DB, 24h expiry
- Email: use existing EmailService, do not create a new one

第三要素:Boundaries(邊界)

Agent 可以修改什麼、不可以修改什麼。路徑級的邊界由 agent-spec 的 BoundariesVerifier 機械執行。如果 Agent 修改了不在 Allowed Changes 列表中的檔案,驗證直接失敗。

## Boundaries
### Allowed Changes
- crates/api/src/auth/**
- crates/api/tests/auth/**
- migrations/
### Forbidden
- Do not add new dependencies
- Do not modify the existing login endpoint

這個設計的意義在於: Agent 的行為邊界不再靠 prompt 裡的一句「請不要修改其他檔案」來約束,那是機率性的約束,Agent 可能遵守也可能不遵守。邊界驗證是確定性的,修改了不該改的檔案就是 fail,沒有灰色地帶。

第四要素:Completion Criteria(完成條件)

BDD 風格的驗收場景,每個場景顯式綁定一個測試函式。這不是普通的 BDD,普通 BDD 需要一個 step definition 層把自然語言對映到程式碼。agent-spec 跳過了這個中間層,直接綁定到已有的測試名:

## Completion Criteria
Scenario: Successful registration
  Test: test_register_returns_201_for_new_user
  Given no user with email "alice@example.com" exists
  When client submits the registration request
  Then response status should be 201
Scenario: Duplicate email rejected
  Test: test_register_rejects_duplicate_email
  Given a user with email "alice@example.com" already exists
  When client submits the same email for registration
  Then response status should be 409

這裡有一個關鍵的寫作原則:異常路徑的場景數量應該大於等於正常路徑。 上面的例子中,如果只寫「註冊成功返回 201」這一個場景,Agent 可以用任何方式實作,包括完全不做輸入校驗、不處理重複信箱、不檢查密碼強度。因為這些邊界情況在 Contract 中沒有被定義為驗收標準。

每多寫一個異常場景,就多覆蓋一個 Agent 可能忽略的邊界條件。寫 Contract 的過程迫使你在 Agent 動手之前就想清楚所有需要處理的情況。

agent-spec 的 DSL 同時支援中文和英文的關鍵詞:

場景:重複信箱被拒絕
  測試:test_register_rejects_duplicate_email
  假設 已存在信箱為 "alice@example.com" 的使用者
  當 客戶端提交相同信箱的註冊請求
  那麼 響應狀態碼為 409

這不是裝飾性的雙語,它讓中文團隊可以用母語編寫和閱讀 Contract,降低 Spec 寫作的認知門檻。

三、七步工作流

Contract 寫好之後,整個流程是一條清晰的流水線,三個角色各司其職:

Step 1:人類編寫 Contract

agent-spec init --level task --lang en --name "User Registration"

生成模板,人類填寫四要素。這是整個流程中人類注意力最集中的環節。60% 的人類時間花在這裡。

當然,這裡也可以交給 AI 輔助編寫 Contract,但 Contract 的 DSL 對人類開發者來說是非常方便審閱和修改的。

Step 2:Contract 品質門檻

agent-spec lint specs/user-registration.spec --min-score 0.7

在把 Contract 交給 Agent 之前,先檢查 Contract 本身的品質。agent-spec 內建了 8 個 linter,檢測模糊動詞(「處理」、「manage」)、缺少量化的約束(「應該快速」而不是「< 200ms」)、不可機械驗證的斷言(「介面應該美觀」)、非確定性措辭(「大約」、「approximately」)、缺少測試綁定的場景、以及可能誘發 Agent Sycophancy 的語言(「find all bugs」這樣的措辭會讓 Agent 編造問題來討好你)。

如果質量分低於閾值,先修 Contract 再繼續。這是「審查點上移」的第一步。在 Agent 動手之前,確保 Contract 本身是高質量的。

Step 3:Agent 讀取 Contract 並編碼

agent-spec contract specs/user-registration.spec

輸出結構化的 prompt fragment。Agent 受到 Contract 的三重約束:Decisions 告訴它「怎麼做」,Boundaries 告訴它「能碰什麼」,Completion Criteria 告訴它「做到什麼程度算完」。

Step 4:lifecycle 驗證(自動 retry 循環)

agent-spec lifecycle specs/user-registration.spec \
  --code . --change-scope worktree --format json

這是整個流程的核心。lifecycle 執行四層驗證:

L1 Structural Verifier:對 Contract 的 Must Not 約束做程式碼模式匹配。如果 Contract 說「禁止使用 .unwrap()」,verifier 掃描所有原始檔中的 .unwrap() 呼叫。零 token 成本,確定性結果。

L2 Boundaries Verifier:檢查 Agent 實際修改的檔案是否在 Contract 的 Allowed Changes 範圍內。路徑 glob 匹配,零 token 成本,確定性結果。

L3 Test Verifier:執行 Completion Criteria 中綁定的測試。每個 Test: test_register_returns_201 會被實際執行。這是最重要的一層。它直接回答「Agent 的程式碼是否滿足了 Contract 定義的驗收標準」。

L4 AI Verifier:對前三層未覆蓋的場景,提供 AI 分析(當前支援 stub 模式和 caller 模式)。AI 的判斷不是 passfail,而是 uncertain,它不宣稱確定性,需要人類最終判斷。

如果 lifecycle 失敗,Agent 收到結構化的 failure_summary,精確到每個失敗場景的原因和證據。Agent 據此修復程式碼並重新執行 lifecycle。這個 retry 循環可以自動進行,不需要人類介入:

Code → lifecycle → FAIL (2/5) → failure_summary → fix → lifecycle → PASS (5/5) ✓

agent-spec 的 run log 會記錄這個過程,「這個 Contract 跑了 3 次才通過」。

Step 5:guard 門檻

agent-spec guard --spec-dir specs --code . --change-scope staged

pre-commit hook 或 CI 檢查。對 specs/ 下所有 spec 檔案執行 lint + verify。任何 spec 不通過,commit 被阻止或 PR 失敗。

圖片

(本專案也是用 agent-spec 自舉,圖為 CI 失敗攔截)

Step 6:Contract Acceptance

agent-spec explain specs/user-registration.spec --format markdown

這是人類的最後一個審查點。Reviewer 看到的不是程式碼 diff,而是 Contract 級別的執行摘要:意圖是什麼、做了哪些決策、修改了哪些檔案(是否在允許範圍內)、所有驗收標準的通過/失敗狀態。

Reviewer 需要回答兩個問題:Contract 定義對嗎?驗證全部通過了嗎?如果兩個都是「是」,approve。

如果需要更多上下文,可以檢視執行歷史:

agent-spec explain specs/user-registration.spec --history

「這個任務 Agent 試了 3 次才通過」,說明 Contract 的驗收標準確實在起作用。

Step 7:stamp 歸檔

agent-spec stamp specs/user-registration.spec --dry-run

透過 Git commit trailer 建立 Contract → Commit 的追溯鏈。以後有人問「這段程式碼為什麼這樣寫」,可以從 trailer 追溯到 Contract,從 Contract 中看到完整的意圖和決策。

四、四種 verdict,零歧義

agent-spec 的驗證結果有且僅有四種語意,不多不少:

pass,場景被確定性驗證器或 AI 驗證器確認通過。

fail,場景被驗證器發現具體違規,附帶證據(程式碼片段、測試輸出、模式匹配結果)。

skip,沒有任何驗證器覆蓋這個場景。這通常意味著綁定的測試不存在或選擇器配置錯誤。

uncertain,AI 驗證器分析了程式碼但無法做出確定性判斷,附帶結構化的分析推理和置信度。

最重要的規則是:skip ≠ pass。一個沒有被驗證的場景不等於一個通過了驗證的場景。is_passing 要求 failed == 0 且 skipped == 0 且 uncertain == 0,只有所有場景都被確定性地驗證為 pass,整個 Contract 才算通過。

這種四值語意比大多數工具的 pass/fail 二值系統更誠實。它承認了一個現實:有些東西我們能確定性地驗證,有些東西我們只能機率性地判斷,有些東西我們完全沒有覆蓋。 把這三種狀態區分開來,而不是都塞進 "pass" 裡,是建立信任的基礎。

五、AI Verifier:兩種模式,一個協議

四層驗證金字塔中,前三層(Structural、Boundaries、Test)是確定性的——零 token 成本,零假陰性。但很多質量維度(競態條件、資源洩漏、隱含的安全漏洞)不在這三層的覆蓋範圍內。

AI Verifier 填補這個空白,但它的設計哲學和傳統的 AI Code Review 工具不同:它不假裝能做確定性判斷。 它的輸出永遠是 uncertain,附帶結構化的分析和置信度。人類(或更高層級的驗證系統)做最終裁決。

agent-spec 支援兩種 AI 驗證模式:

Caller 模式:呼叫方 Agent (比如 claude code)自己做 AI 驗證。這是 tool-first 場景下的預設路徑。lifecycle 執行機械驗證後,把未覆蓋的場景生成為結構化的 AiRequest,寫入 .agent-spec/pending-ai-requests.json。呼叫方 Agent(Claude Code、Codex 等)讀取請求,用自己的推理能力分析程式碼,生成 AiDecision,透過 resolve-ai 命令合併回最終報告。

# Step 1: lifecycle 發現 skip 的場景,生成 AI 請求
agent-spec lifecycle specs/task.spec --code . --ai-mode caller
# Step 2: Agent 讀取請求,分析程式碼,生成決策檔案
# Step 3: 合併 AI 決策到最終報告
agent-spec resolve-ai specs/task.spec --decisions decisions.json

這種模式下,AI 驗證的輸出流向人類而非流向自動化流程。Agent 的 retry 循環基於確定性訊號(測試通過/失敗),AI 的分析留給人類在 Contract Acceptance 階段做判斷。

Backend 模式:透過 Rust API 注入獨立的 AI 後端。適合編排系統(類 Symphony 的 orchestrator)使用不同模型做獨立驗證。宿主程式實現 AiBackend trait,注入 spec-gateway,AI 驗證在 agent-spec 內部完成。

let report = gw.verify_with_ai_backend(code, Arc::new(my_backend)).unwrap();

兩種模式共享同一套資料結構(AiRequest / AiDecision),agent-spec 保持 provider-agnostic。

六、與 jj 的結合:可選加速而非必要依賴

在智能體軟體工程第三篇文章中我們詳細分析了 jj(Jujutsu)的 Agent-friendly 特性:一切皆 commit(無 staging area 儀式)、stable change ID(跨 amend 不變)、conflicts as data(不阻塞 rebase)、operation log(原子級回退)。

agent-spec 和 jj 的結合點是自然的,但設計原則是 jj 作為可選加速器,不是必要依賴。所有核心功能在純 Git 環境下完全工作。

Change Scope:統一的變更發現

# Git 環境
agent-spec lifecycle specs/task.spec --code . --change-scope staged
agent-spec lifecycle specs/task.spec --code . --change-scope worktree
# jj 環境
agent-spec lifecycle specs/task.spec --code . --change-scope jj

在 Git 中,agent-spec 需要三個命令(staged + unstaged + untracked)才能獲取完整的變更檔案列表。在 jj 中,只需要 jj diff --name-only 一個命令——因為 jj 沒有 staging area 的區分。

BoundariesVerifier 不關心檔案列表從哪裡來——它只檢查「這些修改的檔案是否都在 Contract 的 Allowed Changes 範圍內」。

Stamp:stable change ID 追蹤

在 jj 環境下,stamp 命令額外輸出 Spec-Change trailer:

Spec-Name: 使用者註冊 API
Spec-Passing: true
Spec-Summary: 4/4 passed
Spec-Change: kkmpptqz

kkmpptqz 是 jj 的 change ID,它跨 amend 穩定。即使 Agent 後續修改了這個 commit(格式化程式碼、修復 typo),change ID 不變。Contract → Change 的追溯鏈不會斷裂。Git 的 commit hash 在 amend 後就變了,這種追溯鏈在 amend 後會失效。

Run History:跨執行 diff

agent-spec explain specs/task.spec --history

如果兩次 lifecycle 執行之間的 run log 都包含 jj operation ID,agent-spec 會呼叫 jj op diff 展示兩次執行之間 Agent 修改了哪些檔案。這回答了一個 debug 時很有價值的問題:「上次 fail、這次 pass,中間 Agent 到底改了什么?」

檢測而非配置

agent-spec 自動檢測 .jj/ 目錄的存在。有就利用 jj 的能力,沒有就退回 Git。使用者不需要在任何配置檔案中宣告「我用的是 jj」。在 colocated 倉庫中(.git/.jj/ 同時存在),agent-spec 優先使用 jj。

所有 jj 互動透過 std::process::Command 呼叫 jj CLI,不連結 jj-lib。這和 agent-spec 對 Git 的整合方式完全一致,呼叫命令而不是連結庫。如果將來出現了其他 Agent-Native VCS,只需要增加一個新的檢測分支。

七、組合性:agent-spec 不解決所有問題

這是一個需要誠實討論的邊界。

agent-spec 保證的是合約符合性。程式碼是否滿足 Contract 中定義的驗收標準。但「程式碼品質」遠比合約符合性寬泛。一段程式碼可以讓所有驗收標準通過,但仍然有競態條件、資源洩漏、不合理的抽象層次、或者不符合團隊的編碼風格。

這不是 agent-spec 的設計失誤,它是一個有意識的邊界選擇。如果 agent-spec 試圖同時解決合約驗證和程式碼品質的所有維度,它會變成一個大而全的工具,每個維度都做得不夠深。

agent-spec 的定位是編排者,它提供一個框架,讓其他工具的輸出變成 Contract 的驗收標準。程式碼品質的提升透過組合實現:

把品質規則編碼到 Spec 層級

很多程式碼品質規則是可以形式化的:

spec: project
name: "專案規則"
---
## Constraints
### Must NOT
- 禁止使用 `.unwrap()` 和 `.expect()`
- 禁止使用 `panic!` 和 `todo!`
- 禁止使用 `f32` 或 `f64` 處理金額

project.spec 的約束會被所有 task spec 繼承。agent-spec 的 StructuralVerifier 對其中的程式碼模式做機械檢測。這不需要額外的 lint 工具,agent-spec 自己就能檢查「.unwrap() 是否出現在原始碼中」。

把外部工具整合到 Completion Criteria

更強大的組合方式是把 clippy、覆蓋率工具、安全掃描器等現有工具的輸出變成驗收標準:

Scenario: Code passes clippy strict check
  Test: test_clippy_passes_with_deny_warnings
  Given the implementation is complete
  When running `cargo clippy -- -D warnings`
  Then exit code should be 0
Scenario: Test coverage above threshold
  Test: test_coverage_above_80_percent
  Given the implementation is complete
  When running coverage tool on new code
  Then line coverage should be >= 80%

這樣 Agent 不只需要讓功能測試通過,還需要讓 clippy 通過、覆蓋率達標。agent-spec 不替代這些工具。它給它們一個統一的「是否達標」判斷框架。

AI Verifier 覆蓋殘餘維度

機械工具無法檢測的維度(競態條件、設計合理性、安全漏洞推理),由 AI Verifier 做啟發式檢查。它的輸出是 uncertain,不是判決,而是給人類的補充資訊。

組合起來:project.spec 編碼通用規則(L0/L1 約束),task spec 定義任務特定的驗收標準(L2 criteria),Completion Criteria 整合外部工具的輸出,AI Verifier 覆蓋殘餘的機率性維度。每個環節用最擅長的工件,agent-spec 提供組合框架。

八、三層 Spec 繼承

agent-spec 支援三層 Spec 繼承:

org.spec → project.spec → task.spec

org.spec(組織級) 定義跨專案的安全策略和編碼標準。比如「禁止硬編碼憑證」、「所有使用者輸入必須校驗」、「認證相關程式碼必須有安全測試」。這些規則對組織內所有專案生效。

project.spec(專案級) 定義專案的技術棧決策和約定。比如「使用 PostgreSQL」、「所有 API 返回結構化錯誤」、「使用 thiserror 統一錯誤型別」。這些規則對專案內所有 task 生效。

task.spec(任務級) 定義單個任務的意圖、邊界和驗收標準。這是 Agent 直接消費的 Contract。

約束和決策自動向下繼承。task spec 中的 Agent 不需要知道 org.spec 和 project.spec 的存在。它看到的 Contract 已經合併了所有祖先層級的約束。但人類可以分層管理:安全團隊維護 org.spec,專案 lead 維護 project.spec,開發者寫 task spec。各司其職,機械合併。

九、Skills:讓 Agent 學會工作流

agent-spec 不只是一個 CLI 工具。它還需要教 Agent 怎麼使用自己。這是 Skills 的作用。

安裝

npx skills add ZhangHanDong/agent-spec

一行命令把 agent-spec 的 Skills 安裝到專案中。

兩個 Skill 的分工

agent-spec-tool-first 是預設的工作流 Skill。它教 Agent 七步工作流的完整流程:什麼時候讀 Contract、什麼時候跑 lifecycle、失敗後怎麼讀 failure_summary 並修復、什麼時候生成 explain 給人類、什麼時候跑 stamp。它還包含一條關鍵指引:lifecycle 失敗後修復程式碼,不要修改 spec 檔案,防止 Agent 「聰明地」修改驗收標準來讓驗證通過。

agent-spec-authoring 是 Spec 寫作 Skill。它教 Agent 怎麼編寫高質量的 Contract:四要素的結構、雙語關鍵詞、測試綁定的格式、step table 的語法、「異常路徑 ≥ 正常路徑」的原則。當人類讓 Agent 幫忙寫 Contract 時,這個 Skill 確保 Agent 產出的 spec 符合最佳實踐。

多 Agent 支援

Skills 不只針對 Claude Code。agent-spec 專案中還包含 Codex 的 AGENTS.md、Cursor 的 .cursorrules、Aider 的 .aider.conf.yml。雖然這些檔案比 Claude Code Skill 簡略,但它們包含了核心的命令參考和工作流步驟,讓不同的 Agent 工具都能和 agent-spec 配合工作。

agent-spec 的設計原則是 CLI-first, Agent-agnostic,核心功能透過 CLI 命令暴露,任何能呼叫 shell 命令的 Agent 都能使用。Skill 檔案是適配層,CLI 是通用層。

十、一個真實的 self-hosting 循環

agent-spec 用自己來驗證自己。專案的 specs/ 目錄下有一個 project.spec,定義了 agent-spec 自身的開發約束:

spec: project
name: "agent-spec 專案規則"
---
## Constraints
### Must
- 公開 CLI 與 gateway 行為必須有迴歸測試
- DSL 語法變更必須同時更新 AST、解析輸出和迴歸測試
- 驗證結果必須區分 pass、fail、skip、uncertain
...

每次提交都透過 agent-spec guard 檢查。每個新功能的開發都有對應的 task spec。specs/roadmap/ 下有 Phase 0 到 Phase 6 的完整路線圖 spec,它們本身就是 agent-spec 格式的 Task Contract。

這不是作秀——它是最好的測試。如果 agent-spec 不能用自己來管理自己的開發,它就沒有資格管理其他專案。

十一、當前狀態和誠實的邊界

agent-spec 當前最強的場景是 Contract 可以被以下方式檢查的情況:

從 Completion Criteria 中選取的顯式測試、StructuralVerifier 的程式碼模式匹配、BoundariesVerifier 的路徑 glob 檢查、以及針對顯式或 staged 變更集的 boundary 驗證。

它目前的限制也很清楚:

TestVerifier 是 Rust/Cargo 專屬的(透過 cargo test 執行)。非 Rust 專案可以使用 agent-spec 的 Contract 和 Boundaries 能力,但測試執行需要自定義擴充套件。

AI Verifier 的真實後端還沒有接入(stub 和 caller 模式可用)。對抗性多 Agent 驗證(Bug Finder / Skeptic / Referee 三方博弈)是 --adversarial 標誌的預留能力,實作留待真實 AI 後端接入後。

Resolver 當前只繼承 Constraints 和 Decisions,不繼承 Boundaries。如果 project.spec 定義了 Forbidden: tests/golden/**,task spec 不會自動繼承這個 boundary。

Quality score 只衡量三個維度(determinism、testability、coverage),不反映 vague-verb、unquantified、sycophancy 等 lint warning。這些 warning 出現在診斷列表中但不影響數值分數。

這些限制是已知的、已記錄的、有明確的改進路徑的。它們不妨礙 agent-spec 在當前狀態下為 Rust 專案提供真實價值。

十二、AI Coding 團隊的協作模式

當一個團隊中有多個開發者、多個 AI Agent 同時工作時,協作的核心挑戰不再是「程式碼衝突」,jj 和 Git 都能處理檔案級的合併。真正的挑戰是意圖衝突:兩個 Agent 各自完成了自己的任務,程式碼都能編譯、測試都能通過,但合在一起時行為不一致,因為它們對系統的理解不在同一個頻道上。

傳統團隊靠 Code Review 來發現這種問題。一個有經驗的 reviewer 看到兩個 PR 的 diff,腦子裡模擬合併後的行為,發現矛盾。但當 PR 數量從每天 5 個變成每天 50 個,這種靠人腦交叉驗證的方式就不可行了。

agent-spec 的三層 Spec 繼承在這裡提供了一個結構化的協調機制。

org.spec 和 project.spec 是團隊的共識錨點

在一個 AI Coding 團隊中,人類的首要工作不是寫程式碼,也不是一個一個地審查 PR,而是維護 Spec 層級。Tech Lead 維護 project.spec,定義專案的技術棧決策、API 約定、錯誤處理規範。安全團隊維護 org.spec,定義不可違反的安全底線。這些檔案是團隊所有 Agent 的共同約束。不管哪個 Agent 在執行哪個任務,它繼承的 project.spec 約束是一樣的。

這意味著當兩個 Agent 並行開發時,它們不會在技術選型上產生分歧(因為 project.spec 已經決定了用 bcrypt 還是 argon2),不會在 API 風格上產生不一致(因為 project.spec 已經定義了錯誤碼格式),不會違反安全規則(因為 org.spec 的約束被機械執行)。Spec 層級把「團隊共識」從人腦中的隱性知識變成了機器可執行的顯性約束。

Task Contract 是任務的隔離邊界

每個 task spec 的 Boundaries 段落定義了 Agent 可以修改的檔案範圍。當團隊用 agent-spec 分配任務時,一個自然的實踐是確保不同任務的 Allowed Changes 不重疊。或者如果必須重疊,在 Contract 中顯式宣告共享區域的協調策略。

agent-spec 的 lint --cross-check 可以檢測這種衝突:如果 task-A 的 Allowed Changes 和 task-B 的 Allowed Changes 有重疊路徑,cross-check 會報 warning。這不會阻塞開發,有時候兩個任務確實需要修改同一個檔案——但它讓團隊在分配任務時就意識到潛在的並發衝突,而不是等到兩個 PR 合併時才發現。

一個典型的團隊日常

想象一個四人 AI Coding 團隊的日常工作流。

上午,Tech Lead 花 30 分鐘審查和更新 project.spec。上週團隊決定統一使用結構化日誌,這個決策需要寫進 project.spec 的 Decisions 段落,這樣今後所有 Agent 都會遵循這個約定。

然後 Tech Lead 建立三個 task spec,分別分配給三個開發者。每個 task spec 定義了清晰的意圖、技術決策(繼承自 project.spec 加上任務特有的)、檔案邊界(不重疊或有意識地重疊)、和 4-6 個驗收場景(含異常路徑)。

三個開發者各自啟動自己的 AI Agent(可能是 Claude Code、可能是 Codex、可能是 Cursor,agent-spec 不關心)。Agent 讀取 Contract,在 Boundaries 內編碼,跑 lifecycle 驗證,失敗就自動重試。開發者在 Agent 工作期間可以做其他事。寫下一個任務的 Contract、審查上一個任務的 explain 輸出、或者更新 project.spec。

Agent 完成後建立 PR。CI 中的 guard 自動跑機械驗證。PR 評論中自動貼上 explain 的 Contract 摘要。Tech Lead 做 Contract Acceptance,不需要讀三個 PR 的程式碼 diff(可能加起來有 1500 行),只需要看三個 explain 摘要(每個大約 30 行),判斷 Contract 定義是否正確、驗證是否全部通過。

如果三個 PR 都通過了 Contract Acceptance,guard 的 cross-check 沒有報 boundary 衝突,它們可以被合併。整個過程中,Tech Lead 的審查時間從「讀 1500 行 diff」變成了「看 90 行 Contract 摘要」。大約節省了 80% 的 review 時間,同時因為每個 PR 都經過了確定性的四層驗證,實際的品質保證反而更強。

當 Agent 也是貢獻者

在開源場景中,情況更有趣。外部貢獻者可能直接用 AI Agent 來貢獻程式碼。這時候維護者面臨一個信任問題:你不認識這個貢獻者,你也不知道他的 Agent 用了什麼 prompt、做了多少輪修改、中間過程是什麼樣的。

agent-spec 在這裡提供的不是「信任」而是「可驗證性」。維護者不需要信任貢獻者或他的 Agent,他只需要檢查兩件事:Contract 定義的意圖和邊界是否合理(這是人類能快速判斷的),以及 lifecycle 的所有確定性檢查是否通過(這是機器已經驗證的)。信任的物件從「人」轉向了「過程」。 不管程式碼是人寫的還是 AI 寫的,它通過了同一套驗證管道,這就是可合併的充分條件。

這就是為什麼 agent-spec 在貢獻指南中強調「Contract 質量和程式碼質量同等重要」。一個外部貢獻者如果提交了一個寫得很好的 Contract——意圖清晰、決策明確、異常路徑充分、所有場景都有測試綁定。即使他的程式碼風格和團隊不一致,這個貢獻也是可以被安全接受的,因為正確性是被 Contract 和驗證管道保證的,而不是被 reviewer 的主觀判斷保證的。

結語:不是更好的 Code Review,是不同的 Code Review

回到這個系列的核心論點。

本系列文章第二篇中我們說:Agent 時代的 Code Review 不應該是「人讀更多 diff」,它應該變成「人定義意圖,機器驗證符合性」。

第三篇中我們說:Agent 時代的版本控制不應該是「Agent 學會 git add / git commit」。它應該是「VCS 自動捕獲 Agent 的工作過程」。

本文給出了一個具體的實作。agent-spec 不是一個「更好的 Code Review 工具」,它是一個不同的典範。它把審查的物件從程式碼變成了合約,把審查的時間點從編碼之後移到了編碼之前,把驗證的執行者從人變成了機器。

人類的角色不是消失了,而是升級了。從「讀程式碼找 bug」變成了「定義什麼是對的」。這是一個更高價值的活動,也是一個更可擴充套件的活動:一個好的 Contract 可以被無限多個 Agent 執行和驗證,而一個好的 reviewer 每天只能讀有限數量的 diff。

# 開始你的第一個 Contract
cargo install agent-spec
agent-spec init --level task --name "my-first-task"

專案位址:github.com/ZhangHanDong/agent-spec[2]

參考資料

[1] agent-spec: https://github.com/ZhangHanDong/agent-spec

[2] github.com/ZhangHanDong/agent-spec: https://github.com/ZhangHanDong/agent-spec


分享網址
AINews·AI 新聞聚合平台
© 2026 AINews. All rights reserved.