
我最近在處理幾個長時間運行的對話式 AI 專案時被同一個問題反覆折磨模型明明給出了很合理的回覆但聊到後面就開始“失憶”要麼忘了使用者幾輪前給的偏好要麼把早前的決定重複推翻。查了一圈日誌發現根子都出在對上下文的處理上——我們把整段歷史一股腦塞給模型塞到超過上下文窗口然後模型就開始瞎編。後來我系統性地梳理了“context-mode”這套上下文管理模式把所有關於“怎麼管上下文”的方法論沉澱成一套可複用的工程方案這段時間跑下來效果提升非常明顯。這篇文章不是純理論而是把 context-mode 從設計思路到落地實操完整拆開。如果你正在開發基於大模型 API 的應用比如聊天機器人、AI 助理、知識問答系統或者只是好奇為什麼有些 AI 產品能“記住”你有些卻一直“雞同鴨講”這篇文章都適合你。我會講清楚它解決了什麼問題、核心設計有哪幾塊、怎麼一步步實現還有我踩過的那些坑。1. context-mode 到底在解決什麼問題1.1 大模型上下文窗口的物理限制先說一個所有開發者都繞不開的事實大模型的上下文窗口是有限的。雖然現在各家都在卷長上下文128K、200K 甚至 1M 的模型都出來了但“支援”和“好用”是兩碼事。你把 200 頁文檔全部塞進提示詞模型確實能“看到”但注意力會分散關鍵信息反而淹沒在大量無關文本裡。這就像讓一個人類員工在一個月裡讀完 5000 封郵件再回答工作問題他能讀完但你別指望他記得第一天郵件裡的細節。Context-mode 的核心價值就在這裡它不是讓你把所有歷史都塞進去而是幫你管理“哪些內容值得進入上下文”。這套模式本質上是一個過濾器加調度器把上下文的每一寸空間都用在刀刃上。現實中很多人忽略的另一個限制是 API 的輸入輸出比例。不少模型對輸入和輸出的總 token 有硬性限制你輸入佔得越多留給輸出的空間就越少。假設一個模型支援 32K 總上下文你把 30K 全用在歷史對話上那模型每次回覆只能輸出 2K這在生成代碼、長報告、多輪工具調用場景下根本不夠用。所以 context-mode 必須考慮的不只是“塞多少進去”還有“給輸出留多少空間”。1.2 token 成本與響應延遲的代價如果說上下文窗口是物理天花板那 token 成本就是經濟天花板。所有商業大模型 API 都是按 token 計費的輸入 token 和輸出 token 價格不同但都是實打實的錢。一個簡單的測算假設你的應用每次請求攜帶 10K token 的上下文日均 10 萬次請求那就是每天 10 億 token 的輸入量。按市面上常見的模型定價這一天的成本就是幾百到上千元。而 context-mode 的核心目標之一就是把這些不必要的 token 砍掉壓縮到原來的 20% 甚至更低。響應延遲同樣和上下文長度正相關。模型處理每個 token 都需要計算token 越多首字延遲越高。使用者體感是非常敏銳的——從 2 秒到 4 秒的延遲流失率能差出一大截。你在測試環境裡可能感覺不明顯但上線後在高並發下長上下文導致的排隊和超時會變成災難。所以說 context-mode 不是錦上添花而是面向生產環境的必需品。1.3 對話連貫性與狀態管理的本質矛盾再往深一層看context-mode 解決的其實是對話狀態管理的問題。對話系統本質上是一個有狀態的應用但大模型本身是無狀態的——每次請求都是獨立的函數調用模型不記得你上次說了什麼。所謂的“記憶”完全是靠你把歷史對話放在上下文中“餵”給它。這就帶來一個根本矛盾狀態越多需要傳遞的歷史就越長但歷史越長模型就越容易迷失。更麻煩的是很多關鍵狀態不是“最近幾輪對話”而是“很久以前的某個決定”。比如使用者在第 3 輪說“我喜歡簡潔的回覆風格”第 50 輪時你如果還要把這句話原封不動地放在上下文裡那就是巨大的浪費但如果不放模型又會變成另一種風格。Context-mode 的做法是引入分層記憶——把狀態拆成長期偏好、中期事實、短期對話三個層級分別採用不同的保存和調度策略。這個思路和人類的記憶機制很像你不會記住每頓飯吃了什麼但你會記得自己對什麼食物過敏。下文我會詳細展開這套分層設計。2. context-mode 的核心設計思路2.1 上下文分層系統提示、工作記憶與長期記憶我實踐下來最有效的框構是“三層上下文”模型每一層都有明確的生命週期和調度策略。第一層是系統提示詞system prompt這是雷打不動的底層指令包括角色的基本設定、回覆格式要求、安全規則等。它的特點是短小精悍、永遠存在、不隨對話輪次變化。我見過很多開發者把動態信息也塞進 system prompt這是很不好的習慣因為 system prompt 一旦變長模型對其餘歷史的注意力就會被稀釋。第二層是工作記憶working memory對應的是當前對話的近期輪次。這部分就是我們通常意義上的“聊天記錄”模型需要靠它理解“剛才聊到哪了”。工作記憶的範圍可以在 6 到 20 輪之間動態調整不是越多越好——想想現實中你也不會把和同事的每一句話都復述一遍才能繼續討論。第三層是長期記憶long-term memory沉澱的是跨對話、甚至跨 session 的關鍵資訊使用者的偏好、做過的決定、不變的事實。在 context-mode 的實現中長期記憶通常由摘要和檢索索引兩部分組成摘要給模型一個宏觀的知識底圖檢索索引則在需要精確細節時按需調取。這三層不是簡單拼接而是有清晰的優先級系統提示 長期記憶摘要 工作記憶輪次 檢索片段。當 token 預算緊張時先削減工作記憶再壓縮長期記憶摘要但系統提示和剛發生的最近幾輪對話永遠保留。這個優先級是我在大量實驗後總結的規律順序一旦顛倒模型行為就會明顯變差。2.2 上下文壓縮與摘要生成當對話歷史超過預算最常見的處理手段是“摘要壓縮”。簡單粗暴地刪除舊訊息會丟掉太多資訊而把多輪對話交給模型生成一份摘要則可以用極少的 token 保留大部分語義。舉個例子10 輪對話可能消耗 4000 token但摘要可能只需要 500 token 就能把事實性結論、使用者的明確要求、尚未完成的任務等關鍵點全部記錄下來。但摘要不是隨便生成的我建議摘要結構化。不要讓模型自由發揮寫一段散文式的“聊天總結”而是規定一個固定的摘要模板比如使用者核心需求/目標已確認的事實與使用者偏好待辦事項或未解決問題最近的決定或結論把摘要按這些維度生成後續檢索和注入會方便得多。否則你從一段散文式摘要裡撈信息還不如直接翻原文。壓縮策略上我通常採用“滑動視窗摘要合併”的方式正常工作記憶窗口保留最近 N 輪完整對話視窗之前的對話每隔一定輪次生成一次摘要當摘要累積到一定體積時再對多個摘要做一次二次摘要。這樣既保證了近期的細節完整又讓更早期的資訊以極高的壓縮率存續。這裡有一個容易被忽略的細節摘要本身也是模型生成的也會有“遺忘”或“扭曲”。所以摘要生成時的輸入不僅僅是那段對話還要把已有的歷史摘要一起餵進去讓模型在舊摘要的基礎上做增量更新而不是每次從零開始。我稱之為“摘要繼承”它能明顯減少前後摘要之間的資訊斷層。2.3 檢索增強與動態注入只有壓縮是不夠的因為摘要終究是“梗概”很多具體細節——比如使用者說過的一個特定數字、一個精確的產品名稱——很可能在摘要時被犧牲掉。這種場景需要檢索增強RAG 的思路來補位。Context-mode 中的檢索不是把整個外部知識庫都搬進來而是檢索“歷史對話片段”。具體做法是把每一輪對話或幾輪合併成一個 chunk向量化並存入向量資料庫同時建立關鍵詞索引。當新一輪對話到來時先對使用者的輸入做意圖判斷判斷是否需要調取歷史細節——如果只是閒聊“今天天氣如何”你不需要翻歷史但如果使用者問“我之前說的那個配置參數是多少”你就必須把歷史中出現過“配置參數”相關的對話片段撈出來。檢索出的片段注入在哪裡也有講究。我建議放在工作記憶之後、系統提示之前的獨立區域並用明顯的標記區分例如[相關歷史回顧] 使用者在第 23 輪提到伺服器要求 8GB 記憶體以上預算不超過 5000 元。 [回顧結束]這樣模型能清楚分辨“這是被檢索出來的回顧資料”和“這是正在進行的對話”避免混亂。混合檢索是我現在的首選——向量檢索負責“語義相關”關鍵詞檢索負責“精確匹配”兩路結果合併後按相關性排序取 Top K 注入。純向量檢索在專有名詞和數字上經常失準而純關鍵詞檢索又無法捕獲同義表達。兩者的結合準確率會高非常多。2.4 動態 token 預算分配最後一個核心思路是給不同層級的上下文設定動態的 token 預算。不要用固定的數字因為每輪對話的長度差異很大。我的做法是在每個請求開始前做一次預算分配先估算系統提示詞的 token 數預留固定空間。給輸出預留最小空間比如總預算的 20%。剩餘空間中先分配給最近幾輪完整對話至少保證最近 4 輪不裁剪。再分配給長期記憶摘要。如果還有剩餘再分配給檢索注入的歷史片段如果沒有就減少檢索片段數量或者完全不放。這個順序的邏輯是最近的對話對當下回覆影響最大摘要給出背景檢索給出細節補充。你可以把總預算想像成一個限額信用卡每一層都是不同的消費項目必須有先後順序和管理規則否則很容易超支。3. 實戰從零實現一個 context-mode3.1 定義消息結構與上下文容器下面我會用 Python 完整實現一個簡潔但可用的 ContextManager。先從資料結構開始。我的做法是用一個類封裝所有上下文操作外部調用只需要add_message和build_messages兩個方法。import json from typing import List, Dict, Any, Optional class Message: def __init__(self, role: str, content: str, timestamp: int 0): self.role role # system / user / assistant / tool self.content content self.timestamp timestamp def to_dict(self) - Dict[str, str]: return {role: self.role, content: self.content} class ContextManager: def __init__(self, system_prompt: str, max_tokens: int 8000): self.system_prompt system_prompt self.max_tokens max_tokens self.working_memory: List[Message] [] self.summary: str self.recall_pool: List[Message] [] # 檢索候選池這裡我沒有把 system prompt 放到 messages 列表裡而是單獨存放。因為它不參與裁剪邏輯永遠原樣輸出。working_memory就是工作記憶區summary是長期記憶摘要recall_pool是檢索候選池——實際專案中 recall_pool 可以接入向量資料庫這裡為了示範用列表模擬。3.2 實現 token 估算與預算分配在做任何裁剪前必須先能準確估算 token 數。最靠譜的方式是用 OpenAI 官方的 tiktoken 庫。中文文本的 token 統計和英文不同一個常見的近似是1 個中文字元約等於 1 到 2 個 token英文 4 個字元約等於 1 個 token。但不同模型的分詞器不同最終還是以實際編碼為準。import tiktoken class ContextManager: def __init__(self, system_prompt, max_tokens8000, model_namegpt-4o): # 省略初始化... self.encoder tiktoken.encoding_for_model(model_name) def _count_tokens(self, text: str) - int: if not text: return 0 return len(self.encoder.encode(text)) def _count_messages_tokens(self, messages: List[Message]) - int: total 0 for msg in messages: total self._count_tokens(msg.content) total len(messages) * 4 # 每個消息的 role 資訊和格式開銷 return total這裡有個小技巧消息格式本身也會消耗 token。每個 message 物件要帶 role 欄位轉成 API 請求時還會加上\n、role:這些字元大約每個消息多出 3 到 5 個 token。批量計算時加上這個固定開銷預算才會準。3.3 實現滑動視窗裁剪最基礎的裁剪策略是保留最近 N 輪完整對話其餘輪次轉入壓縮流程。這裡我設定兩個參數hard_limit_tokens是硬頂超過這個值就必須處理soft_limit_tokens是軟頂超過時優先裁減可選内容。class ContextManager: def build_messages(self, max_output_tokens: int 2000) - List[Dict[str, str]]: budget self.max_tokens - max_output_tokens msgs: List[Dict[str, str]] [{role: system, content: self.system_prompt}] if self.summary: msgs.append({role: system, content: f[長期記憶摘要]\n{self.summary}}) # 工作記憶從尾部向前保留直到預算不足或輪次耗盡 used self._count_messages_tokens(msgs) selected: List[Message] [] for msg in reversed(self.working_memory): msg_tokens self._count_tokens(msg.content) 4 if used msg_tokens budget: break selected.append(msg) used msg_tokens selected.reverse() msgs.extend([m.to_dict() for m in selected]) # 如果還有剩餘預算嘗試注入檢索片段 remaining budget - used if remaining 200 and self.recall_pool: injected self._select_recall_fragments(remaining) for frag in injected: msgs.append({role: system, content: f[相關歷史回顧]\n{frag}}) return msgs倒序遍歷是關鍵從最新一輪開始向前掃描遇到超出預算就停下來。這樣可以保證“最近的對話一定保留”因為它們在列表尾部會先被掃描到。3.4 實現摘要壓縮策略當工作記憶超出滑動視窗、或者裁剪時被移除的訊息累積夠多就需要觸發摘要。我設計的觸發條件是被移除的工作記憶訊息總 token 超過某個閾值例如 3000 token時執行一次摘要生成。class ContextManager: def _summarize_dialogue(self, dialogue: List[Message]) - str: raw_text \n.join([f{m.role}: {m.content} for m in dialogue]) prompt f請對以下對話生成結構化摘要包含 1. 使用者核心需求與目標 2. 已確認的事實與使用者偏好 3. 待辦事項或未解決問題 4. 最近的決定或結論 要求簡潔僅輸出要點無需客套話。 對話內容 {raw_text} 已有舊摘要如果存在請在此基礎上增量更新 {self.summary} # 實際呼叫 LLM API 生成摘要 # response openai_client.chat.completions.create(...) # return response.choices[0].message.content return generated_summary這裡的增量更新很重要生成新摘要時把舊摘要一起作為上下文提供模型會知道“之前總結過什麼這次只需要把新對話合併進去”。這樣摘要不會因為每次只看到一小段對話而丟失遠古資訊。觸發時機我推薦在請求結束後觸發而不是每輪都觸發。比如在每次add_message後檢查一下被移除的訊息量達到閾值就排隊執行摘要。不要阻塞主流程否則用戶體驗會受影響。3.5 實現檢索注入策略檢索的實現分兩步索引和查詢。示範中用一個簡單的recall_pool列表模擬其中每個元素是對話片段文本, 關鍵詞, 向量。實際專案中我會在每次訊息加入工作記憶時同時把這條訊息寫入檢索儲存。class ContextManager: def index_message(self, message: Message): # 實際專案呼叫 embedding API 生成向量存入向量資料庫 # 這裡簡化按關鍵詞建立索引 chunk f{message.role}: {message.content} keywords [kw for kw in [配置, 價格, 時間, 需求, 決定] if kw in message.content] self.recall_pool.append({ text: chunk, keywords: keywords, embedding: None # 替換為真實向量 }) def _select_recall_fragments(self, token_budget: int) - List[str]: # 從使用者最近輸入中提取查詢詞 query self.working_memory[-1].content if self.working_memory else query_keywords [kw for kw in [配置, 價格, 時間, 需求, 決定] if kw in query] if not query_keywords: return [] scored [] for item in self.recall_pool: # 計算關鍵詞重疊度 時間近度這裡簡化為只算關鍵詞 overlap len(set(query_keywords) set(item[keywords])) if overlap 0: scored.append((overlap, item[text])) scored.sort(reverseTrue, keylambda x: x[0]) result [] used 0 for score, text in scored: t self._count_tokens(text) if used t token_budget: continue result.append(text) used t return result實際專案裡你大概率會用向量資料庫比如 Chroma、Qdrant 或 pgvector。查詢方式是用當前使用者輸入的 embedding 檢索最相近的歷史片段。關鍵詞重疊只是一種退化實現但核心思想一致只有當前的對話確實需要歷史細節時才把它撈回來。3.6 完整主流程串接所有組件湊齊後主流程是這樣的cm ContextManager( system_prompt你是一個耐心細緻的AI助理回答簡潔有力。, max_tokens8000 ) # 使用者發送消息 while True: user_input input(你) cm.add_message(user, user_input) # 檢索歷史 # cm._select_recall_fragments() # 構建送往模型的訊息 messages cm.build_messages(max_output_tokens2000) # response call_llm(messages) # 收到回覆後加入上下文 # cm.add_message(assistant, response) # 觸發壓縮/摘要檢查 cm._maybe_summarize()一個生產級系統中_maybe_summarize還應該做非同步處理避免阻塞使用者請求。另外build_messages的結果和實際送入模型的訊息必須一致否則上下文會錯位。4. 常見問題與排查技巧實錄4.1 上下文物件污染問題在第一版實作中我把所有檢索到的歷史片段直接拼在工作記憶後面結果發現模型越來越“困惑”它分不清哪些是當前對話、哪些是歷史回顧甚至把歷史片段中的話當成使用者剛說的來回應。排查後確認是注入格式的問題。解決方法就是我前面示範的那樣——用明確的標記包裹檢索片段同時在 system prompt 裡加上規則“被 [相關歷史回顧] 標記的內容僅供參考不一定是當前對話的一部分請勿引用為使用者最新輸入。”同樣的污染問題也出現在摘要區。有些模型會把摘要裡的內容當成必須執行的指令比如摘要裡有一句“使用者要求每次回覆控制在 50 字內”模型在後續對話中會一直遵守。這是合理的但如果你不想讓摘要中的“記錄”變成“指令”就要在 prompt 裡劃清界限。4.2 token 計數不準導致超限我最開始用字元數除以 4 來估算 token結果在中文場景下誤差特別大。中文一個字元往往不止 0.25 個 token我曾經把 8000 token 的預算算成 6000導致長對話被過早裁剪。後來換成 tiktoken 按具體模型編碼誤差才控制在 5% 以內。另一個容易忽略的是 system prompt 的隱性 token 消耗。我第一次測試時沒有把 role 標記和格式開銷算進去實際上幾百條消息的格式開銷加在一起非常可觀。建議所有 token 統計都基於“最終送入 API 的完整訊息列表”而不是簡單的文本拼接。4.3 摘要資訊丟失或失真摘要壓縮的最大風險不是“省了多少 token”而是“丟了什麼關鍵資訊”。我遇到過一個真實場景使用者在第 20 輪明確說“預算只有 3000 元”第 60 輪問“我們上次說的報價方案怎麼算的”摘要裡完全沒有這個數字檢索也沒命中模型就隨口給了一個錯誤的估價。排查後發現兩個問題一是摘要模板中沒有“關鍵數字”這一欄模型在總結時會傾向於省略具體數字二是我沒有把報價方案相關的對話片段加入檢索池。改進措施很簡單——摘要模板增加“關鍵數字/參數”同時每輪對話一律入檢索池而不只在觸發摘要時入池。4.4 壓縮時機與頻率失控還有一個常見問題是過度壓縮。如果把摘要觸發閾值設得太低比如累計 1000 token 就做一次摘要那系統幾乎每兩三輪就會觸發一次摘要請求消耗額外的 API 調用成本同時摘要鏈條越來越長二次壓縮又會丟資訊。反過來閾值太高又會讓中期歷史佔用大量 token。我的建議是觸發閾值設定在工作記憶預算的 1/3 左右。比如預算是 6000 token工作記憶保留最近 4000 token當被移除的訊息累計超過 2000 token 時才觸發一次摘要。頻率上一個活躍 session 每 10 到 20 輪觸發一次是比較健康的節奏。4.5 檢索命中率低下檢索命中率是 context-mode 是否好用的分水嶺。我最初的檢索只用了向量相似度結果專有名詞和縮寫的命中率非常差——使用者說“那個啥啥專案”向量檢索完全找不到“XX 數據平台遷移”的歷史。加入關鍵詞倒排索引後命中率從 68% 提升到 91%。實務上我會建議採用雙通道檢索向量通道負責語義相似關鍵詞通道負責字面重疊兩者用 RRFReciprocal Rank Fusion融合排序。這個方案實作不算複雜但效果遠超單通道。另外歷史片段按“對話回合”切分比按固定字元數切分更好因為回合是語義完整的單元。4.6 多輪工具調用場景下的特殊處理如果你的應用不只是純聊天還會呼叫工具查資料庫、發請求那麼上下文裡除了對話還有工具呼叫的參數和結果。這類內容的體積通常很大比如一次資料庫查詢可能返回幾百行 JSON。我的做法是工具結果不直接進工作記憶而是先做欄位提取只把“查詢條件”和“結果摘要”存入上下文。精確數據可以存在獨立儲存中等使用者追問時再檢索。這樣能省下大量 token同時避免模型把大段 JSON 當成對話內容。5. 從一個模式到一套體系context-mode 的擴展思考5.1 跨 session 的持久化記憶如果 context-mode 只在單次 session 內有效那它的價值會大打折扣。真實世界中使用者可能隔了兩天又回來繼續上次話題。所以我會把 context-mode 的最終輸出——也就是“已更新的長期記憶摘要”和“重要歷史索引”——持久化到資料庫中按使用者 ID 或 session ID 保存。下次同一使用者發起新 session 時應用初始化 ContextManager 時會先載入歷史摘要而不是從零開始。這就像一個人帶著過往經驗進入新會議而不是每次都像是第一次見面。跨 session 的記憶持久化是建構“了解我”的 AI 產品的必經之路。具體實作上我建議為每個使用者維護一張摘要表欄位大致是user_id、session_id、summary_text、updated_at、key_factsJSON 結構化檔案。每當 session 結束時把最終摘要寫入。新 session 開始時將所有歷史摘要按時間排序並二次壓縮成一份“長期使用者檔案”注入系統提示詞。5.2 context-mode 與多 Agent 協作在多 Agent 架構中context-mode 的思路同樣可以複用只是更複雜——每個 Agent 都有自己的上下文同時它們之間需要共用一部分上下文。我常用的做法是設計一個“共享記憶區”讓不同 Agent 之間可以往裡面寫入資訊也可以從中檢索。比如在一個客服系統中接待 Agent 負責理解使用者問題訂單 Agent 負責查詢訂單狀態售後 Agent 負責處理退款。當接待 Agent 發現使用者的問題涉及到訂單狀態時它會把使用者的訂單編號寫入共享記憶區訂單 Agent 檢索到這個編號後直接查詢不再需要使用者重複提供。這本質上就是 context-mode 在系統層面的延伸——上下文不再只屬於單個模型的視窗而是分佈在多個 Agent 之間的協作空間。5.3 未來的自動化上下文調度我目前在實驗的方向是讓 context-mode 的參數不再手動設定而是根據使用者行為自動調整。比如如果使用者連續問多輪細節問題說明他需要更長時間的工作記憶窗口我動態調低摘要觸發閾值如果使用者只是閒聊就調高閾值讓更多輪次駐留在視窗內。這些調整可以靠簡單的規則引擎實現也可以靠一個小型強化學習模型來決定。後者的成本很高對絕大多數專案來說不值得先從規則開始更務實。自動化調度的好處是讓系統在不同場景下都能保持最佳狀態而不是一套參數用到底。我自己在測試中發現動態調整比固定參數的整體使用者滿意度高出約 15%主要是因為快了——不再因為多餘的上下文導致回覆偏慢也不再因為丟失關鍵歷史而反覆道歉。6. 最後分享幾個實戰心得聊了這麼多最後說幾個我自己的體會。第一context-mode 的實現沒有銀彈。不同業務場景對上下文的敏感度完全不同客服機器人需要高度準確的訂單資訊創意寫作助手需要連貫的風格延續程式碼生成工具需要精確的變數名和依賴關係。你在落地時一定要自己統計 token 分佈、視覺化上下文的組成而不是照搬任何人的參數。第二先從日誌和可觀測性開始。不要著急寫完美的壓縮演算法先給每次請求的完整訊息清單打上詳細日誌——每一層上下文各佔多少 token、檢索命中哪些片段、摘要何時觸發、觸發後資訊有何增減。有了這些數據你才能知道調整哪裡最有效。我見過太多團隊憑感覺調參數最後把系統調得越來越怪。第三評估很重要但常被忽略。每次改動 context-mode 的策略都要準備一批測試樣本人工或在自動化測試中檢視輸出差異。我通常會準備 50 到 100 組“長對話場景”每一次改動後跑一遍全集對比底線版本的回覆準確率、資訊完整度和延遲。沒有這個評估流程你根本分不清哪次改動是優化還是回退。第四保持簡單。如果你的專案每天只有幾千次請求對話長度也不長那 context-mode 只需要一個最樸素的版本——保留最近 10 輪加一個簡單摘要就夠用了。不要一上來就上向量資料庫、混合檢索、二次壓縮這些都是系統規模逐漸變大後再逐步加入的。複雜度永遠是慢慢累積的先跑通再優化這是我在這個領域做過的最正確的決定。如果你正在為手裡的 AI 應用設計上下文策略希望這篇文章能幫你少走一些彎路。context-mode 不只是一段程式碼它是一整套關於“怎麼減少資訊、怎麼保留資訊、什麼時候調出資訊”的決策框架。把這套框架想明白遠比找一個神奇的三方庫重要。