← 文章列表
LLM

LLM Agent 完整指南:從架構模式到實務應用

2026-03-23 · — views

想讓你的 LLM 能自主執行多步驟任務、動態調用工具、根據結果調整策略?這篇文章帶你深入理解 Agent 系統!你將學到:四大核心架構模式(ReAct、Plan-and-Execute、Tool Calling、Reflexion)、當前演進趨勢(Multi-Agent、LangGraph、Memory System)、以及框架選擇與成本優化。從概念到實踐,一篇搞定。

Intro:為什麼需要 Agent?

傳統 LLM 的限制

大型語言模型(LLM)雖然強大,但在實際應用中有明確的限制:

  1. 單次輸入輸出 - 無法進行多步驟任務
  2. 無法使用工具 - 不能呼叫 API、查詢資料庫、執行程式
  3. 缺乏記憶 - 無法記住上下文與歷史決策
  4. 無法動態決策 - 不能根據中間結果調整策略

核心洞察:LLM 很聰明,但它不會「行動」

想像你要用 LLM 完成「研究某個主題並撰寫報告」這個任務:

  • 傳統 LLM:只能給你一個基於訓練資料的答案
  • 你期望的:搜尋最新資料 → 分析內容 → 整理重點 → 撰寫報告

這之間的差距,就是為什麼我們需要 Agent。

Agent 如何解決?

定義:LLM Agent 是能自主使用工具、進行推理、並執行多步驟任務的 LLM 系統。

Agent 提供四大核心能力:

  1. Reasoning(推理)

    • 理解問題
    • 規劃步驟
    • 評估結果
  2. Tool Use(工具使用)

    • 調用外部 API
    • 查詢資料庫
    • 執行程式碼
    • 搜尋網路
  3. Memory(記憶)

    • 記住上下文
    • 儲存歷史決策
    • 學習經驗
  4. Decision Making(決策)

    • 根據情況選擇下一步
    • 動態調整策略
    • 處理意外情況

與傳統 LLM 的差異

傳統 LLM:
User Query → LLM → Answer

LLM Agent:
Goal → Plan → Action 1 → Observe → Decide → Action 2 → ... → Complete

Agent 是一個「會行動的 LLM」,它能將複雜目標分解成可執行的步驟,並根據執行結果動態調整策略。

何時使用 Agent?

✅ 適合的場景

  • 需要多步驟推理的任務

    • 例:「研究主題並撰寫報告」
    • 需要:搜尋 → 閱讀 → 分析 → 撰寫
  • 需要調用多個外部工具

    • 例:交易系統(查詢價格 → 檢查餘額 → 執行交易)
    • 需要:整合多個 API
  • 需要動態決策的場景

    • 例:客服 Agent(根據問題類型選擇處理方式)
    • 需要:if-then-else 邏輯
  • 需要根據結果調整策略

    • 例:程式碼除錯(執行 → 檢查錯誤 → 修正 → 重試)
    • 需要:迭代改進

❌ 不適合的場景

  • 簡單的單次問答(直接用 LLM 就好)
  • 不需要工具的任務(如創意寫作)
  • 對 latency 要求極高(< 1s)
  • 預算有限(Agent 成本較高,多次 LLM 調用)

決策關鍵:你的任務是否需要多步驟推理和工具使用?如果答案是肯定的,Agent 就是你需要的解決方案。


Chapter 2: Agent 核心架構模式

在深入各種架構前,先理解四大核心模式的本質差異。

2.1 架構模式總覽

四大核心架構:

  1. ReAct - 交替推理與行動(最靈活)

    • 特點:動態、多輪迭代
    • 成本:高(N 次 LLM 調用)
  2. Plan-and-Execute - 先規劃再執行(最有效率)

    • 特點:靜態計畫、依序執行
    • 成本:中(1 次規劃 + 執行)
  3. Tool Calling - 單次工具調用(最簡單)

    • 特點:單次決策
    • 成本:低(1-2 次 LLM 調用)
  4. Reflexion - 自我反思與改進(最高品質)

    • 特點:迭代改進
    • 成本:高(N 次迭代)

核心差異

  • ReAct:邊做邊想,隨時調整
  • Plan-and-Execute:先想好,再依序執行
  • Tool Calling:一次決定,快速執行
  • Reflexion:做完檢討,再做更好

讓我們逐一深入。


2.2 ReAct (Reasoning + Acting)

核心概念

原理:交替進行「推理」(Thought) 與「行動」(Action)

ReAct 的名字就說明了一切:Reasoning + Acting。LLM 不斷在「思考下一步該做什麼」和「實際執行動作」之間切換。

流程範例

User: 我想買 1 BTC

Agent:
Thought 1: 我需要先查詢當前價格

Action 1: get_price("BTC")

Observation 1: BTC price = $40,000

Thought 2: 價格合理,接下來檢查餘額

Action 2: check_balance()

Observation 2: Balance = $50,000

Thought 3: 餘額足夠,可以執行購買

Action 3: buy("BTC", 1)

Observation 3: Order placed successfully

Final Answer: 已成功購買 1 BTC,成交價 $40,000

這個流程展示了 ReAct 的核心:每次行動前都會思考,每次行動後都會觀察結果,然後再決定下一步。

Prompt 結構

ReAct 的魔法在於 prompt 設計。你需要教 LLM「如何思考和行動」:

You have access to the following tools:
- GetPrice: 查詢價格
- CheckBalance: 查詢餘額
- BuyCrypto: 購買加密貨幣

