LangChain vs LlamaIndex:选错框架让我多写了 2000 行代码
我犯过一个代价很高的错误——选错了 LLM 框架。
当时我们团队要做一个 RAG(检索增强生成)项目,我图省事选了 LangChain。结果三个月后发现,为了绕开 LangChain 的各种坑,我多写了将近 2000 行的胶水代码。
这不是 LangChain 的错,是我选错了场景。
一句话总结
- **LangChain**:瑞士军刀,什么都能做,但什么都不精。适合需要编排多个 LLM 调用的复杂工作流。
- **LlamaIndex**:专业 RAG 工具箱,索引、检索、合成一条龙。适合需要高质量文档问答的场景。
场景对比
场景 1:企业文档问答
这是 LlamaIndex 的主场。
# LlamaIndex - 10 行代码搞定
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
documents = SimpleDirectoryReader("./docs").load_data()
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()
response = query_engine.query("公司的年假政策是什么?")
print(response)# LangChain - 同样的事,代码量翻倍
from langchain.document_loaders import DirectoryLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.chains import RetrievalQA
loader = DirectoryLoader("./docs", glob="**/*.txt")
documents = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
texts = text_splitter.split_documents(documents)
embeddings = OpenAIEmbeddings()
db = Chroma.from_documents(texts, embeddings)
qa = RetrievalQA.from_chain_type(
llm=ChatOpenAI(),
chain_type="stuff",
retriever=db.as_retriever()
)
response = qa.run("公司的年假政策是什么?")场景 2:复杂 Agent 工作流
这是 LangChain 的优势区。
# LangChain - Agent 编排天然支持
from langchain.agents import create_openai_functions_agent
from langchain.tools import Tool
tools = [
Tool(name="Search", func=search_tool, description="搜索互联网"),
Tool(name="Calculator", func=calc_tool, description="数学计算"),
Tool(name="Database", func=db_tool, description="查询数据库"),
]
agent = create_openai_functions_agent(llm, tools, prompt)
result = agent.invoke({
"input": "查询上季度销售额最高的产品,然后计算同比增长率"
})LlamaIndex 也能做 Agent,但不如 LangChain 灵活。
为什么我从 LangChain 换到 LlamaIndex
问题 1:过度抽象
LangChain 的抽象层次太多。你只是想改一下 prompt,结果要从 Chain → LLMChain → BaseChain 一路找下去:
# LangChain 的 prompt 定义方式
from langchain.prompts import ChatPromptTemplate, SystemMessagePromptTemplate
template = """You are a helpful assistant.
Context: {context}
Question: {question}
Answer:"""
prompt = ChatPromptTemplate.from_messages([
SystemMessagePromptTemplate.from_template(template)
])
# LlamaIndex 的 prompt 定义方式 - 直接明了
from llama_index.core.prompts import PromptTemplate
template = PromptTemplate(
"You are a helpful assistant.\n"
"Context: {context_str}\n"
"Question: {query_str}\n"
"Answer:"
)问题 2:文档混乱
LangChain 的文档...怎么说呢,有时候你按照文档写,跑不通;去 GitHub 看源码,发现 API 已经变了。
# 文档里的写法
from langchain import OpenAI
llm = OpenAI(temperature=0)
# 实际能跑通的写法
from langchain_openai import OpenAI
llm = OpenAI(temperature=0)问题 3:调试地狱
LangChain 默认把所有东西都藏起来,出了问题你根本不知道是哪一层的事。
# 打开 verbose 模式
from langchain.globals import set_verbose
set_verbose(True)
# 还不够,还要设置回调
from langchain.callbacks import StdOutCallbackHandler
chain.run(input, callbacks=[StdOutCallbackHandler()])我的选择建议
| 场景 | 推荐框架 | 原因 |
|------|---------|------|
| 文档问答 / RAG | LlamaIndex | 专为此场景设计,开箱即用 |
| 多步骤 Agent | LangChain | Agent 编排能力强 |
| 简单 LLM 调用 | 直接用 SDK | 别引入框架,徒增复杂度 |
| 数据管道 + LLM | LlamaIndex | IngestionPipeline 很实用 |
| 原型验证 | LlamaIndex | 代码少,迭代快 |
| 生产系统 | 看情况 | 大规模部署两者都要深度定制 |
我的教训
用框架前先问自己三个问题:
1. 我的核心需求是什么?(RAG → LlamaIndex,Agent → LangChain)
2. 我能不能用原生 SDK 解决?(能的话就别上框架)
3. 这个框架的文档质量如何?(文档差的框架是技术债)
答案清楚了再选,别学我。
读者评论 4