提測前讓 AI 檢查一下程式碼,我的 Bug 率降低了 20%

因為公司給了 Cursor 的席位,所以本文主要以前端使用 Cursor CLI 的視角來說,Claude Code 或其他 AI 工具也可以用這套工作流程,後端也可以用類似的流程。

先說說標題,這裡不是說 AI 能直接把專案品質提升 20%,也不是說它能取代測試、Code Review 或自測。我這裡說的 Bug 率下降,指的是在提測前多加了一道 AI Review 流程之後,測試階段暴露出來的低級問題明顯少了。

比如這些問題:

text 體驗AI程式碼助手 程式碼解讀複製程式碼介面欄位為空導致頁面白屏
按鈕重複點擊導致重複提交
loading / empty / error 狀態漏處理
介面欄位改名後沒有相容舊資料
權限按鈕顯示條件漏了某個狀態
例外被吞掉,測試環境只看到「操作失敗」

這些 Bug 不一定複雜,但很消耗測試和開發的溝通成本。以前經常是提測之後測試同學點出來,開發再回去修。後來我在提測前加了一步:用腳本自動提取本次 git diff,交給 Cursor CLI 做一次程式碼審查,然後輸出一份 Markdown 報告

最後落到專案裡,就一個指令:

bash 體驗AI程式碼助手 程式碼解讀複製程式碼npm run ai-review

跑完會生成:

text 體驗AI程式碼助手 程式碼解讀複製程式碼.review/ai-review.md

這份 Markdown 就是提測前的 AI Review 報告。

它不會替你寫業務邏輯,也不會保證「零 Bug」。但對於一些低級、重複、容易漏看的問題,它確實能提前攔下一部分。對我來說,這一步最大的價值不是「讓 AI 證明程式碼沒問題」,而是:在提測前先讓 AI 幫我掃一遍本次改動,把明顯風險暴露出來


為什麼是提測前,而不是上線前?

很多團隊會把 AI Review 放到上線前,作為發佈前最後一道兜底。這當然也有價值。

但我更建議把它前移到提測前。

原因很簡單:越晚發現問題,修復成本越高。

上線前發現問題,往往已經進入發佈窗口,大家的關注點是「能不能發」。這時候再改程式碼,容易引入新的不確定性。提測前發現問題就不一樣了,此時需求還在開發流轉階段,修復、補測、重新自測都更從容。

這一步不是取代測試,而是減少一些「不該流到測試階段的問題」。

尤其是前端專案,很多 Bug 並不是編譯錯誤,而是狀態邊界沒兜住:空資料、慢介面、重複點擊、彈窗重置、權限顯示、介面欄位相容。這些問題靠人工檢查程式碼不一定能發現,但 AI 基於 diff 做一次 Review,反而有機會提醒出來。


為什麼用 git diff,而不是讓 AI 掃整個專案?

很多人第一次用 AI 審程式碼,會直接問:

text 體驗AI程式碼助手 程式碼解讀複製程式碼幫我檢查目前分支有沒有問題

這個問法通常效果不好。

專案太大,上下文太散,AI 很容易給出一些正確但沒用的建議,比如:

text 體驗AI程式碼助手 程式碼解讀複製程式碼建議補充單元測試
建議優化例外處理
建議增強程式碼可讀性
建議完善註解

這些建議當然不能說錯,但對「這次能不能提測」幫助有限。

提測前真正要看的不是整個專案,而是:

text 體驗AI程式碼助手 程式碼解讀複製程式碼這次到底改了什麼?
這些改動有沒有明顯風險?
有沒有可能導致測試階段直接報 Bug?
有沒有可能影響舊邏輯、舊資料、舊介面?

這就是 git diff 的價值。

git diff 天然就是本次改動的邊界。把 AI Review 的範圍限制在 diff 裡,輸出會更聚焦,也更接近真實 Code Review 的思路。

所以這套流程的核心不是「讓 AI 掃專案」,而是:

text 體驗AI程式碼助手 程式碼解讀複製程式碼自動產生本次 git diff
自動呼叫 Cursor CLI 審查
自動輸出 Markdown 報告
開發者人工確認報告裡的風險

最終使用方式

設定完成後,提測前只需要執行:

bash 體驗AI程式碼助手 程式碼解讀複製程式碼npm run ai-review

預設比較:

