定位
LangChain 和 LlamaIndex 都是 LLM 應用框架,但定位不同:
| LangChain | LlamaIndex | |
|---|---|---|
| 核心 | 通用 LLM 編排 | 數據索引與檢索 |
| 強項 | Agent、Chain、Tool | RAG、Data Connector |
| 生態 | 極大(100+ integrations) | 中等(專注數據) |
| 學習曲線 | 較陡 | 較平緩 |
LangChain
from langchain.chat_models import ChatOpenAI
from langchain.agents import initialize_agent, Tool
llm = ChatOpenAI(model="deepseek-chat", base_url="https://api.deepseek.com/v1")
tools = [
Tool(name="Search", func=search_func, description="搜索互聯網"),
]
agent = initialize_agent(tools, llm, agent="zero-shot-react-description")
agent.run("2026 年奧斯卡最佳影片是什麼?")
適合:需要 Agent、Chain、Tool 的複雜應用。
LlamaIndex
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
docs = SimpleDirectoryReader("data/").load_data()
index = VectorStoreIndex.from_documents(docs)
engine = index.as_query_engine()
response = engine.query("公司的 Q1 收入是多少?")
適合:RAG、文檔問答、數據索引。
如何選擇
| 你的需求 | 推薦 |
|---|---|
| RAG / 文檔問答 | LlamaIndex |
| Agent / Tool 調用 | LangChain |
| 兩者都要 | 兩者可以一起用 |
| 快速原型 | LlamaIndex |
| 生產級應用 | LangChain (生態更大) |
核心抽象對照
從抽象層看,兩者關注的中心不同:LangChain 以「流程編排」為中心,把模型、提示、工具串成一條可組合的執行鏈;LlamaIndex 以「資料流」為中心,把資料從載入、切分、索引、檢索到合成答案走成一條完整管線。理解這一點,選型時就不容易只被 API 名稱或範例長度誤導。
| 關注點 | LangChain | LlamaIndex |
|---|---|---|
| 流程單元 | Chain、Runnable | Query Engine |
| 提示與輸出 | Prompt Template、Output Parser | Prompt Template、Response Synthesizer |
| 檢索 | Retriever 介面 | Retriever、Node Parser |
| 資料建模 | Document | Document、Node |
| 狀態與記憶 | Memory | Chat Engine、Memory |
| 組合方式 | 以鏈式組合為主 | 以管線與索引為中心 |
實務上的差異在於「預設值」:LlamaIndex 對資料切分、節點關係與檢索合成提供了較多現成配置,開箱即用;LangChain 則把更多選擇權交給使用者,彈性大但需要自己決定每個環節。這也解釋了為什麼快速原型通常覺得 LlamaIndex 順手,而需要自訂流程與多工具協作時會偏好 LangChain。
混用的黏合點:LlamaIndex 的 retriever 或 query engine 可以被包成 LangChain 的工具或 retriever,讓前者專責檢索品質,後者專責對話流程與工具調度。混用不是問題,但要把「誰負責檢索、誰負責編排」講清楚,否則除錯時會兩邊找不出原因。
RAG 實作要點與取捨
即使選定 LlamaIndex 做 RAG,品質關鍵仍在幾個可調參數上。以下是可以立即動手調整的環節。
切分策略:固定長度切分實作簡單、行為可預期,但容易把一段完整語意切斷;語意或段落切分能保留上下文,代價是流程較複雜且長度不均。多數情況先從固定長度加上適度重疊(overlap)開始,再觀察檢索結果是否常出現「答案被切在邊界」的情況。
中繼資料:把來源、章節、時間、權限等放進 node metadata,能在檢索時過濾,這是提升準確度最便宜的一步。少了中繼資料,檢索只能靠語意相似度硬碰,很容易撈到過期或無權限的內容。
檢索策略:純向量檢索擅長語意相近但關鍵字不同的查詢;關鍵字檢索(如 BM25)擅長精確名詞與編號。混合檢索再把結果融合,通常比單一方式穩定。若撈回的文件偏多,可加上重排序(rerank)取前幾筆,把最相關的送進模型。
取捨清單
| 選擇 | 好處 | 代價 |
|---|---|---|
| 切分越細 | 命中精準 | 上下文碎片化、召回下降 |
| 切分越粗 | 上下文完整 | 噪聲增加、成本上升 |
| top-k 越大 | 召回較高 | 延遲與成本上升、干擾增加 |
| 加入 rerank | 精確度提升 | 多一次模型呼叫 |
| 混合檢索 | 覆蓋面更廣 | 實作與調參更複雜 |
回覆合成:拿到檢索結果後,要決定如何組成提示。可以只丟最相關的節點,也可以做摘要後再合成。前者還原度高、可追溯,後者省 token 但可能丟失細節。若答案需要引用來源,建議保留節點原文並要求模型標註出處。
選型與實作檢查清單
選型
- 需求是否以資料問答為主?若是,優先評估 LlamaIndex。
- 是否需要多工具協作、複雜分支或人機互動流程?若是,優先評估 LangChain。
- 是否需要兩者兼顧?考慮以 LlamaIndex 管檢索、LangChain 管編排。
- 團隊熟悉哪一套抽象?學習曲線會直接影響交付速度。
- 是否需要長期維護與升級?確認社群活躍度與文件更新頻率。
實作
- 已決定切分策略與重疊長度,並記錄理由。
- 已為文件加上可過濾的中繼資料(來源、時間、權限)。
- 已選擇檢索方式(向量、關鍵字或混合)並設定 top-k。
- 已評估是否需要重排序。
- 已確認答案可追溯到具體來源節點。
常見錯誤
- 只比較範例程式碼的長短,忽略抽象模型與長期維護成本。
- 把「生態大」等同於「一定適合」,卻沒檢查關鍵整合是否真的可用。
- 切分長度沿用預設值就上線,沒有針對自己的文件型態調整。
- 檢索結果不帶中繼資料,導致撈到過期或越權內容。
- top-k 設得過大,把噪聲一起塞進提示,反而降低答案品質。
- 檢索與生成階段混在一起除錯,分不清是撈錯還是寫錯。
- 混用兩套框架時沒有劃清職責,出問題時兩邊都找不出根因。
驗證方式
選型與實作都需要可量測的驗證,而不是憑感覺。
離線評估:準備一組問答對,每題標註正確來源文件。分別量測檢索是否命中正確來源,以及生成答案是否正確。檢索與生成分開量測,才能定位問題在撈資料還是寫答案。
A/B 對照:固定其他條件,只改一個變數(例如切分長度或 top-k),比較命中率與答案品質,確認改動真的帶來改善。
回歸測試:把調整過程中發現的失敗案例存成測試集,每次改動後重跑,避免修好一個問題又弄壞另一個。
人工複核:抽樣檢查高風險或高頻問題,確認答案有出處且沒有越權內容。
效能觀察:記錄檢索與生成的延遲、每次查詢的 token 用量與成本,確認在可接受範圍,再考慮進一步調優。