跳至主要內容
技術

Context Engineering 深度解析:Prompt 寫得好,為什麼 Agent 還是做錯?

Context Engineering 深度解析:Prompt 寫得好,為什麼 Agent 還是做錯?
Updated: 2026-07-15
Agentic Engineering 實戰手冊 第 4 / 14 篇 ,前往系列總覽

這是「Agentic Engineering 實戰手冊」系列第四篇。上一篇:2026 年 AI Coding 工具怎麼選?

Prompt 很清楚,Agent 為什麼還是選錯?

假設你請 agent 替 Astro 部落格加一個「相關文章」區塊。需求寫得很完整:依 tags 排序、顯示三篇、排除自己、手機版要能閱讀。

結果它做出一個 React component,從不存在的 /api/posts 呼叫資料,再用專案沒裝的 CSS-in-JS library 排版。

任務描述沒有錯。Agent 也不是完全沒理解功能;它只是不知道三件事:

  1. 這是 static Astro site,不是有 API server 的 React app
  2. 文章來自 Astro Content Collections
  3. 專案已經有 PostCard.astro 和 Tailwind 樣式

這三件事不一定要全部塞在 prompt 裡,但 agent 在決策前必須有辦法取得。這就是 Context Engineering 要處理的問題:在每一步,把會影響下一個決策的正確資訊,放進模型可用的工作狀態。

Context Engineering 不等於「Prompt 寫更長」

Anthropic 的工程文章把 context engineering 定義成:策劃與維護推論時會進入模型的資訊,不只包含 prompt,也包含 system instructions、tools、外部資料與 message history。

它提出的實用原則是:找出最小、但訊號足夠的 token 集合,提高產生期望結果的機率。

這裡有三個容易忽略的重點:

  • Context 是每一步的狀態,不是開場文件包。 Agent 搜尋檔案、跑測試、讀 log 之後,context 會持續改變。
  • 更多不一定更好。 無關資料會佔用有限注意力,也可能把 agent 帶往錯誤方向。
  • Context 不能取代驗證。 資訊給得再完整,模型仍然可能推論錯誤;最後要靠可執行回饋收斂。

Prompt Engineering 仍然重要,它負責清楚表達當前任務。Context Engineering 則多問一步:模型還看見哪些規則、事實、工具與歷史?哪些資訊已經過期?下一步真正需要的是什麼?

Context 六層模型

我把 coding agent 的 context 分成六層。這是我的實作框架,不是任何廠商的官方分級;用途是幫助你分辨來源、保存期限與維護責任。

Layer 1:System 與 Runtime Policy

這層包含工具廠商提供的 system instructions、可用能力,以及執行環境實際套用的 sandbox、approval 與組織政策。

你通常不能直接改 system instructions,但可以選擇執行模式與權限。不同工具即使收到同一個 prompt,也可能因工具集合、預設規則和安全邊界不同而採取不同路徑。

設計重點:先理解預設行為,不要用 project rules 假裝自己能覆蓋更高層政策。對高風險任務,技術權限限制比一句「不要刪資料」可靠。

Layer 2:Durable Project Instructions

這是 AGENTS.mdCLAUDE.md.cursor/rules/ 或 repo 內的開發文件。適合放跨多個 task 都成立的「房子規則」:

## Commands

npm run check
npm run build

## Architecture

- Astro + MDX + Tailwind CSS + TypeScript
- Blog posts live in src/content/blog/

## Conventions

- Keep lang="zh-TW"
- Reuse existing components and CSS tokens
- Do not modify unrelated generated content

設計重點:短、準確、可執行。第一版只放 build/test、核心架構與高頻限制;當 agent 重複犯同一類錯,再補規則。一次性需求不要永久寫進 rules。

Layer 3:Retrieved Code 與文件

Agent 透過搜尋、讀檔、索引或 language server 取得 repo 內容。不同工具的 retrieval 策略不同,因此不要因為它說「理解 codebase」,就假設每次都看到了正確範圍。

設計重點:在實作前要求它先列出相關檔案、現有模式、資料流與未知處。清楚的檔名、資料夾結構與一致的 abstraction,同時幫助人和 agent 找到事實。

Layer 4:Working History

這是目前 session 的訊息、計畫、程式碼片段與工具結果。它會隨任務累積,也最容易混入已被推翻的方案、重複 log 和過期假設。

設計重點:重要決策與未完成項目要寫入 plan 或 note,不要只靠對話記憶。長任務可以使用 compaction 或開新 session,但摘要後要重新確認限制,因為壓縮一定可能遺失細節。

Layer 5:Tools 與 External Data

MCP、API、issue tracker、設計文件、資料庫 view、瀏覽器與其他工具,讓 agent 能按需取得 repo 之外的資訊或執行動作。

設計重點:只開當前任務需要的最小工具集合,並區分「讀取資料」與「改變外部狀態」的權限。工具回傳的是新 evidence,不是自動可信的真相;來源、時間與存取範圍都要能查核。