text 體驗AI程式碼助手 程式碼解讀複製程式碼origin/main...HEAD

也就是目前分支相對 origin/main 的所有變更。

如果你本機 Cursor CLI 指令不是 agent,而是 cursor-agent,可以這樣執行:

bash 體驗AI程式碼助手 程式碼解讀複製程式碼CURSOR_CLI=cursor-agent npm run ai-review

執行完成後,直接打開報告:

bash 體驗AI程式碼助手 程式碼解讀複製程式碼cat .review/ai-review.md

專案裡會生成幾個輔助檔案:

text 體驗AI程式碼助手 程式碼解讀複製程式碼.review/release.stat       # 改動統計
.review/release.files      # 改動檔案列表
.review/release.diff       # 完整 diff
.review/review-prompt.md   # 本次 Review 使用的 Prompt
.review/ai-review.md       # 最終 AI Review 報告

其中最重要的是 .review/ai-review.md。提測前主要看這份檔案即可。


準備工作

先確認本機已經安裝 Cursor CLI。

官方安裝方式一般是:

bash 體驗AI程式碼助手 程式碼解讀複製程式碼curl https://cursor.com/install -fsSL | bash

安裝後可以看一下指令是否可用:

bash 體驗AI程式碼助手 程式碼解讀複製程式碼agent --version

有些環境或舊教學裡指令名可能還是:

bash 體驗AI程式碼助手 程式碼解讀複製程式碼cursor-agent --version

下面預設用 agent 示範。如果你的本機指令是 cursor-agent,可以透過環境變數切換:

bash 體驗AI程式碼助手 程式碼解讀複製程式碼CURSOR_CLI=cursor-agent npm run ai-review

Cursor CLI 支援在終端機或 headless 環境中使用 Agent,也支援腳本化、自動化場景;-p / --print--output-format--mode ask 等參數可以用於非互動式執行。([Cursor][1])


第一步:新增 npm script

package.json 裡增加一個腳本:

json 體驗AI程式碼助手 程式碼解讀複製程式碼{
  "scripts": {
    "ai-review": "node scripts/ai-review.mjs"
  }
}

這樣團隊成員不需要記住具體腳本路徑,也不需要關心底層到底執行了哪些指令。只要會跑專案裡的 npm script,就能使用這套提測前檢查流程。

後續統一約定為:

bash 體驗AI程式碼助手 程式碼解讀複製程式碼npm run ai-review

這個指令會自動完成三件事:

text 體驗AI程式碼助手 程式碼解讀複製程式碼1. 自動比對 origin/main...HEAD
2. 自動生成本次 diff 檔案
3. 自動呼叫 Cursor CLI 輸出 Markdown 審查報告

第二步:新增自動審查腳本

新增檔案:

text 體驗AI程式碼助手 程式碼解讀複製程式碼scripts/ai-review.mjs

腳本內容如下:

js 體驗AI程式碼助手 程式碼解讀複製程式碼import { execFileSync } from 'node:child_process';
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const rootDir = resolve(__dirname, '..');

const baseBranch = process.argv[2] || 'origin/main';
const target = process.argv[3] || 'HEAD';
const cursorCli = process.env.CURSOR_CLI || 'agent';

const reviewDir = resolve(rootDir, '.review');
const statFile = resolve(reviewDir, 'release.stat');
const filesFile = resolve(reviewDir, 'release.files');
const diffFile = resolve(reviewDir, 'release.diff');
const promptFile = resolve(reviewDir, 'review-prompt.md');
const outputFile = resolve(reviewDir, 'ai-review.md');

const ignorePaths = [
  ':!dist',
  ':!build',
  ':!coverage',
  ':!node_modules',
];

function run(command, args, options = {}) {
  return execFileSync(command, args, {
    cwd: rootDir,
    encoding: 'utf8',
    stdio: options.stdio || ['ignore', 'pipe', 'pipe'],
  });
}

function write(file, content) {
  writeFileSync(file, content, 'utf8');
}

function hasOriginRemote() {
  try {
    run('git', ['remote', 'get-url', 'origin'], { stdio: 'ignore' });
    return true;
  } catch {
    return false;
  }
}

function ensureReviewDir() {
  if (!existsSync(reviewDir)) {
    mkdirSync(reviewDir, { recursive: true });
  }
}

