Python LangChain vs LlamaIndex 的2026选型

1次阅读

langchain 的 runnable 是通用计算流接口,llamaindex 的 queryengine 是专为文档问答封装的黑盒;前者需手动构建链,后者依赖 vectorstoreindex 预置流程。

Python LangChain vs LlamaIndex 的2026选型

LangChain 的 Runnable 和 LlamaIndex 的 QueryEngine 本质不是同类抽象

langchainRunnable 是通用计算流接口,能串任何函数、LLM 调用、工具或异步操作;LlamaIndex 的 QueryEngine 是专为“文档问答”封装的黑盒,输入 query,输出 response,内部固定走 retrieval → synthesis 流程。硬比“谁更好用”容易误判——你真需要的是 pipeline 可控性,还是开箱即用的 RAG 效果?

常见错误现象:ValueError: Cannot run QueryEngine without nodesRunnableSequenceTypeError: Object is not callable,往往是因为混淆了这两者的职责边界:前者要你亲手搭链,后者要你先喂够 VectorStoreIndex

  • 如果你在做多跳推理、混合调用外部 API + LLM + 数据库Runnable 更直觉,但得自己 handle 错误传播和中间态缓存
  • 如果你只做企业文档问答,且数据结构稳定(PDF/Markdown/notion 导出),QueryEngineSubQuestionQueryEngineHybridQueryEngine 开箱就比手写 Runnable 链快 2–3 天
  • QueryEngine 默认不暴露 retrieval 结果,想 debug 检索质量?得手动传 callback_manager 或 patch retrieve() 方法;Runnable 则天然支持每步 invoke(..., config={"callbacks": [...]})

LlamaIndex 的 VectorStoreIndexembedding 模型更敏感

LangChain 的 Chromafaiss vectorstore 接收的是预计算好的向量,embedding 模型换不换,不影响已有索引;但 LlamaIndex 的 VectorStoreIndex 在构建时会直接绑定 embedding model 实例,一旦 model 变(比如从 text-embedding-3-small 换成 gte-Qwen2),旧索引必须重建,否则检索结果完全失效。

使用场景:你正在迭代 embedding 模型,又不想每次重跑全量文档处理流水线?LangChain 的向量存储解耦更友好;LlamaIndex 则要求你在 ServiceContext 里显式冻结 embed_model,且不能跨版本混用 .json 索引文件。

立即学习Python免费学习笔记(深入)”;

  • 性能影响:LlamaIndex 默认用 hnswlib,10 万 chunk 下查询延迟比 LangChain+FAISS 低 15–20%,但内存占用高约 1.8 倍
  • 兼容性坑:VectorStoreIndex.from_vector_store(...) 看似能复用外部向量库,实际仍会尝试调用原 embed_modelget_text_embedding_batch,导致 schema 不匹配报错
  • 小技巧:用 SimpleDirectoryReader 加载时设 filename_as_id=True,后续查不到结果时至少能快速定位是 embedding 还是分块问题

LangChain 的 AgentExecutor 和 LlamaIndex 的 ReActAgent 都依赖 prompt 工程,但失败信号完全不同

AgentExecutor 卡住时通常抛 OutputParserException 或无限循环Thought: ... Action: ... Observation: ...ReActAgent 则静默返回空 response 或 fallback 到 default_response,连 error log 都不打——因为它的 output_parser 是硬编码在 ReActOutputParser 里的,没做异常透出。

参数差异:LangChain 允许你替换 agent_executoroutput_parser 为自定义类,也能关掉 handle_parsing_errors 强制 crash;LlamaIndex 的 ReActAgent 只能通过 max_iterationsverbose=True 看中间 step,想改解析逻辑?得继承 ReActAgentWorker 重写 _get_response

  • 调试建议:对 AgentExecutor,加 callbacks=[ConsoleCallbackHandler()];对 ReActAgent,必须设 callback_manager=CallbackManager([LlamaDebugHandler()]) 才能看到 tool call 输入输出
  • 容易踩的坑:两者都默认用 gpt-4-turbo 级 prompt template,但若换成本地 Qwen2-7B,LangChain 可以直接换 prompt 参数,LlamaIndex 得重写整个 ReActPrompt 并注册进 BasePromptTemplate

2026 年真实项目里,90% 的“选型纠结”其实来自数据管道而非框架本身

LangChain 的 DocumentLoader 和 LlamaIndex 的 BaseReader 都支持 PDF 解析,但 PyMuPDFReader(LlamaIndex)默认保留表格结构,PyPDFLoader(LangChain)默认丢弃;你如果靠 ocr 后的 PDF 做合同比对,这个差异会让召回率差 40% 以上。

真正卡住进度的,从来不是 QueryEngine 还是 Runnable,而是:unstructured 版本升级后 partition_pdf 返回字段名从 "text" 变成 "element_text",而你的 NodeParser 还在按老字段切分;或是 Chroma 升级到 v0.5 后 Collection.get() 不再返回 metadatas 字段,LangChain 的 RetrievalQA 直接崩。

所以别花三天对比 API 设计哲学。先跑通一条最小路径:PDF → 分块 → embed → 存 → 检索 → 问答。哪一步断了,就盯死那层——是 loader 输出不对,还是 embedding batch size 超限,还是 vectorstore 的 metadata Filter 语法写错了。框架只是胶水,胶水粘不住漏气的管道。

text=ZqhQzanResources