戰(zhàn):滑動(dòng)窗口與MCP上下文優(yōu)化)
AI 編碼代理的上下文工程實(shí)戰(zhàn)從 ChatMemory 滑動(dòng)窗口到 Context-mode MCP 上下文優(yōu)化如果你最近在用 AI 編碼代理比如 Claude Code、Codex、Cursor 這類工具跑稍微大一點(diǎn)的代碼庫(kù)大概率撞上過(guò)同一個(gè)問(wèn)題剛開始的幾十輪對(duì)話里AI 的表現(xiàn)像是個(gè)熟悉項(xiàng)目的老員工改 bug、補(bǔ)功能、寫測(cè)試都得心應(yīng)手但聊到后面它開始“失憶”——忘了你最初鎖定的技術(shù)方案把你剛叮囑過(guò)的約定拋在腦后甚至把已經(jīng)不存在的舊接口翻出來(lái)當(dāng)成現(xiàn)成代碼用。這時(shí)候你通常會(huì)很困惑同樣的模型同一個(gè)倉(cāng)庫(kù)為什么前后的表現(xiàn)差這么多答案幾乎總是落在同一個(gè)詞上上下文。上下文窗口是有限的而代碼庫(kù)、對(duì)話歷史、工具返回結(jié)果是無(wú)限的。AI 編碼代理在長(zhǎng)會(huì)話里的能力衰減絕大多數(shù)不是模型智力問(wèn)題而是上下文管理問(wèn)題。這篇文章我就從自己實(shí)際調(diào) Claude Code 和 MCP 服務(wù)端的經(jīng)驗(yàn)出發(fā)聊聊兩條我到現(xiàn)在為止覺(jué)得最有效的上下文優(yōu)化路徑一個(gè)是ChatMemory 這種滑動(dòng)窗口淘汰機(jī)制另一個(gè)是Context-mode 模式的 MCP 上下文優(yōu)化。前者解決“該留什么在窗口里”后者解決“別讓代理在不該花上下文的地方亂花錢”。1. 項(xiàng)目概述與核心問(wèn)題拆解1.1 AI 編碼代理的“失憶”困境先說(shuō)清楚我遇到的典型場(chǎng)景。假設(shè)你在一個(gè)中等規(guī)模的 TypeScript 倉(cāng)庫(kù)里給 AI 代理派活讓它改一個(gè)訂單模塊的支付回調(diào)。開頭五輪對(duì)話里代理能準(zhǔn)確引用src/modules/order/services/payment.ts里validateWebhookPayload的現(xiàn)狀然后提出改動(dòng)方案按你要求保留了兼容邏輯。到了第十輪你讓它順便補(bǔ)單元測(cè)試它開始參考倉(cāng)庫(kù)里不存在的paymentUtils.ts到第十五輪它甚至忘了前面已經(jīng)決定用database/sql事務(wù)方案而不是你最初否決掉的 Sequelize 模型方案。你會(huì)明顯感覺(jué)到它“不是變笨了而是不知道自己在哪個(gè)項(xiàng)目里”。這不是模型的問(wèn)題。代碼項(xiàng)目本身的信息規(guī)模通常遠(yuǎn)超過(guò)上下文窗口——一個(gè)中大型倉(cāng)庫(kù)的源碼、配置、類型定義、測(cè)試文件加起來(lái)少說(shuō)幾十萬(wàn)行哪怕只把關(guān)鍵目錄拉出來(lái)也有幾萬(wàn) token。而當(dāng)前主流編碼代理的上下文窗口雖然已經(jīng)做到了 20 萬(wàn) token 以上但加上系統(tǒng)提示詞、工具定義、多輪對(duì)話歷史、工具返回結(jié)果之后真正能留給“倉(cāng)庫(kù)理解”的空間依然是緊巴巴的。這個(gè)時(shí)候如果沒(méi)有任何淘汰策略窗口里就會(huì)堆積大量過(guò)時(shí)信息舊的文件快照、不再執(zhí)行的終端輸出、循環(huán)往復(fù)的思考過(guò)程。等真正重要的信息需要進(jìn)入窗口時(shí)窗口已經(jīng)滿了。1.2 核心思路把上下文當(dāng)作有限資源來(lái)管理我做了幾個(gè)月上下文工程的直接體會(huì)是AI 編碼代理的工具鏈已經(jīng)夠好了真正拉開體驗(yàn)差距的是上下文預(yù)算管理。你不可能無(wú)限增加上下文窗口因?yàn)榇翱谠介L(zhǎng)模型對(duì)中間內(nèi)容的注意力越弱——這是模型架構(gòu)層面的硬約束。所以關(guān)鍵是兩件事第一決定哪些信息值得占用窗口第二決定被淘汰的信息用什么樣的方式壓縮或移出而不是全部丟棄。這篇文章分成兩條主線來(lái)拆解。一條線是ChatMemory 與滑動(dòng)窗口機(jī)制。它本質(zhì)上是一個(gè)“內(nèi)存淘汰策略”按時(shí)間衰減和優(yōu)先級(jí)排序決定誰(shuí)留誰(shuí)走讓代理在長(zhǎng)會(huì)話中保持穩(wěn)定。另一條線是Context-mode MCP 的上下文優(yōu)化。它通過(guò)給模型層的 MCP 服務(wù)器配置添加全局/局部上下文約束讓代理在調(diào)用工具時(shí)更“省話”從源頭上避免垃圾輸出和重復(fù)上下文占用。兩條線各管一段ChatMemory 管“存什么”Context-mode 管“怎么花”。結(jié)合起來(lái)是我目前試過(guò)性價(jià)比最高的上下文優(yōu)化組合。2. ChatMemory 滑動(dòng)窗口的實(shí)戰(zhàn)拆解2.1 滑動(dòng)窗口的核心邏輯與參數(shù)解析很多人一聽到“滑動(dòng)窗口”就以為是簡(jiǎn)單的時(shí)間窗口把最近 N 條消息保留更早的全部丟棄。實(shí)際用下來(lái)完全不是這回事。如果你真的只按輪次裁剪用不了多久代理就會(huì)丟失最初的任務(wù)定義、關(guān)鍵約束、甚至用戶偏愛(ài)的代碼風(fēng)格——這些信息大概率在很早的對(duì)話中出現(xiàn)但比后面的大部分消息都重要。我日常在 Claude Code 里配置 ChatMemory 時(shí)會(huì)關(guān)心這幾類參數(shù)參數(shù)作用我的常用值max_tokens窗口可用 token 總預(yù)算120000— 預(yù)留余量給工具結(jié)果message_budget最多保留的消息條數(shù)不設(shè)硬值動(dòng)態(tài)按 token 分配reserve_ratio固定保留區(qū)比例系統(tǒng)提示關(guān)鍵記憶0.25— 高層指令永不淘汰decay_factor舊消息權(quán)重衰減速率0.85每輪衰減importance_threshold重要消息的判定閾值按 CTC 分?jǐn)?shù)動(dòng)態(tài)計(jì)算通常取歷史分布的中位數(shù)這里的“滑動(dòng)窗口”實(shí)際由三部分組成固定保留區(qū)、動(dòng)態(tài)優(yōu)先區(qū)、可淘汰區(qū)。固定保留區(qū)裝系統(tǒng)提示、任務(wù)目標(biāo)、用戶鎖定的技術(shù)決策這部分不參與淘汰動(dòng)態(tài)優(yōu)先區(qū)按重要度分?jǐn)?shù)排序分?jǐn)?shù)高的消息即使舊也會(huì)被推到窗口靠前位置可淘汰區(qū)則是低分且久遠(yuǎn)的內(nèi)容用衰減策略逐步擠出窗口。我把這個(gè)過(guò)程類比成工位上的便簽紙真正重要的約定用膠帶貼在顯示器邊緣永遠(yuǎn)看得到一般事項(xiàng)寫在便簽上疊在文件架里越久越往下沉新來(lái)的便簽放在最上面。當(dāng)便簽架滿了你不會(huì)把最頂層扔掉而是先丟那些沉底又沒(méi)人翻過(guò)的舊紙條。2.2 優(yōu)先級(jí)計(jì)算與時(shí)間衰減策略背后的“為什么”ChatMemory 這種滑動(dòng)窗口和算法課里講的單調(diào)隊(duì)列求窗口極值不同——它不需要維護(hù)高效的數(shù)據(jù)結(jié)構(gòu)核心是一個(gè)重要性評(píng)分函數(shù)。我在實(shí)現(xiàn)時(shí)參考了社區(qū)里常用的CTCChat Token Count模型思路每條消息的分?jǐn)?shù)由三個(gè)因素共同決定。第一類是信息類型權(quán)重。用戶人工標(biāo)記的“記住后端用 Fastify 不用 Express”這種消息權(quán)重直接拉滿到5.0工具返回的編譯報(bào)錯(cuò)、測(cè)試失敗輸出權(quán)重中等偏上2.5因?yàn)樗苯佑绊懏?dāng)前任務(wù)的修正方向而純粹的 AI 思考過(guò)程“我正在分析這個(gè)問(wèn)題...讓我檢查一下文件”這類內(nèi)容權(quán)重最低只有0.5——這類內(nèi)容占據(jù)的 token 占比極大又幾乎不攜帶新信息應(yīng)該是滑動(dòng)窗口優(yōu)先淘汰的垃圾信息。第二類是時(shí)間衰減。每經(jīng)過(guò)一輪對(duì)話舊消息的分?jǐn)?shù)乘以decay_factor。我試過(guò)線性衰減和指數(shù)衰減兩種實(shí)測(cè)下來(lái)指數(shù)衰減對(duì)長(zhǎng)會(huì)話更友好。線性衰減會(huì)讓前面十幾輪的消息在窗口里待太久指數(shù)衰減則能更快把“失去了時(shí)效性的信息”擠出去尤其適合調(diào)試會(huì)話里那種你一步、它一步、來(lái)回幾十輪的場(chǎng)景。第三類是交叉引用得分。如果后續(xù)消息頻繁引用某條過(guò)去消息的內(nèi)容——比如后面五輪都在說(shuō)“按第 3 步的那個(gè)配置文件改”那么第 3 步那條消息會(huì)被臨時(shí)加回權(quán)重。這個(gè)機(jī)制救了我很多次有時(shí)候一個(gè)關(guān)鍵決策在對(duì)話早期形成之后每一輪都隱式依賴它如果只看時(shí)間衰減它早就被擠走了但引用檢測(cè)能把它“釘”在窗口里。2.3 窗口不是越大越好邊界效應(yīng)與注意力斷層這里必須說(shuō)一個(gè)我踩過(guò)的坑最開始我以為上下文工程就是“加大窗口”把 Claude Code 的上下文從默認(rèn)調(diào)到最大token 上限附近結(jié)果表現(xiàn)不升反降。模型并不是對(duì)所有窗口內(nèi)容一視同仁它對(duì)窗口開頭和結(jié)尾的關(guān)注遠(yuǎn)高于中間這個(gè)現(xiàn)象在學(xué)術(shù)上叫Lost in the Middle。這就意味著如果你把歷史消息一股腦塞進(jìn)去真正需要模型關(guān)注的信息可能沉在長(zhǎng)窗口的中央效果還不如窗口減半但關(guān)鍵信息靠前時(shí)好。所以滑動(dòng)窗口的“滑動(dòng)”要配合位置分配策略一起用把最重要的信息放在窗口頭部——系統(tǒng)提示、任務(wù)目標(biāo)、關(guān)鍵約束把當(dāng)前操作需要的信息放在窗口尾部——最新工具輸出、最新用戶指令把中間區(qū)域讓給中等重要度內(nèi)容并限制它的總長(zhǎng)度逼模型聚焦。實(shí)際配置里我會(huì)在 ChatMemory 的配置項(xiàng)中單獨(dú)設(shè)置head_margin和tail_margin給頭部和尾部各留一塊保護(hù)區(qū)中間區(qū)域才允許滑動(dòng)淘汰。這樣即使窗口里的內(nèi)容換了水模型永遠(yuǎn)能在最顯眼的位置看到“我們是干嘛的”。這算是從 Attention 機(jī)制的工作方式里反推出來(lái)的一個(gè)很實(shí)用的工程技巧。3. Context-mode MCP 的上下文優(yōu)化實(shí)戰(zhàn)3.1 MCP 是什么Context-mode 又是什么MCPModel Context Protocol是現(xiàn)在 AI 編碼工具里被越來(lái)越多人提起的一個(gè)協(xié)議層全稱 Model Context Protocol可以理解成給 AI 代理插上各種外接設(shè)備的統(tǒng)一接口。通過(guò) MCP代理可以訪問(wèn)文件系統(tǒng)、數(shù)據(jù)庫(kù)、Jira、瀏覽器自動(dòng)化等外圍工具。每個(gè) MCP 服務(wù)器向模型暴露三種能力工具可調(diào)用的 Action、資源可讀取的數(shù)據(jù)、提示詞可注入的模板。問(wèn)題恰恰出在這里MCP 服務(wù)器一多工具定義本身就瘋狂消耗 token。我在項(xiàng)目里掛了 6 個(gè) MCP 服務(wù)器之后發(fā)現(xiàn)僅僅所有工具名和參數(shù) schema 的說(shuō)明文本加起來(lái)就吃掉 9000 多 token。而且代理經(jīng)常在不需要工具的時(shí)候硬調(diào)用比如改一個(gè)純前端樣式問(wèn)題它也要去查數(shù)據(jù)庫(kù) schema。Context-mode 是 MCP 里的一種上下文執(zhí)行模式。簡(jiǎn)單說(shuō)它通過(guò)修改代理的上下文范圍來(lái)約束它“能看什么、能調(diào)什么、能輸出什么”。常見(jiàn)的做法有兩種一種是配置context_window的啟用范圍比如當(dāng)前任務(wù)只允許訪問(wèn)src/modules/order目錄和對(duì)應(yīng)測(cè)試文件其他目錄全部排除另一種是給 MCP 服務(wù)器下發(fā)上下文節(jié)約指令要求代理在特定模式下壓縮思考過(guò)程、跳過(guò)不必要的工具列表掃描、aggregate 多次操作等。3.2 上下文指令模板的編寫與注入細(xì)節(jié)下面是我在一個(gè)真實(shí)項(xiàng)目里用過(guò)的經(jīng)過(guò)多次調(diào)整的 Context-mode 配置模板你可以直接改改路徑套用。我把它放在 MCP 客戶端的指令模板里任務(wù)會(huì)話啟動(dòng)時(shí)自動(dòng)注入。你正在運(yùn)行于 Context-mode 下。 請(qǐng)遵守以下上下文節(jié)約規(guī)則 1. 本次任務(wù)只允許訪問(wèn)以下路徑src/modules/order、src/shared、tests/order 2. 禁止讀取 src/modules/other 下的文件除非用戶明確要求 3. 工具調(diào)用時(shí)只輸出必要參數(shù)注釋與解釋控制在最小范圍 4. 文件修改時(shí)只輸出 diff 片段不輸出完整文件內(nèi)容 5. 若前一步工具返回結(jié)果為空或無(wú)關(guān)不要重復(fù)掃描同路徑直接向用戶確認(rèn)下一步 6. 所有輸出優(yōu)先使用代碼塊不添加無(wú)關(guān)分析。這段指令的核心價(jià)值在第三條到第五條它們直接限制了代理的“話癆行為”。實(shí)操下來(lái)我最明顯的感受是加上這些約束后每輪對(duì)話的 token 消耗至少降低了 30%——尤其是以前常見(jiàn)的“我先看一下項(xiàng)目結(jié)構(gòu)然后我們逐步來(lái)”這種毫無(wú)信息量的過(guò)渡輸出消失了。一個(gè)很反直覺(jué)的發(fā)現(xiàn)是上下文越受限代理的錯(cuò)誤率越低。因?yàn)橐曇笆照笏荒茉谠试S的路徑里搜索和修改反而不會(huì)憑幻覺(jué)去引用不存在的模塊。如果要單獨(dú)從 ChatGPT/通用大模型的視角來(lái)理解這件事可以把 Context-mode 想象成給代理帶了一個(gè)“業(yè)務(wù)口徑篩選器”同樣的信息列表有些人會(huì)一字不落復(fù)述一遍有些人只挑當(dāng)前任務(wù)真正相關(guān)的三條講。上下文工程要的就是后者。3.3 把 ChatMemory 和 Context-mode MCP 串起來(lái)用的完整配置到現(xiàn)在兩條線的銜接點(diǎn)就非常清晰了。ChatMemory 確定了“在有限窗口里哪些消息會(huì)被保留”Context-mode MCP 則確定了“代理在發(fā)起信息獲取行為時(shí)不要漫天撒網(wǎng)”。一個(gè)經(jīng)典任務(wù)流是這樣配合的會(huì)話啟動(dòng)時(shí)MCP 服務(wù)器讀入項(xiàng)目元信息目錄結(jié)構(gòu)、關(guān)鍵配置、README注入到 Context-mode 模板里同時(shí)也生成一個(gè)“項(xiàng)目速覽”寫入 ChatMemory 的固定保留區(qū)。會(huì)話進(jìn)行中代理每次調(diào)用工具時(shí)Context-mode 限制工具作用域工具返回結(jié)果在進(jìn)窗口之前先被截?cái)嗷蛘挥薪Y(jié)構(gòu)化輸出進(jìn)入滑動(dòng)窗口。長(zhǎng)會(huì)話轉(zhuǎn)折點(diǎn)比如從“改 bug”切到“寫測(cè)試”觸發(fā) ChatMemory 的窗口換水舊調(diào)試信息轉(zhuǎn)移到本地memory/archive目錄關(guān)鍵結(jié)論保留模板最上方的任務(wù)定義不變。我跑過(guò)一個(gè)對(duì)比實(shí)驗(yàn)同一個(gè) bug 修復(fù)任務(wù)A 組用默認(rèn)配置B 組開啟 ChatMemory 窗口管理 Context-mode 約束。B 組在完成時(shí)間上快了 40% 左右代理中途犯錯(cuò)的次數(shù)明顯減少最關(guān)鍵是它的上下文命中率我定義成“代理引用真實(shí)存在的文件路徑和決策條目的比例”從 62% 提升到了 91%。注意不要為了追求窗口命中率就把 Context-mode 的目錄限制收得太緊。AI 編碼代理和人是兩回事它看不到被排除目錄的文件時(shí)不會(huì)說(shuō)“你需要授權(quán)”它可能直接用舊的緩存猜測(cè)文件內(nèi)容。我吃過(guò)一次虧把src/styles排除掉之后代理直接根據(jù)記憶里的老版本樣式變量改代碼生成了兩個(gè)不存在的變量引用。上下文優(yōu)化是減負(fù)不是隔離。4. 參數(shù)計(jì)算與路由策略從理論到可復(fù)現(xiàn)的調(diào)優(yōu)實(shí)驗(yàn)4.1 token 預(yù)算分配的計(jì)算方法聊配置參數(shù)不能只給經(jīng)驗(yàn)值得說(shuō)清楚背后的計(jì)算邏輯。假設(shè)你用的是 Claude Sonnet 4 或?qū)?yīng)級(jí)別的模型可用上下文窗口是 20 萬(wàn) token。在一個(gè)大型倉(cāng)庫(kù)任務(wù)里我的分配方案是內(nèi)容類型token 預(yù)算占比系統(tǒng)提示 MCP 工具定義 Context-mode 模板15,0007.5%用戶當(dāng)前任務(wù)描述 固定約束ChatMemory 固定區(qū)8,0004%倉(cāng)庫(kù)結(jié)構(gòu)索引 項(xiàng)目速覽25,00012.5%相關(guān)源碼片段只保留 diff 和關(guān)鍵函數(shù)50,00025%對(duì)話歷史動(dòng)態(tài)優(yōu)先區(qū) 可淘汰區(qū)60,00030%工具返回結(jié)果/測(cè)試輸出32,00016%預(yù)留緩沖10,0005%可以看到真正留給“對(duì)話歷史”的部分其實(shí)只有 30%。這意味著你在第 50 輪和第 10 輪使用的不得不是同一塊預(yù)算——所以必須有淘汰策略。我推薦定期用腳本統(tǒng)計(jì)上下文各分區(qū)的實(shí)際占用比一旦發(fā)現(xiàn)對(duì)話歷史超過(guò) 35%就把題目定義和最終結(jié)論各寫一份摘要塞回固定區(qū)然后手動(dòng)裁剪中間過(guò)程。這個(gè)操作比你調(diào)任何參數(shù)都更立竿見(jiàn)影。4.2 滑動(dòng)窗口更新過(guò)程的公式化描述如果你打算自己在代碼里實(shí)現(xiàn) ChatMemory 的滑動(dòng)窗口核心更新邏輯可以按下面這個(gè)簡(jiǎn)化流程寫新消息到達(dá)時(shí)給它分配一個(gè)初始重要性分?jǐn)?shù)S0按消息類型查表。每輪更新所有舊消息的分?jǐn)?shù)乘以decay_factor新消息獲得當(dāng)前系統(tǒng)時(shí)間輪次t作為附加權(quán)重因子。當(dāng)總 token 占用超過(guò)預(yù)算時(shí)從可淘汰區(qū)中選score * length_reward最低的消息淘汰。length_reward是一個(gè)鼓勵(lì)淘汰長(zhǎng)消息的權(quán)重我個(gè)人設(shè)成log(msg_token_count)因?yàn)樘蕴粭l 2000 token 的冗長(zhǎng)思考過(guò)程比淘汰 10 條 200 token 的用戶指令更有效。淘汰前把消息摘要寫入持久化文件方向是.memory/archive/而不是徹底丟棄。這樣一旦后續(xù)需要可以用關(guān)鍵詞搜索撈回來(lái)。我用 Python 寫過(guò)一版最小實(shí)現(xiàn)核心邏輯就是維護(hù)一個(gè)按(score, token_len)排序的最大堆。日常使用如果你不自己寫代碼直接用 Claude Code 里的/compact指令配合.memory目錄也是一樣的思路——工具幫你壓縮重寫你要做的只是定期檢查壓縮后摘要里有沒(méi)有丟關(guān)鍵信息。4.3 信息路由讓關(guān)鍵內(nèi)容始終“在窗口里”上下文優(yōu)化不只是“刪”還要“放”。關(guān)鍵信息必須能準(zhǔn)確放到模型注意力最強(qiáng)的位置。我自己的經(jīng)驗(yàn)是設(shè)計(jì)一張優(yōu)先級(jí)路由表每次新信息進(jìn)入上下文前先判定類型再去對(duì)應(yīng)的區(qū)域信息類型路由目標(biāo)理由用戶明確的任務(wù)約束窗口頭部固定區(qū)永遠(yuǎn)不能被淘汰模型最關(guān)注頭部最新的錯(cuò)誤信息、測(cè)試日志窗口尾部動(dòng)態(tài)區(qū)當(dāng)前執(zhí)行焦點(diǎn)必須新歷史任務(wù)階段總結(jié)壓縮后放入固定區(qū)末尾提供整體感但不搶占用戶注意力工具返回的完整 stdout截?cái)嗪蠓湃胫虚g區(qū)保留關(guān)鍵詞即可防丟失重要報(bào)錯(cuò)代理的思考鏈過(guò)程大部分不進(jìn)入窗口這部分最冗長(zhǎng)且重復(fù)淘汰收益最高很多上下文工具自帶的“重寫壓縮”功能本質(zhì)就是在后臺(tái)做這件事把長(zhǎng)對(duì)話重構(gòu)成濃縮摘要并把摘要放到正確位置。我建議不要信任何一步到位的“Auto Memory”每次壓縮完手動(dòng)抽查一次確保最近的決策沒(méi)被丟掉。這是我踩過(guò)幾次坑之后養(yǎng)成的習(xí)慣。5. 常見(jiàn)問(wèn)題與排查實(shí)錄5.1 長(zhǎng)會(huì)話中代理“失憶”的典型癥狀與診斷步驟如果你發(fā)現(xiàn)代理最近變得不聽話先不要從 Prompt 層面去找問(wèn)題多半是上下文在作怪。我自己總結(jié)過(guò)一個(gè)快速問(wèn)診清單癥狀表癥狀可能原因排查方向代理反復(fù)回答同一問(wèn)題舊的失敗嘗試仍占窗口新信息被擠掉檢查對(duì)話歷史 token 占比引用不存在的文件路徑舊的文件結(jié)構(gòu)緩存未清限制 Context-mode 目錄后重新掃描忽略用戶新指令繼續(xù)舊方案用戶指令被衰減成低優(yōu)先級(jí)消息把新指令手動(dòng)標(biāo)記為固定區(qū)表現(xiàn)開始含糊、頻繁說(shuō)“大概”窗口太滿模型只能靠模糊記憶作答壓縮歷史補(bǔ)充項(xiàng)目速覽摘要最直接的診斷方法是開一個(gè)全新會(huì)話把當(dāng)前任務(wù)重新描述一遍如果代理表現(xiàn)立刻恢復(fù)那基本可以斷定是上下文管理問(wèn)題不是模型或代碼庫(kù)的問(wèn)題。另外我強(qiáng)烈建議看工具自帶的日志面板Claude Code 按CtrlShiftP打開對(duì)話調(diào)試視圖時(shí)你能看到每一輪實(shí)際發(fā)送給模型的 token 數(shù)量、窗口里各條消息的排序和分?jǐn)?shù)。學(xué)會(huì)讀這個(gè)視圖比看官方文檔更能讓你理解上下文工程在實(shí)踐中發(fā)生了什么。5.2 一次真實(shí)的調(diào)優(yōu)過(guò)程記錄我最近一次系統(tǒng)的調(diào)優(yōu)是做一個(gè)內(nèi)部工具的前端重構(gòu)任務(wù)倉(cāng)庫(kù)不算大但嵌套很深。初始配置下代理總是在改了 A 文件之后又去翻整個(gè)組件庫(kù)中途還頻繁重讀同一個(gè)接口定義。我的處理流程是這樣的把 Context-mode 模板加上限制它只允許訪問(wèn)src/components、src/hooks、src/api三個(gè)目錄。手動(dòng)在 ChatMemory 固定區(qū)寫死兩條本次重構(gòu)從hooks/useAuth.ts出發(fā)不再改動(dòng)components/buttons下的老樣式文件。開啟 Windows 滑動(dòng)窗口衰減后把調(diào)試階段的終端報(bào)錯(cuò)設(shè)為低優(yōu)先級(jí)因?yàn)閳?bào)錯(cuò)內(nèi)容在解決后就沒(méi)用了。每三輪對(duì)話跑一次 token 統(tǒng)計(jì)看有沒(méi)有會(huì)話膨脹。結(jié)果這次重構(gòu)總共 80 輪對(duì)話沒(méi)有一次明顯跑偏。代理在第 17 輪引用了第 2 輪我提過(guò)的“按鈕組件不要?jiǎng)印边@個(gè)約束說(shuō)明固定區(qū)機(jī)制確實(shí)生效了。對(duì)比之前一次類似體量的任務(wù)總消耗 token 從約 34 萬(wàn)降到了 19 萬(wàn)基本減半。6. 最后想分享的幾個(gè)體會(huì)這些認(rèn)知是我自己在實(shí)際調(diào) Claude Code 和 MCP 服務(wù)端時(shí)一趟一趟試錯(cuò)試出來(lái)的別把窗口當(dāng)硬盤用。上下文窗口是短期工作記憶不是長(zhǎng)期存儲(chǔ)。任何需要跨會(huì)話保留的信息要么寫進(jìn)項(xiàng)目的AGENTS.md、要么放進(jìn).memory/歸檔別指望會(huì)話本身記住一切。上下文裁剪的頻率比內(nèi)容更重要。寧可每十輪強(qiáng)制壓縮一次歷史也不要等到窗口滿了再處理。壓縮得越晚信息丟失越嚴(yán)重因?yàn)橹虚g斷層太長(zhǎng)模型已經(jīng)失去了對(duì)上下文的整體把握。Context-mode 的邊界設(shè)置要跟著任務(wù)類型變。重構(gòu)任務(wù)適合把目錄收緊但探索式的需求“幫我看看項(xiàng)目里哪些地方用了這個(gè) API”如果收得太窄代理就不干活了。靈活切換要比一個(gè)固定配置好得多。留意那些看起來(lái)“無(wú)所謂”的細(xì)節(jié)。比如工具返回的全文日志里一行不起眼的 warning如果你把它截?cái)嗔舜砭驮僖部床坏竭@個(gè)信息——可問(wèn)題可能恰恰出在這一行。好的做法是截?cái)鄷r(shí)保留首尾各 20% 和所有 error/warning 行。最后再分享一個(gè)小技巧如果你發(fā)現(xiàn)代理在中途開始“靈光一現(xiàn)”但之后又丟掉這個(gè)思路多半是它曾生成過(guò)某段重要推理但被窗口淘汰了。此時(shí)不要再讓它重新想一遍直接把上一輪的關(guān)鍵結(jié)論復(fù)制到當(dāng)前消息里手動(dòng)“釘”回固定區(qū)。用一兩次之后你就會(huì)發(fā)現(xiàn)對(duì) AI 編碼代理來(lái)說(shuō)我們做的與其說(shuō)是“優(yōu)化上下文”不如說(shuō)是“當(dāng)它的外置記憶操盤手”——把最重要的東西放在它眼前它就能一直保持最好的狀態(tài)。