LangChain 深度教學

從核心組件到 RAG 完整實作,掌握 LangChain 生態系,建構生產級 LLM 應用。

LangChain 是什麼?

LangChain 是目前最主流的 LLM 應用開發框架,由 Harrison Chase 於 2022 年底創立並開源,在短短數月內成為 GitHub 上成長最快的專案之一。其核心設計哲學是:「將 LLM 呼叫與各類工具、資料來源像積木一樣組合串接(Composability)」。框架提供跨模型廠商的統一介面,讓開發者只需改動一行設定即可切換 OpenAI、Anthropic Claude、Google Gemini、Ollama 本地模型等不同後端,同時維持完全相同的應用程式碼與業務邏輯。

LangChain 生態系目前分為三個主要子套件:langchain-core(基礎抽象與 LCEL 語法)、langchain-community(第三方整合,如各種向量資料庫、文件載入器)、以及各廠商專屬套件(如 langchain-openai、langchain-anthropic)。另有 LangGraph 負責有狀態的多 Agent 工作流,LangSmith 負責監控與評估。

LangChain 的三大核心價值:① 標準化介面(一套 API 呼叫所有模型)② 豐富生態系(700+ 個整合套件)③ 快速原型開發(從 RAG 知識問答到多步驟 Agent,都能以一致的開發模式實現)。

五大核心組件詳解

理解這五個組件的職責與邊界,是掌握 LangChain 架構思維的關鍵。它們並非各自獨立,而是互相組合共同構成完整的 Agent 系統。

Chain(鏈)

Chain 是 LangChain 最基礎的抽象——將多個步驟(Prompt 模板 → LLM 呼叫 → 輸出解析器)串接成可重用、可測試的管線。舊版使用 LLMChain 類別,v0.1 後統一改用 LCEL(LangChain Expression Language),以 | 運算子表達串接關係,語法直觀且天然支援非同步、串流(streaming)與批次(batch)執行模式。Chain 的執行路徑是固定的、可預期的,適合流程明確的場景。

Agent(代理)

Agent 讓 LLM 從「執行固定腳本」進化為「自主決策行動者」。Agent 透過 ReAct(Reason + Act) 循環反覆推理:先思考(Thought)需要做什麼,再行動(Action)呼叫工具,然後觀察(Observation)結果,直到判斷任務完成才輸出最終答案。與 Chain 的固定流程不同,Agent 的執行路徑由 LLM 在執行期間動態決定,因此更靈活但也更難預測。

Memory(記憶)

Memory 組件管理對話歷史,讓 Agent 能記住跨輪次的上下文,實現真正的多輪對話體驗。LangChain 提供多種記憶策略:BufferMemory 保留完整對話歷史;SummaryMemory 自動將舊對話壓縮為摘要以節省 Token;ConversationTokenBufferMemory 依 Token 數量截斷;VectorStoreRetrieverMemory 將使用者偏好存入向量庫,下次以語意相似度檢索相關記憶。選擇策略時需在「保真度」與「Token 成本」之間取得平衡。

Tool(工具)

Tool 是 Agent 與外部世界互動的橋樑,可代表搜尋引擎、資料庫查詢、計算機、程式碼執行環境、REST API 呼叫等任何外部功能。用 @tool 裝飾器定義工具時,函數的 docstring 會成為 LLM 決定「何時呼叫此工具」的唯一依據,因此清晰的描述至關重要。工具設計需考慮冪等性、錯誤處理與結構化輸出,才能讓 Agent 可靠地執行。

Retriever(檢索器)

Retriever 是 RAG 架構的核心元件,負責從向量資料庫或其他資料來源中找出與問題最相關的文件片段,再注入 Prompt 作為 LLM 的參考資料。LangChain 支援多種檢索策略:相似度搜尋(純向量距離)、MMR(Maximal Marginal Relevance)(兼顧相關性與多樣性,避免重複內容)、SelfQueryRetriever(LLM 自動將自然語言查詢轉換為結構化過濾條件)、以及 Ensemble Retriever(混合關鍵字與向量搜尋,提升召回率)。

LCEL 語法範例

LCEL(LangChain Expression Language)是 LangChain v0.1+ 的核心語法,以函數式管線風格取代舊式類別繼承方式。所有 LCEL 元件都實作同一組介面(invokebatchstreamainvoke),可無縫組合。

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
from langchain_core.runnables import RunnableParallel

# --- 基本 Chain:Prompt | LLM | Parser ---
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一個專業的技術翻譯師,請將以下英文翻譯成繁體中文。"),
    ("human", "{text}")
])

chain = prompt | llm | StrOutputParser()