Layer 6:Runtime Feedback

這是 test failure、type error、build output、browser screenshot、git diff、log 與 metric。它們反映程式在真實環境的反應,是 agent 從猜測走向收斂的關鍵。

提出假設 → 修改 → 執行檢查 → 讀取結果 → 修正或回退

設計重點:把驗證指令做成 agent 可直接執行、結果可判讀。若測試需要一串只存在某位工程師腦中的手動步驟,agent 和新同事都很難利用它。

六層總覽

下面的表格列出六層各自的內容和風險,但沒講一件事:同一次 agent 執行裡,這六層「動」的頻率完全不一樣。畫出來會更清楚:

flowchart TD
    subgraph FIXED["幾乎不動:跨任務都成立"]
        L1["Layer 1<br/>System 與 Runtime Policy"]
        L2["Layer 2<br/>Durable Project Instructions"]
    end
    subgraph LOOP["每輪變動:隨任務持續累積"]
        L3["Layer 3<br/>Retrieved Code 與文件"]
        L4["Layer 4<br/>Working History"]
        L5["Layer 5<br/>Tools 與 External Data"]
        L6["Layer 6<br/>Runtime Feedback"]
    end
    L1 --> L2
    L2 --> L3
    L3 --> L4
    L4 --> L5
    L5 --> L6
    L6 -->|"讀取結果<br/>修正或回退"| L4

Layer 1 和 Layer 2 幾乎不會在一次任務裡變動——一個是你通常改不了的政策,一個是刻意寫成跨任務都成立的房子規則。真正在轉的是 Layer 3 到 Layer 6:retrieved code 隨搜尋而變、working history 隨任務累積、tools 按需呼叫、runtime feedback 每輪都重新產生。那條從 Layer 6 繞回 Layer 4 的線,才是整張圖的重點:讀到的測試結果、build output 不會自動消失,而是被寫回 working history,變成下一輪「提出假設」的依據。這也是為什麼 Layer 4 的設計重點特別提醒你把決策寫進 plan 或 note——這層才是真正在累積、也真正該花力氣維護的地方,不是每次都重寫一遍 Layer 1、Layer 2 那種幾乎不動的規則

典型內容主要風險維護責任
System / Policy系統規則、tools、sandbox誤解權限與優先順序廠商、平台、管理者
Project Instructionsrules、commands、conventions過長、衝突、過期Repo 維護者
Retrieved Code / Docs原始碼、測試、架構文件找錯範圍、讀到舊資料Agent + 工程師
Working History對話、plan、工具輸出累積雜訊、遺失決策Agent + 使用者
Tools / External DataMCP、API、ticket、browser權限過大、不可信內容使用者、平台
Runtime Feedbacktest、log、diff、metric驗證不完整、錯誤解讀工程團隊

一份好 Project Rules,應該寫什麼?

最常見的兩個極端是「什麼都沒寫」和「把整本團隊手冊塞進去」。比較耐用的做法是三層:

必須常駐:每個 Task 都用得到

  • build、test、lint、type check 指令
  • 主要技術棧與目錄位置
  • 重要的禁止事項與安全限制
  • 會造成大量返工的核心慣例

用路徑引用:需要時才讀

  • 架構決策紀錄
  • API contract 與 data model
  • deploy、migration、incident runbook
  • 完整 style guide 與 review checklist

主規則檔只需要說「何時讀哪一份」,不必複製全文。

做成 Skill 或自動化:重複流程

如果同一套步驟會反覆使用,例如 pre-commit review、部署檢查或文章發佈,把它做成可載入的 skill、script 或 CI job。規則負責導航,自動化負責穩定執行。

判斷某一條是否值得加入時,我會問:

  1. 它會跨多個 task 長期成立嗎?
  2. Agent 是否已重複在這裡犯錯?
  3. 能否寫成具體動作,而不是「寫出高品質 code」?
  4. 有沒有更可靠的 test、lint 或 permission 可以取代文字提醒?

Context Window 很大,為什麼還要節制?

Context window 的容量增加,不代表模型在每個位置都同樣穩定地使用資訊。

《Lost in the Middle》研究在多文件問答與 key-value retrieval 任務中發現,相關資訊位於長 context 中間時,受測模型的表現常比資訊放在開頭或結尾差。這不是說所有新模型都會以相同比例失準,而是提醒我們:能放進去,不等於能可靠取用。

此外,大量無關 context 還有三個實務成本:

  • 增加 latency 與 token cost
  • 讓衝突或過期資訊更難被發現
  • 誘導 agent 花時間解釋與任務無關的資料

因此不要追求「完整載入」,要追求「當下決策所需」。

三種管理長任務的方法

Anthropic 的 context engineering 指南整理了幾種長任務策略。放進 coding workflow,可以這樣理解。

Progressive Disclosure:先給索引,再按需讀取

開場提供任務、project rules 與關鍵路徑;讓 agent 用搜尋與工具逐步展開,而不是直接貼上五十個檔案。

