> ## Documentation Index
> Fetch the complete documentation index at: https://felimet-hub.jmcores.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 01-4 上下文工程（Context Engineering）

> 在模型有限的注意力預算內，管理進入上下文視窗的一切，包括指令、知識、歷史與工具結果，決定 agentic 工具產出品質的關鍵。

export const ContextWindow = ({lang = "zh", title, slots = [], footer}) => {
  const L = lang === "en" ? {
    top: "top",
    bottom: "bottom",
    empty: "No slots"
  } : {
    top: "開頭",
    bottom: "結尾",
    empty: "（無內容）"
  };
  const PALETTE = {
    sienna: {
      base: "#bf7551",
      bg: "#bf755118",
      border: "#bf755155"
    },
    indigo: {
      base: "#5b6c8f",
      bg: "#5b6c8f18",
      border: "#5b6c8f55"
    },
    sage: {
      base: "#8a9a7b",
      bg: "#8a9a7b18",
      border: "#8a9a7b55"
    },
    ochre: {
      base: "#c9a35b",
      bg: "#c9a35b18",
      border: "#c9a35b55"
    },
    plum: {
      base: "#8a6f8e",
      bg: "#8a6f8e18",
      border: "#8a6f8e55"
    }
  };
  const ROTATION = ["indigo", "plum", "ochre", "sage"];
  const safe = Array.isArray(slots) ? slots : [];
  const colorFor = (slot, i) => {
    if (slot.color && PALETTE[slot.color]) return PALETTE[slot.color];
    if (slot.pos === "top" || slot.pos === "bottom") return PALETTE.sienna;
    return PALETTE[ROTATION[i % ROTATION.length]];
  };
  const css = `
  .cw-root {
    --cw-bg: #FAF8F3; --cw-surface: #fff; --cw-border: rgba(0,0,0,0.10);
    --cw-text: #2b2722; --cw-dim: #6f6a62; --cw-faint: #9a9490;
    border: 1px solid var(--cw-border); border-radius: 14px;
    background: var(--cw-bg); padding: 16px; font-size: 14px; color: var(--cw-text);
  }
  .dark .cw-root {
    --cw-bg: #1b1a18; --cw-surface: rgba(255,255,255,0.035); --cw-border: rgba(255,255,255,0.10);
    --cw-text: #e7e3da; --cw-dim: #a8a299; --cw-faint: #807a72;
  }
  .cw-title {
    font-size: 11.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--cw-faint); margin-bottom: 11px;
  }
  .cw-stack { display: flex; flex-direction: column; gap: 7px; }
  .cw-slot {
    display: flex; align-items: center; gap: 12px;
    background: var(--cw-surface); border: 1px solid var(--cw-border);
    border-left: 3px solid var(--slot-c); border-radius: 5px 9px 9px 5px;
    padding: 10px 13px; transition: transform 0.12s, box-shadow 0.12s;
  }
  .cw-slot:hover { transform: translateX(2px); box-shadow: -2px 2px 0 0 var(--slot-bg); }
  .cw-slot-body { flex: 1 1 0; min-width: 0; }
  .cw-slot-label { font-size: 13.5px; font-weight: 600; color: var(--cw-text); line-height: 1.4; }
  .cw-slot-sub { font-size: 12px; color: var(--cw-dim); margin-top: 2px; line-height: 1.45; }
  .cw-pos {
    flex-shrink: 0; font-size: 10px; font-weight: 700; letter-spacing: 0.05em;
    padding: 2px 8px; border-radius: 20px; color: var(--slot-c);
    background: var(--slot-bg); border: 1px solid var(--slot-bdr); white-space: nowrap;
  }
  .cw-footer {
    margin-top: 12px; padding-top: 11px; border-top: 1px dashed var(--cw-border);
    font-size: 12.5px; color: var(--cw-dim); display: flex; align-items: center; gap: 8px;
  }
  .cw-footer-dot { width: 7px; height: 7px; border-radius: 2px; transform: rotate(45deg); background: #8a9a7b; flex-shrink: 0; }
  `;
  return <div className="cw-root">
      <style>{css}</style>
      {title && <div className="cw-title">{title}</div>}
      <div className="cw-stack">
        {safe.length === 0 && <div className="cw-slot-sub">{L.empty}</div>}
        {safe.map((slot, i) => {
    const c = colorFor(slot, i);
    const style = {
      "--slot-c": c.base,
      "--slot-bg": c.bg,
      "--slot-bdr": c.border
    };
    const posLabel = slot.pos === "top" ? L.top : slot.pos === "bottom" ? L.bottom : null;
    return <div className="cw-slot" style={style} key={slot.label + i}>
              <div className="cw-slot-body">
                <div className="cw-slot-label">{slot.label}</div>
                {slot.sub && <div className="cw-slot-sub">{slot.sub}</div>}
              </div>
              {posLabel && <span className="cw-pos">{posLabel}</span>}
            </div>;
  })}
      </div>
      {footer && <div className="cw-footer">
          <span className="cw-footer-dot" />
          <span>{footer}</span>
        </div>}
    </div>;
};