# 單次呼叫
result = chain.invoke({"text": "AI Agents are autonomous programs."})
print(result)  # "AI Agent 是自主運作的程式。"

# 串流輸出(逐 token 印出,提升使用者體驗)
for chunk in chain.stream({"text": "Retrieval-Augmented Generation"}):
    print(chunk, end="", flush=True)

# 批次執行(並行呼叫,效率比 for 迴圈高約 3-5 倍)
results = chain.batch([
    {"text": "Machine learning"},
    {"text": "Neural network"},
    {"text": "Reinforcement learning"}
])

# 非同步執行
import asyncio
async def run():
    result = await chain.ainvoke({"text": "Deep learning"})
    return result

# --- 並行執行兩條 Chain(同時呼叫)---
parallel = RunnableParallel(
    translation=chain,
    summary=(ChatPromptTemplate.from_template("請用一句話摘要:{text}") | llm | StrOutputParser())
)
out = parallel.invoke({"text": "Large language models are transformer-based neural networks."})
print(out["translation"])
print(out["summary"])

# --- ConversationChain:帶記憶的對話 ---
from langchain.memory import ConversationSummaryBufferMemory
from langchain.chains import ConversationChain

memory = ConversationSummaryBufferMemory(
    llm=ChatOpenAI(model="gpt-4o-mini"),
    max_token_limit=2000,  # 超過 2000 token 自動摘要
    return_messages=True
)
conv_chain = ConversationChain(
    llm=ChatOpenAI(model="gpt-4o-mini"),
    memory=memory,
    verbose=False
)
conv_chain.predict(input="我是一名後端工程師,想學 AI Agent 開發。")
resp = conv_chain.predict(input="根據我的背景,該從哪個框架入手?")
print(resp)
常用 Chain 類型一覽:ConversationChain(帶記憶的多輪對話)、RetrievalQA(RAG 問答,從向量庫檢索後回答)、LLMChain(基本 Prompt + LLM,舊式但仍廣泛使用)、SequentialChain(多步驟串行,前一步的輸出作為下一步的輸入)、RouterChain(根據輸入內容動態路由到不同子 Chain)、TransformChain(純函數轉換,不呼叫 LLM)。

RAG 完整實作範例

RAG(Retrieval-Augmented Generation,檢索增強生成)讓 LLM 能夠存取外部知識庫,解決兩大痛點:知識截止日期(LLM 訓練資料有時效限制)與私有資料問題(企業內部文件無法直接給 LLM 使用)。標準 RAG 流程分為建索引(Indexing)與查詢(Querying)兩個階段,通常離線執行建索引,線上即時執行查詢。

RAG 核心流程:① 載入文件② 切分段落(Chunking)③ 生成 Embedding④ 儲存向量庫⑤ 查詢時檢索 Top-K 段落⑥ 注入 Prompt⑦ LLM 生成有來源依據的答案
from langchain_community.document_loaders import WebBaseLoader, PyPDFLoader, DirectoryLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import FAISS
from langchain.chains import RetrievalQA
from langchain_core.prompts import ChatPromptTemplate

# ===== 階段一:建立向量索引(離線執行)=====

# 1. 載入文件(支援 Web、PDF、Markdown、CSV、Notion、Google Drive 等)
loader = PyPDFLoader("./company_knowledge_base.pdf")
docs = loader.load()

# 2. 切分段落(chunk_overlap 確保語意不被截斷於段落邊界)
splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,           # 每段最多 1000 字元
    chunk_overlap=200,         # 前後重疊 200 字元,保留跨段語意
    separators=["\n\n", "\n", "。", ",", " "]  # 優先在段落/句子邊界切分
)
chunks = splitter.split_documents(docs)
print(f"共切分為 {len(chunks)} 個段落")

# 3. 生成 Embedding 並存入向量資料庫
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = FAISS.from_documents(chunks, embeddings)
vectorstore.save_local("./faiss_index")   # 持久化儲存,避免重複建索引

# ===== 階段二:RAG 查詢(線上即時執行)=====

# 4. 載入已建好的索引
vectorstore = FAISS.load_local(
    "./faiss_index", embeddings,
    allow_dangerous_deserialization=True
)

# 5. 建立 Retriever(MMR 策略:兼顧相關性與多樣性,避免重複段落)
retriever = vectorstore.as_retriever(
    search_type="mmr",
    search_kwargs={"k": 4, "fetch_k": 20, "lambda_mult": 0.7}
)