路徑、query、ticket ID 與文件連結都是輕量索引。它們讓 agent 在需要時取得原文,也比較不容易把舊副本長期留在 context。

Compaction 與 Structured Notes:保留決策,不保留噪音

長 session 接近上限時,把已確認決策、完成項目、失敗嘗試、風險與下一步寫成結構化摘要。大段重複 log 和早已推翻的草案可以丟掉。

摘要不是無損壓縮。重新開始後,要先檢查 acceptance criteria、限制與未驗證項目是否仍在。

Sub-Agent:隔離探索 Context

當任務真的有多個可獨立查核的探索面,可以讓不同 sub-agent 研究 code path、測試模式或外部文件,只把來源、結論與未知處交回主線。

它的代價是更多 token、協調與摘要風險。小任務不需要為了「看起來很 agentic」硬拆;邊界不清的子任務,也容易得到彼此衝突的答案。

Context 也是安全邊界

Agent 讀到的 README、issue、網頁、MCP 回應或 log,都可能包含錯誤內容,甚至刻意引導它忽略原任務。外部文字進入 context 後,不應自動升格成可信指令。

實務上要做四件事:

  • 把不可信內容當資料,不當高優先級指令
  • 限制 tools、網路與 secrets 到任務最小需要
  • 對寫入外部系統、執行部署與刪除資料保留核准
  • 要求關鍵主張附來源,關鍵動作留下 audit trail

Context Engineering 不只是在追求更好的答案,也是在控制 agent 能被什麼資訊影響,以及影響之後能做多大的事。

Before / After:同一個任務,Context 怎麼改?

Before:只有功能描述

在文章底部加相關文章區塊,依 tags 推薦三篇。

這句話說清楚了產品功能,沒有說清楚技術環境。Agent 若找不到 project rules 或沒有先探索 repo,就可能選擇訓練資料裡常見、但不適合這個專案的實作。

After:任務 + 可發現的專案事實 + 驗證

Project rules 已經包含技術棧、目錄與檢查指令。Task spec 再補上當次限制:

在 BlogLayout.astro 底部加入相關文章。

Acceptance criteria:
- 使用 Astro Content Collections 取得文章
- 依 tags 交集數量排序,最多三篇
- 排除當前文章與 draft
- 重用既有 PostCard.astro
- 不新增 client-side framework
- 完成後執行 npm run check 與 npm run build

Agent 還是要自己搜尋 BlogLayout.astro、collection schema 與 PostCard.astro;不同之處是它知道去哪裡找、哪些限制不能自行發明,最後也有可執行的完成證據。

差別不在 prompt 變長,而在每一種資訊放到對的生命週期:長期規則留在 repo,任務限制留在 spec,程式事實即時讀取,正確性透過 runtime 驗證。

五個常見失敗模式

1. 把所有文件都設成 Always-On

常駐內容越多,越容易衝突與過期。主規則保留導航和高頻限制,細節按需讀取。

2. 規則只寫偏好,沒有可執行結果

「保持 clean code」沒有共同判準;「不要新增日期 formatter,先搜尋 src/lib」才會改變行為。

3. 同一條規則散落多處

Global、repo、子目錄與 task prompt 各寫一份,遲早互相矛盾。保留單一事實來源,其他地方只引用。

4. 相信 Tool Output 就是真相

API 可能回舊資料、測試可能只跑了一部分、文件可能已過期。記錄來源、時間、執行範圍與 exit code。

5. 任務結束後不把教訓帶回系統

若 agent 每次都在同一處失敗,問題可能不在 prompt,而在缺少 regression test、文件、命名或權限邊界。把一次修正轉成下一次可重用的防線。

實作 Checklist

開始任務前:

  • 成功、失敗與非目標是否清楚?
  • Project rules 是否仍正確、沒有衝突?
  • Agent 是否知道去哪裡找相關 code 與文件?
  • 權限與 tools 是否縮到最小需要?

執行過程中:

  • 新證據是否讓原本假設失效?
  • 對話是否累積大量無關輸出或舊方案?
  • 關鍵決策是否寫進 plan/note,而不是只留在聊天?

完成之前:

  • 測試與檢查真的覆蓋 acceptance criteria 嗎?
  • 最終 diff、未驗證項目與風險是否清楚?
  • 這次重複失敗是否該變成規則、測試或自動化?

Takeaway

  1. Context Engineering 管的是模型每一步可用的完整狀態,不只是開場 prompt。
  2. 最小且高訊號,比把所有資料塞滿 context window 更可靠。
  3. 好的 context 讓 agent 找到事實;runtime feedback 才讓它驗證假設。
  4. 外部 context 也可能不可信,必須和權限、核准與 audit 一起設計。

上一篇:2026 年 AI Coding 工具怎麼選?

下一篇:Spec-Driven Development

留言討論

esc
輸入關鍵字搜尋文章...
查看收藏 →