function generateDiffFiles() {
  const range = `${baseBranch}...${target}`;
  const pathspec = ['--', '.', ...ignorePaths];

  write(statFile, run('git', ['diff', '--stat', range, ...pathspec]));
  write(filesFile, run('git', ['diff', '--name-only', range, ...pathspec]));
  write(diffFile, run('git', ['diff', '--unified=80', range, ...pathspec]));
}

function generatePrompt() {
  const prompt = `你現在是一名資深前端程式碼審查員,請基於本次 git diff 做提測前 Review。

請讀取以下檔案:
- .review/release.stat:改動統計
- .review/release.files:改動檔案列表
- .review/release.diff:完整程式碼 diff

Review 目標:
找出本次變更中可能在測試階段暴露為 Bug 的風險點,重點關注業務正確性、執行時穩定性、介面相容性和使用者操作邊界。

請重點檢查:
1. 是否有 undefined、null、空陣列、空物件導致的執行時錯誤
2. 是否有介面入參、出參、欄位名、欄位型別的相容性問題
3. 是否有權限、驗證、越權存取或權限顯示問題
4. 是否有重複請求、請求競態、按鈕重複提交問題
5. 是否有 loading、error、empty 狀態缺失問題
6. 是否有彈窗、表單、分頁、篩選條件狀態沒有重置的問題
7. 是否有快取更新、快取失效、快取髒資料問題
8. 是否有例外處理不完整,或者錯誤被吞掉的問題
9. 是否有配置、環境變數、灰度開關缺失預設值的問題
10. 是否有埋點、日誌缺失,導致問題難以定位
11. 是否有回滾風險,或者新舊邏輯不能相容的問題

輸出格式:

## Review 結論

用一句話說明是否建議提測。如果存在 P0,請明確寫「不建議提測」。

## P0 阻塞提測問題

沒有則寫「無」。

## P1 高風險問題

沒有則寫「無」。

## P2 建議優化

只寫和本次 diff 強相關的建議,不要輸出套話。

## 人工確認項

列出 AI 無法完全判斷、但提測前應該人工確認的事項。

要求:
- 只基於本次 diff 分析,不要泛泛而談。
- 每個問題都要寫清楚:檔案、問題描述、風險、建議修改、是否阻塞提測。
- 不要評價程式碼風格,除非它會導致真實 Bug。
- 不要輸出「建議補充單元測試」這種空泛建議,除非能指出具體應該測試哪個分支。
- 如果 diff 資訊不足,可以明確說明需要補充哪個檔案或哪段上下文。
- 如果沒有明顯問題,直接說明「未發現阻塞提測問題」,不要硬湊建議。
`;

  write(promptFile, prompt);
  return prompt;
}

function runCursorReview(prompt) {
  const result = run(cursorCli, [
    '-p',
    '--mode',
    'ask',
    '--output-format',
    'text',
    prompt,
  ]);

  write(outputFile, result);
}

function main() {
  ensureReviewDir();

  console.log(`Base branch: ${baseBranch}`);
  console.log(`Target: ${target}`);
  console.log(`Cursor CLI: ${cursorCli}`);

  if (hasOriginRemote()) {
    console.log('Fetching origin...');
    run('git', ['fetch', 'origin', '--prune'], { stdio: 'inherit' });
  }

  console.log('Generating git diff files...');
  generateDiffFiles();

  console.log('Generating review prompt...');
  const prompt = generatePrompt();

  console.log('Running Cursor CLI review...');
  runCursorReview(prompt);

  console.log(`AI review report generated: ${outputFile}`);
}

main();

這個腳本做了幾件事:

text 體驗AI程式碼助手 程式碼解讀複製程式碼1. 預設比較 origin/main...HEAD
2. 生成改動統計、改動檔案列表、完整 diff
3. 自動寫入提測前 Review Prompt
4. 呼叫 Cursor CLI 做唯讀審查
5. 把結果寫入 .review/ai-review.md

第三步:執行 npm run ai-review

設定好以後,直接執行:

bash 體驗AI程式碼助手 程式碼解讀複製程式碼npm run ai-review

控制台大概會輸出:

text 體驗AI程式碼助手 程式碼解讀複製程式碼Base branch: origin/main
Target: HEAD
Cursor CLI: agent
Fetching origin...
Generating git diff files...
Generating review prompt...
Running Cursor CLI review...
AI review report generated: /your-project/.review/ai-review.md

