19 min給工具使用者

Agent 不只是 LLM:State、Tools、Memory 如何組成可運作系統

Agent 不只是 LLM 加 Tool。理解 State、Context、Memory、Retrieval、Tools 與 Agent Runtime 如何組成可持續運作的閉環,以及為什麼 system truth 不該只存在模型文字裡。

Aaron Huang系統、產品與 AI 實作

Agent 不只是 LLM:State、Tools、Memory 如何組成可運作系統

上一篇我們做了一個重要的選擇:

不是每個問題都需要 Agent。

如果:

Code

可以解,就先用 Code。

如果需要語意理解:

LLM

如果缺外部知識:

Retrieval / RAG

如果流程大致知道:

Workflow

只有當:

下一步必須根據 runtime 的結果動態決定

Agent 才真正開始有價值。

但一旦我們決定:

這個問題確實需要 Agent。

下一個問題就來了。

前一篇的 Agent loop 是:

Goal
↓
Observe
↓
Decide
↓
Act
↓
Observe Result
↓
Continue or Stop

看起來很簡單。

但如果真的把它寫成系統,很快就會遇到三個問題:

系統怎麼知道現在做到哪裡?
↓
State

模型怎麼對外做事情?
↓
Tools

前面發生過的事情怎麼保留下來?
↓
Memory

這三個東西,才讓:

LLM

變成一個能持續運作的 Agent system。

Agent Runtime 如何把 State、Memory、Retrieved Knowledge、Context Engineering、LLM Decision、Tools 與 Observation 串成可運作系統。


一、先拆掉一個誤會:Agent 的「腦」不是整個 Agent

很多 Agent 架構圖會把中間畫成:

LLM

旁邊接:

Tools
Memory

於是很容易產生一個印象:

Agent 就是一個比較會思考的 LLM。

但實際系統比較接近:

                 ┌──────────────┐
                 │     State    │
                 └──────┬───────┘
                        ↓
Observation → Context → LLM
                        ↓
                    Decision
                        ↓
                      Tool
                        ↓
                    Result
                        ↓
                  Update State
                        ↓
                     Memory

LLM 很重要。

但它通常只是:

某一次 decision 的 reasoning component。

真正維持任務持續運作的,是外面的 application system。


二、為什麼 LLM 自己無法維持一個 Agent?

假設我們要求:

幫我把測試失敗修好。

第一輪:

User:
Fix the failing tests.

↓

LLM:
先跑 tests。

Tool 執行:

run_tests()

得到:

12 passed
2 failed

第二輪模型需要知道:

Goal 是什麼?
剛剛跑過什麼?
結果是什麼?
哪些 test failed?
下一步應該做什麼?

問題是:

LLM 本身並不天然擁有一個永久存在的:

task object

它收到的是:

這一次 inference 的 input

然後產生:

這一次 inference 的 output

所以下一輪如果什麼都沒有重新提供:

模型不會神奇地知道:

我們剛剛跑過 tests。

這就是為什麼 Agent 需要:

State。


三、State 是「任務現在的真實狀態」

State 可以先用一句話理解:

State 是 application 持有的、描述目前任務進度與環境狀態的資料。

例如:

Goal:
修復 login test

Current State:
- 已讀 authentication.py
- 已執行 tests
- 12 passed
- 2 failed
- failure: token expired
- refresh logic 尚未修改

下一輪 Decision 不應該從:

空白

開始。

而應該從:

Current State

繼續。

所以:

Decision = f(Current State, Observation, Goal)

這比:

Decision = f(User Prompt)

更接近 Agent。


四、State 不只是 Conversation History

這裡很容易把 State 理解成:

把聊天紀錄全部保存。

但真正的 State 可以包含很多不是自然語言對話的東西。

例如 Coding Agent:

task_id
current_goal
files_read
files_modified
test_results
current_branch
failed_attempts
pending_actions
last_tool_result

Travel Agent:

destination
travel_dates
budget
selected_flights
rejected_hotels
current_itinerary
booking_status

Research Agent:

research_question
queries_completed
sources_found
claims_supported
claims_conflicted
open_questions