Use the following format:
Thought: [你的思考過程]
Action: [要執行的動作]
Action Input: [動作的輸入參數]
Observation: [動作的結果]
... (可重複 N 次)
Thought: I now know the final answer
Final Answer: [最終答案]

Question: 我想買 1 BTC
Thought:

LLM 會按照這個格式輸出,系統解析 Action 並執行,將結果作為 Observation 回傳,然後 LLM 繼續下一輪 Thought。

關鍵套件(LangChain)

from langchain.agents import initialize_agent, AgentType

agent = initialize_agent(
    tools,                                      # 可用的工具列表
    llm,                                        # LLM model
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,  # ReAct 模式
    verbose=True                                # 顯示推理過程
)

result = agent.run("我想買 1 BTC")

ZERO_SHOT_REACT_DESCRIPTION 就是標準的 ReAct 模式,LLM 會根據工具的 description 決定何時使用哪個工具。

優勢與劣勢

優勢

  • 靈活性高:能應對意外情況,動態調整策略
    • 例:如果餘額不足,可以改成查詢其他幣種
  • 可解釋性強:每一步的推理過程都可追蹤
    • 你能看到 Agent 為什麼做出某個決定
  • 適合探索性任務:如「研究 X 主題並總結」
    • 不需要預先知道所有步驟

劣勢

  • Token 消耗大:每次迭代都包含完整的 Thought + Action + Observation
    • 10 步驟可能消耗 10,000+ tokens
  • 容易陷入循環:LLM 可能重複執行相同動作
    • 例:不斷查詢價格但忘記執行購買
  • 速度較慢:多輪 LLM 調用
    • 10 步驟 = 10 次 API call

適用場景

  • 需要動態決策的任務(如客服 Agent)
  • 工具調用順序不確定的任務
  • 需要根據中間結果調整策略的任務

核心洞察:ReAct 適合「邊做邊學」的任務。如果你無法預先規劃所有步驟,ReAct 是最佳選擇。


2.3 Plan-and-Execute

核心概念

原理:先規劃完整步驟,再依序執行

與 ReAct 的「邊做邊想」不同,Plan-and-Execute 是「先想好再做」。

流程範例

User: 我想買 1 BTC

[Planning Phase]
Agent 生成計畫:
Plan:
1. 查詢 BTC 當前價格
2. 檢查帳戶餘額
3. 如果餘額足夠,執行購買
4. 回報結果

[Execution Phase]
Execute Step 1: get_price("BTC") → $40,000
Execute Step 2: check_balance() → $50,000
Execute Step 3: buy("BTC", 1) → Success
Execute Step 4: Return "已成功購買 1 BTC"

計畫是一次性生成的,然後按部就班執行。這類似軟體工程中的「先設計再實作」。

兩階段設計

Phase 1: Planning(規劃階段)

讓 LLM 生成結構化的計畫:

planning_prompt = """
根據用戶目標,制定詳細的執行步驟。

可用工具:
- get_price(symbol): 查詢價格
- check_balance(): 查詢餘額
- buy_crypto(symbol, amount): 購買加密貨幣

用戶目標:{goal}

請制定步驟計畫(JSON 格式):
[
  {"step": 1, "action": "get_price", "params": {"symbol": "BTC"}},
  ...
]
"""

plan = planning_chain.run(goal="我想買 1 BTC")

Phase 2: Execution(執行階段)

按照計畫依序執行:

for step in plan:
    action = step["action"]
    params = step["params"]
    result = execute_action(action, params)
    print(f"Step {step['step']}: {action} → {result}")

LangGraph 實作

LangGraph 特別適合實作 Plan-and-Execute,因為它支援複雜的狀態管理和條件分支:

from langgraph.graph import StateGraph, END

class AgentState(TypedDict):
    goal: str
    plan: List[dict]
    current_step: int
    results: List[str]

def plan_node(state):
    """規劃階段"""
    plan = generate_plan(state["goal"])
    return {"plan": plan, "current_step": 0}

def execute_node(state):
    """執行階段"""
    step = state["plan"][state["current_step"]]
    result = execute_action(step)
    return {
        "results": state["results"] + [result],
        "current_step": state["current_step"] + 1
    }

def should_continue(state):
    """判斷是否繼續執行"""
    if state["current_step"] >= len(state["plan"]):
        return "finalize"
    return "execute"

# 建立 Graph
workflow = StateGraph(AgentState)
workflow.add_node("plan", plan_node)
workflow.add_node("execute", execute_node)
workflow.add_node("finalize", finalize_node)

workflow.set_entry_point("plan")
workflow.add_edge("plan", "execute")
workflow.add_conditional_edges("execute", should_continue)

優勢與劣勢

優勢

  • 步驟清晰:計畫一目了然,容易除錯
    • 你能立刻看到整個執行流程
  • Token 效率高:Planning 只需一次 LLM 調用
    • 相比 ReAct 節省 50%+ tokens
  • 適合明確任務:當步驟可預測時效率高
    • 例:「下載資料 → 分析 → 產生報告」

劣勢

  • 缺乏靈活性:計畫錯誤導致全盤失敗
    • 如果步驟 2 失敗,無法動態調整
  • 難以應對變化:無法根據中間結果調整計畫
    • 例:發現餘額不足時無法改變策略
  • 需要好的規劃能力:對 LLM 的規劃能力要求高
    • 弱模型可能生成不完整的計畫

適用場景

  • 目標明確、步驟可預測的任務
  • 需要優化效率的場景(減少 LLM 調用次數)
  • 步驟之間依賴性強的任務

核心洞察:Plan-and-Execute 適合「已知路徑」的任務。如果你能預先規劃所有步驟,這是最省成本的方式。