export const LearnerPrimer = ({items = [], lang = "zh"}) => {
  const t = lang === "en" ? {
    title: "Before this unit, be honest with yourself",
    sub: "If you can't answer these, that gap is exactly what this unit closes."
  } : {
    title: "讀這個單元前，先誠實面對",
    sub: "這幾題答不出來，正是這個單元要替你補的洞。"
  };
  const css = `
  .lp-root{--lp-bg:#FAF7F1;--lp-surface:rgba(191,117,81,0.05);--lp-border:rgba(0,0,0,0.09);--lp-edge:rgba(191,117,81,0.42);--lp-text:#2b2722;--lp-dim:#6f6a62;--lp-accent:#bf7551;border:1px solid var(--lp-border);border-left:3px solid var(--lp-edge);border-radius:13px;background:var(--lp-bg);color:var(--lp-text);overflow:hidden;margin:1.25rem 0;}
  .dark .lp-root{--lp-bg:#1b1a18;--lp-surface:rgba(207,138,104,0.07);--lp-border:rgba(255,255,255,0.08);--lp-edge:rgba(207,138,104,0.5);--lp-text:#e7e3da;--lp-dim:#a8a299;--lp-accent:#cf8a68;}
  .lp-head{display:flex;align-items:center;gap:9px;padding:13px 18px 11px;border-bottom:1px solid var(--lp-border);background:var(--lp-surface);}
  .lp-ic{color:var(--lp-accent);flex-shrink:0;}
  .lp-htx{display:flex;flex-direction:column;gap:1px;min-width:0;}
  .lp-title{font-size:14px;font-weight:650;line-height:1.3;letter-spacing:.01em;}
  .lp-sub{font-size:12px;color:var(--lp-dim);line-height:1.4;}
  .lp-list{list-style:none;margin:0;padding:10px 18px 14px;display:flex;flex-direction:column;gap:0;}
  .lp-item{display:flex;align-items:baseline;gap:11px;padding:7px 0;font-size:14px;line-height:1.6;border-top:1px solid var(--lp-border);}
  .lp-item:first-child{border-top:none;}
  .lp-mark{flex-shrink:0;color:var(--lp-accent);font-size:13px;font-weight:700;line-height:1.55;font-variant-numeric:tabular-nums;opacity:.85;}
  .lp-q{flex:1 1 0;min-width:0;color:var(--lp-text);}
  @media (max-width:620px){.lp-head{padding:12px 14px 10px;}.lp-list{padding:8px 14px 12px;}}
  `;
  return <div className="lp-root">
      <style>{css}</style>
      <div className="lp-head">
        <svg className="lp-ic" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10" /><circle cx="12" cy="12" r="6" /><circle cx="12" cy="12" r="2" /></svg>
        <span className="lp-htx">
          <span className="lp-title">{t.title}</span>
          <span className="lp-sub">{t.sub}</span>
        </span>
      </div>
      <ul className="lp-list">
        {items.map((q, i) => <li className="lp-item" key={i}>
            <span className="lp-mark">{String(i + 1).padStart(2, "0")}</span>
            <span className="lp-q">{q}</span>
          </li>)}
      </ul>
    </div>;
};

