跳轉到

7.3 API 的上下文結構:訊息列表的角色#

看到 API 內部的結構#

在 7.2 節,我們把「上下文」當成一個黑箱概念。本節深入它的具體結構——大模型的 API 如何接收上下文,以及這個結構如何影響我們設計 Agent。

當你呼叫一個 LLM 的 API(例如 OpenAI 的 Chat Completions),輸入不是一句話,而是一個訊息列表(Messages List)。這個列表定義了「模型看到的一切」,是上下文工程的最小操作單元。

messages = [
    {"role": "system",    "content": "你是一位友善的訂位系統客服。"},
    {"role": "user",      "content": "我要訂明晚 7 點,4 人。"},
    {"role": "assistant", "content": "好的,請確認是明晚 7 點、4 位用餐嗎?"},
    {"role": "user",      "content": "是的,請幫我訂靠窗的位置。"},
]

三種主要的訊息角色#

LLM 的訊息列表裡,通常有三種核心角色,各有不同的用途:

1. System Message(系統訊息)#

放在最前面,是「總指揮」:設定模型的角色、行為規範、任務目標、以及最重要的——全域的上下文與約束。

system: 你是「訂位系統」的 AI 客服。你必須:
- 使用繁體中文,語氣親切
- 在沒確認資料前,不可直接建立訂位
- 若使用者問到與訂位無關的問題,禮貌地引導回主題
- 所有操作必須透過「建立訂位」工具,禁止自行偽造確認訊息

系統訊息是「橫跨整個對話始終有效的設定」——它是 Agent「長期人格與規則」的載體(呼應 7.1 節的 AGENTS.md 概念)。

2. User Message(使用者訊息)#

代表使用者的輸入或外部注入的資訊。它可以是使用者的真實問話,也可以是系統注入的資料(例如「這是使用者目前的購物車內容:...」)。需要注意的是——使用者是可以(甚至被引導)注入任何文字的,這正是 13.1 節「提示注入」的風險來源。

3. Assistant Message(助手訊息)#

代表模型之前的回應。它形成「對話歷史」,讓模型「記得」之前講過什麼、維持對話的連貫性。它也是 Agent 的「決策軌跡」(6.3 節)的一部分。

訊息列表的意義:為什麼它很關鍵#

把上下文理解成訊息列表,有幾個實際的意義:

1. 順序很重要#

模型是從前到後閱讀上下文的。系統訊息在最前(定義全域規則)、歷史在中間、當前請求在最後。這符合「先給規則、再給歷史、最後是問題」的自然順序。過於後的規則可能被後面的內容稀釋。

2. 歷史是上下文的主要消耗者#

多輪對話的歷史訊息,會「吃掉」大量上下文視窗(呼應 7.2 節的「視窗有限」)。延伸的對話越長,歷史越占空間,越需管理(7.4 節的壓縮/截斷/摘要)。

3. 注入 = 在訊息列表中「塞東西」#

「把知識注入上下文」,本質上就是在訊息列表中加入一段內容。無論是放系統訊息、還是放使用者訊息欄位,都在「操作訊息列表」。這讓「上下文管理」有了具體的操作對象。

4. 角色的信任邊界#

系統安排的內容(系統訊息)與使用者提供的內容(使用者訊息)須被區分——因為前者是「可信設定」,後者可能含惡意注入(13.1 節)。Agent 設計要在架構上把這兩者隔離開,避免使用者輸入覆蓋了系統規則。

從「單次請求出上下文」到「多步動態上下文」#

理解了訊息列表,我們可以把「上下文工程」的視野進一步拉高:

  • 單次請求(Single-shot):一次呼叫,你組好一份訊息列表,模型回一次
  • 多步動態(Multi-step Agentic):一個 Agent 任務會多次呼叫模型,每次都在動態重建訊息列表——讀了新檔案就加進去、完成了步驟就移除、輸出了結果就要追加

這就是 4.4 節 Agentic Coding 迴圈的底層機制:每一次「思考」都是在一個精心組裝的上下文之上。而「動態決定下一步該把哪些資訊放進上下文」——正是 Agent(與其 Harness,第 9 章)永不停歇的核心工作。

在 OpenCode 中的對應(與附錄連結)#

我們在附錄 B 使用的 OpenCode 這類 Agent 工具,內部正是這樣運作:

  • AGENTS.md(B.3 節) → 扮演系統訊息的角色:定義 AI 的「長期崗位說明」
  • 權限設定(B.4 節)、工具定義(B.5 節) → 在上下文中告訴 AI「有哪些工具、能不能用」
  • 讀取檔案、執行指令的結果 → 被動態注入進使用者/助手訊息,形成當前的上下文

理解訊息列表,你就能「看懂」這些工具底層在做什麼:一切都不過是在「精巧地管理模型每一次所見的訊息列表」。

本章小結#

  • LLM API 的輸入是訊息列表(Messages List),是上下文工程的最小操作單元
  • 三種角色:System(總指揮,全域規則)、User(使用者/注入資訊)、Assistant(模型歷史回應)
  • 意義:順序重要、歷史占空間、注入=在列表中塞東西、角色有信任邊界
  • 從「單次請求出上下文」到「多步動態上下文」:Agent 每次都在動態重建訊息列表
  • OpenCode 等工具底層:一切都在「管理模型每次所見的訊息列表」

想一想#

  1. 為什麼「系統訊息」要放在最前面,而且要承載「橫跨整個對話」的規則?
  2. 為什麼使用者注入的內容與系統設定的規則要「隔離」?如果不隔離會發生什麼(提示:13.1 節)?
  3. 一個 Agent「動態重建上下文」具體可能是怎麼運作的?試著為一個「寫程式」的任務,想像每次呼叫會怎麼組訊息列表。