2.4 Tool Calling / Function Calling

核心概念

原理:LLM 決策「調用哪個工具」及「傳入什麼參數」,但不進行多輪推理

Tool Calling 是最簡單的 Agent 模式,也是 OpenAI 和 Anthropic 原生支援的功能。

與 ReAct 的差異

  • ReAct:多輪 Thought → Action 迭代
  • Tool Calling:單次決策,LLM 輸出 function call,系統執行後回傳結果

流程範例

User: "查詢 BTC 價格並買 1 個"

LLM 分析 → 需要 2 個 function calls:
  1. get_price("BTC")
  2. buy_crypto("BTC", 1)

System 執行 → Results: [$40,000, "Success"]

LLM 生成回覆 → "BTC 目前 $40,000,已成功購買 1 個"

整個過程通常只需要 1-2 次 LLM 調用。

Function Schema 設計

Tool Calling 的關鍵在於清楚定義 function schema:

functions = [
    {
        "name": "get_price",
        "description": "查詢加密貨幣的當前價格",
        "parameters": {
            "type": "object",
            "properties": {
                "symbol": {
                    "type": "string",
                    "description": "幣種代號,如 BTC, ETH"
                }
            },
            "required": ["symbol"]
        }
    },
    {
        "name": "buy_crypto",
        "description": "購買加密貨幣",
        "parameters": {
            "type": "object",
            "properties": {
                "symbol": {"type": "string"},
                "amount": {"type": "number"}
            },
            "required": ["symbol", "amount"]
        }
    }
]

Schema 要寫得清楚,LLM 才知道何時該用哪個工具。

原生 API 支援

OpenAI Function Calling

response = openai.ChatCompletion.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "查詢 BTC 價格並買 1 個"}],
    functions=functions,
    function_call="auto"  # 讓 LLM 自動決定
)

# 解析並執行 function call
function_name = response["choices"][0]["message"]["function_call"]["name"]
function_args = json.loads(response["choices"][0]["message"]["function_call"]["arguments"])

LangChain 封裝

from langchain.agents import create_openai_functions_agent

agent = create_openai_functions_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools)

result = agent_executor.invoke({"input": "查詢 BTC 價格並買 1 個"})

優勢與劣勢

優勢

  • 效率高:通常只需 1-2 次 LLM 調用
  • 結構化:Function schema 清楚定義輸入輸出
  • 容易除錯:Function call 格式標準化
  • 原生支援:OpenAI, Anthropic, Google 都有原生 API

劣勢

  • 缺乏推理過程:看不到 LLM 的思考
  • 難以處理複雜任務:單次決策,無法多輪迭代
  • 依賴 schema 品質:Schema 不清楚會導致錯誤調用

適用場景

  • 工具數量有限且明確定義
  • 需要快速響應的場景(如聊天機器人)
  • 簡單的工具調用(1-2 個工具)

核心洞察:Tool Calling 適合「一次搞定」的任務。如果任務簡單且工具明確,這是最快最便宜的方式。


2.5 Reflexion / Self-Refinement

核心概念

原理:Agent 自我評估輸出品質,迭代改進

Reflexion 的核心是「自我反思」。Agent 不僅生成答案,還會評估自己的答案,發現問題,然後改進。

流程圖

User Query

[Generation] 第一版答案

[Self-Reflection] LLM 評估:
  - 這個答案是否完整?
  - 有沒有錯誤?
  - 如何改進?

[Refinement] 根據反思改進答案

[Repeat] 直到達到品質標準或 max iterations

這類似人類寫作的過程:寫初稿 → 檢討 → 修改 → 再檢討 → 再修改。

三階段循環

Stage 1: Generation(生成)

answer_v1 = llm.predict("什麼是 RAG?")
# 輸出:RAG 是一種技術...

Stage 2: Reflection(反思)

reflection_prompt = """
請評估以下答案的品質:

問題:什麼是 RAG?
答案:{answer}

評估標準:
1. 是否完整回答問題?
2. 是否有事實錯誤?
3. 是否清楚易懂?
4. 有什麼可以改進的地方?

請提供改進建議。
"""

reflection = llm.predict(reflection_prompt.format(answer=answer_v1))
# 輸出:答案基本正確,但沒有解釋為什麼需要 RAG,建議補充...

Stage 3: Refinement(改進)

refinement_prompt = """
原始問題:{question}
原始答案:{answer}
改進建議:{reflection}

請根據改進建議,重寫答案。
"""

answer_v2 = llm.predict(refinement_prompt.format(
    question="什麼是 RAG?",
    answer=answer_v1,
    reflection=reflection
))
# 輸出:RAG (Retrieval-Augmented Generation) 是一種技術,它結合了...(更完整的答案)

優勢與劣勢

優勢

  • 品質高:透過迭代改進提升輸出品質
  • 可控:可以定義明確的評估標準
  • 適合高要求任務:如程式碼生成、報告撰寫

劣勢

  • 成本高:多次 LLM 調用(Generation + Reflection + Refinement)
  • 速度慢:每次迭代都需要時間
  • 可能過度優化:改來改去反而變差

適用場景

  • 需要高品質輸出的任務(如技術文件撰寫)
  • 有明確評估標準的任務
  • Cost 與 latency 不是瓶頸

核心洞察:Reflexion 適合「追求完美」的任務。如果品質比速度和成本更重要,值得使用。


章節總結

四大架構模式的本質

架構核心特點適合場景成本
Tool Calling一次搞定簡單任務
Plan-and-Execute先想好再做明確任務
ReAct邊做邊想動態任務
Reflexion做完檢討高品質任務