<LearnerPrimer
  lang="zh"
  items={[
"你以為塞越多越保險，模型越塞越退化。",
"200K 視窗不是有效容量，是物理容量。",
"規則寫進 CLAUDE.md，口頭交代會被壓縮蒸發。",
"你把整個 repo 拖進對話，那叫稀釋指令。",
"開了長期記憶就不用管上下文，這想法很危險。",
"凡事都上 RAG，你只是在自動化檢索不準。",
"探索性子任務丟主視窗，注意力先被雜訊吃掉。"
]}
/>

<Info>
  **這個單元解決什麼問題**

  prompt engineering 教你「這一句怎麼問」，context engineering 教你「模型在回答前，它的工作記憶裡應該有什麼、不該有什麼」，包括系統記憶體、外部資料注入、即時 RAG 檢索、工具調用狀態等等，統一用 context window 的視角來設計。在 agentic 工具上，模型會自己跑很多輪、自己累積讀檔與搜尋的結果，這時決定產出品質的，不是你某一句話的措辭，而是你對「進入視窗的一切」的管理。
</Info>

## 學習目標

* [ ] 能說出進入上下文視窗的四個來源，並判斷每個來源的相關性與成本。
* [ ] 能解釋上下文腐化（context rot）與「lost in the middle」現象，並說出對「該塞多少」的實務影響。
* [ ] 能說明壓縮、即時載入、子代理隔離如何在有限的上下文預算下管理資訊。
* [ ] 能把「短期上下文」與「跨 session 長期記憶」分清楚，並對應到各工具的機制與風險。

***

## 1. 從 prompt engineering 到 context engineering

prompt engineering 的隱含假設是「一問一答」：你把問題雕琢到位，模型回一個答案，互動就結束了。這個假設在對話框時代成立，在 agentic 工具上失效。

Coding Agent 接到一個任務後，會自己讀檔、自己搜尋、自己執行、再根據結果決定下一步，一個任務可能跑幾十輪。每一輪的輸出都會堆回上下文視窗，下一輪的推理就建立在這堆東西之上。這時你能控制的槓桿，從「我這句話怎麼寫」變成「視窗裡此刻有什麼、它們的訊號雜訊比是多少」。

Anthropic 把 context engineering 定義為：在模型有限的「注意力預算（attention budget）」內，找出能最大化目標達成率的、最小的一組高訊號 token \[1]。關鍵字是**最小**與**高訊號**。不是塞越多越好，是「剛好夠、而且都相關」。這跟工程直覺相反，多數人的第一反應是「把所有可能相關的都丟進去讓模型自己挑」，這正是品質崩壞的起點，原因見第 3 節。

## 2. 上下文的四個來源

進入視窗的東西，不管哪個工具，都可以歸到四類。每一類都有它的成本（佔多少 token、稀釋多少注意力）與相關性（對當前任務有多少幫助），你要對每一類都能做這個權衡。

```mermaid theme={null}
graph LR
  I["指令<br/>系統提示、規則檔"] --> W["上下文視窗<br/>(有限注意力預算)"]
  K["知識<br/>附加檔案、RAG、@ 引用"] --> W
  H["歷史<br/>對話、跨 session 記憶"] --> W
  T["工具結果<br/>讀檔、搜尋、執行輸出"] --> W
  W --> O["這一輪的推理與產出"]
```

* **指令**：系統提示、規則檔（`CLAUDE.md` / `AGENTS.md` / `.claude/rules/`）。這類訊號密度最高、最該留，因為它定義了模型的角色與約束，且整個 session 都在用。
* **知識**：附加的檔案、RAG 檢索回來的片段、`@` 引用的內容。相關性差異最大的一類，引對了是關鍵證據，引錯了是純雜訊。
* **歷史**：當前對話的前文，加上跨 session 的長期記憶。會隨互動單調膨脹，是最需要主動壓縮的一類。
* **工具結果**：讀檔、grep、執行指令的回傳。常常體積巨大（一個 `ls -R` 或一份完整測試 log 動輒上千 token）卻只有一兩行真正有用。

