與工作模式15_Plan模式下的信息補(bǔ)充策略)
Plan模式下的信息補(bǔ)充策略摘要在 AI 輔助編程工具如 Cursor、Claude Code、Cline、Windsurf 等中Plan 模式規(guī)劃模式允許模型在動(dòng)手寫代碼之前先與你對(duì)齊需求、列出執(zhí)行步驟。但在實(shí)際使用中幾乎每個(gè)人都會(huì)遇到同一個(gè)問題模型會(huì)拋出一連串問題讓你確認(rèn)——“這個(gè)接口用 REST 還是 GraphQL”“數(shù)據(jù)庫(kù)用 PostgreSQL 還是 MySQL”“要不要加緩存”面對(duì)這些提問你只有兩種選擇逐項(xiàng)回答認(rèn)真回答每一個(gè)問題讓模型獲得完整信息跳過讓 AI 自行假設(shè)不回答直接讓模型基于合理默認(rèn)值繼續(xù)。這兩種策略沒有絕對(duì)的對(duì)錯(cuò)關(guān)鍵在于判斷哪些信息是高杠桿的——即哪些問題的答案會(huì)顯著改變最終產(chǎn)物的結(jié)構(gòu)哪些只是無(wú)關(guān)痛癢的細(xì)節(jié)。本文將從工程實(shí)踐角度系統(tǒng)分析 Plan 模式下信息補(bǔ)充的策略、判斷框架并給出可落地的代碼實(shí)現(xiàn)一個(gè)自動(dòng)分級(jí)問題、輔助決策的小工具幫助你把回答問題這件事從被動(dòng)應(yīng)付變成主動(dòng)控制。引言為什么回答問題本身是個(gè)技術(shù)問題很多人把 Plan 模式下的問答當(dāng)成走流程模型問什么就答什么或者干脆一路你看著辦。但這兩者都會(huì)帶來(lái)隱性成本。逐項(xiàng)回答的成本在于注意力稅每個(gè)問題都需要你切換上下文、回憶項(xiàng)目細(xì)節(jié)、組織語(yǔ)言。20 個(gè)問題就是 20 次上下文切換實(shí)際耗時(shí)遠(yuǎn)超想象。過度約束有些問題一旦你給出具體答案反而限制了模型的發(fā)揮空間。比如你隨口說(shuō)用 Redis 做緩存模型可能就放棄了更合適的本地 LRU 方案。偽精確陷阱你可能并不真的確定答案比如到底該用哪種消息隊(duì)列但為了回答問題而倉(cāng)促?zèng)Q定把不確定性固化進(jìn)了方案。跳過讓 AI 自行假設(shè)的成本在于假設(shè)漂移模型的默認(rèn)假設(shè)可能與你的真實(shí)約束沖突比如它默認(rèn)用 TypeScript而你的團(tuán)隊(duì)全是 Python。返工放大Plan 階段一個(gè)錯(cuò)誤假設(shè)到實(shí)現(xiàn)階段可能演變成大面積重構(gòu)。黑箱感你不知道模型假設(shè)了什么出了問題難以定位。所以真正的策略不是二選一而是建立一個(gè)分級(jí)判斷框架把模型的問題按影響面分類高影響的問題認(rèn)真回答低影響的問題明確授權(quán)模型自行假設(shè)并要求模型把假設(shè)顯式列出來(lái)。這就是本文要展開的核心思想。正文一、先理解 Plan 模式的工作機(jī)制要制定策略先要理解 Plan 模式下模型為什么會(huì)提問。典型流程如下用戶提出需求 │ ▼ ┌─────────────────┐ │ 需求解析階段 │ ← 模型識(shí)別信息缺口 └─────────────────┘ │ ▼ ┌─────────────────┐ │ 澄清提問階段 │ ← 拋出一批問題本文焦點(diǎn) └─────────────────┘ │ ▼ ┌─────────────────┐ │ 方案規(guī)劃階段 │ ← 基于已有信息 假設(shè)生成計(jì)劃 └─────────────────┘ │ ▼ ┌─────────────────┐ │ 執(zhí)行/實(shí)現(xiàn)階段 │ └─────────────────┘關(guān)鍵認(rèn)知模型在澄清階段提出的問題本質(zhì)上是它在信息缺口和繼續(xù)推進(jìn)之間的權(quán)衡。一個(gè)訓(xùn)練良好的模型會(huì)把它認(rèn)為重要的缺口拋給你。但模型并不知道你的組織約束、歷史包袱、團(tuán)隊(duì)偏好——這些它只能靠問或者靠猜。因此你的信息補(bǔ)充策略實(shí)際上是在替模型補(bǔ)全它無(wú)法從上下文推斷的那部分知識(shí)。判斷標(biāo)準(zhǔn)很清晰凡是模型無(wú)法從代碼庫(kù)、項(xiàng)目文件、歷史對(duì)話中推斷出來(lái)的信息且對(duì)方案有實(shí)質(zhì)影響就值得回答反之可以授權(quán)假設(shè)。二、問題分級(jí)哪些必須答哪些可以跳過實(shí)踐中模型的問題大致可以分為四類。建議按下面的矩陣處理問題類型典型例子影響面建議策略約束類目標(biāo)語(yǔ)言/框架、部署環(huán)境、性能紅線、合規(guī)要求極高決定方案骨架必須逐項(xiàng)回答接口類API 風(fēng)格、數(shù)據(jù)模型字段、鑒權(quán)方式高影響模塊邊界盡量回答可給方向而非細(xì)節(jié)實(shí)現(xiàn)類用哪個(gè)庫(kù)、要不要加緩存、日志格式中可逆授權(quán)假設(shè)要求列出風(fēng)格類變量命名、注釋密度、目錄結(jié)構(gòu)低隨時(shí)可改直接跳過讓模型定約束類問題是唯一不能跳過的。因?yàn)橐坏┘僭O(shè)錯(cuò)誤整個(gè)方案可能推倒重來(lái)。比如模型默認(rèn)你要寫一個(gè) Web 服務(wù)而你其實(shí)要寫一個(gè) CLI 工具——這個(gè)假設(shè)錯(cuò)了后面全錯(cuò)。接口類問題值得回答但不必過度精確。例如模型問用戶表需要哪些字段你不必列出全部 30 個(gè)字段只需回答核心是 id、email、created_at其余你按常見實(shí)踐補(bǔ)全并標(biāo)注。實(shí)現(xiàn)類和風(fēng)格類是最應(yīng)該被跳過的。這類問題數(shù)量往往最多模型喜歡問細(xì)節(jié)但影響面最小。你回答它們純粹是在消耗注意力。一個(gè)實(shí)用的經(jīng)驗(yàn)法則如果一個(gè)問題的答案在方案評(píng)審時(shí)你根本不會(huì)去看那它就該被跳過。三、逐項(xiàng)回答的正確姿勢(shì)結(jié)構(gòu)化、最小充分決定回答后怎么答也有講究。逐項(xiàng)回答不等于每問必詳答。推薦三個(gè)原則1. 用結(jié)構(gòu)化格式回答而非散文。模型對(duì)結(jié)構(gòu)化輸入的理解更穩(wěn)定也方便它對(duì)齊。2. 最小充分原則。只給足以消除歧義的信息不主動(dòng)擴(kuò)展。你給的信息越多模型的假設(shè)空間被壓縮得越厲害可能錯(cuò)過更優(yōu)解。3. 顯式標(biāo)注硬約束與軟偏好。讓模型知道哪些不能動(dòng)、哪些可以商量。下面是一個(gè)回答模板的示例你可以直接復(fù)制到對(duì)話里## 硬約束不可變更 - 語(yǔ)言Python 3.11 - 部署單機(jī) Docker無(wú) K8s - 數(shù)據(jù)庫(kù)必須用現(xiàn)有 PostgreSQL 14 實(shí)例 ## 軟偏好可協(xié)商若你有更好理由可提出 - Web 框架傾向 FastAPI但如果你認(rèn)為 Flask 更合適可以說(shuō)明 - 希望有基礎(chǔ)單元測(cè)試 ## 授權(quán)假設(shè)以下你不必再問自行決定并在計(jì)劃中列出 - 日志庫(kù)、代碼格式化工具、目錄結(jié)構(gòu) - 緩存方案若需要自行選擇并說(shuō)明理由這個(gè)模板的價(jià)值在于它一次性把要答的和不用答的都交代清楚把多輪問答壓縮成一輪大幅降低交互成本。四、跳過讓 AI 假設(shè)的正確姿勢(shì)顯式授權(quán) 假設(shè)清單“跳過絕不等于不回復(fù)”。正確的跳過是顯式授權(quán)模型自行假設(shè)并要求它輸出假設(shè)清單。這樣做有三個(gè)好處模型知道可以繼續(xù)推進(jìn)不會(huì)卡在等待你獲得了假設(shè)的可見性出問題能快速定位假設(shè)清單本身成為方案評(píng)審的一部分。一個(gè)標(biāo)準(zhǔn)的授權(quán)話術(shù)以下問題我不回答請(qǐng)你基于合理默認(rèn)值自行假設(shè)并繼續(xù)規(guī)劃。 要求 1. 在計(jì)劃開頭單獨(dú)列出假設(shè)清單每條注明假設(shè)內(nèi)容和理由 2. 對(duì)于影響較大的假設(shè)標(biāo)注 ?? 并說(shuō)明如果假設(shè)不成立需要改動(dòng)哪些部分 3. 優(yōu)先選擇主流、保守、易替換的方案。這里的關(guān)鍵是要求模型標(biāo)注高影響假設(shè)。這樣即使你跳過了所有問題也能一眼看到哪些假設(shè)值得回頭確認(rèn)。下面給出一個(gè)可運(yùn)行的 Python 小工具用于自動(dòng)對(duì)模型提出的問題做分級(jí)輔助你決定哪些答、哪些跳過。它基于關(guān)鍵詞規(guī)則打分你可以按自己團(tuán)隊(duì)的習(xí)慣擴(kuò)展規(guī)則。 plan_question_triage.py 對(duì) Plan 模式下模型提出的問題做影響面分級(jí)輔助決定回答 or 跳過。 用法: python plan_question_triage.py questions.txt 其中 questions.txt 每行一個(gè)問題。 importreimportsysfromdataclassesimportdataclass,fieldfromtypingimportListdataclassclassRule:一條分級(jí)規(guī)則命中關(guān)鍵詞則累加權(quán)重。name:strkeywords:List[str]weight:intcategory:str# 規(guī)則表權(quán)重越高越應(yīng)該逐項(xiàng)回答RULES:List[Rule][Rule(約束-語(yǔ)言,[語(yǔ)言,python,java,go,typescript,版本],5,約束類),Rule(約束-部署,[部署,docker,k8s,kubernetes,云,服務(wù)器,環(huán)境],5,約束類),Rule(約束-數(shù)據(jù),[數(shù)據(jù)庫(kù),postgres,mysql,mongo,存儲(chǔ),持久化],5,約束類),Rule(約束-合規(guī),[合規(guī),隱私,加密,權(quán)限,審計(jì),安全],5,約束類),Rule(約束-性能,[性能,并發(fā),延遲,qps,吞吐,內(nèi)存],4,約束類),Rule(接口-風(fēng)格,[rest,graphql,grpc,接口,api,協(xié)議],3,接口類),Rule(接口-模型,[字段,表結(jié)構(gòu),數(shù)據(jù)模型,schema,實(shí)體],3,接口類),Rule(接口-鑒權(quán),[鑒權(quán),認(rèn)證,token,oauth,登錄],3,接口類),Rule(實(shí)現(xiàn)-庫(kù),[庫(kù),依賴,框架,package,sdk],2,實(shí)現(xiàn)類),Rule(實(shí)現(xiàn)-緩存,[緩存,redis,memcache],2,實(shí)現(xiàn)類),Rule(實(shí)現(xiàn)-日志,[日志,log,監(jiān)控,埋點(diǎn)],1,實(shí)現(xiàn)類),Rule(風(fēng)格-命名,[命名,目錄,結(jié)構(gòu),注釋,風(fēng)格,格式],1,風(fēng)格類),]dataclassclassTriageResult:question:strscore:int0categories:List[str]field(default_factorylist)matched:List[str]field(default_factorylist)propertydefadvice(self)-str:根據(jù)分?jǐn)?shù)給出處理建議。ifself.score5:return? 必須逐項(xiàng)回答高影響假設(shè)錯(cuò)誤代價(jià)大ifself.score3:return 建議回答方向細(xì)節(jié)可授權(quán)假設(shè)ifself.score1:return 可跳過要求模型列出假設(shè)return? 無(wú)明確信號(hào)默認(rèn)跳過并授權(quán)假設(shè)deftriage(question:str)-TriageResult:對(duì)單個(gè)問題分級(jí)。resultTriageResult(questionquestion)q_lowerquestion.lower()forruleinRULES:ifany(kw.lower()inq_lowerforkwinrule.keywords):result.scorerule.weight result.matched.append(rule.name)ifrule.categorynotinresult.categories:result.categories.append(rule.category)returnresultdefmain(path:str)-None:withopen(path,r,encodingutf-8)asf:questions[line.strip()forlineinfifline.strip()]results[triage(q)forqinquestions]# 按分?jǐn)?shù)降序排列高影響問題優(yōu)先處理results.sort(keylambdar:r.score,reverseTrue)print(f{分?jǐn)?shù):6}{建議:40}問題)print(-*100)forrinresults:print(f{r.score:6}{r.advice:40}{r.question})# 統(tǒng)計(jì)有多少問題其實(shí)可以跳過skippablesum(1forrinresultsifr.score3)print(-*100)print(f共{len(results)}個(gè)問題其中{skippable}個(gè)可跳過{skippable/len(results):.0%})if__name____main__:iflen(sys.argv)!2:print(用法: python plan_question_triage.py questions.txt)sys.exit(1)main(sys.argv[1])準(zhǔn)備一個(gè)questions.txt這個(gè)項(xiàng)目用什么編程語(yǔ)言和版本 數(shù)據(jù)庫(kù)用 PostgreSQL 還是 MySQL API 風(fēng)格用 REST 還是 GraphQL 用戶表的字段需要包含哪些 要不要加 Redis 緩存 日志用什么庫(kù) 變量命名和目錄結(jié)構(gòu)有什么要求 部署到 Docker 還是 K8s運(yùn)行結(jié)果示例分?jǐn)?shù) 建議 問題 ---------------------------------------------------------------------------------------------------- 10 ? 必須逐項(xiàng)回答高影響假設(shè)錯(cuò)誤代價(jià)大 數(shù)據(jù)庫(kù)用 PostgreSQL 還是 MySQL 10 ? 必須逐項(xiàng)回答高影響假設(shè)錯(cuò)誤代價(jià)大 部署到 Docker 還是 K8s 5 ? 必須逐項(xiàng)回答高影響假設(shè)錯(cuò)誤代價(jià)大 這個(gè)項(xiàng)目用什么編程語(yǔ)言和版本 6 建議回答方向細(xì)節(jié)可授權(quán)假設(shè) API 風(fēng)格用 REST 還是 GraphQL 6 建議回答方向細(xì)節(jié)可授權(quán)假設(shè) 用戶表的字段需要包含哪些 2 可跳過要求模型列出假設(shè) 要不要加 Redis 緩存 1 可跳過要求模型列出假設(shè) 日志用什么庫(kù) 2 可跳過要求模型列出假設(shè) 變量命名和目錄結(jié)構(gòu)有什么要求 ---------------------------------------------------------------------------------------------------- 共 8 個(gè)問題其中 3 個(gè)可跳過38%這個(gè)工具的意義不在于精確而在于強(qiáng)迫你在回答前先分類。哪怕規(guī)則粗糙它也能幫你把注意力從挨個(gè)回答轉(zhuǎn)移到哪些值得答。你可以把規(guī)則表替換成自己團(tuán)隊(duì)的術(shù)語(yǔ)甚至接入一次 LLM 調(diào)用做更智能的分級(jí)。五、混合策略一輪回答 一輪授權(quán)在真實(shí)項(xiàng)目中最優(yōu)解往往是混合而不是純回答或純跳過。推薦一個(gè)可復(fù)用的兩輪交互模式第一輪只回答約束類問題其余全部授權(quán)假設(shè)。關(guān)于你提出的問題 【回答】語(yǔ)言用 Python 3.11部署用 Docker數(shù)據(jù)庫(kù)用現(xiàn)有 PostgreSQL。 【授權(quán)假設(shè)】其余問題API 風(fēng)格、緩存、日志、命名等請(qǐng)你自行假設(shè) 在計(jì)劃開頭列出假設(shè)清單高影響假設(shè)標(biāo) ??。第二輪審視模型輸出的假設(shè)清單只糾偏高影響項(xiàng)。模型返回類似## 假設(shè)清單 1. ?? API 風(fēng)格采用 REST理由主流、易調(diào)試 2. 緩存暫不引入理由先跑通功能 3. 日志使用 Python logging 標(biāo)準(zhǔn)庫(kù) 4. 目錄結(jié)構(gòu)采用 src/ 布局你只需針對(duì)第 1 條標(biāo)了 ??做確認(rèn)或修正其余默認(rèn)接受。這樣把交互輪次從 N 輪壓縮到 2 輪。這個(gè)模式之所以有效是因?yàn)樗鸦卮饐栴}的成本從線性降到對(duì)數(shù)級(jí)約束類問題通常只占 20% 左右但決定了 80% 的方案骨架。抓住這 20%剩下的交給模型假設(shè) 清單審計(jì)。六、假設(shè)清單的驗(yàn)收讓假設(shè)變成可追蹤的契約最后一步常被忽略假設(shè)清單不是看完就算而應(yīng)沉淀為方案的一部分。建議在計(jì)劃文檔里保留一節(jié)假設(shè)與風(fēng)險(xiǎn)并在實(shí)現(xiàn)階段回查。一個(gè)可落地的做法是把假設(shè)清單結(jié)構(gòu)化為 JSON方便后續(xù)做自動(dòng)化校驗(yàn)比如在 CI 里檢查高風(fēng)險(xiǎn)假設(shè)是否已被確認(rèn){plan_id:feature-user-auth-001,assumptions:[{id:A1,content:API 風(fēng)格采用 REST,impact:high,confirmed:false,fallback:若改為 GraphQL需重寫 controller 層與前端請(qǐng)求封裝},{id:A2,content:暫不引入緩存層,impact:low,confirmed:true,fallback:后續(xù)可在 service 層插入 cache 裝飾器}]}配套一個(gè)簡(jiǎn)單的校驗(yàn)?zāi)_本在進(jìn)入實(shí)現(xiàn)階段前檢查是否還有未確認(rèn)的高影響假設(shè) check_assumptions.py 在 Plan 轉(zhuǎn)實(shí)現(xiàn)前檢查是否還有未確認(rèn)的高影響假設(shè)。 importjsonimportsysdefcheck(path:str)-bool:withopen(path,r,encodingutf-8)asf:planjson.load(f)pending[aforainplan.get(assumptions,[])ifa.get(impact)highandnota.get(confirmed,False)]ifpending:print(f?? 存在{len(pending)}個(gè)未確認(rèn)的高影響假設(shè)建議先確認(rèn))forainpending:print(f - [{a[id]}]{a[content]})print(f 若不成立:{a.get(fallback,未說(shuō)明)})returnFalseprint(? 所有高影響假設(shè)均已確認(rèn)可以進(jìn)入實(shí)現(xiàn)階段。)returnTrueif__name____main__:okcheck(sys.argv[1]iflen(sys.argv)1elseplan.json)sys.exit(0ifokelse1)把這一步納入工作流后跳過讓 AI 假設(shè)就不再是放任而是有審計(jì)、有兜底的授權(quán)。這才是跳過策略能安全落地的前提??偨Y(jié)Plan 模式下的信息補(bǔ)充本質(zhì)是一個(gè)注意力分配問題。本文的核心觀點(diǎn)可以濃縮為以下幾點(diǎn)不要二選一要分級(jí)。把模型的問題分為約束類、接口類、實(shí)現(xiàn)類、風(fēng)格類只有約束類必須逐項(xiàng)回答