選擇建議

  • 不確定?從 Tool Calling 開始
  • 需要靈活性?用 ReAct
  • 需要效率?用 Plan-and-Execute
  • 需要品質?用 Reflexion

Chapter 3: Agent 系統的演進與趨勢

從單一 Agent 到複雜的 Agent 生態系統,讓我們了解當前 Agent 技術的五大演進方向。

3.1 Multi-Agent Systems(多智能體系統)

核心概念

為什麼需要 Multi-Agent?

單一 Agent 就像一個全能選手,什麼都會但什麼都不精。而 Multi-Agent 系統就像一個專業團隊,每個 Agent 負責自己擅長的領域。

實際問題: 假設你要讓 Agent 完成「開發一個網站」:

  • 單一 Agent:同時負責需求分析、設計、前端、後端、測試
  • Multi-Agent:
    • Product Manager Agent:負責需求分析
    • Designer Agent:負責 UI/UX 設計
    • Frontend Agent:負責前端開發
    • Backend Agent:負責後端開發
    • QA Agent:負責測試

哪種方式更合理?顯然是 Multi-Agent。

典型架構

架構 1:協調者模式 (Coordinator Pattern)

User Query

[Coordinator Agent] 分析任務、分配工作

├─ [Research Agent] 負責研究(查詢資料、閱讀文件)
├─ [Code Agent] 負責寫程式(實作功能)
├─ [Review Agent] 負責檢查(Code review、測試)

[Coordinator Agent] 整合結果

Final Output

Coordinator 是核心,負責任務分配和結果整合。其他 Agent 是專家,各司其職。

架構 2:流水線模式 (Pipeline Pattern)

[Agent 1: Data Collection] → 收集資料

[Agent 2: Analysis] → 分析資料

[Agent 3: Visualization] → 產生圖表

[Agent 4: Report Generation] → 撰寫報告

像工廠流水線,每個 Agent 完成自己的工作後傳給下一個。

架構 3:辯論模式 (Debate Pattern)

[Proposer Agent] 提出方案

[Critic Agent] 挑戰方案(找出問題)

[Refiner Agent] 改進方案

Repeat until consensus

透過辯論提升方案品質,類似團隊的 brainstorming。

關鍵挑戰

挑戰 1:Agent 之間的溝通協議

問題:如何定義清楚的介面?

  • Agent A 輸出什麼格式?
  • Agent B 期望什麼輸入?
  • 如何處理訊息格式不一致?

解決:定義標準化的訊息格式(如 JSON schema)

挑戰 2:任務分配與協調

問題:Coordinator 如何決定分配給誰?

  • 根據 Agent 的專長?
  • 根據當前工作負載?
  • 如何處理依賴關係?

解決:建立任務路由機制,根據任務類型分配

挑戰 3:衝突解決

問題:不同 Agent 給出矛盾建議時如何處理?

  • Reviewer Agent 說「需要重寫」
  • Coder Agent 說「已經很好了」
  • Coordinator 該聽誰的?

解決:建立優先級機制或投票機制

實作框架

LangGraph Multi-Agent

from langgraph.graph import StateGraph

class MultiAgentState(TypedDict):
    task: str
    research_result: str
    code_result: str
    review_result: str

def research_agent(state):
    # Research 邏輯
    result = perform_research(state["task"])
    return {"research_result": result}

def code_agent(state):
    # Coding 邏輯
    code = generate_code(state["research_result"])
    return {"code_result": code}

def review_agent(state):
    # Review 邏輯
    review = review_code(state["code_result"])
    return {"review_result": review}

# 建立 Multi-Agent Workflow
workflow = StateGraph(MultiAgentState)
workflow.add_node("research", research_agent)
workflow.add_node("code", code_agent)
workflow.add_node("review", review_agent)

workflow.set_entry_point("research")
workflow.add_edge("research", "code")
workflow.add_edge("code", "review")

AutoGen (Microsoft)

Microsoft 的 AutoGen 專門為 Multi-Agent 設計:

from autogen import AssistantAgent, UserProxyAgent, GroupChat

# 創建多個 Agent
researcher = AssistantAgent(
    name="researcher",
    system_message="你是研究專家,負責搜尋和分析資料。"
)

coder = AssistantAgent(
    name="coder",
    system_message="你是程式開發專家,負責實作功能。"
)

reviewer = AssistantAgent(
    name="reviewer",
    system_message="你是 Code reviewer,負責檢查程式碼品質。"
)

# 建立對話群組
groupchat = GroupChat(
    agents=[researcher, coder, reviewer],
    messages=[],
    max_round=10
)

# 執行
manager = autogen.GroupChatManager(groupchat=groupchat)
manager.run("開發一個 TODO app")

適用場景

  • 軟體開發:需求分析 → 設計 → 實作 → 測試
  • 研究任務:文獻搜尋 → 閱讀 → 分析 → 撰寫
  • 複雜決策:多角度評估(法律、財務、技術)

核心洞察:Multi-Agent 適合「需要專業分工」的任務。單一 Agent 很難同時擁有所有領域的專業知識。


3.2 Graph / Workflow Agent

核心概念

原理:將 Agent 的執行流程定義為有向圖(Graph),支援條件分支、循環、並行

傳統 Agent 的執行流程是線性或樹狀的,但實際任務往往更複雜:

  • 需要條件分支(if-then-else)
  • 需要循環(重試機制)
  • 需要並行(同時執行多個任務)

Graph Agent 讓你能定義任意複雜的執行流程。

與傳統 Agent 的差異

  • 傳統:線性執行(A → B → C)
  • Graph Agent:任意拓撲(可以有循環、條件分支、並行)

