本文 AI 產出,尚未審核

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 能夠在真實世界中執行多步驟、具備記憶與工具互動的框架。它解決了以下三大痛點:

  1. 單一步驟的局限 – 透過 Chain、Agent 把任務拆解成可管理的子流程。
  2. 缺乏上下文記憶 – Memory 把對話或檢索結果自動注入 Prompt,讓模型保持「連貫」與「相關」。
  3. 無法直接操作外部系統 – Tool 把 API、資料庫、搜尋引擎等功能以統一介面暴露給模型,使得 LLM 能成為「智慧的指揮官」。

對於想要從 「把問題丟給 GPT」 走向 「讓 GPT 成為業務流程的一部分」 的開發者而言,掌握 LangChain 的核心概念與實作模式是必經之路。從本文的範例可以看出,僅需幾行程式碼就能構建 搜尋 → 摘要 → 回答 的完整工作流,並且透過記憶與工具的組合,讓系統在面對更複雜的需求時仍能保持可維護、可測試與可擴充。

下一步:建議先在本機環境使用 npm i langchain openai 撰寫簡單的 ConversationChain,熟悉 Memory 與 PromptTemplate;之後再逐步加入 Tool 與 Agent,挑戰更高階的自動化應用。祝開發順利,期待看到你用 LangChain 打造的精彩 AI 產品!