戰(zhàn)方法)
過去這一個(gè)多月我的編碼速度肉眼可見地快了一大截。不管是新接的業(yè)務(wù)接口、臨時(shí)要補(bǔ)的數(shù)據(jù)腳本還是重構(gòu)時(shí)繞不開的樣板代碼我都習(xí)慣先讓 AI 編程助手打底。以前一個(gè)功能從動(dòng)手到跑通怎么也得一兩個(gè)小時(shí)現(xiàn)在經(jīng)常十幾分鐘就出活。按這個(gè)效率項(xiàng)目排期應(yīng)該輕松不少才對(duì)??墒聦?shí)是越寫越快我反而開始不敢點(diǎn)那個(gè)“上線”按鈕了。原因很簡(jiǎn)單。代碼跑通了單測(cè)也綠了但這段代碼到底是怎么想出來的、有沒有我沒想到的角落我心里沒有底。以前自己手寫的代碼哪怕有 bug至少在出問題的時(shí)候我能沿著思路快速定位AI 生成的代碼出問題的時(shí)候它對(duì)我來說就像一堵墻——看著平整推不動(dòng)。這篇文章想聊聊我在這個(gè)狀態(tài)里的真實(shí)經(jīng)歷AI Coding 寫出來的代碼風(fēng)險(xiǎn)到底集中在哪幾個(gè)地方我現(xiàn)在上線前會(huì)做哪些檢查以及踩了哪些坑之后總結(jié)出來的一套還能落地的流程。如果你最近也在大量用 AI 寫代碼而且剛好要上一個(gè)重要功能這篇應(yīng)該能幫你少交一點(diǎn)學(xué)費(fèi)。1. AI編碼速度上來了但心里總有一個(gè)坎1.1 從“寫得快”到“不敢上”的真實(shí)轉(zhuǎn)變最開始接觸 AI 寫代碼的時(shí)候我其實(shí)只敢讓它干雜活生成一段配置、寫一個(gè) CRUD 的模板、補(bǔ)幾行測(cè)試用例。那時(shí)候的心態(tài)是這些東西本來就沒啥創(chuàng)新性讓 AI 代勞省時(shí)間出了問題自己也一眼能看懂。后來膽子大了開始讓它寫真正的核心邏輯——查數(shù)據(jù)庫、調(diào)第三方接口、做狀態(tài)流轉(zhuǎn)。效率提升確實(shí)驚人一個(gè)帶分頁、帶篩選、帶排序的后端查詢接口它幾秒就能給你抬出來而且風(fēng)格統(tǒng)一、命名規(guī)范比我手寫還整潔。那段時(shí)間我一度以為以后寫業(yè)務(wù)就是“提需求”的活了。但問題也出現(xiàn)在這個(gè)階段。有一次我讓 AI 實(shí)現(xiàn)一個(gè)訂單超時(shí)關(guān)閉的定時(shí)任務(wù)它非常流暢地寫完了查超時(shí)訂單、更新狀態(tài)、記日志邏輯完整測(cè)試也過了。我上線之后第二天運(yùn)營(yíng)反饋說很多訂單在支付頁明明還有效后臺(tái)卻把它關(guān)了。我查了半天才發(fā)現(xiàn)AI 在比較時(shí)間的時(shí)候用的是服務(wù)器本地時(shí)區(qū)而訂單表里存的是 UTC 時(shí)間。也就是說它代碼寫得越“順暢”我越容易因?yàn)樾湃味^逐字推敲而它錯(cuò)的地方往往不是語法是語義。從那以后我就意識(shí)到AI 寫代碼這個(gè)事真正讓人不適的不是“它會(huì)不會(huì)寫”而是“我和這段代碼之間沒有建立信任”。信任沒有建立起來上線就變成了一次賭博。1.2 為什么AI生成的代碼容易讓人心里沒底要解釋這種“心里沒底”得先說清楚 AI 寫代碼和人類寫代碼在本質(zhì)上的區(qū)別。我們自己寫代碼的時(shí)候每一步都是帶著意圖的這里為什么用 map 而不是 for 循環(huán)那里為什么先查緩存而不是直接查庫這個(gè)異常為什么吞掉那個(gè)值為什么兜底。哪怕你不寫注釋你腦子里有一個(gè)完整的“意圖地圖”。出了問題你只要順著地圖走一遍很快能找到哪個(gè)岔路走錯(cuò)了。AI 生成代碼則完全不同。它本質(zhì)上是根據(jù)海量代碼學(xué)出來的統(tǒng)計(jì)規(guī)律在預(yù)測(cè)“下一個(gè) token 最可能是什么”。它沒有真正理解你的業(yè)務(wù)也沒有運(yùn)行過你的系統(tǒng)。它寫出來的代碼可能和你項(xiàng)目的風(fēng)格高度一致看起來很像一個(gè)資深工程師的手筆但這里的每一行都沒有經(jīng)過你的腦內(nèi)驗(yàn)證。你接手的時(shí)候腦子里沒有地圖只有一個(gè)看起來很完整的外殼。我用一個(gè)類比來理解這件事AI 像一個(gè)表達(dá)流利、態(tài)度極好、但偶爾會(huì)一本正經(jīng)胡說八道的實(shí)習(xí)生。你說“幫我把這個(gè)需求做了”他點(diǎn)點(diǎn)頭說“沒問題”然后交給你一份格式工整、用詞專業(yè)的文檔。你讀起來覺得邏輯通順但里面某些關(guān)鍵結(jié)論其實(shí)是錯(cuò)的。如果你因?yàn)椤八@么專業(yè)應(yīng)該靠譜”而直接簽了字后面出問題的時(shí)候你甚至都不知道該從哪里開始質(zhì)疑。這就是“不敢上線”的根源不是 AI 寫的代碼一定有問題而是我失去了對(duì)代碼的“掌控感”。掌控感這種東西平時(shí)不覺得有什么真到出事的時(shí)候它就是你能不能在十分鐘內(nèi)定位問題、三十分鐘內(nèi)完成回滾的關(guān)鍵。2. AI生成代碼的主要風(fēng)險(xiǎn)點(diǎn)拆解2.1 幻覺代碼看似合理但語義錯(cuò)誤AI 生成代碼最大的坑不是語法錯(cuò)誤而是“幻覺”。這里的幻覺不是指它胡言亂語而是它會(huì)生成一段看起來非常合理、實(shí)際卻在語義層面有問題的代碼。語法檢查發(fā)現(xiàn)不了普通測(cè)試也測(cè)不出來因?yàn)樗皇恰芭懿黄饋怼倍恰芭芷饋淼慕Y(jié)果不符合真實(shí)業(yè)務(wù)預(yù)期”。舉個(gè)我實(shí)際遇到的例子。我需要解析一批來自第三方系統(tǒng)的日期字符串格式是“yyyy-MM-dd HH:mm:ss”但是這些字符串里的時(shí)間是帶時(shí)區(qū)偏移的。我讓 AI 寫一個(gè)解析工具函數(shù)它很快給出了一段干凈的代碼直接用標(biāo)準(zhǔn)庫解析成本地時(shí)間。本地測(cè)試的時(shí)候因?yàn)槲宜诘臅r(shí)區(qū)和第三方系統(tǒng)一致結(jié)果完全正確。等部署到生產(chǎn)環(huán)境服務(wù)器時(shí)區(qū)不一樣所有時(shí)間都偏差了好幾個(gè)小時(shí)定時(shí)任務(wù)、對(duì)賬邏輯全部受到影響。這類問題的共同點(diǎn)是代碼的“形”對(duì)但“神”不對(duì)。AI 不知道你的時(shí)間存儲(chǔ)規(guī)范、不知道你服務(wù)的部署環(huán)境、不知道你的上游系統(tǒng)約定它只能根據(jù)最常見的情況來生成。而“最常見的情況”往往不等于“你系統(tǒng)里真實(shí)的情況”。還有一個(gè)高頻出現(xiàn)的問題就是 AI 生成數(shù)據(jù)庫查詢時(shí)容易漏條件。比如一個(gè)需要統(tǒng)計(jì)“當(dāng)前有效訂單數(shù)”的接口它會(huì)把主查詢里的狀態(tài)過濾寫好但統(tǒng)計(jì)總數(shù)的那個(gè)查詢忘了加同樣的過濾條件。結(jié)果就是列表頁顯示的條數(shù)和總數(shù)對(duì)不上。這種 bug 不會(huì)崩不會(huì)報(bào)錯(cuò)只會(huì)在某個(gè)深夜被某個(gè)較真的用戶發(fā)現(xiàn)。應(yīng)對(duì)幻覺我現(xiàn)在的原則是凡是我不能從業(yè)務(wù)上解釋清楚的代碼一律不讓它上線。你可以寫得慢一點(diǎn)但絕不能把一段自己講不出道理的邏輯放到生產(chǎn)環(huán)境里。2.2 依賴與安全隱患第三方庫的坑AI 寫代碼還特別喜歡“引依賴”。你讓它實(shí)現(xiàn)一個(gè)“把 XML 轉(zhuǎn)成 JSON”的功能它可能不會(huì)手寫解析邏輯而是直接推薦一個(gè)第三方庫。這本身沒錯(cuò)而且很多時(shí)候是好的做法。但它不會(huì)告訴你這個(gè)庫的維護(hù)狀態(tài)、安全漏洞、許可證類型、和你項(xiàng)目里已有版本的兼容性。有段時(shí)間我的項(xiàng)目里出現(xiàn)了一個(gè)很隱蔽的構(gòu)建問題某天 CI 突然全紅報(bào)錯(cuò)信息指向一個(gè)底層依賴的行為變化。查了一圈才發(fā)現(xiàn)AI 在某個(gè)功能里引入了某個(gè)工具庫而配置構(gòu)建文件的時(shí)候沒有鎖版本。兩周之后這個(gè)庫發(fā)了新版行為變了我的項(xiàng)目在毫不知情的情況下被“升級(jí)”了。不是 AI 直接搞壞了我的項(xiàng)目但它給了這個(gè)風(fēng)險(xiǎn)一個(gè)入口。更值得警惕的是安全屬性。AI 生成的接口代碼里偶爾會(huì)出現(xiàn)沒有鑒權(quán)校驗(yàn)的隱患。你讓它生成一個(gè)查詢用戶信息的 handler它會(huì)把參數(shù)解析、數(shù)據(jù)庫查詢、結(jié)果返回都寫得整整齊齊唯獨(dú)忘了這個(gè)接口應(yīng)該先驗(yàn)證調(diào)用方身份。這種情況在代碼審查的時(shí)候特別容易漏掉因?yàn)槿说淖⒁饬?huì)被那些“看起來正常”的業(yè)務(wù)邏輯吸引很少有人會(huì)刻意去檢查一個(gè) AI 生成得極其流暢的接口是不是少了安全前置步驟。所以我現(xiàn)在對(duì) AI 推薦的每一個(gè)第三方依賴都會(huì)按三件事去核對(duì)它是不是有必要引入、有沒有鎖版本、項(xiàng)目里有沒有人真正了解它。滿足不了這三條的寧可自己手寫也不讓 AI 幫我“方便”。2.3 測(cè)試負(fù)債綠到發(fā)慌的假自信“讓 AI 把測(cè)試也寫了”是很多人用 AI 寫代碼的常規(guī)操作但這也是最容易被騙的地方。AI 生成的測(cè)試很多時(shí)候是在“自證清白”。什么叫自證清白就是它生成的功能代碼里有一個(gè)日期解析邏輯它就寫一個(gè)測(cè)試傳一個(gè)正常格式的日期字符串?dāng)嘌越馕龀晒?。這個(gè)測(cè)試當(dāng)然會(huì)過因?yàn)樗蛯?shí)現(xiàn)用的是同一套邏輯甚至是從同一個(gè)“統(tǒng)計(jì)規(guī)律”里生成的。它驗(yàn)證的是“代碼按它自己的方式工作”而不是“代碼符合你的業(yè)務(wù)預(yù)期”。我曾經(jīng)讓 AI 給一個(gè)優(yōu)惠券核銷功能補(bǔ)測(cè)試。它生成了一組漂亮的單元測(cè)試覆蓋了幾個(gè)主要分支斷言也寫得有模有樣。我把一個(gè)關(guān)鍵條件——比如“優(yōu)惠券已過期”——做了反向驗(yàn)證手動(dòng)把過期時(shí)間改成未來再看核銷邏輯結(jié)果發(fā)現(xiàn)實(shí)現(xiàn)代碼里的邊界判斷寫反了。而 AI 生成的測(cè)試恰好沒覆蓋這個(gè)分支所以測(cè)試全綠功能確實(shí)是壞的。這就是“測(cè)試負(fù)債”你以為測(cè)試給了你保障實(shí)際上它們只是讓代碼看起來更可信。覆蓋率數(shù)字再好看如果你沒有真正思考過哪些分支會(huì)出錯(cuò)、哪些輸入是異常的那些測(cè)試就只是數(shù)字游戲。解決這個(gè)問題我個(gè)人最有效的做法是“破壞性驗(yàn)證”拿到 AI 生成的代碼和測(cè)試之后故意去改一些關(guān)鍵條件——把大于號(hào)改成小于號(hào)、把“已支付”改成“未支付”——然后看測(cè)試到底會(huì)不會(huì)亮紅。如果測(cè)試沒有反應(yīng)說明它根本沒有在守護(hù)這個(gè)關(guān)鍵邏輯。這個(gè)方法不復(fù)雜但對(duì) AI 生成的測(cè)試特別有效能快速篩掉一批“看起來有用”的廢物測(cè)試。3. 我現(xiàn)在的上線前檢查實(shí)操流程3.1 先把AI的代碼當(dāng)成“實(shí)習(xí)生寫的”來審既然心里沒底那就把流程補(bǔ)上。我現(xiàn)在的第一個(gè)原則非常簡(jiǎn)單粗暴所有 AI 生成的代碼一律按“實(shí)習(xí)生提交的代碼”標(biāo)準(zhǔn)來審查。實(shí)習(xí)生寫的代碼你會(huì)直接合并上線嗎不會(huì)。你會(huì)打開 diff逐行看它有沒有理解需求有沒有考慮異常情況。對(duì) AI 生成的東西我現(xiàn)在就是這個(gè)待遇。具體來說我的審查順序是固定的。先看整體 diff確認(rèn)這段代碼到底改了什么、為什么改、和需求是否對(duì)應(yīng)。這時(shí)候我會(huì)特別警惕那些“順手改掉”的地方——AI 經(jīng)常會(huì)在實(shí)現(xiàn)一個(gè)功能的時(shí)候順手幫你重構(gòu)了另一段無關(guān)代碼這在地球上叫做“范圍蔓延”在 AI 這里是“默認(rèn)行為”。然后我會(huì)挑最關(guān)鍵的一兩條路徑做“腦內(nèi)執(zhí)行”。比如一個(gè)支付回調(diào)處理函數(shù)我會(huì)在心里把它跑一遍收到回調(diào)、驗(yàn)簽、查單、更新狀態(tài)、返回響應(yīng)。每一步都問自己“它在這一步做了什么、如果這一步失敗了會(huì)怎樣”。只要我在某個(gè)環(huán)節(jié)說不清楚它的行為我就會(huì)在這里打住把 AI 叫回來重新解釋直到我能復(fù)述為止。如果 AI 生成的代碼里包含我完全看不懂的部分我不會(huì)選擇“先上線再說”。以前我可能會(huì)覺得“反正測(cè)試過了”現(xiàn)在我的態(tài)度是看不懂就是最大的風(fēng)險(xiǎn)。一個(gè)合格的程序員不應(yīng)該把一段自己無法解釋的代碼放進(jìn)生產(chǎn)環(huán)境里。還有一個(gè)小技巧我管它叫“復(fù)述法”讓 AI 自己把這段代碼“講”一遍說清楚每個(gè)函數(shù)為什么存在、每個(gè)邊界條件為什么這么處理。如果它講得含糊其辭那大概率這段代碼也經(jīng)不起深究。這個(gè)方法聽起來有點(diǎn)玄學(xué)但實(shí)操下來非常好用因?yàn)樗鼙浦闳ズ痛a建立那種丟失的“掌控感”。3.2 強(qiáng)制驗(yàn)證清單上線前必過除了代碼審查我還會(huì)跑一套固定的驗(yàn)證清單。這套清單不是給 AI 的是給我自己的防止我因?yàn)椤按a看起來沒問題”而跳過關(guān)鍵的驗(yàn)證環(huán)節(jié)。第一靜態(tài)檢查和規(guī)范檢查必須全綠。這個(gè)看似基礎(chǔ)但在 AI 生成的代碼里經(jīng)常能發(fā)現(xiàn)未使用的變量、不一致的命名、明顯的壞味道。靜態(tài)檢查能把這些低級(jí)的信任消耗提前排除掉。第二新引入的依賴要單獨(dú)過一遍。前面講過AI 特別喜歡引依賴。我會(huì)確認(rèn)它引入的每個(gè)包都是必要的、版本被鎖住的、項(xiàng)目里有人能說清楚它是干什么的。第三方依賴進(jìn)入生產(chǎn)環(huán)境等于把一個(gè)不明身份的人請(qǐng)進(jìn)了家門這個(gè)審核不能省。第三單元測(cè)試之外必須有針對(duì)“異常分支”的驗(yàn)證。正常流程跑通了不算數(shù)我會(huì)構(gòu)造幾個(gè)明顯異常的輸入超長(zhǎng)的字符串、空的集合、超時(shí)返回的第三方接口、重復(fù)提交的請(qǐng)求。AI 生成的代碼在“順利路徑”上通常表現(xiàn)很好但異常路徑經(jīng)常是它的盲區(qū)。第四數(shù)據(jù)一致性檢查。時(shí)間字段的時(shí)區(qū)、金額字段的精度、狀態(tài)字段的流轉(zhuǎn)是否冪等這些是 AI 最容易犯錯(cuò)的地方也恰恰是線上事故的高發(fā)區(qū)。我寧可在這上面多花十分鐘也不愿意半夜被監(jiān)控告警叫醒。第五安全自查。生成這個(gè)功能的時(shí)候有沒有校驗(yàn)權(quán)限有沒有對(duì)輸入做邊界限制有沒有把敏感信息打到日志里我會(huì)把這三個(gè)問題當(dāng)成固定動(dòng)作每次上線前都過一遍而不是等安全評(píng)審的時(shí)候再想。這套清單看起來繁瑣但真正執(zhí)行起來大部分功能十五分鐘就能過完。它最大的作用不是“發(fā)現(xiàn)所有 bug”而是逼著我在上線前把心態(tài)從“應(yīng)該沒問題”切換到“有沒有我不知道的問題”。3.3 小步發(fā)布與灰度策略讓風(fēng)險(xiǎn)可控最后一道防線是發(fā)布策略?,F(xiàn)在我再也不敢把 AI 生成的代碼“一把梭”地全量上線了。不管代碼審查多仔細(xì)、測(cè)試多充分只要這段代碼的核心邏輯里有 AI 的貢獻(xiàn)我就會(huì)假設(shè)它可能藏著沒發(fā)現(xiàn)的問題然后用發(fā)布方式把爆炸半徑控制到最小。我的標(biāo)準(zhǔn)做法是三步走。第一步功能開關(guān)先行。把新功能放在一個(gè)配置開關(guān)后面代碼先上線但默認(rèn)不啟用。這樣即使代碼本身有問題也不會(huì)立刻影響線上用戶。第二步灰度放量。先讓 5% 的流量走新邏輯盯一段時(shí)間日志和錯(cuò)誤率沒問題再逐步放量到 20%、50%、100%。這個(gè)過程可能多花一兩天但它能把“一個(gè)隱藏 bug 炸掉整個(gè)系統(tǒng)”變成“一個(gè)隱藏 bug 只影響一小部分用戶而且能被快速發(fā)現(xiàn)”。第三步確?;貪L通路。不光是“代碼能回滾”還要確認(rèn)“數(shù)據(jù)變更也能回滾”。AI 生成的數(shù)據(jù)庫遷移腳本尤其危險(xiǎn)它很可能直接把舊字段刪了導(dǎo)致代碼回滾了數(shù)據(jù)卻回不來。有人覺得灰度是流程負(fù)擔(dān)但經(jīng)歷過一次全量發(fā)布事故之后你就會(huì)明白灰度不是額外成本它是給“不確定的代碼”買的保險(xiǎn)。AI 寫代碼提高了我們的產(chǎn)出速度但并沒有降低出錯(cuò)的概率。越是快越要控制住風(fēng)險(xiǎn)敞口不然快的那部分效率遲早會(huì)因?yàn)橐淮问鹿寿r回去。4. AI代碼上線的常見翻車場(chǎng)景與排查經(jīng)驗(yàn)4.1 我踩過的幾個(gè)具體場(chǎng)景翻車場(chǎng)景見得多了我挑幾個(gè)有代表性的說一說每個(gè)都是我或者身邊朋友的真實(shí)經(jīng)歷細(xì)節(jié)已經(jīng)改過。第一個(gè)是“重試邏輯堵死隊(duì)列”。某個(gè)下游服務(wù)偶爾不穩(wěn)定我讓 AI 給調(diào)用方加一個(gè)“失敗自動(dòng)重試”的機(jī)制。AI 很快就寫好了看起來也很合理失敗就等幾秒再重試最多重試三次。但它沒有做異步化重試是同步阻塞的。結(jié)果下游一抖動(dòng)所有線程都卡在重試等待里調(diào)用超時(shí)鏈路雪崩。上線后半小時(shí)監(jiān)控面板上一片紅。這類問題在單測(cè)里根本不會(huì)暴露因?yàn)閱螠y(cè)不會(huì)模擬“下游服務(wù)大面積變慢”的場(chǎng)景。第二個(gè)是“定時(shí)任務(wù)沒有冪等控制”。AI 生成一個(gè)每分鐘執(zhí)行一次的掃描任務(wù)邏輯很簡(jiǎn)單找出滿足條件的記錄處理更新狀態(tài)。正常情況沒問題但部署的時(shí)候如果新老實(shí)例交接出現(xiàn)重疊任務(wù)可能被兩個(gè)實(shí)例同時(shí)執(zhí)行。AI 沒寫分布式鎖也沒寫冪等判斷結(jié)果同一條記錄被處理了兩次產(chǎn)生了重復(fù)數(shù)據(jù)。這個(gè) bug 不影響主流程但會(huì)污染數(shù)據(jù)后面修起來特別費(fèi)勁。第三個(gè)是“數(shù)據(jù)庫遷移腳本太激進(jìn)”。我讓 AI 幫忙寫一個(gè)“把舊表結(jié)構(gòu)調(diào)整成新結(jié)構(gòu)”的遷移腳本它直接生成了刪舊列、建新列的方案。這種方案在全新環(huán)境下沒問題但我們的生產(chǎn)環(huán)境里舊列里是有數(shù)據(jù)的。如果直接執(zhí)行數(shù)據(jù)就沒了。好在我在測(cè)試環(huán)境先跑了一遍發(fā)現(xiàn)不對(duì)勁最后改成了“新增列、遷移數(shù)據(jù)、逐步廢棄舊列”的平滑方案避免了一場(chǎng)災(zāi)難。這三個(gè)場(chǎng)景的共同點(diǎn)都是“代碼邏輯本身沒錯(cuò)但對(duì)真實(shí)生產(chǎn)環(huán)境的假設(shè)錯(cuò)了”。AI 看到的約束只有你在提示詞里寫的那幾句話。你沒有告訴它“這個(gè)服務(wù)是多實(shí)例部署的”它就默認(rèn)是單實(shí)例你沒有告訴它“下游服務(wù)有超時(shí)風(fēng)險(xiǎn)”它就默認(rèn)調(diào)用一定會(huì)返回。所以用 AI 寫代碼本質(zhì)上是把一部分你沒有說出口的“系統(tǒng)常識(shí)”賭上了。上線前多問自己“它不知道但必須知道的東西是什么”能幫你規(guī)避掉很多這類事故。4.2 排查與止血先回滾還是先debug如果 AI 生成的代碼已經(jīng)上線出問題了我會(huì)建議你遵循一個(gè)順序先止血再排查。很多工程師的習(xí)慣是線上報(bào)錯(cuò)了第一時(shí)間打開日志開始找原因。這個(gè)習(xí)慣在面對(duì)自己手寫代碼的時(shí)候還行但面對(duì) AI 生成代碼的時(shí)候你要做好思想準(zhǔn)備你可能會(huì)花很長(zhǎng)時(shí)間才能定位到問題因?yàn)槟銓?duì)這段代碼沒有“意圖地圖”排查的速度天然就慢。這期間用戶一直在受影響業(yè)務(wù)損失在持續(xù)擴(kuò)大。所以我現(xiàn)在的鐵律是上線后一小時(shí)內(nèi)出現(xiàn)任何不正常先執(zhí)行回滾預(yù)案或者直接關(guān)閉功能開關(guān)把影響面先控制住。止血不需要等“搞清楚為什么”止血只需要“回到上一個(gè)穩(wěn)定狀態(tài)”。線上恢復(fù)穩(wěn)定之后你再慢慢和 AI 一起復(fù)盤、一起定位根因這個(gè)階段多花點(diǎn)時(shí)間都沒關(guān)系。排查階段我也有一個(gè)相對(duì)高效的路徑。第一看錯(cuò)誤日志和調(diào)用鏈確定是哪個(gè)環(huán)節(jié)出了問題。第二把這個(gè)環(huán)節(jié)的代碼 diff 出來和上一個(gè)穩(wěn)定版本做對(duì)比看 AI 到底改了什么。第三把報(bào)錯(cuò)的堆棧和這段生成代碼一起丟給 AI讓它以“代碼審查員”的身份給你分析可能原因。這一步有時(shí)候能給出不錯(cuò)的線索但記住它給你的結(jié)論仍然是“建議”必須人工驗(yàn)證后才能采信。還有一個(gè)經(jīng)驗(yàn)當(dāng)你不確定問題是不是 AI 代碼引起的時(shí)候先做“隔離驗(yàn)證”。把 AI 生成的獨(dú)立函數(shù)單獨(dú)用一套真實(shí)數(shù)據(jù)跑一遍看它輸出是否合理。這比在整條調(diào)用鏈里大海撈針要快得多。4.3 常見問題速查表我把項(xiàng)目里遇到過的典型問題整理成一張速查表方便你在上線前或者排查時(shí)快速對(duì)照。這張表不是萬能的但覆蓋了 AI 生成代碼最容易出問題的那幾個(gè)大類。癥狀常見原因排查方向建議處理方案接口偶發(fā)超時(shí)、調(diào)用堆積同步重試、連接池配置不足、缺少熔斷錯(cuò)誤日志、調(diào)用鏈耗時(shí)分布改為異步重試增加超時(shí)和熔斷機(jī)制數(shù)據(jù)重復(fù)、訂單狀態(tài)錯(cuò)亂缺少冪等控制、唯一約束缺失、定時(shí)任務(wù)并發(fā)執(zhí)行查任務(wù)執(zhí)行日志、重復(fù)記錄的特征值增加冪等鍵、唯一索引、分布式鎖時(shí)間顯示偏差數(shù)小時(shí)時(shí)區(qū)處理不當(dāng)、存儲(chǔ)格式不統(tǒng)一檢查日期解析代碼和存儲(chǔ)層字段類型統(tǒng)一使用標(biāo)準(zhǔn)時(shí)間格式解析時(shí)明確指定時(shí)區(qū)列表總數(shù)和明細(xì)不一致AI 生成統(tǒng)計(jì)查詢時(shí)漏掉過濾條件對(duì)比兩條 SQL 的 where 子句重構(gòu)為同一個(gè)查詢條件來源避免重復(fù)編寫新功能上線后部分用戶無法訪問缺少鑒權(quán)校驗(yàn)、角色判斷寫反檢查接口入口的權(quán)限攔截邏輯補(bǔ)齊權(quán)限校驗(yàn)并加針對(duì)未授權(quán)用戶的分支測(cè)試舊數(shù)據(jù)無法回滾遷移腳本直接刪除舊字段在測(cè)試環(huán)境執(zhí)行遷移、檢查回滾腳本采用“新增列、遷移、廢棄”三步平滑方案這張表里每一行背后都是一個(gè)真實(shí)的事故或者說是一次“差點(diǎn)出事”的教訓(xùn)。你可以直接把它作為 AI 代碼上線前的自查項(xiàng)來用。5. 最后再分享幾個(gè)讓我睡得更安穩(wěn)的習(xí)慣聊了這么多風(fēng)險(xiǎn)和流程最后說幾個(gè)我自己一直在堅(jiān)持的小習(xí)慣吧。它們不是某個(gè)標(biāo)準(zhǔn)流程里的規(guī)定但確實(shí)是這段時(shí)間踩坑踩出來的經(jīng)驗(yàn)。第一個(gè)習(xí)慣是每天上線前把當(dāng)天所有 AI 生成的代碼里“最讓我不放心的一段”親手重寫一遍。不是為了否定 AI 的產(chǎn)出而是為了強(qiáng)制自己把這段代碼的邏輯徹底想清楚。重寫的過程就是在建立掌控感哪怕最后改成和 AI 差不多這個(gè)過程本身的價(jià)值就夠了。第二個(gè)習(xí)慣是不讓 AI 一次生成太大的改動(dòng)。以前我喜歡讓它“幫我重寫整個(gè)模塊”現(xiàn)在我會(huì)刻意拆小一次只讓它寫一個(gè)函數(shù)、一個(gè)獨(dú)立步驟。改動(dòng)越小每次審查的負(fù)擔(dān)越輕出問題的范圍也越小。這個(gè)道理和“小步提交”是一樣的只是應(yīng)用到了 AI 協(xié)作上。第三個(gè)習(xí)慣是不定期讓 AI“找茬”。我經(jīng)常把一段自己寫的代碼發(fā)給 AI讓它以代碼審查者的身份挑毛病。我發(fā)現(xiàn)這個(gè)反向使用的效果非常好因?yàn)?AI 的統(tǒng)計(jì)模型見過足夠多的代碼模式能指出一些我因?yàn)閼T性忽略的壞味道。當(dāng)然它的意見我不會(huì)全盤接受但多一個(gè)視角總比閉門造車強(qiáng)。第四個(gè)習(xí)慣也是最重要的一個(gè)我接受了一個(gè)現(xiàn)實(shí)——AI 寫代碼的“快”本質(zhì)上是用“不確定”換來的。它幫你省掉了大量機(jī)械編碼的時(shí)間但也把一部分“隱性系統(tǒng)知識(shí)”的責(zé)任轉(zhuǎn)移給了你。你多問一句“這段代碼真的懂我的系統(tǒng)嗎”比盲目信任它來得踏實(shí)得多?!安桓疑暇€”這件事我現(xiàn)在覺得它不是一個(gè)壞狀態(tài)。它說明你還保留著對(duì)生產(chǎn)環(huán)境的敬畏還知道代碼是要跑到真實(shí)用戶面前的。真正危險(xiǎn)的是哪天你變得非常流暢地生成代碼、非常流暢地合并、非常流暢地發(fā)布卻完全不再有猶豫。到那時(shí)候翻車就不是偶然而是必然。我自己也在慢慢學(xué)習(xí)怎么和 AI 協(xié)作得更穩(wěn)。速度還會(huì)繼續(xù)提上去信任也會(huì)一點(diǎn)點(diǎn)建立起來但那個(gè)“上線前必須把每一行都搞懂”的原則我會(huì)一直留著。