LangGraph 深入

LangGraph 是 LangChain 推出的 workflow 框架,專門用來建立複雜的 Agent 系統。

核心元素

  1. State(狀態)

    • 共享狀態,所有節點都能讀寫
    • 類似程式的全域變數
  2. Node(節點)

    • 執行單元(可以是 Agent、Tool、Function)
    • 每個節點接收 state,執行邏輯,更新 state
  3. Edge(邊)

    • 節點之間的連接
    • 可以是固定邊(always go to next node)
    • 可以是條件邊(根據 state 決定下一個節點)

範例:動態決策流程

from langgraph.graph import StateGraph, END

class AgentState(TypedDict):
    query: str
    plan: List[str]
    current_step: int
    results: List[str]
    quality_score: float

def planning_node(state):
    """規劃步驟"""
    plan = generate_plan(state["query"])
    return {"plan": plan, "current_step": 0}

def execution_node(state):
    """執行當前步驟"""
    step = state["plan"][state["current_step"]]
    result = execute_step(step)
    return {
        "results": state["results"] + [result],
        "current_step": state["current_step"] + 1
    }

def evaluation_node(state):
    """評估結果品質"""
    quality = evaluate_results(state["results"])
    return {"quality_score": quality}

def should_continue(state):
    """條件分支:決定下一步"""
    if state["current_step"] >= len(state["plan"]):
        return "evaluate"
    return "execute"

def should_replan(state):
    """條件分支:品質不足時重新規劃"""
    if state["quality_score"] < 0.7:
        return "planning"  # 重新規劃
    return "finalize"

# 建立 Graph
workflow = StateGraph(AgentState)
workflow.add_node("planning", planning_node)
workflow.add_node("execute", execution_node)
workflow.add_node("evaluate", evaluation_node)
workflow.add_node("finalize", finalize_node)

workflow.set_entry_point("planning")
workflow.add_edge("planning", "execute")
workflow.add_conditional_edges("execute", should_continue)
workflow.add_conditional_edges("evaluate", should_replan)
workflow.add_edge("finalize", END)

# 執行
app = workflow.compile()
result = app.invoke({"query": "分析銷售數據"})

這個範例展示了:

  • 循環:execute 節點可以重複執行
  • 條件分支:根據品質決定是否重新規劃
  • 狀態管理:所有節點共享 state

優勢

  • 可視化:Workflow 一目了然
    • LangGraph 可以生成流程圖
  • 靈活:支援複雜的控制流程
    • if-then-else、循環、並行都能實現
  • 可測試:每個節點可獨立測試
    • 不用執行整個 workflow 就能測試單一節點
  • 可復用:節點可在不同 workflow 中復用
    • planning_node 可以用在多個專案

適用場景

  • 複雜的多步驟任務
  • 需要條件分支和循環
  • 需要人工審核點(Human-in-the-loop)
  • 需要可視化執行流程

核心洞察:LangGraph 是實作複雜 Agent 的最佳選擇。如果你的 Agent 需要複雜的控制流程,LangGraph 能讓你的程式碼更清晰、更易維護。


3.3 Memory System(記憶系統)

核心概念

為什麼需要 Memory?

想像一個沒有記憶的助理:

  • 你:「我想買 BTC」
  • 助理:「好的,已購買」
  • (5 分鐘後)
  • 你:「我剛才買了什麼?」
  • 助理:「我不記得了」

沒有記憶的 Agent 就像患了失憶症,無法提供持續的服務。

Memory 的價值

  • 記住之前的對話和決策
  • 避免重複犯錯
  • 學習用戶偏好
  • 長期任務的上下文管理

Memory 的層次

Level 1: Short-term Memory (工作記憶)

用途:記住當前對話的上下文

實作:Message History(最近 N 輪對話)

class ShortTermMemory:
    def __init__(self, max_length=10):
        self.messages = []
        self.max_length = max_length

    def add(self, message):
        self.messages.append(message)
        if len(self.messages) > self.max_length:
            self.messages.pop(0)  # 移除最舊的

    def get_context(self):
        return "\n".join(self.messages)

類似人類的工作記憶,只記住最近發生的事。

Level 2: Long-term Memory (長期記憶)

用途:跨會話的知識累積

實作:Vector Store + Retrieval

class LongTermMemory:
    def __init__(self, vectorstore):
        self.vectorstore = vectorstore

    def remember(self, experience):
        """儲存經驗到 vector store"""
        self.vectorstore.add_documents([{
            "content": experience,
            "timestamp": datetime.now()
        }])

    def recall(self, query, k=5):
        """檢索相關經驗"""
        return self.vectorstore.similarity_search(query, k=k)

類似 RAG,但不是檢索文件,而是檢索過去的經驗。

範例

# 儲存經驗
memory.remember("User prefers concise answers")
memory.remember("User is interested in Python")

# 檢索經驗
relevant_memories = memory.recall("How should I respond to this user?")
# 回傳:["User prefers concise answers", ...]

Level 3: Episodic Memory (情節記憶)

用途:記住完整的任務執行過程

實作:結構化儲存(Database)

class EpisodicMemory:
    def __init__(self, db):
        self.db = db

    def store_episode(self, task, actions, outcome):
        """儲存完整的執行記錄"""
        episode = {
            "task": task,
            "actions": actions,
            "outcome": outcome,
            "success": outcome.get("success", False),
            "timestamp": datetime.now()
        }
        self.db.insert(episode)

    def retrieve_similar_episodes(self, current_task):
        """找出類似任務的歷史執行記錄"""
        return self.db.query(similar_to=current_task)

