在前一篇文章中,我們已經學會如何用 LangGraph 建立基本的 AI Agent 流程。今天,我們要更進一步,介紹一個經典的 Agent 設計模式:ReAct(Reasoning + Acting)。
ReAct 模式的核心概念是結合「推理」與「行動」,讓模型不僅能回答問題,還能在需要時選擇合適的工具來完成任務。這種設計使得 AI Agent 具備更高的靈活性與解題能力。
ReAct(Reasoning + Acting) 模式最早由 Google Research 在論文 ReAct: Synergizing Reasoning and Acting in Language Models 中提出,目的是讓大型語言模型(LLM)同時具備 推理(Reasoning) 與 行動(Acting) 能力。
它的核心運作流程可以拆解為以下循環:
這樣的設計使得 ReAct 將 Chain-of-Thought(CoT) 與 工具調用(Tool Use) 結合在一起,不再只是單向的「輸入 Prompt → 輸出答案」,而是形成一個動態的「推理—行動—觀察—再推理」循環。這讓 LLM 能更有條理地處理複雜任務,並在需要時引入外部能力,透過實際操作與驗證逐步推進,最終獲得更準確、可解釋的結果。
舉例來說,假設使用者詢問:「台北今天適合跑步嗎?」ReAct 模式的過程可能如下:
這個流程展現了 ReAct 的精髓:模型並不是一次性輸出結論,而是透過推理與工具調用的交互循環,逐步累積資訊,最終形成可靠的答案。
在 ReAct 概念落地之前,傳統的 LLM 應用中,模型通常採取「單次輸入 Prompt → 輸出答案」的方式運作。這種模式雖然簡單,但也存在一些限制:
ReAct 模式的循環設計,則帶來了以下幾個關鍵優勢:
換句話說,ReAct 是讓 Agent 從「純對話機器人」進化為「能思考、能行動的智慧助手」的關鍵設計。
面向 | 傳統 LLM | ReAct 模式 |
---|---|---|
工作方式 | 一次性輸入 Prompt,直接產生最終回覆 | 在推理(Thought)與行動(Action)間循環,逐步收斂答案 |
資訊來源 | 完全依賴模型的內部知識 | 可結合外部工具與檢索結果 |
推理透明度 | 模型內部隱性推理,開發者難以追蹤 | 每一步都有可觀察的「思考」與「行動」輸出 |
適用任務 | 簡單問答、生成文本 | 複雜任務、多步推理、需要外部資料或工具輔助 |
優勢 | 快速、直接 | 更準確、可解釋、能處理更廣泛的情境 |
ReAct 的核心精神是「推理與行動交替進行」,而 LangGraph 恰好非常適合用來實作這種迴圈式流程。要在 LangGraph 中落地 ReAct 模式,我們可以把「推理」與「行動」拆分成不同的 節點(Node),並透過 狀態(State) 與 邊(Edge) 的設計,讓 Agent 在兩者之間反覆循環,直到產生最終答案。
在這個設計中,通常會包含三個核心元件:
在 LangGraph 中,ReAct 的運作可以想成是一個「推理 → 行動 → 觀察 → 再推理」的循環:
這個過程可以用下圖表示:
透過這樣的節點設計,LangGraph 能夠完整支援 ReAct 模式,讓 Agent 不再只是一次性回覆,而是能像人類一樣透過「推理—行動—觀察—再推理」的循環,不斷修正與補充資訊,最終得出更合理、精確且可解釋的答案。
接下來我們用一個最小可行的案例示範 ReAct 模式:「查詢天氣,並根據結果建議今天是否適合出門運動。」這個範例會結合 OpenAI 模型 與 Tavily Search 工具,展示 LLM 如何一邊思考、一邊透過工具取得資訊,再回過頭做出合理的建議。
首先,我們使用官方工具 create-langgraph
來建立一個全新的專案:
create-langgraph react-agent
當工具詢問模板類型時,選擇 New LangGraph Project 即可。這個模板會自動幫你建立一個包含 src/agent
目錄的專案骨架。
接著進入專案資料夾並安裝相依套件:
cd react-agent
yarn install
初始化專案後,接著安裝以下套件:
yarn add @langchain/openai @langchain/tavily
這裡我們會用到兩個主要套件:
@langchain/openai
:LangChain 官方的 OpenAI 模型整合套件,用於提供推理能力(Reasoning)。@langchain/tavily
:LangChain 官方支援的工具封裝,用來呼叫 Tavily Search API,這裡把它當作查詢天氣的資訊來源。在專案根目錄建立 .env
檔案,填入必要的 API 金鑰:
LANGSMITH_KEY=llsv2...
OPENAI_API_KEY=sk-...
TAVILY_API_KEY=tvly-dev-...
LANGSMITH_KEY
:啟用 LangSmith 觀察功能(可選,但建議填入,方便後續在 Studio UI 追蹤流程)。OPENAI_API_KEY
:OpenAI 模型的金鑰。TAVILY_API_KEY
:Tavily 搜尋工具的金鑰。專案的 src/agent
目錄下已經有兩個檔案:
state.ts
:定義狀態結構,預設已經包含訊息處理,我們直接沿用即可。graph.ts
:主要的流程定義檔,我們會在這裡實作 ReAct Agent。開啟 src/agent/graph.ts
,加入以下程式碼:
// src/agent/graph.ts
import { StateGraph, START, END } from '@langchain/langgraph';
import { ToolNode } from '@langchain/langgraph/prebuilt';
import { AIMessage } from '@langchain/core/messages';
import { ChatOpenAI } from '@langchain/openai';
import { TavilySearch } from '@langchain/tavily';
import { StateAnnotation } from './state.js';
// 建立可用的工具 (Act)
const tools = [new TavilySearch({ maxResults: 3 })];
const toolNode = new ToolNode(tools);
// 建立 LLM 並綁定工具 (Reason)
const model = new ChatOpenAI({
model: 'gpt-4o-mini',
temperature: 0,
}).bindTools(tools);
// 判斷是否要繼續迴圈
function shouldContinue({ messages }: typeof StateAnnotation.State) {
const lastMessage = messages[messages.length - 1] as AIMessage;
if (lastMessage.tool_calls?.length) {
return 'tools'; // 如果 LLM 決定要呼叫工具
}
return END; // 否則結束,輸出最終答案
}
// LLM 推理節點
async function callModel(state: typeof StateAnnotation.State) {
const response = await model.invoke(state.messages);
return { messages: [response] };
}
// 建立 ReAct Agent 流程
const builder = new StateGraph(StateAnnotation)
.addNode('agent', callModel) // Reasoning
.addEdge(START, 'agent')
.addNode('tools', toolNode) // Acting
.addEdge('tools', 'agent') // Observation 回傳給 LLM
.addConditionalEdges('agent', shouldContinue);
export const graph = builder.compile();
graph.name = 'ReAct Agent';
這裡最重要的部分是 addConditionalEdges
,它會根據 LLM 是否提出工具調用(tool_calls
)來決定流程走向:
tools
節點,執行外部動作,並將結果傳回 LLM。END
,輸出最終答案。完成程式碼後,可以啟動 LangGraph Server,並透過 LangGraph Studio 觀察流程:
npx @langchain/langgraph-cli dev
啟動後,終端機會顯示本地伺服器 URL,例如:
http://127.0.0.1:2024
將它帶入 Studio UI 的網址:
https://smith.langchain.com/studio/?baseUrl=http://127.0.0.1:2024
在 Studio UI 的 Chat 分頁輸入問題,例如:
台北今天適合跑步嗎?
你會看到流程圖清楚呈現:
今天台北的天氣大致晴朗,氣溫在33℃左右,降雨機率很低(約5%)。這樣的天氣條件很適合跑步,但建議注意防曬和保持水分。如果你打算在戶外運動,記得穿著輕便的運動服裝,並在早晨或傍晚的時候進行,以避免高溫。
這樣,我們就完成了一個最小可行的 ReAct Agent 範例。它雖然只是查詢天氣,但已經完整展現了 ReAct 的核心精神:先思考,再行動,根據結果再思考,直到完成任務。
createReactAgent
快速建立 ReAct Agent如果你希望快速上手,不必手動設計所有節點與邊,LangGraph 提供了高階封裝函式 createReactAgent
,能自動幫你建立一個符合 ReAct 模式的 Agent。
這個函式會將 LLM 節點 與 Tool 節點 的互動邏輯封裝起來,你只需要:
以下是一個最小化範例:
import { ChatOpenAI } from '@langchain/openai';
import { TavilySearch } from '@langchain/tavily';
import { HumanMessage } from '@langchain/core/messages';
import { createReactAgent } from '@langchain/langgraph/prebuilt';
const tools = [new TavilySearch({ maxResults: 3 })];
const model = new ChatOpenAI({
model: 'gpt-4o-mini',
temperature: 0,
});
const graph = createReactAgent({
llm: model,
tools,
});
const finalState = await graph.invoke({
messages: [new HumanMessage('台北今天適合跑步嗎?')],
});
console.log(finalState.messages[finalState.messages.length - 1].content);
在這個範例中,createReactAgent
自動幫我們處理了 ReAct 模式的整個迴圈:
TavilySearch
工具,獲取查詢結果。這種高階封裝大幅降低了 ReAct Agent 的實作門檻,非常適合快速原型開發或不需要高度客製化的場景。如果未來需要更精細的流程控制,仍然可以回到前一節的做法,利用 StateGraph
手動定義節點與邊,打造更靈活的 ReAct 流程。
今天我們學會如何在 LangGraph 中實作經典的 ReAct 模式,讓 Agent 能透過「思考—行動—觀察—再思考」的循環,逐步完成複雜任務。
createReactAgent
高階封裝,能快速建立 ReAct Agent,適合原型開發或簡單應用場景。ReAct 模式的出現,讓 AI 不再只是單向的「回答者」,而能像人類一樣邊思考邊行動,成為更靈活、可靠的智慧助手。