📦 什麼是 Context Window?
💡 一句話理解 Context Window = AI 一次能「看到」多少內容。就像工作桌面大小——桌子越大,能同時攤開的資料越多。
2026 主流模型 Context Window
| 模型 | Context Window | 約等於 |
|---|---|---|
| GPT-4o | 128K tokens | ~10 萬字中文 |
| Claude Sonnet 4.6 | 200K tokens | ~15 萬字中文 |
| Gemini 3.1 Pro | 1M tokens | ~75 萬字中文 |
| DeepSeek V4 | 1M tokens | ~75 萬字中文 |
| GPT-4o-mini | 128K tokens | ~10 萬字中文 |
| Llama 3.1 405B | 128K tokens | ~10 萬字中文 |
⚠️ 能放不代表品質一樣好。研究顯示,當 context 超過 64K tokens,大部分模型在「中間位置」的資訊理解力會明顯下降(“Lost in the Middle” 問題)。
🤔 什麼時候 Context 不夠用?
| 場景 | 需要的 context | 問題 |
|---|---|---|
| 分析一本書 | 50-200K tokens | 大部分模型放得下,但品質不穩 |
| 分析一整個 codebase | 200K-2M tokens | 超過大部分模型上限 |
| 長對話(100+ 輪) | 50K+ tokens | Token 費用爆炸 |
| 知識庫問答 | 無限文件 | 不可能全塞進去 |
🔧 四大策略
策略 1:RAG(最常用)
不把所有資料塞進 context——只檢索最相關的段落。
全部文件(10 萬份)
↓ Embedding + 向量搜尋
最相關的 5 段(2000 tokens)
↓ 和問題一起送給 LLM
精準回答
適合: 知識庫問答、客服、文件搜尋
優點: context 用量極小、可擴展到無限文件量
缺點: 檢索品質決定回答品質
→ 詳見 RAG 完全指南
策略 2:Map-Reduce(處理超長文件)
把長文件切段,每段分別處理,最後合併結果。
def map_reduce_summarize(long_text, chunk_size=3000):
"""Map-Reduce 摘要:處理超長文件"""
# 1. Map:把長文切成小段,各自摘要
chunks = split_text(long_text, chunk_size)
summaries = []
for i, chunk in enumerate(chunks):
summary = client.chat.completions.create(
model="gpt-4o-mini", # 用便宜的模型做 Map
messages=[{
"role": "user",
"content": f"請摘要以下段落的重點(150 字內):\n\n{chunk}"
}],
max_tokens=200
).choices[0].message.content
summaries.append(summary)
print(f"Map {i+1}/{len(chunks)} 完成")
# 2. Reduce:合併所有摘要,生成最終摘要
combined = "\n\n".join(summaries)
final = client.chat.completions.create(
model="gpt-4o", # 用強模型做 Reduce
messages=[{
"role": "user",
"content": f"以下是一份文件各段落的摘要,請整合成一篇完整的摘要:\n\n{combined}"
}],
max_tokens=1000
).choices[0].message.content
return final
適合: 超長文件摘要、報告分析
優點: 理論上無文件長度限制
缺點: 各段獨立處理,可能遺漏跨段落的關聯
策略 3:Refine(迭代精練)
逐段讀取,每讀完一段就更新當前的理解。像人讀書一樣——邊讀邊記筆記。
def refine_analysis(chunks, question):
"""Refine:逐步精練回答"""
current_answer = "目前還沒有足夠資訊回答。"
for i, chunk in enumerate(chunks):
current_answer = client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": f"""根據以下新的資訊,更新你的回答。
## 問題
{question}
## 目前的回答
{current_answer}
## 新的資訊(第 {i+1} 段)
{chunk}
請整合新資訊,更新回答。如果新資訊和問題無關,保持現有回答不變。"""
}],
max_tokens=1000
).choices[0].message.content
print(f"Refine {i+1}/{len(chunks)} 完成")
return current_answer
適合: 需要跨段落理解的深度分析
優點: 保持上下文連貫性
缺點: 逐段處理速度慢、前面段落資訊可能被稀釋
策略 4:對話記憶管理
長對話(100+ 輪)的 token 會快速膨脹,需要策略管理。
Sliding Window(滑動窗口)
def sliding_window_chat(messages, max_context=20):
"""只保留最近 N 輪對話"""
system_msg = messages[0] # 永遠保留 system prompt
recent = messages[-max_context:] # 保留最近 20 輪
return [system_msg] + recent
Summary Memory(摘要記憶)
class SummaryMemory:
"""自動摘要壓縮歷史對話"""
def __init__(self, max_messages=10):
self.max_messages = max_messages
self.summary = ""
self.recent_messages = []
def add(self, role, content):
self.recent_messages.append({"role": role, "content": content})
# 對話超過上限時,壓縮舊對話為摘要
if len(self.recent_messages) > self.max_messages:
old = self.recent_messages[:5]
self.recent_messages = self.recent_messages[5:]
old_text = "\n".join(f"{m['role']}: {m['content']}" for m in old)
self.summary = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{
"role": "user",
"content": f"將以下對話摘要為 100 字:\n\n之前的摘要:{self.summary}\n\n新對話:\n{old_text}"
}],
max_tokens=150
).choices[0].message.content
def get_messages(self, system_prompt):
msgs = [{"role": "system", "content": system_prompt}]
if self.summary:
msgs.append({
"role": "system",
"content": f"先前對話摘要:{self.summary}"
})
msgs.extend(self.recent_messages)
return msgs
💰 Token 省錢技巧
| 技巧 | 節省 | 做法 |
|---|---|---|
| 精簡 System Prompt | 20-40% | 刪除冗餘指令,用條列取代長文 |
| 壓縮歷史對話 | 50-70% | 用 Summary Memory 取代完整歷史 |
| 只傳必要的 context | 30-50% | RAG 只傳 top-3 相關段落 |
| 用便宜模型做 Map | 60-80% | Map-Reduce 的 Map 階段用 mini 模型 |
| 設定 max_tokens | 10-30% | 避免模型產生過長的輸出 |
| Prompt Caching | 50-90% | OpenAI/Anthropic 的 Prompt Cache 功能 |
Prompt Caching(重大省錢術)
當你的 System Prompt 或 context 很長且不常變時,API 會自動快取,減少 Token 計費。
# OpenAI Prompt Caching(自動啟用)
# 當 system prompt 超過 1024 tokens 且重複使用時
# 快取命中的 token 只收 50% 費用
# Anthropic Prompt Caching(需明確啟用)
response = client.messages.create(
model="claude-sonnet-4-20260514",
max_tokens=1000,
system=[{
"type": "text",
"text": LONG_SYSTEM_PROMPT, # 你的長 system prompt
"cache_control": {"type": "ephemeral"} # 啟用快取
}],
messages=[{"role": "user", "content": user_input}]
)
# 快取命中的 token 只收 10% 費用!
🆚 Long Context vs RAG:怎麼選?
| 面向 | Long Context | RAG |
|---|---|---|
| 文件數量 | 少量大文件 | 大量文件 |
| 成本 | 💰💰💰 每次都送全文 | 💰 只送相關段落 |
| 精度 | 可能 Lost in the Middle | 取決於檢索品質 |
| 速度 | 長 context 推理較慢 | 快(context 短) |
| 適合 | 單一文件深度分析 | 知識庫搜尋、客服 |
💡 實用建議
- 文件 < 50 頁 → 直接塞進 context(Long Context)
- 文件 > 50 頁或多份文件 → 用 RAG
- 需要跨文件比較 → Map-Reduce
- 兩者結合:RAG 先縮小範圍 → Long Context 做深度分析
📐 為什麼 Context Window 是錢坑也是品質坑
Context window 管理的核心焦慮有兩個,剛好在對角線:
成本焦慮(線性成長): Token 計費是每次呼叫都重算。你的對話從 5K 長到 50K,不是多付 10 倍——因為 LLM 是 stateless 的,每輪對話都把完整歷史重送一次,累積成本是 O(n²)。
品質焦慮(非線性衰退): 模型對「中間位置」的資訊理解力會明顯下降。Anthropic 2025 年的 Needle-in-a-Haystack 測試顯示:
- 20K tokens 內:準確率 > 95%
- 50K tokens:91%
- 100K tokens:78%
- 150K tokens:62%(最差區段在 40-60% 位置)
- 200K tokens:51%
💡 實務含義 把 180K tokens 塞滿 Claude Sonnet 4.6,不會讓它變聰明,只會讓你多付錢買更糟的答案。
🧪 具體案例:100 輪客服對話的三策略對照
假設一個客服場景,用戶和 AI 已經對話 100 輪,累積約 40K tokens。下一句話進來時,怎麼處理?
策略 A:直接全送(Full History)
messages = [system_prompt] + full_history # 40K tokens
response = client.chat.completions.create(
model="gpt-4o", messages=messages + [new_msg]
)
成本: 輸入 40K tokens × $2.50/M = $0.10 / 次 品質: 中段資訊容易漏,第 50 輪提過的偏好可能被忽略 100 輪後總花費: 約 $5.00
策略 B:Sliding Window(只保留最近 20 輪)
recent = full_history[-20:] # 約 8K tokens
messages = [system_prompt] + recent + [new_msg]
成本: 輸入 8K tokens × $2.50/M = $0.02 / 次 品質: 早期重要資訊(用戶身份、偏好)全丟 100 輪後總花費: 約 $1.00 致命傷: 用戶第 80 輪問「你記得我第 3 輪說過的生日嗎」——AI 完全斷線
策略 C:Summary Memory + Sliding
# 每 20 輪觸發一次摘要壓縮
summary = "用戶:張先生,40 歲,買了 iPhone 15 Pro,
問過 3 次退貨流程,偏好 email 聯繫。"
recent = full_history[-10:] # 最近 10 輪原始對話
messages = [system_prompt, summary_msg] + recent + [new_msg]
成本: 輸入 5K tokens × $2.50/M = $0.0125 / 次
- 每 20 輪一次摘要壓縮 ≈ $0.03 品質: 關鍵事實保留,細節表達遺失(可接受) 100 輪後總花費: 約 $1.40
對照表
| 策略 | 單次成本 | 100 輪總成本 | 品質 | 適合 |
|---|---|---|---|---|
| 全送 | $0.10 | $5.00 | 中等(中段漏) | 短對話、高價值諮詢 |
| Sliding Window | $0.02 | $1.00 | 差 | Demo、非個人化場景 |
| Summary Memory | $0.013 | $1.40 | 好 | 生產環境客服首選 |
| RAG + Summary | $0.015 | $1.60 | 最好 | 多用戶、跨 session 記憶 |
🔄 Claude Code / Cursor 該什麼時候「重開 session」
用 AI coding 工具寫程式時,session 會越來越肥,症狀包含:
- 回覆速度明顯變慢(context 從 5K 長到 80K)
- 開始混淆檔案(把 A 檔的函數寫進 B 檔)
- 重複犯剛修好的錯
- 「記得」早就改過的舊需求
這是典型的 上下文污染(Context Pollution)——歷史對話累積的誤導資訊開始主導模型行為。和 Token 效率 有直接關聯。
重開 session 的三個時機點
- 任務切換時: 從「修 bug」切到「寫新 feature」,先
/clear或開新 session。 - Token 使用超過 60%: Claude Code 會顯示 context usage,過 60% 就該收尾,別硬撐到 90%。
- 你發現自己在「說服」AI: 如果要花三輪解釋「不,我要的是 X 不是 Y」,通常是 context 已污染,重開會比繼續吵更快。
重開前的存檔技巧
# 在 session 結尾讓 AI 產出 handoff 文件
請整理目前任務狀態,輸出為 Markdown:
- 已完成的部分(含檔案 + 行號)
- 待辦事項(排優先序)
- 重要設計決策和原因
- 已知的坑和踩過的雷
我會在新 session 開頭貼給你,幫我延續進度。
這份 handoff 通常 500-1500 tokens,比 30K 的完整歷史有效十倍。
🦠 上下文污染:症狀、成因、偵測
「上下文污染」指 context 中累積了誤導性資訊,讓模型持續偏離。三種典型來源:
污染源 1:錯誤的假設被保留
AI 第 5 輪時誤判「這個專案用 React」,後面 20 輪都基於這個錯誤繼續寫。即使你第 25 輪糾正,模型仍可能受前面影響。
污染源 2:過時的工具輸出
Agent 工具在第 10 輪讀了某個檔案,第 40 輪該檔案已被修改,但 context 裡的舊內容還在,模型基於舊版本建議。
污染源 3:惡意注入殘留
用戶輸入含 Prompt Injection 嘗試(見 Prompt Injection),即使當下被攔截,攻擊字串仍留在 history 裡,後續可能被重新觸發。
偵測方法
def detect_context_pollution(messages: list) -> dict:
"""簡易污染偵測"""
signals = {
"too_long": sum(len(m["content"]) for m in messages) > 100000,
"contradictions": 0,
"repeated_corrections": 0,
}
# 偵測「更正模式」:用戶說「不對」「不是這樣」的次數
correction_words = ["不對", "不是", "錯了", "我說的是", "no, i meant"]
for m in messages:
if m["role"] == "user":
if any(w in m["content"].lower() for w in correction_words):
signals["repeated_corrections"] += 1
signals["recommend_reset"] = (
signals["too_long"] or signals["repeated_corrections"] >= 3
)
return signals
當 recommend_reset=True 時,前端就提示用戶「建議開新對話」。
📊 2026 長上下文模型對照
| 模型 | Context | 有效品質區 | 輸入價格 | 特色 |
|---|---|---|---|---|
| Claude Sonnet 4.6 | 200K | ~150K 品質穩定 | $3/M | Needle 測試最穩 |
| GPT-5.4 | 1M | ~400K 後明顯衰退 | $5/M | 多模態最強 |
| Gemini 3.1 Pro | 1M | ~700K 仍可用 | $2.5/M | 真正能用完 1M 的少數 |
| DeepSeek V4 | 1M | ~500K | $0.5/M | CP 值王 |
| Claude Opus 4.5 | 500K | ~300K | $15/M | 高端推理 |
💡 選型原則 「能放 1M」不等於「1M 都好用」。實測自己的場景比看 benchmark 重要——同一個 legal document 分析任務,Gemini 3.1 Pro 在 800K 的表現可能比 GPT-5.4 在 400K 更好。
🚧 生產環境踩坑
實務上管理 context 的常見錯誤:
- Summary 用強模型 ——壓縮對話歷史用 gpt-4o-mini 就夠,用 gpt-4o 等於白燒錢。和 Token 效率 的省錢原則一致。
- Prompt Cache 沒用上 ——system prompt 超過 1024 tokens 且穩定時,Claude/OpenAI 的 cache 可以省 50-90% 費用。沒開等於多付錢。
- RAG 和 Long Context 二選一的思維 ——RAG 負責「找到相關內容」,Long Context 負責「深度理解找到的內容」,兩者可以串聯。
- 全憑直覺切 chunk 大小 ——chunk_size 會影響檢索品質和成本。實測用 500/1000/2000 三種切法,跑 50 題評估集比較 F1。
- 忘記 output tokens 也要錢 ——設
max_tokens不只是截斷,是省錢。模型想寫 3000 字但你只需要 500 字時,設max_tokens=600直接省 80% 輸出費用。 - 多人協作的 session 不隔離 ——Agent 幫 A 用戶查完資料,context 還在,B 用戶的請求進來時可能拿到 A 的資料。每個用戶一個獨立 session。
🎯 實戰建議:如何選策略
一句話決策樹:
對話會超過 20 輪嗎?
├─ 否 → 全送,不用想太多
└─ 是 → 需要記住早期細節嗎?
├─ 否 → Sliding Window(最便宜)
└─ 是 → 需要跨 session 記憶嗎?
├─ 否 → Summary Memory
└─ 是 → RAG + Summary(向量庫存對話)
要處理單一長文件時:
文件多長?
├─ < 50K tokens → 直接塞,搭配 Prompt Caching
├─ 50-200K → Long Context 模型(Claude Sonnet 4.6)
├─ 200K-1M → Gemini 3.1 Pro 或切 Map-Reduce
└─ > 1M → 強制上 RAG,沒有第二條路
❓ FAQ
Context Window 是越大越好嗎?
不一定。大 context window 有兩個問題:1) 成本高——128K tokens 的單次呼叫可能花幾塊美金 2) 品質不穩——“Lost in the Middle” 問題讓中間位置的資訊容易被忽略。針對性地用 RAG 檢索通常品質更好。實測在 50K+ tokens 的長文件 QA,RAG 的準確率常常比 full context 高 15-30%。
中文的 token 怎麼算?
中文大約每字 1-2 個 token。128K tokens ≈ 8-10 萬字中文。可以用 tiktoken 套件精確計算。注意不同模型的 tokenizer 不同,同一段文字的 token 數可能不一樣——Claude 的 tokenizer 處理中文通常比 GPT 省 10-20%。
對話太長怎麼辦?
三種方案:1) Sliding Window——只保留最近 N 輪 2) Summary Memory——壓縮舊對話為摘要 3) RAG——把歷史對話存入向量 DB,需要時檢索。推薦 Summary Memory,兼顧成本和連貫性。如果用 Claude Code 寫程式,單純 /clear 重開 session 常常是最快的方案。
什麼是 "Lost in the Middle"?
Stanford 2023 年提出的現象:當資訊放在長 context 的「中間位置」(約 30-70%),模型的召回率明顯低於「開頭」或「結尾」。2026 年的新模型(Claude Sonnet 4.6、Gemini 3.1 Pro)已大幅改善,但在 100K+ tokens 時仍可觀察到。實用做法: 把最關鍵的指令放 system prompt 開頭,關鍵資訊放 user message 結尾。
Prompt Caching 怎麼用?要注意什麼?
Anthropic 需明確標記 cache_control,OpenAI 自動啟用(超過 1024 tokens 的 system prompt)。關鍵:cache 需要「prefix 完全相同」才命中——system prompt 的任何變動(連一個空白)都會 cache miss。實務上把 system prompt 寫成固定模板,動態內容放 user message。詳見 Token 效率。
多模態(圖片/PDF)怎麼算 token?
圖片:OpenAI 約 85 tokens(低解析度)到 1105 tokens(高解析度)每張。Claude 依圖片尺寸線性計算,1000×1000 約 1300 tokens。PDF:先被拆成圖片 + OCR 文字雙重計算,10 頁 PDF 可能花掉 5-15K tokens。所以別隨便塞 50 頁 PDF 進 context。
Agent 的長期記憶怎麼做?
三層架構最常見:1) Working Memory——當前 session 的 context(滑動窗口)2) Episodic Memory——過往對話摘要,存向量庫 3) Semantic Memory——從對話中抽取的事實/偏好,存結構化 DB(例如用戶喜好、重要日期)。詳見 AI Agent 實作教學。
1M context 的 Gemini / DeepSeek 能完全取代 RAG 嗎?
不能取代,但改變了分工。過去 50K tokens 就要上 RAG,現在 500K 內都能直接塞。RAG 仍然必要的場景:1) 文件總量 > 1M tokens 2) 需要跨 session 的長期知識 3) 多用戶共享知識庫 4) 頻繁更新的資料(RAG 可以只更新索引)。成本考量上,1M context 的單次呼叫可能 $2-5 美金,RAG 只要 $0.01,流量大時差距懸殊。