範例

# 儲存執行記錄
memory.store_episode(
    task="Buy BTC",
    actions=["get_price", "check_balance", "buy"],
    outcome={"success": True, "price": 40000}
)

# 下次遇到類似任務
past_episodes = memory.retrieve_similar_episodes("Buy ETH")
# 可以參考過去的成功經驗

實作框架

LangChain Memory

from langchain.memory import ConversationBufferMemory, VectorStoreMemory

# Short-term
buffer_memory = ConversationBufferMemory()

# Long-term
vector_memory = VectorStoreMemory(
    vectorstore=vectorstore,
    memory_key="long_term_memory"
)

Mem0(專門的 Memory 管理)

from mem0 import Memory

memory = Memory()

# 儲存
memory.add("User prefers concise answers", user_id="user_123")
memory.add("User is working on a Python project", user_id="user_123")

# 檢索
relevant_memories = memory.search(
    "How should I help this user?",
    user_id="user_123"
)

適用場景

  • 需要記住用戶偏好的助理
  • 長期任務(跨多個會話)
  • 需要學習和改進的 Agent
  • 個人化服務

核心洞察:Memory 讓 Agent 從「無狀態的函式」變成「有記憶的助理」。這是打造真正有用的 Agent 的關鍵。


3.4 Dynamic Planning(動態規劃)

核心概念

與 Plan-and-Execute 的差異

  • Plan-and-Execute:規劃一次,依序執行(固定計畫)
  • Dynamic Planning:根據執行結果動態調整計畫(彈性計畫)

為什麼需要 Dynamic Planning?

實際任務往往充滿不確定性:

  • 初始計畫可能不完美
  • 執行過程中出現意外
  • 獲得新資訊後需要調整策略

範例

初始計畫:
1. 查詢 BTC 價格
2. 檢查餘額
3. 購買 1 BTC

執行 Step 2 後發現:餘額不足!

Dynamic Planning:
→ 重新規劃:
1. 查詢其他便宜的幣種
2. 購買能負擔的數量

固定計畫會失敗,動態計畫能調整。

實作策略

策略 1:Replanning(重新規劃)

定期檢查進度,必要時重新規劃:

def dynamic_planning_loop(goal):
    plan = initial_planning(goal)

    while not goal_achieved():
        # 執行當前計畫的一步
        result = execute_next_step(plan)

        # 評估結果
        if is_on_track(result):
            continue  # 計畫順利,繼續執行
        else:
            # 重新規劃
            plan = replan(
                goal=goal,
                executed_steps=executed_steps,
                current_situation=result
            )

    return final_result

策略 2:Hierarchical Planning(分層規劃)

高層計畫保持穩定,低層計畫動態調整:

# 高層計畫(穩定)
high_level_plan = ["Research", "Implement", "Test"]

for high_level_step in high_level_plan:
    # 每個高層步驟展開成詳細計畫(動態)
    detailed_plan = create_detailed_plan(high_level_step)

    for detail_step in detailed_plan:
        result = execute(detail_step)

        # 根據結果動態調整
        if need_adjustment(result):
            detailed_plan = adjust_plan(detailed_plan, result)

策略 3:Opportunistic Planning(機會主義規劃)

發現新機會時調整計畫:

def opportunistic_planning(goal):
    plan = initial_plan(goal)

    while executing:
        result = execute_step()

        # 發現新機會?
        opportunities = detect_opportunities(result)

        if opportunities:
            # 評估是否值得調整計畫
            if should_pursue(opportunities):
                plan = integrate_opportunities(plan, opportunities)

範例

原計畫:研究 RAG → 實作

執行中發現:有個很好的開源專案可以參考

機會主義規劃:
→ 調整計畫:研究 RAG → 研究開源專案 → 參考實作 → 實作

LangGraph 實作

def replanning_node(state):
    """根據執行結果重新規劃"""
    executed_steps = state["executed_steps"]
    current_situation = state["current_situation"]

    # 評估當前進度
    if is_plan_working(executed_steps, current_situation):
        return state  # 不需要重新規劃

    # 重新規劃
    new_plan = replan(
        goal=state["goal"],
        history=executed_steps,
        situation=current_situation
    )

    return {"plan": new_plan, "replanned": True}

workflow = StateGraph(AgentState)
workflow.add_node("plan", planning_node)
workflow.add_node("execute", execution_node)
workflow.add_node("replan", replanning_node)

# 條件分支:需要重新規劃時跳到 replan 節點
workflow.add_conditional_edges(
    "execute",
    lambda s: "replan" if need_replan(s) else "continue"
)

適用場景

  • 不確定性高的任務(探索性研究)
  • 長期任務(環境會變化)
  • 探索性任務(邊做邊學)
  • 需要應對意外的任務

核心洞察:Dynamic Planning 讓 Agent 能「邊做邊調整」。這是應對複雜現實世界的必備能力。


3.5 Guardrails(防護欄)

核心概念

為什麼需要 Guardrails?

Agent 的自主性是雙面刃:

  • ✅ 優點:能自主決策、靈活應對
  • ❌ 風險:可能產生有害輸出、調用危險工具、洩漏敏感資訊

實際風險

  • Agent 可能產生歧視性、暴力性內容
  • 可能調用不該調用的工具(如刪除資料庫)
  • 可能洩漏用戶的個人資訊
  • 可能進入無限循環浪費資源

Guardrails 是 Agent 的「安全帶」,確保它不會偏離軌道。

Guardrails 的層次

  1. Input Guardrails - 檢查輸入是否合法
  2. Output Guardrails - 檢查輸出是否安全
  3. Action Guardrails - 限制可執行的動作
  4. Resource Guardrails - 限制資源使用