所以 State 更接近:

Application Data Model

而不是單純:

Chat History。


五、State 讓 Agent 不需要每一步重新猜

如果沒有明確 State,系統很容易變成:

LLM:
我記得剛剛好像做過……

這其實非常危險。

因為模型開始用自然語言「推測」系統狀態。

例如:

模型:
我已經修改完成。

但實際檔案:

根本沒改。

或者:

模型:
所有 tests 都通過。

但真實狀態:

integration test 根本還沒跑。

所以重要資訊不應只存在:

模型說過的文字

而應該存在:

System State

例如:

{
  "tests_run": true,
  "passed": 12,
  "failed": 2
}

這就是:

不要讓模型自己發明 system truth。


六、State 和 Context 完全不是同一件事

這是 Agent architecture 裡非常重要的一條界線。

State

是:

系統目前持有什麼資訊。

Context

是:

這一次 inference,你決定把哪些資訊提供給模型。

假設 State 有:

100 個 tool results
30 個 files
20 次 decision
5 個 failed attempts

這些全部都可以存在 application state。

但下一輪 LLM 不一定需要全部看到。

真正送進 Context 的可能只有:

Current Goal

Relevant File

Last Test Result

Important Constraints

Current Plan

所以:

State
≠
Context

更精確地說:

State
↓
Context Engineering
↓
Relevant Context
↓
LLM

這和 Article 02 談的 Context Engineering 就接起來了。


七、不是所有 State 都應該塞進 Context Window

如果每一次 Agent loop 都做:

把所有歷史資料全部塞進 Prompt

很快會出現:

  • token 越來越多
  • latency 越來越高
  • cost 越來越高
  • irrelevant information 越來越多
  • important information 反而更難被注意

所以 Agent 系統通常需要做一件事情:

從 State 中選出現在 Decision 真正需要的資訊。

也就是:

Large State
↓
Select / Summarize / Retrieve
↓
Working Context
↓
LLM

因此:

Context Engineering 並沒有因為 Agent 出現而消失。

反而更重要。


八、Tool 是 Agent 與 Environment 之間的介面

有了 State,Agent 知道:

現在在哪裡。

但它還需要:

對外做事情。

這就是 Tools。

上一篇 Article 04 已經談過:

Tool Calling

模型可能輸出:

{
  "tool": "run_tests",
  "arguments": {
    "scope": "auth"
  }
}

但在 Agent 系統裡,Tool 的角色可以看得更清楚:

State
↓
LLM Decision
↓
Tool
↓
Environment
↓
Tool Result
↓
Observation
↓
Update State

Tool 其實是:

Agent 可以感知或改變 environment 的 interface。


九、Tool 不只是「執行 Action」

有些 Tool 是用來:

Read

read_file
search_web
query_database
get_order

它們主要產生:

Observation

有些 Tool 是:

Write / Act

write_file
send_email
update_ticket
create_booking

它們會改變:

Environment

也有些 Tool 是:

Compute

calculator
run_code
run_tests

它們把一個問題交給 deterministic system。

所以 Tool 不只是:

Agent 的手。

它也可能是:

Agent 的眼睛、計算器、資料入口。


十、好的 Tool Interface 會直接影響 Agent 的可靠性

假設我們給 Agent 一個 Tool:

do_everything(input)

模型必須自己猜:

這個 input 要怎麼寫?
會做什麼?
結果代表什麼?

這會增加 ambiguity。

如果改成:

search_orders(
  customer_id,
  date_range
)

以及:

request_refund(
  order_id,
  reason
)

模型的 Action Space 就比較清楚。

所以 Agent system design 很大一部分其實是:

設計好的 Tool Interface。

包括:

Tool Name
Description
Input Schema
Output Schema
Error Contract

Tool interface 越清楚:

模型越容易做正確 decision。


十一、Tool Result 不應直接等於「任務成功」

假設:

send_email()

回傳:

200 OK

只能證明:

API call 成功。

它不代表:

Email 內容正確
寄給正確的人
任務已經完成

同樣:

run_tests()

成功執行。

不代表:

tests passed

所以 Tool Result 必須變成:

Observation

然後系統重新判斷:

這個結果對 Goal 代表什麼?

這也就是:

Act
↓
Observe
↓
Decide Again

真正形成閉環的地方。


十二、那 Memory 又是什麼?

如果 State 是:

現在這個任務做到哪裡。

Memory 可以先理解成:

系統希望跨時間保留下來、未來可能再次使用的資訊。

例如:

今天 Agent 幫使用者規劃旅行。

State:

目前正在找東京飯店
已比較 12 家
剩 3 家候選

任務完成後:

這些不一定需要永遠保留。

但可能有某些資訊值得留下:

User prefers:
- non-smoking room
- near MRT
- budget around JPY 20,000

下一次旅行:

這些資訊可能再次有價值。

這就比較接近:

Memory。


十三、State 和 Memory 的差別

可以先用這個方式區分:

State Memory
主要用途 完成現在任務 幫助未來任務
時間範圍 current execution across executions
內容 step、tool result、progress reusable knowledge / preference / experience
是否全部給模型 不一定 更不一定
誰管理 application application / memory system

例如:

State:
目前第 4 步
API call failed
準備 retry

Memory:

這個 API 在 rate limit 時應降低 batch size

兩者不是完全不能重疊。

但用途不同。


十四、Memory 也不是「把所有聊天都存起來」

如果 Memory 的策略是:

Everything → Save Forever

很快就會出問題。

例如:

過期資訊
錯誤推論
互相矛盾的偏好
重複資料
無關資訊

所以 Memory system 真正困難的問題其實不是:

怎麼存?

而是:

What to remember?
When to retrieve?
What to update?
What to forget?

也就是:

Memory Management。


十五、Memory 通常需要兩個動作:Write 與 Read

最簡單可以拆成:

Memory Write

以及:

Memory Read

Memory Write

任務過程中:

Observation
↓
Worth remembering?
↓
Yes
↓
Store

Memory Read

下一次 Decision:

Current Task
↓
Relevant memory?
↓
Retrieve
↓
Context
↓
LLM

所以 Memory 不應該只是:

database

它其實還需要:

selection
retrieval
update

十六、Memory 和 RAG 看起來很像,差在哪?

這兩個常常在 implementation 上使用類似技術。

例如都可能:

embed
↓
store
↓
retrieve

但概念上的來源不同。

RAG

通常回答:

外部世界有哪些知識是模型現在需要的?

例如:

公司政策
產品文件
研究報告
Knowledge Base

Memory

通常回答:

這個系統過去互動或執行中,有哪些資訊值得未來繼續使用?

例如:

user preference
previous decision
past failure pattern
task history

所以:

RAG

比較像:

External Knowledge

Memory 比較像:

Persisted System Experience

技術可以重疊。

但 semantic role 不一樣。


十七、Memory 和 Context 也不能混在一起

再整理一次:

Memory

Stored information across time

State

Current task information

Context

Information given to the model right now

三者的關係可能是:

State ──────┐
            │
Memory ─────┼→ Context Engineering → Current Context → LLM
            │
Retrieved ──┘
Knowledge

所以 Context 不是資料來源本身。

Context 是:

這一次 inference 的 working set。

這是非常重要的架構觀念。


十八、一個完整 Agent Loop 現在長什麼樣?

現在可以把前面的東西全部組起來。

Goal
↓
Load State
↓
Retrieve relevant Memory
↓
Get relevant external Knowledge
↓
Build Context
↓
LLM Decision
↓
Select Tool
↓
Execute Tool
↓
Observe Result
↓
Update State
↓
Write Memory if needed
↓
Continue or Stop

這時你會發現:

LLM 只在其中一小段:

Build Context
↓
LLM Decision

Agent 真正的 architecture 大部分其實都在模型外面。


十九、Agent Runtime 才是真正把這些東西串起來的地方

誰負責:

讀 State?

誰負責:

建立 Context?

誰負責:

把 Tool Result 寫回 State?

誰負責:

下一輪再呼叫模型?

答案通常不是 LLM。

而是:

Agent Runtime / Application Runtime。

可以想成:

while not done:

    state = load_state()

    context = build_context(
        state,
        retrieve_memory(state),
        retrieve_knowledge(state)
    )

    decision = llm(context)

    result = execute_tool(decision)

    state = update_state(
        state,
        result
    )

    save_state(state)

這只是概念 pseudo-code。

但它很接近 Agent system 真正的骨架。


二十、所以 Agent Framework 到底在幫你做什麼?

到了這裡,才比較容易理解:

Agent Framework

到底存在的原因。

它通常不是提供:

更聰明的模型。

而是在幫你處理:

State Management
Tool Registry
Tool Execution
Message / Context Assembly
Loop Control
Memory Integration
Tracing

也就是:

模型外面的 Agent Runtime infrastructure。

所以不同 framework 的差異,很多時候不是:

誰的 LLM 比較聰明。

而是:

誰怎麼管理這整個 execution loop。


二十一、但不要因為有 Framework,就把所有東西交給 Framework

這裡又回到上一篇:

Minimum Necessary Complexity。

如果你的系統只有:

User
↓
LLM
↓
Database Search
↓
Answer

可能根本不需要複雜 Agent Framework。

你完全可以自己寫:

retrieve()
generate()
validate()

只有當:

State
Tools
Memory
Dynamic Decisions
Multiple Steps

開始變複雜時:

Framework 才可能真的幫你減少 orchestration cost。


二十二、最重要的不是「有沒有 Memory」,而是資料責任在哪裡

很多 Agent Demo 會強調:

我有 Memory。

但 Production System 更應該問:

誰寫入?
寫什麼?
什麼時候更新?
哪個資料才是真實來源?
衝突怎麼處理?
什麼時候失效?

例如:

User says:
我喜歡靠近捷運的飯店。

系統可能記成 preference。

但如果下一次使用者說:

這次我要住山上,不用靠捷運。

Agent 不能因為:

Memory = near MRT

就覆蓋當前 Task Requirement。

因此一般來說:

Current explicit task constraint

應該比:

Old memory

更有優先權。

Memory 是 context source。

不是絕對真理。


二十三、同樣地,State 也需要 System of Record

假設 Tool Result 說:

booking_status = failed

但模型輸出:

Booking completed successfully.

哪一個是真實狀態?

應該是:

Tool / System State

而不是:

LLM narrative

所以 Production Agent 最重要的一條原則之一是:

System truth 應該由可靠的 application state / external system 保存,而不是存在模型生成的文字裡。


二十四、這也是為什麼 Agent Engineering 很像 Software Engineering

做到這裡會發現:

真正的 Agent Engineering 不只是:

Prompt Engineering

它開始涉及:

Data Model
State Machine
API Design
Tool Contract
Persistence
Retrieval
Error Handling
Observability
Evaluation

LLM 只是其中一個:

Probabilistic Decision Component

所以:

Agent Engineer 不是只會讓模型回答。

而是:

知道怎麼把一個 probabilistic model 放進可管理的 software system。


二十五、把 Article 06–08 串起來

現在三篇其實形成一條很清楚的線:

Article 06

回答:

Agent 是什麼?

Goal
→ Observe
→ Decide
→ Act
→ Feedback

Article 07

回答:

什麼時候真的需要 Agent?

Minimum Necessary Complexity

Article 08

回答:

Agent 真正怎麼運作?

State
+
Tools
+
Memory
+
Runtime

接下來就剩最後一個非常重要的問題。


二十六、Agent 能做事之後,下一個問題不是「還能做什麼」

一旦 Agent 有:

State
Tools
Memory
Dynamic Decisions

它就開始真的具有:

Agency

這時真正危險的問題不是:

能不能多接幾個 Tool?

而是:

它到底可以做哪些 Action?
哪些 Action 需要 Permission?
什麼時候要 Human Approval?
怎麼避免 Loop 一直跑?
什麼情況必須 Stop?

這些就不再只是:

Agent Capability

而是:

Agent Governance。

這也是 S09 最後一篇 Article 09 要處理的問題:

Action Space、Permissions、HITL、Stop Conditions:怎麼讓 Agent 有能力但不失控