<Tip>
  **把四個來源當成有預算的採購，不是吃到飽**

  注意力預算是零和的。你多塞一份「可能有用」的檔案，等於從「確定有用」的指令與證據那裡，挪走了模型的注意力。每一個你放進去的東西，都該能回答「它為什麼非在這裡不可」。
</Tip>

## 3. 上下文腐化與 lost in the middle

「視窗有 200K token，所以我可以塞 200K」是錯的。視窗大小是物理容量，不是有效容量；模型用得好的部分，遠小於它能裝的部分。兩個有實證的現象支撐這個判斷。

**Lost in the middle**：Liu, et al.（2023）的研究發現，模型在長上下文裡的表現，與關鍵資訊的**位置**強相關，放在開頭或結尾時準確率最高，放在中段時顯著掉落，長到一定程度，中段資訊幾乎像沒給一樣 \[2]。

**Context rot**：Chroma（2025）的技術報告測了 18 個模型（含 GPT-4.1、Claude 4、Gemini 2.5、Qwen3），發現模型對上下文的使用並非均勻，輸入越長、表現越不可靠；尤其當任務需要的是「語意比對」而非「字面比對」時，長輸入下的退化特別明顯 \[3]。

兩個發現的共同含意很直接：**更多上下文不等於更好，常常更糟**。一份精準的 5K token 上下文，會打敗一份摻了大量「可能相關」雜訊的 100K token 上下文。對你的實務操作有兩個推論：

1. **控制總量**：寧可少而準。把「全塞進去讓模型自己挑」的衝動戒掉。
2. **控制位置**：最關鍵的指令與證據，放在上下文的開頭或結尾，不要埋在中段一大坨檔案內容裡。規則檔之所以有效，部分原因就是它通常被放在最前面。

## 4. 壓縮與即時載入：在預算內延續工作

長任務一定會撞到視窗上限。處理方式有兩條主線。

**壓縮（compaction）**：把接近上限的對話摘要成一段結構化的總結，再用這段總結開一個新視窗繼續，是維持長程連貫性的主要手段 \[1]。在 Claude Code 裡，這件事一部分自動發生（接近上限時先清掉舊的工具輸出，再摘要對話），一部分你可以主動用 `/compact` 觸發，還能帶焦點（如 `/compact focus on the API changes`）指定要保留什麼 \[4]。

這裡有一個你必須知道的機制細節：**早期對話在自動壓縮時可能被丟掉，但專案根目錄的 `CLAUDE.md` 不會**，壓縮後 Claude 會從磁碟重讀並重新注入。子目錄的 `CLAUDE.md` 不會自動重注入，要等 Claude 下次讀到那個子目錄裡的檔案才重新載入；壓縮摘要也只保留你實際用過的 skill，沒用到的 skill 描述不會被帶回新視窗（截至 2026-06）\[4]。這就是為什麼「持久的規則寫進 `CLAUDE.md`，而不是在對話裡口頭交代」是硬建議，口頭交代的約束會在某次壓縮後悄悄蒸發 \[4]。