實作策略

策略 1:Input Validation(輸入驗證)

阻擋惡意輸入:

def validate_input(user_input):
    # 檢查是否包含惡意內容
    if contains_injection_attempt(user_input):
        raise SecurityError("Potential injection detected")

    # 檢查是否符合格式
    if not is_valid_format(user_input):
        raise ValidationError("Invalid input format")

    # 移除危險字元
    return sanitize(user_input)

策略 2:Output Filtering(輸出過濾)

移除敏感資訊,檢查有害內容:

def filter_output(agent_output):
    # 移除個人資訊(PII)
    output = remove_pii(agent_output)

    # 檢查是否有害
    if is_harmful(output):
        return "I cannot provide that information."

    # 檢查是否包含敏感資訊
    if contains_sensitive_data(output):
        output = redact_sensitive_data(output)

    return output

策略 3:Action Whitelist(動作白名單)

限制 Agent 能執行的動作:

ALLOWED_ACTIONS = {
    "search": {
        "max_calls_per_session": 10
    },
    "read_file": {
        "allowed_paths": ["/data/public"]
    },
    "send_email": {
        "require_approval": True
    }
}

def check_action_allowed(action, params):
    if action not in ALLOWED_ACTIONS:
        raise PermissionError(f"Action '{action}' not allowed")

    rules = ALLOWED_ACTIONS[action]

    # 檢查調用次數限制
    if "max_calls_per_session" in rules:
        if get_call_count(action) >= rules["max_calls_per_session"]:
            raise RateLimitError("Too many calls")

    # 檢查路徑限制
    if "allowed_paths" in rules:
        if params["path"] not in rules["allowed_paths"]:
            raise PermissionError("Path not allowed")

    # 檢查是否需要人工批准
    if rules.get("require_approval"):
        if not has_approval(action, params):
            raise ApprovalRequiredError("Human approval required")

策略 4:Resource Limits(資源限制)

防止 Agent 消耗過多資源:

class ResourceGuardrails:
    def __init__(self):
        self.max_iterations = 20       # 最多 20 步
        self.max_tokens = 100000        # 最多 100K tokens
        self.max_time = 300             # 最多 5 分鐘

    def check_limits(self, state):
        if state["iterations"] >= self.max_iterations:
            raise LimitExceeded("Max iterations exceeded")

        if state["total_tokens"] >= self.max_tokens:
            raise LimitExceeded("Max tokens exceeded")

        if time.time() - state["start_time"] >= self.max_time:
            raise LimitExceeded("Max time exceeded")

實作框架

Guardrails AI

from guardrails import Guard
from guardrails.validators import ValidLength, ToxicLanguage

guard = Guard.from_string(
    validators=[
        ValidLength(min=10, max=500),      # 長度限制
        ToxicLanguage(threshold=0.8)       # 毒性檢測
    ]
)

# 驗證輸出
validated_output = guard.parse(agent_output)

NeMo Guardrails (NVIDIA)

from nemoguardrails import RailsConfig, LLMRails

config = RailsConfig.from_path("config")
rails = LLMRails(config)

# 自動套用 guardrails
response = rails.generate(messages=[{
    "role": "user",
    "content": "Tell me how to hack a system"
}])
# 輸出:"I cannot provide that information."

適用場景

  • 面向用戶的 Agent:避免有害輸出
  • 高風險操作:如金融交易、資料刪除
  • 企業環境:合規要求(GDPR、隱私保護)
  • Production 系統:穩定性和安全性

核心洞察:Guardrails 不是可選功能,而是 Production Agent 的必備。自主性越高,安全機制就越重要。


章節總結

Agent 系統的五大演進方向

  1. Multi-Agent - 從單打獨鬥到團隊協作

    • 專業分工,提升效率和品質
  2. Graph / Workflow - 從線性執行到複雜流程控制

    • 支援條件分支、循環、並行
  3. Memory System - 從無記憶到長期學習

    • 記住經驗,避免重複犯錯
  4. Dynamic Planning - 從固定計畫到動態調整

    • 應對不確定性,靈活調整策略
  5. Guardrails - 從無限制到安全可控

    • 確保 Agent 不會偏離軌道

實務建議

  • 從基礎架構開始(ReAct / Tool Calling)
  • 根據需求逐步加入進階功能
  • Multi-Agent 和 Guardrails 是 Production 的必備
  • LangGraph 是實作複雜 Agent 的最佳選擇

Chapter 4: 實務決策指南

4.1 架構選擇決策

決策矩陣:根據你的需求快速選擇架構

需求特徵推薦架構原因
簡單工具調用(1-2 個工具)Tool Calling快速、低成本、足夠用
動態任務(無法預測步驟)ReAct靈活應對變化
固定流程(步驟可預測)Plan-and-Execute效率高、成本省 50%
高品質要求(如程式碼生成)Reflexion迭代改進品質
需要專業分工Multi-Agent各司其職
複雜流程控制(條件、循環)LangGraph精細控制

升級路徑:從簡單開始,讓需求驅動演進

Tool Calling(驗證需求)
    ↓ 需要多步驟?
ReAct(靈活執行)
    ↓ 步驟可預測?
Plan-and-Execute(優化效率)
    ↓ 需要高品質?
Reflexion(迭代改進)

決策原則

  • 能用簡單的,就不要用複雜的
  • 從 Tool Calling 開始,根據瓶頸升級
  • 每個階段評估:用戶滿意度、成本、品質
  • 達標就停止升級

4.2 框架選擇:LangChain vs LangGraph