然後查看報告:

bash 體驗AI程式碼助手 程式碼解讀複製程式碼cat .review/ai-review.md

如果想在編輯器裡看,也可以直接:

bash 體驗AI程式碼助手 程式碼解讀複製程式碼code .review/ai-review.md

這時候 .review/ai-review.md 裡會有類似這樣的結構:

markdown 體驗AI程式碼助手 程式碼解讀複製程式碼## Review 結論

未發現阻塞提測問題,但有 2 個 P1 風險建議提測前確認。

## P0 阻塞提測問題

無。

## P1 高風險問題

...

## P2 建議優化

...

## 人工確認項

...

相比直接把 Cursor CLI 的輸出印在終端機裡,生成 Markdown 檔案有幾個好處:

text 體驗AI程式碼助手 程式碼解讀複製程式碼1. 方便貼到需求卡片、MR / PR 評論或提測說明裡
2. 方便作為提測前檢查記錄保存
3. 方便團隊回顧哪些問題是在提測前被攔下的
4. 修完問題後可以重新跑一遍,比對前後報告

我一般重點看報告裡的哪些內容?

Cursor CLI 生成報告後,不要只看最後一句「建議提測」或者「不建議提測」。

我一般重點看三塊。

1. P0 阻塞提測問題

P0 一般是提測前必須處理的問題,比如:

text 體驗AI程式碼助手 程式碼解讀複製程式碼新增頁面直接讀取 data.list[0].name,但介面返回空陣列時會報錯。

或者:

text 體驗AI程式碼助手 程式碼解讀複製程式碼提交按鈕沒有禁用,連續點擊可能發起多次建立請求。

這種問題只要命中,就不要糾結是不是 AI 誤判,直接回到程式碼裡人工確認。

如果確實成立,就先修掉再提測。

2. P1 高風險問題

P1 不一定馬上阻塞,但很可能在測試階段被打回來。

比如:

text 體驗AI程式碼助手 程式碼解讀複製程式碼介面欄位從 userName 改成 username,但頁面裡仍然讀取舊欄位,歷史快取資料可能顯示為空。

或者:

text 體驗AI程式碼助手 程式碼解讀複製程式碼彈窗關閉後沒有重置表單狀態,再次打開時可能帶出上一次填寫的資料。

這類問題要結合業務場景判斷。有些必須馬上修,有些可以和產品、測試確認後再決定。

3. 人工確認項

這個部分很有價值。

因為 AI 不一定知道測試環境配置、後端介面狀態、灰度策略和歷史資料情況。它如果能提示:

text 體驗AI程式碼助手 程式碼解讀複製程式碼需要確認 VITE_xxx 開關是否已經在測試環境配置預設值。

或者:

text 體驗AI程式碼助手 程式碼解讀複製程式碼需要確認後端是否已經相容新增欄位為空的情況。

這類資訊比單純指出程式碼問題更貼近提測流程。


前端專案裡最容易被提前掃出來的問題

我主要是前端視角,所以這裡重點說前端專案。

1. 空資料導致頁面崩潰

前端很多線上或測試環境問題不是語法錯誤,而是介面資料不符合預期。

比如:

js 體驗AI程式碼助手 程式碼解讀複製程式碼const name = user.profile.name;

如果 profile 為空,頁面就直接崩了。

AI Review 很適合幫忙掃這類問題,尤其是 diff 裡出現了新的欄位存取、新的陣列取值、新的物件解構時。

2. loading / error / empty 狀態缺失

常見問題包括:

text 體驗AI程式碼助手 程式碼解讀複製程式碼請求中按鈕沒有禁用
介面失敗沒有錯誤提示
空陣列沒有空狀態
介面慢時頁面展示舊資料
彈窗關閉後狀態沒有重置

這些問題本地自測不一定穩定復現,但測試同學很容易點出來。

3. 介面欄位相容性

比如後端把欄位從:

js 體驗AI程式碼助手 程式碼解讀複製程式碼userName

改成:

js 體驗AI程式碼助手 程式碼解讀複製程式碼username

如果前端沒有做相容,舊介面、快取資料、灰度環境都可能出問題。

所以我會讓 Prompt 明確檢查:

text 體驗AI程式碼助手 程式碼解讀複製程式碼介面入參、出參、欄位名、欄位型別是否相容

4. 重複請求和請求競態

比如搜尋框、篩選項、分頁切換、彈窗提交,這些地方很容易出現請求時序問題。

典型場景是:

text 體驗AI程式碼助手 程式碼解讀複製程式碼使用者先搜 A,再搜 B
B 請求先返回,A 請求後返回
頁面最後顯示成 A 的結果

這種問題人工 Review 有時會漏,AI 對 diff 做狀態流分析時反而能提醒一下。

5. 權限顯示和按鈕禁用邏輯

前端權限問題不一定是安全邊界,但會影響使用者操作體驗。

比如:

text 體驗AI程式碼助手 程式碼解讀複製程式碼無權限使用者看到了操作按鈕
按鈕置灰條件漏了某個狀態
審批完成後還能繼續點擊提交

這類問題如果出現在提測 diff 裡,也值得在報告裡單獨列出來。


AI 發現問題後,要不要讓它順手修?

可以,但我不建議把「自動修復」做進 npm run ai-review 這條指令裡。

npm run ai-review 的職責應該很單一:

text 體驗AI程式碼助手 程式碼解讀複製程式碼自動比對本次程式碼變更
自動生成 Review 報告
把風險點暴露出來

至於後面的修復動作,應該由開發者看完報告後主動發起

比如報告裡提示某個元件可能存在 undefined 存取風險,開發者確認後,可以再單獨讓 AI 輔助修改:

text 體驗AI程式碼助手 程式碼解讀複製程式碼請根據 .review/ai-review.md 中提到的 P1 問題,幫我修復 UserTable.vue 裡的空值兜底問題。
要求:只修改這個問題相關程式碼,不要順手重構其它邏輯。

或者更收斂一點:

text 體驗AI程式碼助手 程式碼解讀複製程式碼請只修復 UserTable.vue 中介面欄位為空時頁面崩潰的問題。
不要修改樣式,不要調整其它業務邏輯。

這樣做有兩個好處。

第一,Review 和 Fix 是兩個不同階段。Review 階段只負責發現問題,不應該直接改變工作區程式碼。這樣即使 AI 有誤判,也不會把誤判變成程式碼改動。

第二,使用者主動發起修復,可以保留人的判斷權。哪些問題是真問題,哪些是誤報,哪些需要現在修,哪些可以放到後續優化,應該由開發者結合業務上下文決定。

所以更穩妥的流程應該是:

text 體驗AI程式碼助手 程式碼解讀複製程式碼npm run ai-review
查看 .review/ai-review.md
人工確認問題是否成立
確認後再讓 AI 針對單個問題修復
人工 Review AI 的修改
重新執行測試和 npm run ai-review

不建議做成:

text 體驗AI程式碼助手 程式碼解讀複製程式碼npm run ai-review
AI 自動發現問題
AI 自動修改程式碼
AI 自動提交

這類全自動流程看起來很省事,但風險很明顯:AI 可能誤解業務規則,可能順手改掉無關邏輯,也可能把一個局部問題修成更隱蔽的問題。

我的建議是:AI 可以參與修復,但修復必須是使用者主動觸發的動作,不要作為 npm run ai-review 的預設自動化能力。

總結

用 Cursor CLI 配合 git diff 做提測前程式碼審查,本質上不是「讓 AI 幫我 Review 整個專案」,而是把問題收斂到一個具體範圍:

text 體驗AI程式碼助手 程式碼解讀複製程式碼本次改動有沒有可能在測試階段暴露為 Bug?

比較推薦的落地方式是:

text 體驗AI程式碼助手 程式碼解讀複製程式碼package.json 增加 npm run ai-review
Node 腳本自動生成 git diff
Cursor CLI 唯讀審查本次 diff
自動輸出 .review/ai-review.md
人工確認 P0 / P1 / 人工確認項
確認問題成立後,再由開發者主動讓 AI 輔助修復
修復後重新跑一遍
再提測

它不能取代 Code Review,也不能取代測試,但很適合做提測前的自動化兜底。


原文出處:https://juejin.cn/post/7639667928959893547


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝17   💬11   ❤️1
572
🥈
alicec
📝1   ❤️2
79
🥉
我愛JS
💬2  
7
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
📢 贊助商廣告 · 我要刊登