<Tip>
  **用官方互動式視覺化看視窗裝了什麼**

  Anthropic 有一頁互動式的上下文視窗模擬，逐項標出 session 起手自動載入的東西（系統提示、自動記憶 `MEMORY.md`、環境資訊、MCP 工具、skill 描述、`~/.claude/CLAUDE.md`、專案 `CLAUDE.md`）與各自的 token 估計，並示範 `/compact` 後哪些留、哪些走：[探索上下文視窗（官方）](https://code.claude.com/docs/zh-TW/context-window)（截至 2026-06）。把它當成你的「視窗預算」對照表。
</Tip>

**即時載入（just-in-time）**：不要一開始就把所有可能用到的資料全載進來，而是讓代理持有輕量的指標（檔案路徑、查詢、連結），需要時才用工具把對應資料拉進視窗 \[1]。對 Coding Agent，這意味著給它檔案路徑與搜尋能力，比把整個 repo 貼進去更好；對研究工作流，這意味著給它資料集的位置與讀取工具，而不是把整份資料倒進對話。

<Tip>
  **重要任務預留緩衝**

  一個經驗法則（非官方數字，見 [01-2](/code-agent/foundations/llm-agent-basics)）：跨多檔的重要任務，盡量在視窗用到約八成前就收斂或主動壓縮，留約兩成緩衝。視窗越接近滿載，前面 lost in the middle 與 context rot 的效應越強，模型越容易在你最不希望出錯的收尾階段掉鏈子。
</Tip>

## 5. 記憶：短期 vs 長期

「記憶」這個詞被各家用得很混，但底層只有兩種，分清楚才不會誤用。

**短期上下文**：單一 session 視窗裡的對話。session 一關就沒了，本質是工作記憶。前面四節談的都是這層。

**長期記憶**：跨 session 持久化的資訊，下次開新對話它還在。三家主力工具的機制與名稱不同（截至 2026-05）：

* **Anthropic Claude**：Claude.ai 有跨對話的記憶功能；Claude Code 則用磁碟上的檔案做持久層，專案級 `CLAUDE.md`、使用者級 `~/.claude/`，外加 `~/.claude/projects/<repo>/memory/` 的自動記憶（v2.1.59+ 預設開啟，可用 `autoMemoryEnabled` 或環境變數停用）\[4]。它的長期記憶是**檔案、可讀可審、可進版控**，這對可重現性是優點。
* **OpenAI ChatGPT**：分「Saved Memories」（明確要它記的事實偏好）與「Reference chat history」（自動參考過去對話）。設定在 Settings > Personalization；關掉「Reference saved memories」會連帶關掉「Reference chat history」\[5]。
* **Google Gemini**：在「Personal context」下的「Memory」設定，預設開啟，會從過去對話學習；另有把其他應用的記憶匯入 Gemini 的功能 \[6]。

<Warning>
  **開了長期記憶，不等於可以不管上下文**

  兩個常被忽略的代價。其一，長期記憶是**安全面**：跨 session 持久化的記憶，是記憶污染（memory poisoning）與提示注入的載體，惡意內容可以分多次植入、日後組裝觸發，細節與防護見 [03-3](/code-agent/judgment/security-privacy-supply-chain)。其二，自動記憶會把你沒打算帶進來的舊偏好悄悄注入當前任務，反而是一種你沒控制的上下文污染。處理一次性敏感任務時，用暫時對話、或關掉記憶，是預設動作。
</Warning>

## 6. 檢索與引用：把外部知識接進視窗

當任務需要的知識不在模型訓練資料裡（你的論文、你的程式庫、最新文件），你得把它接進上下文。手段有兩類。

**主動引用**：你明確指定要載入什麼。`@` 引用某個檔案、`#` 索引某個 repo、把檔案丟進 Projects（Claude / ChatGPT）/ Gems（Gemini）的知識庫。適合你已經知道哪幾份資料相關的情況，精準、可控。

**RAG（檢索增強生成）**：當資料量大到不可能全塞、你也不確定哪段相關時，先把資料切塊、向量化存進資料庫，查詢時只檢索回最相關的幾塊再放進視窗。它本質上是「即時載入」的自動化版本。你不需要為每個任務都上 RAG，先問：相關資料是否大到無法用 `@` 直接引用？不是的話，直接引用更簡單也更準。

對研究者，這層的實務對應是：把要精讀的兩三篇論文用 `@` 直接引用（精準），把要泛查的整個文獻庫接成知識庫或 RAG（規模）。兩者不要對調：泛查的東西全塞進視窗會觸發第 3 節的退化，精讀的東西丟進 RAG 又可能檢索不回關鍵段落。

### 向量檢索不是唯一解：以 PageIndex 為例

RAG 幾乎成了「外接知識」的同義詞，但向量檢索有結構性弱點，尤其在金融、法律這類高精度場景：語意相似不等於內容相關（查「營運利潤率」可能撈回一堆提到這詞的零散段落，卻漏掉真正含答案的那張表）、切塊破壞了原文的結構與語境、檢索結果不可追溯（你問不出「為什麼選這段」）。

PageIndex（MIT 授權的開源專案 \[8]）走另一條路：**vectorless、以推理取代相似度**。它不做嵌入、不切塊，而是先把文件解析成一棵語意樹（每個節點帶標題、頁碼範圍與 LLM 生成的摘要），查詢時讓 LLM 像人類專家一樣讀目錄、定位章節、逐層往下推理，作法受 AlphaGo 的樹搜尋啟發 \[8]。據其官方 repo，以此為底的系統在 FinanceBench 上達 98.7% 準確率（官方自報為 SOTA、明顯優於傳統向量 RAG；截至 2026-05）\[8]。

兩條路的取捨：

| 維度      | PageIndex（樹狀推理）    | 傳統向量 RAG     |
| ------- | ------------------ | ------------ |
| 檢索機制    | LLM 逐層讀樹推理         | 嵌入 + 餘弦相似度   |
| 預處理     | 解析結構、生成節點摘要        | 切塊、向量化       |
| 可解釋性    | 高（檢索路徑即文件結構）       | 低（只有數值距離）    |
| 推論成本與延遲 | 較高（多次 LLM 推理遍歷節點）  | 較低（向量距離計算極快） |
| 最適場景    | 單一深度文件（財報、合約）的精準問答 | 大規模跨文件的模糊檢索  |

判準延續本節主線：**先問規模與精度需求，再選手段**。對一份結構清晰的長文件做高精度、可追溯的問答，樹狀推理檢索值得一試；在海量跨文件裡做模糊搜尋，向量檢索的速度與成本仍佔優，兩者也可混用。PageIndex 走 MCP，支援 MCP 的客戶端（如 Claude、Cursor）可直接接入（截至 2026-05）。

## 7. 子代理與上下文隔離

一個反直覺但極有效的技巧：把子任務丟給一個**乾淨上下文**的子代理（subagent）去做，主代理只接收它的結論。

為什麼有用？假設主任務需要「先理清這個模組怎麼運作」。如果讓主代理自己去探索，它讀的二十個檔案、跑的十次 grep、走過的三條死路，全都會堆進主視窗，把後續真正要做的事擠到中段（觸發 lost in the middle），還燒掉大量 token。改成派一個子代理去探索，子代理在自己的獨立視窗裡翻完所有檔案，只回主代理一段「這個模組的運作摘要」。主代理的視窗裡，從頭到尾只有任務本身與這段乾淨摘要。

這就是隔離的雙重好處：**省 token**（探索過程不佔主視窗）與**提品質**（主代理不被探索雜訊干擾）。對應到工具，Claude 的 Subagent 機制就是為此設計，每個子代理有自己的上下文、自己的工具集、回傳結論而非過程 \[7]，深入用法見 [02-5](/code-agent/configuration/skills-hooks-subagents-plugins)。

## 8. 實務原則：最少必要上下文

把前七節收斂成可操作的判準。每次要往視窗裡放東西前，跑一遍：

* **最少必要**：預設不放，除非它能回答「為什麼非在這裡不可」。能用指標即時載入的，就不要預先全塞。
* **高訊號優先**：指令與直接證據留，「可能相關」的整包檔案砍。訊號雜訊比比絕對數量重要。
* **管好位置**：最關鍵的放開頭或結尾，不要埋中段。
* **主動壓縮**：長任務不要等視窗爆掉才被動壓縮，在收斂點主動 `/compact` 並指定焦點。
* **持久的進檔案**：要跨壓縮、跨 session 活下來的約束，寫進 `CLAUDE.md`，不要靠對話口述。
* **隔離雜訊**：探索性、發散性的子任務，丟給子代理，主視窗只收結論。

**同一個研究任務，兩種上下文管理**

任務：「根據這個 repo 的現有架構，幫我實作一個新的資料載入模組，風格要跟現有的一致，並參考這十篇論文裡的最佳實踐。」

**Before（全塞，憑感覺）**：把整個 repo（80 檔）拖進對話，把十篇 PDF 全貼上，然後說那句話。視窗瞬間用掉 150K token，真正的指令那句話埋在最前面、早被一堆檔案內容推到「中段」。模型開始實作，風格卻跟某個不相關的舊模組對齊，只因為那個檔案剛好排在它還「看得到」的位置；論文裡的關鍵做法埋在中段，完全沒被引用到（context rot）。

**After（最少必要 + 隔離）**：

1. 先寫四行 `CLAUDE.md`：專案的命名慣例、錯誤處理規約、「新模組對齊 `src/loaders/` 下的現有實作」。
2. 只用 `@src/loaders/base_loader.py` 精準引用那一個要對齊的範本檔。
3. 派一個子代理讀那十篇論文，回一段「資料載入相關的三個最佳實踐 + 出處」。
4. 主代理視窗裡此刻只有：四行規則（開頭）、一個範本檔、一段論文摘要、那句任務。約 8K token，全部高訊號。

<ContextWindow
  lang="zh"
  title="視窗內容（After）"
  slots={[
{ label: "CLAUDE.md 四行規則", sub: "命名慣例、錯誤處理規約、對齊指示", pos: "top" },
{ label: "base_loader.py 範本", sub: "精準 @ 引用的單一對齊檔" },
{ label: "子代理摘要：三個最佳實踐", sub: "十篇論文壓縮成結論 + 出處" },
{ label: "任務指令", sub: "真正要做的那句話", pos: "bottom" },
]}
  footer="總計 ≈ 8K token，全高訊號"
/>

結果差異不是「prompt 更聰明」，是 After 把模型的注意力，從「在 150K 雜訊裡撈訊號」變成「在 8K 全訊號裡執行」。多花的成本是前期三十秒的整理，省下的是一份對齊錯誤、得整個重做的產出。

## 工具對照

各家把同一組 context engineering 概念包裝成不同名稱（截至 2026-05，精確設定位置與查證見 [02-2](/code-agent/configuration/anthropic-claude-setup)、[02-6](/code-agent/configuration/other-tools-comparison)）。

| 機制    | Anthropic Claude（主範本）                               | OpenAI                                  | Google                    | GitHub Copilot        | Cursor                            |
| ----- | --------------------------------------------------- | --------------------------------------- | ------------------------- | --------------------- | --------------------------------- |
| 長期記憶  | Claude.ai 記憶 / Claude Code `CLAUDE.md`、`~/.claude/` | Saved Memories + Reference chat history | Personal context → Memory | instructions 檔（非自動記憶） | User Rules / Memories             |
| 知識附加  | Projects 知識庫 / `@` 檔案引用                             | Projects / Custom GPT Knowledge         | Gems Knowledge / Drive 連接 | `#` 檔案、repo 索引        | `@` 檔案 / `@Docs` / codebase index |
| 主動壓縮  | 自動 compaction + `/compact`（可帶 focus）                | 自動對話摘要                                  | 自動摘要                      | 自動                    | 自動                                |
| 子代理隔離 | Subagent（獨立上下文、回傳結論）                                | 多代理 / Agents                            | Antigravity agents        | （無使用者層對等機制）           | Background agents                 |

<Note>
  **對照表只給座標，不給細節**

  這張表的用途是讓你知道「同一個概念在你的工具叫什麼」。各 cell 的精確設定路徑、開關位置、版本差異屬快變動事實，統一在 [02-2](/code-agent/configuration/anthropic-claude-setup) 與 [02-6](/code-agent/configuration/other-tools-comparison) 查證並標註截至日期，本表不重複，以免出現多處不一致的版本。Copilot 與 Cursor 兩欄的部分機制名稱以較穩定的描述呈現，精確名稱以該工具官方文件為準。
</Note>

## 常見誤區

<Warning>
  **反模式清單**

  * **把視窗容量當有效容量**：「有 200K 所以塞 200K」。有效容量遠小於物理容量，越滿越退化（第 3 節）。
  * **全塞讓模型自己挑**：你以為是給模型更多資訊，實際是降低訊號雜訊比、把關鍵指令推進中段。少而準勝過多而雜。
  * **以為開了長期記憶就不用管上下文**：自動記憶會注入你沒打算帶進來的舊偏好，是一種你沒控制的污染；且是記憶污染與提示注入的安全載體（[03-3](/code-agent/judgment/security-privacy-supply-chain)）。
  * **靠對話口述持久約束**：自動壓縮會丟掉早期對話。要活下來的約束寫進 `CLAUDE.md`，它壓縮後會被重讀注入。
  * **凡事都上 RAG**：相關資料小到能用 `@` 直接引用時，RAG 只是增加檢索不準的風險。先問規模，再決定手段。
  * **讓主代理自己做發散探索**：探索雜訊會塞爆主視窗又干擾推理。發散子任務丟給子代理，主視窗只收結論。
</Warning>

## 自我檢核

<Check>
  **通過本單元的標準**

  1. 給你一個跨多檔的複雜任務，你能說出「哪些該進上下文、哪些該留在外面用指標即時載入」，並講出理由嗎？
  2. 你能解釋為什麼「把關鍵約束寫進 `CLAUDE.md`」比「在對話裡交代一次」更可靠？答案跟壓縮機制有關。
  3. 你能指出你主力工具的長期記憶開關在哪、以及為什麼處理敏感任務時該關掉它嗎？
  4. 下次任務視窗開始膨脹時，你的第一個動作是繼續塞、還是主動壓縮或派子代理？為什麼？
</Check>

## 來源與延伸閱讀

事實主張依官方文件與原始研究，快變動項標註截至 2026-05。

<div className="references">
  * \[1] Anthropic, "Effective context engineering for AI agents," Anthropic Engineering, 2025.（注意力預算、即時載入、壓縮）[https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents](https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents) （截至 2026-05）
  * \[2] N. F. Liu, K. Lin, J. Hewitt, A. Paranjape, M. Bevilacqua, F. Petroni, P. Liang, "Lost in the Middle: How Language Models Use Long Contexts," *Transactions of the ACL*, 2024（arXiv:2307.03172, 2023）。[https://arxiv.org/abs/2307.03172](https://arxiv.org/abs/2307.03172)
  * \[3] Chroma, "Context Rot: How Increasing Input Tokens Impacts LLM Performance," Chroma Technical Report, 2025. [https://www.trychroma.com/research/context-rot](https://www.trychroma.com/research/context-rot) （截至 2026-05）
  * \[4] Anthropic, "How Claude remembers your project"（memory 與 `/compact`、壓縮後重讀 `CLAUDE.md`）與 "探索上下文視窗"（視窗載入順序與壓縮存活規則），Claude Code Docs. [https://code.claude.com/docs/en/memory](https://code.claude.com/docs/en/memory) 、 [https://code.claude.com/docs/zh-TW/context-window](https://code.claude.com/docs/zh-TW/context-window) （截至 2026-06）
  * \[5] OpenAI, "What is Memory?" / "Memory FAQ"（Saved Memories、Reference chat history），OpenAI Help Center. [https://help.openai.com/en/articles/8983136-what-is-memory](https://help.openai.com/en/articles/8983136-what-is-memory) （截至 2026-05）
  * \[6] Google, "Get personalization in Gemini Apps"（Personal context → Memory），Gemini Apps Help. [https://support.google.com/gemini/answer/16598623](https://support.google.com/gemini/answer/16598623) （截至 2026-05）
  * \[7] Anthropic, "Create custom subagents"（子代理獨立上下文、工具集、回傳結論），Claude Code Docs. [https://code.claude.com/docs/en/sub-agents](https://code.claude.com/docs/en/sub-agents) （截至 2026-05）
  * \[8] VectifyAI, "PageIndex: vectorless, reasoning-based RAG"（樹狀推理檢索、AlphaGo 啟發、FinanceBench 98.7% 官方自報、MIT 授權、MCP 支援），GitHub, 2025. [https://github.com/VectifyAI/PageIndex](https://github.com/VectifyAI/PageIndex) （截至 2026-05）
</div>

* 銜接：[01-1](/code-agent/foundations/why-correct-usage) 心智模型、[01-2](/code-agent/foundations/llm-agent-basics) token 與視窗的技術基礎、[02-2](/code-agent/configuration/anthropic-claude-setup) Claude 設定、[02-5](/code-agent/configuration/skills-hooks-subagents-plugins) Subagent、[03-3](/code-agent/judgment/security-privacy-supply-chain) 記憶污染與供應鏈風險。