對比

維度LangChainLangGraph
學習曲線低(3-5 行程式碼)中(需理解 Graph 概念)
適用複雜度簡單到中等中等到複雜
狀態管理基本(對話歷史)精細(完整 State)
流程控制線性為主條件分支、循環、並行
可測試性高(節點可獨立測試)
Production適合簡單場景更穩定可靠

決策流程

Agent 是否很簡單(< 5 步驟)?
    ├─ 是 → LangChain
    └─ 否 ↓

是否需要條件分支或循環?
    ├─ 是 → LangGraph
    └─ 否 ↓

是否是 Production 環境?
    ├─ 是 → LangGraph
    └─ 否 → LangChain

推薦策略

  • POC 階段:LangChain(快速驗證)
  • Production 階段:LangGraph(穩定可靠)
  • 不確定? 先用 LangChain,需要時再遷移(成本不高)

4.3 Production Checklist

上線前必做

1. 監控與可觀測性

  • [ ] 記錄執行成功率、失敗原因
  • [ ] 追蹤 Latency、LLM 調用次數、Token 消耗
  • [ ] 啟用 Verbose Mode 或 Logging(開發環境)
  • [ ] 設定 Alert(成功率 < 80%、Latency > 10s)

2. 安全與 Guardrails

  • [ ] 輸入驗證(防止 prompt injection)
  • [ ] 輸出過濾(移除敏感資訊、有害內容)
  • [ ] 工具權限控制(白名單、調用次數限制)
  • [ ] 資源限制(max_iterations, max_tokens, timeout)

3. 錯誤處理

  • [ ] 設定 Retry 機制(LLM 調用失敗時)
  • [ ] 定義 Fallback 策略(Agent 無法完成時)
  • [ ] 優雅降級(複雜 Agent 失敗時回退到簡單模式)

4. 測試

  • [ ] 單元測試(每個節點 / 工具)
  • [ ] 整合測試(完整流程)
  • [ ] 邊界條件測試(意外輸入、工具失敗)
  • [ ] 成本測試(預估 Token 消耗是否可接受)

除錯技巧

  • 啟用 verbose=True 查看 Agent 的思考過程
  • 使用 LangGraph 的 visualize() 查看執行流程
  • 記錄每個關鍵步驟(Thought、Action、Observation)

4.4 成本優化的關鍵決策

成本對比(以 GPT-4 為例):

架構LLM 調用次數平均 Token每次任務成本
Tool Calling1-2 次500-1000~$0.015-0.03
Plan-and-Execute1 次2000~$0.06
ReAct (10 步驟)10 次10000~$0.30
Reflexion (3 輪)6-9 次15000+~$0.45+

三大優化決策

1. 架構選擇(影響最大:50-80%)

  • 優先級最高!選對架構比任何優化都重要
  • 能用 Tool Calling 就不要用 ReAct
  • 能用 Plan-and-Execute 就不要用 ReAct

2. Model 選擇(影響:10 倍差異)

  • 混合使用策略
    • 重要決策用 GPT-4(規劃、反思)
    • 簡單執行用 GPT-3.5(工具調用、文字生成)
  • 新模型考慮
    • Claude 3.5 Haiku(便宜且快)
    • GPT-4o-mini(平衡性價比)

3. Token 管理(影響:20-30%)

  • 精簡 System Prompt(移除冗長描述)
  • 截斷過長的 Observation(限制 500 字元)
  • 壓縮歷史對話(保留最近 10 輪)
  • Cache 重複查詢結果

優化優先級

1. 架構選擇(最重要)
2. Model 混合使用
3. Token 優化
4. 其他(並行、Streaming 等)

核心原則:先做影響最大的優化。架構選對了,能省 80% 成本;架構選錯了,再怎麼優化也是浪費。


全文總結

我們從頭到尾走過了 Agent 系統的完整知識體系:

核心概念

Agent = Reasoning + Tool Use + Memory + Decision Making

四大核心架構:

  1. Tool Calling - 一次搞定(最簡單)
  2. Plan-and-Execute - 先想好再做(最有效率)
  3. ReAct - 邊做邊想(最靈活)
  4. Reflexion - 做完檢討(最高品質)

五大演進趨勢:

  1. Multi-Agent - 專業分工
  2. Graph / Workflow - 複雜流程控制
  3. Memory System - 長期學習
  4. Dynamic Planning - 動態調整
  5. Guardrails - 安全可控

關鍵技術

架構選擇

  • 簡單任務 → Tool Calling
  • 明確任務 → Plan-and-Execute
  • 動態任務 → ReAct
  • 高品質任務 → Reflexion

框架選擇

  • POC → LangChain
  • Production → LangGraph

成本優化

  • 選對架構(節省 50-80%)
  • 混合使用 Model
  • Cache 重複結果

實務建議

升級路徑

Tool Calling(驗證需求)
    → ReAct(靈活執行)
    → Plan-and-Execute(優化效率)
    → Reflexion(提升品質)

核心原則

  1. 從簡單開始,讓實際需求驅動演進
  2. 選擇合適的架構比追求完美更重要
  3. Production 環境必須加入 Guardrails
  4. 無法衡量就無法優化

開始行動

  1. 從 Tool Calling 開始,驗證需求
  2. 根據任務特性選擇合適架構
  3. 加入監控與除錯機制
  4. 根據成本和效能持續優化

最重要的建議:不要一開始就追求完美架構。從簡單的 Tool Calling 開始,根據實際需求逐步演進。記住:能用的 Agent 比完美的設計更有價值。


參考資料

論文

框架文件

實戰教學