
AI 編程代理AI coding agent進入研發(fā)流程后團隊最先感受到的往往不是效率提升而是代碼評審壓力的增加。Figma 工程師在 AI Engineer 相關分享中討論過同一個問題當代理自動完成跨文件修改、自動執(zhí)行命令、自動生成測試時如何保證最終提交的代碼仍然是干凈、可維護、可回滾的。核心結論并不是“少用 AI”而是先用工程手段把 AI 約束在安全邊界內。這篇文章不準備逐句復述某一場演講而是把這一類實踐整理成一套可以在自己團隊中復用的落地流程。整個過程會圍繞一條主線展開先理解 AI 編程代理為什么會產(chǎn)出質量不可控的代碼然后從任務邊界、倉庫規(guī)則、自動化校驗、代碼評審、線上監(jiān)控和回滾幾個環(huán)節(jié)建立護欄。每個環(huán)節(jié)都會給出可執(zhí)行的配置、命令和檢查清單盡量做到看完就能在自己項目里試點。1. 先理解 AI 編程代理為什么會寫出“垃圾代碼”1.1 輔助補全工具與自主代理的最大區(qū)別很多團隊已經(jīng)習慣了 AI 補全工具的工作方式人寫函數(shù)名AI 補函數(shù)體人再手動修改。這種模式下修改方向和整體結構都由人控制AI 只是加速了局部輸入。AI 編程代理不一樣。它接收的是一個任務描述而不是某一行代碼的上下文。它會自己搜索代碼庫、修改多個文件、執(zhí)行構建命令、讀取測試結果甚至反復重試。人從“逐行寫代碼”退后到“發(fā)布任務和檢查結果”。這一變化帶來的風險是結構性的人不再對每個修改點有直接感知。AI 可能為了滿足任務描述修改超出范圍的文件。AI 傾向于讓測試通過但不一定理解代碼庫的歷史約定和設計意圖。一旦任務描述模糊AI 會主動腦補業(yè)務規(guī)則產(chǎn)生“看起來合理、實際上錯誤”的代碼。所以把 AI 編程代理接入倉庫第一步不是打開工具開關而是先理解它和補全工具完全不同的工作模式。1.2 “垃圾代碼”在代理場景下有哪些典型表現(xiàn)“垃圾代碼”不是一個籠統(tǒng)的貶義而是一類可以在評審和運行時被識別的問題。在 AI 編程代理場景下最常見的是這幾種現(xiàn)象具體表現(xiàn)為什么容易發(fā)生表面可用但內部混亂大量 if else 堆疊、復制粘貼式修改、命名隨意AI 優(yōu)化的是“讓測試通過”而不是可讀性錯誤處理空白吞掉異常、空值不判斷、網(wǎng)絡錯誤不重試任務描述里沒有提出錯誤分支要求過度設計為一個簡單字段引入抽象接口和工廠AI 從訓練數(shù)據(jù)中學習到“看起來專業(yè)的寫法”修改范圍失控改完目標函數(shù)后順手改掉公共工具類代理在檢索上下文時發(fā)現(xiàn)“相關代碼”就會一并改測試失效測試斷言被調整成恒真條件或只覆蓋正向路徑代理為了自圓其說會修改測試來匹配實現(xiàn)隱性破壞調用方?jīng)]改、函數(shù)簽名變了、返回結構變了代理只關注當前任務覆蓋到的調用點這些問題的共同根源是代理在優(yōu)化一個局部目標。它沒有項目全局視角也不清楚哪些代碼是核心資產(chǎn)、哪些代碼是臨時方案、哪些修改需要同步通知其他團隊。1.3 先設護欄再談效率Figma 工程師在分享中反復強調的一點是把 AI 編程代理當作“高速但經(jīng)驗不足的工程師”來管理而不是當成一個純生成器。一個剛入職的工程師公司會給他什么明確的任務邊界。倉庫結構和編碼規(guī)范。構建、測試、lint 命令。代碼評審機制。上線后的監(jiān)控和回滾手段。這些就是護欄。AI 編程代理同樣需要這套東西而且需要得更嚴格因為它的“理解能力”來自上下文而不是長期記憶。如果倉庫里沒有明確的規(guī)則文件代理就會按照自己的默認偏好寫代碼如果任務描述沒有邊界它就會把相關文件全改一遍如果合并前沒有強制校驗它就能把編譯不過或測試失敗的代碼直接推進主干。所以安全落地的核心不是“更聰明的模型”而是更完整的工程流程。后續(xù)章節(jié)按這個順序展開接入前準備、任務拆分、自動校驗、代碼評審、線上監(jiān)控、失敗復盤。2. 接入 AI 編程代理前確定邊界、規(guī)則和基線2.1 先回答三個問題做什么、不做什么、怎么算完成接入代理前團隊需要先對使用場景達成一致。不是所有任務都適合交給代理也不是所有代碼庫都適合在第一天開放全部目錄。推薦先按任務類型做評估任務類型適合交給代理嗎風險等級說明生成單元測試適合中需要人檢查斷言是否有效代碼補全適合低人在當前文件中掌握上下文Bug 修復視情況中高必須先有穩(wěn)定復現(xiàn)路徑跨模塊重構謹慎高建議拆成小步執(zhí)行自動化腳本生成適合低獨立腳本影響范圍小底層公共庫修改不建議初期開放極高影響所有調用方這三個問題必須在試點前回答清楚這個任務允許代理修改哪些目錄和文件。這個任務禁止代理修改哪些目錄和文件。任務完成的驗收標準是什么包括測試覆蓋率、構建通過、無 lint 錯誤等。沒有邊界判斷就放代理進倉庫等于讓一個新工程師自己決定改哪里。區(qū)別是真人會問代理不會問。2.2 在倉庫根目錄建立規(guī)則文件把團隊的編碼約束寫進一個代理可讀、人也可見的規(guī)則文件。目前很多編程代理會主動讀取倉庫根目錄下的AGENTS.md或等價文件并把它作為系統(tǒng)的上下文注入。這個文件可以包括項目技術棧和關鍵依賴。構建、測試、lint 的準確命令。目錄結構和職責劃分。編碼風格約定。禁止修改的目錄和文件。提交信息規(guī)范。完成任務的 Definition of Done。下面是一個AGENTS.md示例可以直接作為起點# 項目規(guī)則 ## 技術棧 - Python 3.11 - FastAPI - SQLAlchemy 2.x - pytest ## 常用命令 - 安裝依賴: pip install -e .[dev] - 單測: pytest tests/ -x -q - 類型檢查: mypy app/ - 格式化: ruff format app/ tests/ - lint: ruff check app/ tests/ ## 目錄職責 - app/api: 路由層只做參數(shù)解析和響應封裝 - app/services: 業(yè)務邏輯層 - app/models: ORM 模型 - app/migrations: 數(shù)據(jù)庫遷移文件禁止手動改動 ## 禁止修改 - app/migrations/ - docs/ - gen/ ## 編碼約束 - 函數(shù)需要 docstring - 禁止裸 except必須捕獲具體異常類型 - 新增對外接口必須包含輸入校驗 - 錯誤信息不允許直接暴露內部堆棧 ## 提交信息 - 遵循 Conventional Commits - 示例: fix(api): handle empty user id ## 完成定義 - pytest 全部通過 - mypy 無錯誤 - ruff check 無錯誤 - 不修改任務范圍之外的文件注意不要把規(guī)則文件寫得像散文。代理對長文本的理解能力有限規(guī)則要短、要清晰、要可檢查。比如“保持代碼整潔”這種話沒有意義要寫成“函數(shù)長度不超過 50 行超出則拆分”。2.3 先把代碼庫基線跑穩(wěn)態(tài)在讓代理開始改代碼之前倉庫本身必須是健康的。否則會出現(xiàn)一個經(jīng)典的死循環(huán)代理跑出錯誤你分不清是它造成的還是倉庫原本就有的。建議先完成# 本地完整執(zhí)行一遍 pip install -e .[dev] pytest tests/ -x -q mypy app/ ruff check app/ tests/ # 記錄執(zhí)行結果和時間 echo baseline done .ai_agent_baseline這道工序有幾個作用確認 CI 命令和本地命令一致避免代理在本地通過了、CI 卻失敗。確認測試基線是綠的代理后續(xù)改動如果破壞測試可以直接定位到它。確認構建時間合理如果一次測試要跑 30 分鐘代理的每次嘗試都會很昂貴。如果倉庫里存在大量歷史遺留的失敗測試先把它們清理掉或者標注skip再讓代理介入。否則代理會修復失敗測試作為“完成目標”而不會關心這些測試是否應該有。3. 任務拆分與上下文注入不要讓代理吃下過大的任務3.1 一個任務對應一個可評審的變更集把 AI 編程代理想象成一個只會專注當前 prompt 的工程師。給它一個“優(yōu)化整個訂單系統(tǒng)”的任務它會輸出一個幾百行甚至上千行的 diff。這種 diff 很難評審而且一旦產(chǎn)生問題很難定位是哪一步引入的。推薦的拆分粒度是一個任務只解決一個問題一個任務生成的變更集要能被人在 15 到 30 分鐘內評審完。下面的任務描述模板可以直接復制使用## 目標 修復 API 層在用戶 ID 為空時返回錯誤碼的問題。 ## 范圍 - app/api/users.py - tests/test_api_users.py ## 禁止修改 - app/services/ - app/models/ - app/migrations/ ## 驗收標準 - 新增測試覆蓋 user_id 為 None 和空字符串兩種情況 - pytest tests/test_api_users.py -x -q 通過 - ruff check app/api/users.py 通過 - 不修改范圍之外的文件這個模板的關鍵是明確了邊界和驗收標準。代理不需要猜測它只需要執(zhí)行。3.2 上下文越多不代表效果越好有些團隊為了讓代理更“懂業(yè)務”會把整個技術設計文檔、需求文檔、歷史變更記錄全部塞進 prompt。這會導致幾個問題上下文過長后代理會把注意力分散到無關信息上。關鍵約束被淹沒在大量文本中間。每次請求的成本和時間都會上升。更合理的做法是分三層提供上下文上下文類型內容示例全局規(guī)則倉庫級規(guī)則文件代理自行讀取AGENTS.md任務上下文當前需求的背景和業(yè)務規(guī)則prompt/issue 描述局部參考類似功能的實現(xiàn)代碼或接口定義粘貼少量代碼片段在實際操作中不需要把整個業(yè)務背景都復制到 prompt 里。告訴代理“這個函數(shù)是給前端登錄接口用的user_id 來自 JWT token為空說明鑒權失效應該返回 401”遠好于貼三頁需求文檔。3.3 分支策略讓代理的錯誤被隔離代理在執(zhí)行任務時可能會反復嘗試、提交失敗代碼。不要讓它在主干分支上直接工作至少在試點階段給每次任務開一個獨立分支。git checkout -b feat/ai-agent/user-id-validation如果需要多個代理并行處理不同任務命名規(guī)則可以用ai-agent/任務標簽作為前綴方便后續(xù)統(tǒng)一 review 和清理。代理完成后的工作流# 拉取最新主干并合并到當前分支 git fetch origin main git merge origin/main # 運行完整校驗 pytest tests/ -x -q mypy app/ ruff check app/ tests/ # 查看最終變更范圍 git diff --stat main...git diff --stat main...這一步很重要它能讓你在合入前直觀看到代理到底改了哪些文件。如果出現(xiàn)大量與任務無關的文件應該直接打回而不是手動挑揀。4. 從生成到合并強制自動校驗和人工評審關卡4.1 合并前的自動化檢查不能只依賴“代理自測”代理在執(zhí)行任務時通常會自己運行一遍測試但這個自測結果只能作為參考。它的測試目標可能被污染它也可能因為環(huán)境差異在自己的沙箱里通過、在 CI 里失敗。所以倉庫必須有一套不依賴代理自身的強制檢查流程。最簡單的方式是在 CI 中增加一個獨立的 job專門校驗代理分支name: ai-agent-check on: pull_request: types: [opened, synchronize] jobs: verify: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 with: fetch-depth: 0 - uses: actions/setup-pythonv5 with: python-version: 3.11 - run: pip install -e .[dev] - run: pytest tests/ -x -q - run: mypy app/ - run: ruff check app/ tests/ - run: ruff format --check app/ tests/ - name: check diff scope run: | # 如果任務只允許修改 app/api/則檢測是否出現(xiàn)其他目錄變更 if git diff --name-only origin/main...HEAD | grep -qv ^app/api/ ; then echo 發(fā)現(xiàn)代理修改了范圍之外的目錄 exit 1 fi這里的check diff scope是關鍵步驟。它做了一件代碼評審中最容易被忽略的事情確認變更范圍是否越界。代理也許能通過所有測試但如果它改壞了app/models/下的數(shù)據(jù)模型AI 生成的測試根本無法覆蓋所有調用方的影響。本地同樣可以做一個 pre-push 鉤子避免代理把明顯不合規(guī)的代碼推到遠端#!/usr/bin/env bash # .git/hooks/pre-push 或項目內的 pre-push 腳本 set -e echo running ai-agent pre-push checks... pytest tests/ -x -q mypy app/ ruff check app/ tests/4.2 人工評審的重點不是“讀代碼”而是“問問題”即使自動化檢查全綠也不能直接把 AI 生成的代碼合入。人工評審仍然不可省略但評審方式需要調整。AI 生成代碼的評審重點不是逐行檢查語法而是回答這幾個問題這個改動解決了任務描述里的問題嗎它有沒有修改任務范圍之外的文件錯誤處理是否真實還是只是讓測試通過有沒有引入重復邏輯或新的抽象而這個抽象沒有明顯收益測試是否真的會失敗把關鍵斷言暫時改錯測試是否變紅是否有并發(fā)、時間、數(shù)據(jù)一致性方面的問題依賴和數(shù)據(jù)庫遷移是否被無意修改可以把這些整理成評審模板合入每個 AI 代理 MR 時使用評審點檢查內容通過標準范圍控制與git diff --stat對比任務范圍無越界文件正確性能復述這次改動解決的業(yè)務場景理解與任務一致異常處理空值、異常、超時等分支有處理不吞錯、不裸 except測試質量故意破壞斷言測試是否失敗測試有實際約束力重復代碼搜索是否已有相似實現(xiàn)沒有重復邏輯修為接口公共函數(shù)簽名、返回結構是否改變調用方已經(jīng)同步更新性能風險是否有循環(huán)內查詢、N1、大對象復制明顯性能隱患已消除4.3 要求代理先完成自檢并通過 prompt 約束行為可以讓代理在生成代碼后自動執(zhí)行一系列檢查并把輸出結果帶回。比如在任務描述中追加## 提交前自檢 在生成最終結果之前你必須執(zhí)行以下命令 1. pytest tests/test_api_users.py -x -q 2. mypy app/api/users.py 3. ruff check app/api/users.py 如果檢查失敗繼續(xù)修復直至通過。如果無法通過需要說明具體原因和待確認問題。這種方式相當于要求代理輸出一份“自檢報告”。它不一定完全準確但可以提升代理對錯誤的關注程度也能幫你快速判斷代理卡在了哪個環(huán)節(jié)。要注意不要因為代理報告“全部通過”就直接合入報告需要和 CI 結果交叉驗證。5. 上線后的監(jiān)控與回滾質量問題是運行時才暴露的5.1 區(qū)分學習環(huán)境與生產(chǎn)環(huán)境的要求在本地試用 AI 編程代理時可以只關注“代碼能不能跑”。但一旦進入生產(chǎn)環(huán)境AI 生成代碼的質量判斷標準就要切換到運行表現(xiàn)上維度學習環(huán)境生產(chǎn)環(huán)境驗收標準編譯通過、本地測試綠錯誤率、耗時、業(yè)務指標無回退檢查手段IDE、手動測試日志、監(jiān)控、告警、鏈路追蹤問題處理改代碼重新跑先止血、再定位、再修復數(shù)據(jù)要求造數(shù)方便、無真實用戶需要考慮兼容和數(shù)據(jù)遷移回滾方式git revert功能開關、版本回滾、數(shù)據(jù)庫兼容方案如果團隊正在用代理生成數(shù)據(jù)庫變更或涉及支付、權限的核心代碼上線前必須增加一層額外評審并且盡量讓變更可以在不重新發(fā)布代碼的前提下被關閉。5.2 上線后先看異常率再看耗時最后看業(yè)務指標生產(chǎn)環(huán)境不會直接告訴你“代碼寫錯了”它只會通過指標異常間接表達。針對 AI 生成代碼建議上線后按這個順序觀察錯誤率如果部署后錯誤率出現(xiàn)明顯增長優(yōu)先懷疑新增邏輯的異常分支沒有處理好。耗時P50、P95、P99 是否上漲提示可能存在循環(huán)內查詢、不必要的重試或無界緩存。業(yè)務指標訂單成功率、接口調用量、轉化率是否有回退防止代理把業(yè)務邏輯改出偏差。下面是一個簡單的壓測對比方式用于上線前快速暴露代理改動的性能問題# 部署前在基準版本上記錄指標 k6 run --summary-exportbaseline.json load-test.js # 部署代理分支后再次執(zhí)行 k6 run --summary-exportafter.json load-test.js # 對比 P95 耗時 python -c import json with open(baseline.json) as f: base json.load(f) with open(after.json) as f: after json.load(f) b base[metrics][http_req_duration][values][p(95)] a after[metrics][http_req_duration][values][p(95)] print(fP95 baseline{b:.2f}ms after{a:.2f}ms) 如果 P95 從 300ms 漲到 500ms就要懷疑代理是否在高頻路徑里加了不需要的同步邏輯或重復查詢。5.3 回滾方案要在合入之前寫好AI 生成代碼合入之前應該先回答一個問題如果線上出了問題怎么最快回到上一個穩(wěn)定版本。推薦三種回滾手段按速度排序手段速度適用場景功能開關秒級新功能可以整體關閉版本回滾分鐘級代碼變更和數(shù)據(jù)庫兼容補丁修復半小時以上問題定位明確、影響面小同時要注意數(shù)據(jù)庫回滾。如果代理生成的代碼包含數(shù)據(jù)庫遷移不能只回滾代碼而不回滾數(shù)據(jù)。例如新增了一個非空字段代碼回滾后舊代碼不會寫這個字段而數(shù)據(jù)庫又要求它非空就會出現(xiàn)線上寫入失敗。這類問題必須在評審階段提前規(guī)避盡量讓數(shù)據(jù)庫變更向后兼容。5.4 把線上問題反哺給規(guī)則文件每一次由 AI 生成代碼引發(fā)的線上故障都是規(guī)則文件迭代的素材。問題修復后應回答這幾個問題規(guī)則文件里缺少了哪條約束任務描述模板里缺少了哪個驗收標準評審清單里漏掉了哪個檢查點例如如果代理因為吞掉了 Redis 連接異常導致緩存雪崩那就應該把這條加入規(guī)則## 編碼約束 - 所有 Redis 調用必須設置超時時間 - Redis 異常必須記錄日志并返回降級響應不允許吞掉異常規(guī)則文件不是一次性寫好的它是團隊和 AI 協(xié)作過程的“沉淀物”。出現(xiàn)一次問題就補一條規(guī)則一段時間后代理能犯的錯誤會明顯變少。6. 常見失敗模式與排查路徑6.1 問題現(xiàn)象、原因、檢查方式對照表實踐中AI 編程代理相關的問題通常集中在幾個固定場景。下面這張表可以直接用于團隊內部排查問題現(xiàn)象常見原因檢查方式處理建議代理生成大量無關代碼任務描述沒有明確禁止目錄用git diff --stat查看文件范圍補充禁止修改列表設定范圍檢查腳本測試全綠但線上出錯測試斷言被改弱或沒有覆蓋真實業(yè)務分支抽查關鍵斷言故意破壞實現(xiàn)看是否變紅要求測試必須驗證業(yè)務結果代理反復執(zhí)行命令失敗本地命令和 CI 命令不一致或依賴版本沖突對比AGENTS.md命令與 CI 配置統(tǒng)一命令先跑通基線代理一直修改同一個問題上下文里缺少錯誤信息或根因提示查看代理的執(zhí)行日志和最后一次報錯補充日志或錯誤信息到任務上下文規(guī)則文件沒有生效文件名不在代理支持的范圍內或路徑不對查看代理讀取的文件列表使用標準AGENTS.md文件名代理改壞公共函數(shù)對調用方感知不足檢查公共 API 變更 diff對公共模塊單獨設置評審人和保護分支6.2 典型排查示例代理完成任務但 CI 失敗假設你收到一個代理分支的 PRCI 報錯顯示類型檢查失敗但代理在任務描述里聲稱“所有檢查通過”??梢园聪旅孢@條鏈路排查第一步確認它改了哪些文件git diff --name-only origin/main...HEAD第二步檢查是否改動了AGENTS.md里聲明過的依賴或配置git diff origin/main...HEAD -- pyproject.toml requirements.txt第三步在本地用 CI 相同的命令復現(xiàn)rm -rf .venv python -m venv .venv source .venv/bin/activate pip install -e .[dev] mypy app/第四步如果本地能復現(xiàn)類型錯誤讓代理重新修復時把錯誤信息完整放到 prompt 中類型檢查失敗錯誤如下 app/api/users.py:42: error: User has no attribute name 請修復類型問題不要修改 users.py 之外的文件。這個流程的關鍵是按順序排查先看輸入任務和規(guī)則再看環(huán)境依賴和命令最后看輸出代碼和錯誤。不要一上來就懷疑模型能力大多數(shù)問題其實出在流程和上下文上。7. 從試點到制度化讓 AI 編程代理真正可控7.1 先在小范圍試點不要全團隊鋪開AI 編程代理落地不適合“一刀切”。建議先挑選 2 到 3 個具備以下特征的項目有完整的自動化測試至少覆蓋核心用例。構建時間相對短在 10 分鐘內可以完成。技術棧統(tǒng)一依賴清晰。團隊成員愿意接受新的評審方式。試點期間定義兩個核心指標不要追求過度復雜的度量AI 分支被合入的比例反映代理產(chǎn)出是否有可用性。AI 分支引發(fā) CI 失敗或線上問題的次數(shù)反映代理是否穩(wěn)定。每周復盤一次重點看失敗案例而不是成功案例。成功案例只能說明流程沒被觸發(fā)失敗案例才能暴露流程缺口。7.2 將規(guī)則、模板和評審清單固化為團隊規(guī)范當試點驗證有效后再把流程制度化把AGENTS.md納入倉庫根目錄評審范圍規(guī)則變更需要走 MR。把任務描述模板、評審模板上傳到團隊文檔庫或 MR 模板中。在 CI 中增加代理分支專用的范圍檢查任務。讓團隊每個成員都學會寫“可執(zhí)行的任務描述”而不是一句話需求。在評審 AI 生成代碼時要求提交者附帶代理的自檢日志。制度化不是為了增加流程負擔而是為了讓每一次代理使用都產(chǎn)生可追蹤、可復測、可改進的記錄。沒有記錄的流程無法沉淀經(jīng)驗。7.3 可復用的落地檢查清單下面是一份可以直接打印出來貼在工位旁的檢查清單也可以作為 MR 模板的一部分。接入前檢查[ ] 倉庫能穩(wěn)定通過 build、test、lint[ ]AGENTS.md已包含技術棧、命令、目錄邊界、禁止修改項[ ] CI 已有獨立的代理分支校驗 job[ ] 已知哪些任務類型適合代理哪些不適合每次任務開始時[ ] 任務描述包含目標、涉及文件、禁止修改項、驗收標準[ ] 任務粒度控制在可評審的 diff 范圍內[ ] 代理在獨立分支上工作合并前檢查[ ] 對比git diff --stat確認沒有越界文件[ ] 自動檢查全部通過[ ] 評審清單中的錯誤處理、測試有效性、公共接口影響已確認[ ] 數(shù)據(jù)庫變更確認向后兼容[ ] 回滾方案已準備好上線后觀察[ ] 錯誤率、P95 耗時、核心業(yè)務指標與基線對比[ ] 發(fā)現(xiàn)問題先回滾再定位根因[ ] 將根因和預防措施更新到AGENTS.md這一套流程做完AI 編程代理會在倉庫里留下大量高質量代碼同時把風險控制在可接受的范圍。它不會自動寫出完美代碼但團隊可以通過流程讓“垃圾代碼”很難通過每一道關卡。Figma 工程師的分享之所以值得借鑒不是因為 Figma 使用了某個特別的工具而是因為它把 AI 編程代理當作系統(tǒng)中的一個組件來治理。任何團隊都可以用同樣的思路先設置規(guī)則再開放權限先用小范圍驗證再擴大使用先保證能回滾再追求效率。方向對了代碼質量自然會向好的方向收斂。