LangChain 基礎概念 – LangChain 解決的問題
簡介
在 2023 年之後,大型語言模型(LLM)已經從研究實驗室走入產業實務,開發者可以直接呼叫 OpenAI、Claude、Gemini 等模型取得自然語言回應。然而,僅僅「呼叫」模型往往只能解決 單一 的文字生成任務,無法應付 複雜的工作流程、多步驟推理 或 與外部系統的互動。
LangChain 正是為了彌補這個缺口而誕生的框架。它把 LLM 視為「思考的引擎」,提供 串接(Chain)、記憶(Memory)、工具(Tool)、代理(Agent) 等概念,讓開發者能以程式化的方式構建「可組合、可重用、可追蹤」的 AI 應用。
本篇文章將說明 LangChain 想解決的核心問題、相關概念與實作範例,並提供常見陷阱、最佳實踐與實務應用場景,幫助初學者快速上手,進一步打造中等複雜度的 LLM 應用。
核心概念
1. 為什麼需要「Chain」?
LLM 本身是一個 stateless 的文字生成器,對於「先問問題、再根據答案執行資料庫查詢、最後把結果整理成報告」這類多步驟流程,需要外部程式自行管理狀態與流程。LangChain 把這些步驟抽象成 Chain,每個 Chain 都是一個 函式,輸入 → 處理 → 輸出,且可以相互嵌套、串接。
核心優點:
- 可視化 流程(每一步都有清晰的輸入/輸出)
- 可測試(單元測試每個 Chain)
- 可重用(相同的查詢 Chain 可在不同專案中直接引用)
2. Memory(記憶)
在對話型應用中,LLM 需要「看得見」先前的對話內容,否則每次回應都會忘記上下文。LangChain 提供 Memory 抽象,讓開發者把歷史訊息自動加入 prompt。常見的記憶類型包括:
| 記憶類型 | 說明 |
|---|---|
ConversationBufferMemory |
把所有對話紀錄以文字串接,適合簡單聊天 |
ConversationSummaryMemory |
以 LLM 自動產生摘要,降低 token 數 |
VectorStoreRetrieverMemory |
使用向量資料庫檢索相關記憶,適合大量長文 |
3. Tool(工具)
LLM 本身不具備執行外部程式的能力。LangChain 允許開發者把 API、資料庫、檔案系統、搜尋引擎 等封裝成 Tool,然後在 Prompt 中告訴模型「如果需要資訊,請呼叫 search_tool」的指令。模型在推理時會根據指令自動呼叫對應的 Tool,形成 Tool‑augmented generation。
4. Agent(代理)
當任務不僅是單一的 Chain,而是需要 動態決策(例如:先搜尋、再計算、最後產出報告),LangChain 提供 Agent 來扮演「決策者」的角色。Agent 會根據 LLM 給出的指令(如 Action: search_tool, Input: "台北天氣")自動呼叫相應的 Tool,並把結果回饋給模型,形成迴圈。
5. PromptTemplate(提示模板)
為了避免每次手寫長篇 Prompt,LangChain 使用 PromptTemplate 讓變數化的提示可以重複使用。例如:
template = """以下是一段對話:
{history}
User: {question}
Assistant:"""
在 JavaScript 中同理:
import { PromptTemplate } from "langchain/prompts";
const template = new PromptTemplate({
inputVariables: ["history", "question"],
template: `以下是一段對話:
{history}
User: {question}
Assistant:`,
});
程式碼範例
以下範例全部採用 JavaScript (Node.js),使用 LangChain 官方套件 langchain(v0.1+)。
1️⃣ 基礎 Chain:把問題交給 OpenAI 並回傳答案
// 1. 安裝套件
// npm install langchain openai
import { OpenAI } from "langchain/llms/openai";
import { LLMChain } from "langchain/chains";
const llm = new OpenAI({ temperature: 0.7, modelName: "gpt-3.5-turbo" });
const prompt = `請用簡短的中文回答以下問題:
{question}`;
const chain = new LLMChain({
llm,
prompt,
});
async function ask(question) {
const res = await chain.run({ question });
console.log("答案:", res);
}
ask("什麼是 LangChain?");
說明:
LLMChain只負責「把變數插入 Prompt → 呼叫 LLM → 回傳文字」的單一步驟。temperature控制回應的隨機度,0.0 為最確定。
2️⃣ 加入 Memory:保留對話歷史
import { ConversationBufferMemory } from "langchain/memory";
import { ChatOpenAI } from "langchain/chat_models/openai";
import { ConversationChain } from "langchain/chains";
const memory = new ConversationBufferMemory({ memoryKey: "history" });
const chat = new ConversationChain({
llm: new ChatOpenAI({ temperature: 0.5 }),
memory,
});
async function chatDemo() {
console.log(await chat.call({ input: "嗨,你好!" }));
console.log(await chat.call({ input: "請說明 LangChain 的概念。" }));
// 第三次提問會自動帶入前兩次的對話
console.log(await chat.call({ input: "它解決了什麼問題?" }));
}
chatDemo();
說明:
ConversationChain內建把memory的內容插入 Prompt,讓模型能「看到」先前的對話。memoryKey決定在 Prompt 中使用的變數名稱(預設history)。
3️⃣ 使用 Tool:結合搜尋 API
import { SerpAPI } from "langchain/tools";
import { initializeAgentExecutorWithOptions } from "langchain/agents";
const searchTool = new SerpAPI(process.env.SERPAPI_API_KEY, {
location: "Taiwan",
hl: "zh-TW",
});
const tools = [searchTool];
const executor = await initializeAgentExecutorWithOptions(tools, {
llm: new OpenAI({ temperature: 0 }),
agentType: "zero-shot-react-description", // 讓模型自行決策使用哪個 tool
});
const result = await executor.invoke({
input: "請告訴我今天台北的天氣如何?",
});
console.log(result.output);
說明:
SerpAPI會把搜尋結果以 JSON 回傳,Agent 會把結果整理後再交給 LLM。zero-shot-react-description讓模型在沒有事先訓練的情況下,根據工具描述自行決策。
4️⃣ 多步驟 Chain:先搜尋、再摘要、最後回覆
import { LLMChain } from "langchain/chains";
import { PromptTemplate } from "langchain/prompts";
import { OpenAI } from "langchain/llms/openai";
// 1) 搜尋 Chain
const searchPrompt = new PromptTemplate({
inputVariables: ["question"],
template: `使用以下搜尋 API 取得資訊,僅回傳原始 JSON 結果:
{question}`,
});
const searchChain = new LLMChain({
llm: new OpenAI({ temperature: 0 }),
prompt: searchPrompt,
});
// 2) 摘要 Chain
const summaryPrompt = new PromptTemplate({
inputVariables: ["searchResult"],
template: `請將以下搜尋結果整理成 3 條要點,使用中文:
{searchResult}`,
});
const summaryChain = new LLMChain({
llm: new OpenAI({ temperature: 0.3 }),
prompt: summaryPrompt,
});
// 3) 最終回覆 Chain
const finalPrompt = new PromptTemplate({
inputVariables: ["summary", "question"],
template: `根據以下要點,回答使用者的問題:
要點:
{summary}
問題:{question}
回答:`,
});
const finalChain = new LLMChain({
llm: new OpenAI({ temperature: 0.6 }),
prompt: finalPrompt,
});
// 組合成一個流程
async function answerWithSearch(question) {
const searchRes = await searchChain.run({ question });
const summary = await summaryChain.run({ searchResult: searchRes });
const answer = await finalChain.run({ summary, question });
console.log("最終答案:", answer);
}
answerWithSearch("2024 年台灣的 AI 產業發展趨勢是什麼?");
說明:
- 這裡把 三個 LLMChain 串成流水線,每一步的輸出自動成為下一步的輸入。
- 透過 PromptTemplate 保持 Prompt 的可讀性與可維護性。
5️⃣ 使用 VectorStore 作為長期記憶
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
import { MemoryVectorStore } from "langchain/vectorstores/memory";
import { RetrievalQAChain } from "langchain/chains";
const embeddings = new OpenAIEmbeddings();
const vectorStore = await MemoryVectorStore.fromTexts(
[
"LangChain 是一個用於建構 LLM 應用的框架。",
"向量資料庫可以讓模型在大量文件中快速檢索相關段落。",
"Memory 可以把檢索結果自動加進 Prompt。",
],
[],
embeddings,
);
const retriever = vectorStore.asRetriever();
const qaChain = RetrievalQAChain.fromLLM(
new OpenAI({ temperature: 0 }),
retriever,
);
const answer = await qaChain.run("什麼是 LangChain?");
console.log("檢索式回答:", answer);
說明:
MemoryVectorStore為簡易的記憶向量庫,適合測試或小型專案。RetrievalQAChain會先根據問題檢索相似段落,再把段落內容注入 LLM 產生答案,解決「資訊過於龐大」的問題。
常見陷阱與最佳實踐
| 陷阱 | 說明 | 最佳做法 |
|---|---|---|
| Token 超限 | 把整段對話或大量檢索結果直接塞入 Prompt,會迅速耗盡模型的 token 配額。 | 使用 摘要記憶(ConversationSummaryMemory)或 向量檢索,只帶入關鍵資訊。 |
| Tool 呼叫失敗 | 工具返回錯誤或延遲,導致 Agent 卡住。 | 為每個 Tool 包裝 重試機制(ex. retry)與 超時設定,並在 Prompt 中加入「若工具失敗請直接說明」的指示。 |
| Prompt 過度依賴硬編碼 | 直接在程式碼中寫長文字,難以維護。 | 使用 PromptTemplate 或外部 YAML/JSON 檔案管理 Prompt,保持程式與文字分離。 |
| 缺乏測試 | Chain 複雜時,錯誤難以追蹤。 | 為每個 Chain 撰寫 單元測試(mock LLM 回傳),確保輸入/輸出符合預期。 |
| 記憶泄漏 | 長時間聊天時,Memory 會無限制累積,佔用記憶體。 | 定期 截斷(例如只保留最近 10 條)或使用 向量摘要 取代純文字緩衝。 |
| 模型回應不符合指令 | LLM 有時會忽略「只使用工具」的指示。 | 在 Prompt 中加入 嚴格的格式說明(如 Action:、Action Input:),並在 Agent 設定 maxIterations 防止無限循環。 |
實際應用場景
| 場景 | LangChain 如何提供價值 |
|---|---|
| 客服聊天機器人 | 使用 ConversationBufferMemory 保存對話,結合 Tool(如訂單查詢 API)即時回覆客戶。 |
| 內部知識庫檢索 | 把公司文件放入向量資料庫,透過 RetrievalQAChain 讓員工以自然語言提問。 |
| 自動化報表產生 | 先用 searchTool 抓取最新財報,接著使用 LLMChain 撰寫摘要,最後寄送 Email。 |
| 程式碼輔助生成 | 結合 CodeExecutionTool(如 Docker)讓 LLM 產生、測試、修正程式碼,形成 ReAct 迴圈。 |
| 行銷文案創作 | 使用 PromptTemplate 結合產品資訊,結合 ConversationSummaryMemory 產出多版本文案,同時保持風格一致。 |
| 教育與教學平台 | 透過 Agent 結合數學計算工具、圖表產生器,提供即時解題步驟與視覺化圖形。 |
總結
LangChain 並不是「另一個 LLM」的包裝,而是一套 讓 LLM 能夠在真實世界中執行多步驟、具備記憶與工具互動的框架。它解決了以下三大痛點:
- 單一步驟的局限 – 透過 Chain、Agent 把任務拆解成可管理的子流程。
- 缺乏上下文記憶 – Memory 把對話或檢索結果自動注入 Prompt,讓模型保持「連貫」與「相關」。
- 無法直接操作外部系統 – Tool 把 API、資料庫、搜尋引擎等功能以統一介面暴露給模型,使得 LLM 能成為「智慧的指揮官」。
對於想要從 「把問題丟給 GPT」 走向 「讓 GPT 成為業務流程的一部分」 的開發者而言,掌握 LangChain 的核心概念與實作模式是必經之路。從本文的範例可以看出,僅需幾行程式碼就能構建 搜尋 → 摘要 → 回答 的完整工作流,並且透過記憶與工具的組合,讓系統在面對更複雜的需求時仍能保持可維護、可測試與可擴充。
下一步:建議先在本機環境使用
npm i langchain openai撰寫簡單的 ConversationChain,熟悉 Memory 與 PromptTemplate;之後再逐步加入 Tool 與 Agent,挑戰更高階的自動化應用。祝開發順利,期待看到你用 LangChain 打造的精彩 AI 產品!