# 6. 自訂 RAG Prompt(明確指示 LLM 只依據參考資料回答,不自行捏造)
rag_prompt = ChatPromptTemplate.from_messages([
    ("system", """你是一個專業的企業知識庫助理。請根據以下參考資料回答使用者問題。
回答時務必:
- 只使用參考資料中的資訊,不要加入訓練資料中的外部知識
- 如果資料中找不到答案,明確回答「根據現有資料無法回答此問題」
- 引用具體的資料來源(例如:「根據第 3 頁的說明…」)

參考資料:
{context}"""),
    ("human", "{question}")
])

# 7. 建立 RetrievalQA Chain(return_source_documents=True 可追溯來源)
rag_chain = RetrievalQA.from_chain_type(
    llm=ChatOpenAI(model="gpt-4o-mini", temperature=0),
    retriever=retriever,
    chain_type_kwargs={"prompt": rag_prompt},
    return_source_documents=True
)

# 8. 查詢並顯示答案與來源
result = rag_chain.invoke({"query": "公司的退款政策是什麼?"})
print("答案:", result["result"])
print("\n參考來源:")
for doc in result["source_documents"]:
    src = doc.metadata.get("source", "未知")
    page = doc.metadata.get("page", "?")
    print(f"  - {src}(第 {page} 頁):{doc.page_content[:80]}…")

LangSmith 監控介紹

LangSmith 是 LangChain 官方提供的可觀測性(Observability)與評估平台。對於 LLM 應用而言,傳統的程式除錯工具無法有效處理「輸入輸出都是自然語言」的非確定性問題,LangSmith 正是為此而生。它能追蹤每一次 LLM 呼叫與工具呼叫的完整 trace:輸入 Prompt、模型輸出、每步 Token 消耗、延遲時間、錯誤訊息,並以視覺化時間軸呈現整個 Agent 的執行過程,讓除錯從「猜測」變為「精確定位」。

import os

# 設定 LangSmith 環境變數(只需這幾行,其餘程式碼完全不用修改)
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "ls__your_api_key_here"
os.environ["LANGCHAIN_PROJECT"] = "my-rag-project"   # 專案名稱,用於分組管理

# 之後所有 Chain / Agent 的呼叫都會自動記錄到 LangSmith Dashboard
# 前往 https://smith.langchain.com 即可查看完整執行 trace

# --- 手動建立 Run(為特定邏輯加上追蹤標記)---
from langsmith import traceable

@traceable(name="custom-rag-pipeline", tags=["production", "v2"])
def run_rag_query(question: str) -> str:
    result = rag_chain.invoke({"query": question})
    return result["result"]

answer = run_rag_query("LangChain 支援哪些向量資料庫?")
LangSmith 四大核心功能:① Trace 追蹤(完整呼叫鏈視覺化,精確顯示每個步驟的輸入輸出)、② Dataset 管理(建立標準評估資料集,支援版本控制)、③ Evaluation(自動化 RAG 品質評分,包含忠實度、相關性、完整性等指標)、④ Playground(在 UI 上直接修改 Prompt 並即時對比效果,無需重新部署)。開發期間建議全程開啟 tracing,生產環境可設定 sampling rate(例如只追蹤 10% 的請求)以控制費用。

與 AutoGen、CrewAI 的框架比較

三大主流 AI Agent 框架各有設計哲學與適用場景,選擇前需先釐清自身需求:

面向 LangChain AutoGen CrewAI
設計哲學 元件組合(積木式) 多 Agent 對話協作 角色扮演(Role-based)
核心優勢 生態最豐富(700+ 整合)、RAG 最完整 程式碼自動生成與執行驗證閉環 設定簡單、角色分工直覺
學習曲線 中等(LCEL 需適應) 中等 低(yaml 設定即可)
Multi-agent 需搭配 LangGraph 原生支援,GroupChat 模式 原生支援,Crew 定義角色
最適場景 RAG 知識問答、Tool-use Agent 自動化程式碼生成與測試 模擬研究員/撰稿人/審閱者團隊
可觀測性 LangSmith(官方,最易整合) 需自行整合 需自行整合
選擇建議:RAG 知識問答與 Tool-use Agent 首選 LangChain;程式碼自動生成與自動化驗證首選 AutoGen;模擬角色分工工作流首選 CrewAI。三者並非互斥——例如可用 CrewAI 定義 Agent 角色與工作流骨架,底層 Tool 呼叫仍使用 LangChain 的 RAG Chain;或以 AutoGen 管理多 Agent 協作,每個 Agent 內部使用 LangChain 工具。
學完 LangChain 後,建議前往 AutoGen 教學 深入學習多 Agent 協作模式,再閱讀 進階應用 了解生產環境部署的注意事項。