ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

RAG框架选型指南:LangChain、LlamaIndex与Haystack实战对比

RAG框架选型指南:LangChain、LlamaIndex与Haystack实战对比

最近技术交流群里有个老问题又吵起来了:"新项目要做RAG,到底选 LangChain、LlamaIndex 还是 Haystack?"三派群友各有立场,谁也说服不了谁。说实话,这个选择题我三年前就做过一次,当时参考的是 GitHub Star 数、教程数量和直觉,结果在项目中途被迫换过一次底层库,代价不小。后来在几个真实项目里把三家都用了一遍,才慢慢想明白:选 RAG 框架,本质不是选"谁最流行",而是选"谁的心智模型跟你团队最合拍"。

这里先给一个基本盘判断:进入 2026 年,RAG 并没有死。虽然长上下文模型一度让"检索增强"听起来像伪需求,但只要你的场景需要"引用可追溯的答案""在私有文档里找到事实依据"或者"把几十万份文档的处理成本控制在可接受范围",RAG 依然是最高性价比的解法。而说到 RAG 框架,市面上 90% 的讨论都集中在三家里——LangChain 以编排见长,LlamaIndex 以数据为中心,Haystack 以生产化为核心。下面我不会做实验室测评,而是从实际落地视角拆解它们的定位差异、真实代码量、生产化成熟度以及 2026 年的生态格局,最后给出可以直接用的选型建议。

1. 三个框架的定位差别:它们不是同一道菜的三种做法

1.1 LangChain:先有 Chain,后有 RAG

LangChain 的起点是"把大模型能力串成链"。它的最初设计目标并不是检索,而是让开发者可以用"链"和后来的 LCEL 表达式把提示词、模型调用、工具执行、记忆这些环节编排起来。RAG 只是它支持的众多模式之一,甚至可以说是因为用户需求推动,它才把检索组件越做越全。

这个出身决定了 LangChain 的长板和短板。长板是:当你需要的不只是问答,而是多步骤 Agent、动态路由、多工具调度时,LangChain(以及官方主推的 LangGraph)是三者中抽象最完整、资料最多的。短板则是:它离"开箱即用"最远,概念物件多——Runnable、Retriever、Chain、Agent、Tool……你要先理解它的运行模式,才能流畅使用。早期接口频繁变更是出了名的,虽然近几年已经大幅收敛,但网上大量老教程仍然会误导新人。

1.2 LlamaIndex:数据进、答案出,检索玩法最细

LlamaIndex 最早叫 GPT Index,从名字就能看出来,它的初心是"给大模型一个索引"。它把 RAG 这件事拆得非常细:数据连接器、节点解析器、各类索引(向量索引、属性图索引、关键词索引等)、查询引擎、语义路由等。官方文档里一直称自己是"数据框架"而非"应用框架",这个定位区分非常关键。

如果你要做的是知识库问答、私有文档分析、PDF 这类非结构化数据抽取,LlamaIndex 几乎总是最快的起点。尤其是它的文档解析服务,在处理表格、复杂排版时能省掉大量前置清洗工作。它的短板在 Agent 泛化能力和端到端应用层:虽然现在也推出了 Agent 模块和 Workflow,但相比 LangChain 的 Agent 生态还是偏薄;同时查询引擎的"开箱即用"也会掩盖一部分对检索细节的控制难度,遇到问题时需要往下钻一层。

1.3 Haystack:从一开始就站在生产一侧

Haystack 出自做语义搜索起家的团队,早期版本就是为"企业级搜索 + 问答"设计的。它最鲜明的特征是组件化流水线:一切概念都被收拢成"组件 + Pipeline",每个组件有明确的输入输出 schema,组件之间用 connect 显式接线。这种设计在调试和生产部署时体验很好,因为流程可视化程度高,出错时你能直接定位是哪个环节挂了。

它的劣势也能从定位里找到:生态规模明显小于前两家,社区里能搜到的教程、开源插件要少一截。同时,它对"高度自由的 Agent 编排"支持相对保守——AgentPipeline 是有的,但与 LangGraph 那种把状态机玩出花的编排方式相比,灵活度还是有差距。整体上它是三者中最"正经"的工程框架,适合那些希望 RAG 部分稳定可控、不追求炫技的场景。

1.4 三家定位速览

维度LangChainLlamaIndexHaystack
核心心智LLM 应用编排数据加载与索引可部署流水线
最擅长Agent、工具调用、复杂工作流多源文档接入、细粒度检索稳定、可观测、易上生产
RAG 专重度中等偏上最深上等
上手速度慢,概念多快,高级用法需深入中,思路直观
生产配套LangSmith、LangGraph官方云服务、可自建内置 tracing、官方云端
社区体量最大大中小但活跃

这三家不是"同一道菜的三种做法",而是"三个不同侧重点的厨房",后面所有的对比都建立在这个差异之上。

2. RAG 链路逐环节实测:文档处理、检索策略与索引设计的真实差距

2.1 文档加载与解析:数据源接得多,不代表接得好

做 RAG 第一步永远是"把数据弄进来"。这个环节三家差距很明显。

LangChain 的 Document Loader 数量很多,覆盖网页、PDF、数据库、云盘、各类 SaaS 工具,基本你能想到的源它都有对应 Loader。但实际用过会发现,这些 Loader 的集成质量参差不齐,很多只是包了一层 API 或简单的文件读取,面对复杂 PDF(表格、多栏、扫描件)时需要自行串联 OCR 和版面分析组件。

LlamaIndex 的连接器数量更大,并且它把"文档解析"作为核心能力持续投入。例如专门的文档解析服务能把 PDF、Word、PPT 里的表格结构、阅读顺序尽量还原成干净的文本或 Markdown,这在真实项目里省下的时间非常可观。到了 2026 年,各家都在卷多模态解析,但 LlamaIndex 在这块起步更早、默认配置更完善。

Haystack 的转换器(Converters)覆盖面比前两家窄,但胜在稳定清晰。它默认支持文本、PDF、HTML、Docx 等常见格式,底层用的是成熟解析库,输出结构规范。如果你需要处理高度异构的扫描件或复杂版面,Haystack 通常建议你外挂专门的解析服务,然后把解析结果以文本形式喂进来。

2.2 文本切分与节点化:三家对"切"的哲学不一样

切分是 RAG 召回质量的隐形杀手。同样的文档,切分策略不同,问答效果可能天差地别。

LangChain 默认的 RecursiveCharacterTextSplitter 很实用,它按层级分隔符递归切分,能保证块与块之间的大致语义连贯。但 LangChain 对"切"的态度比较工具化——它把 splitter 当成一个预处理函数,切完后进入向量库就完事了。

LlamaIndex 强调的是"Node"概念,切分只是从 Document 到 Node 的一组转换之一。它还提供按句切分、按语义相似度切分等更精细的节点化方式。这种精细度在你需要"按句检索、按段生成"或做引用溯源时很有价值。在 LlamaIndex 的文档结构里,元数据、节点间关系都是节点自带的一等公民,这对于做结构化知识库很关键。

Haystack 的 Splitter 较为基础,但胜在组合简单。它的理念是"切分只做切分",你把 Splitter 接到 Pipeline 里,前后依赖一目了然。相对地,高级切分策略(如语义切分、基于版面分析的切分)你需要自己封装成自定义组件。

2.3 索引与向量存储:适配广度与控制力的权衡

关于向量存储,三家的策略也完全不同:

  • LangChain 对向量数据库的适配最广,主流方案都有官方集成。它采取"统一接口 + 各自实现"的方式,切换向量库通常改动很小。但问题也在于统一接口过于简化,部分数据库独有的检索参数会被隐藏。
  • LlamaIndex 同样适配主流向量库,并且对索引类型有更细的概念分层:向量索引只是其中一种,你还可以用属性图索引做知识图谱 RAG,用摘要索引做摘要式检索,用关键词索引做关键词过滤。这种"按场景选索引"的思维是 LlamaIndex 最大的差异化优势。
  • Haystack 的做法是把向量存储封装成统一的 DocumentStore 接口,各类存储都实现同一套 API,检索组件直接对接 store。接口收敛度最高,可替换性最强,但如果你要使用某个向量库的专属高级能力(比如某些混合检索的特定实现),需要确认对应集成是否支持。

2.4 检索阶段:召回、重排与图 RAG 的完整度

2026 年的 RAG 早就不再是"embedding 相似度 top-k 然后扔给 LLM"那么简单。混合检索(BM25 + 向量)、重排、查询改写、多路召回几乎成了标配;知识图谱 RAG 也是这两年的热门方向。这一点上三家的支持程度差别很大:

检索玩法LangChainLlamaIndexHaystack
基础向量检索支持支持且控制细支持
混合检索依 store 而定支持较好有组件,需选对 store
重排 Rerank可接第三方内置或接第三方有 Rerank 组件
查询改写/路由通过 Agent/Chain路由查询引擎、子问题引擎需要自定义组件
图 RAG社区集成属性图索引相对完善基本靠自定义

这段表格背后有个实际教训:同样的数据,用"混合检索 + 轻量重排"通常就能比单纯 top-k 提升不少效果(具体取决于语料和问题分布)。所以如果你刚起步,与其纠结框架选谁,不如先把混合检索和重排这条链路跑起来。选框架时重点看它对这两件事的支持是内置还是需要你绕路。

3. 同一个问答机器人,三家代码量差多少

理论说再多不如看代码。我用一个非常标准的 RAG 任务来对比:读一个本地文档,向量化保存,用户提问时检索相关片段并生成带上下文的回答。三份代码都按"常规用法"来写。

3.1 LangChain 版本

from langchain_community.document_loaders import TextLoader from langchain_text_splitters import RecursiveCharacterTextSplitter from langchain_openai import OpenAIEmbeddings, ChatOpenAI from langchain_chroma import Chroma from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough from langchain_core.output_parsers import StrOutputParser # 1. 加载与切分 loader = TextLoader("docs/manual.txt") documents = loader.load() splitter = RecursiveCharacterTextSplitter(chunk_size=800, chunk_overlap=80) chunks = splitter.split_documents(documents) # 2. 向量化入库 vectorstore = Chroma.from_documents(chunks, OpenAIEmbeddings()) # 3. 构造检索 retriever = vectorstore.as_retriever(search_kwargs={"k": 4}) # 4. 组装 LCEL 链 llm = ChatOpenAI(model="gpt-4o-mini") prompt = ChatPromptTemplate.from_template(""" 请根据下面的资料回答问题,如果资料没有相关内容,请直接说不知道。 资料: {context} 问题:{question} """) def format_docs(docs): return "\n\n".join(doc.page_content for doc in docs) chain = ( {"context": retriever | format_docs, "question": RunnablePassthrough()} | prompt | llm | StrOutputParser() ) print(chain.invoke("如何配置网络?"))

LangChain 的写法体现的是"链式组装":检索器、提示词、模型、输出解析器都是可组合的组件,中间还可以插路由、条件分支。代价是概念和导入路径较多,刚接触时容易在 import 这一步就晕掉。

3.2 LlamaIndex 版本

from llama_index.core import VectorStoreIndex, SimpleDirectoryReader from llama_index.core.node_parser import SentenceSplitter from llama_index.llms.openai import OpenAI # 1. 加载目录下所有文档 documents = SimpleDirectoryReader("docs").load_data() # 2. 构建索引时可指定转换器(切分策略) splitter = SentenceSplitter(chunk_size=800, chunk_overlap=80) # 3. 直接建索引 index = VectorStoreIndex.from_documents( documents, transformations=[splitter], ) # 4. 构造查询引擎 query_engine = index.as_query_engine( similarity_top_k=4, llm=OpenAI(model="gpt-4o-mini"), ) # 5. 直接提问 response = query_engine.query("如何配置网络?") print(response.response)

LlamaIndex 这个版本突出一个"少即是多":一行读完目录,一行完成切分、向量化入库,一行搞定检索 + 提示词 + 生成。默认的提示词模板写得不错,响应对象还自带来源节点可以做引用溯源。但如果你要换掉它的默认提示词、默认检索逻辑,就得往下钻一层,这一层的学习资料没有 LangChain 那么多。

3.3 Haystack 版本

from haystack import Pipeline from haystack.components.converters import TextFileToDocument from haystack.components.preprocessors import DocumentSplitter from haystack.components.embedders import ( SentenceTransformersDocumentEmbedder, SentenceTransformersTextEmbedder, ) from haystack.components.retrievers import InMemoryEmbeddingRetriever from haystack.components.builders import PromptBuilder from haystack.components.generators import OpenAIGenerator from haystack.document_stores.in_memory import InMemoryDocumentStore # 1. 索引流水线 document_store = InMemoryDocumentStore() doc_embedder = SentenceTransformersDocumentEmbedder( model="sentence-transformers/all-MiniLM-L6-v2" ) indexing = Pipeline() indexing.add_component("converter", TextFileToDocument()) indexing.add_component("splitter", DocumentSplitter(split_length=800, split_overlap=80)) indexing.add_component("doc_embedder", doc_embedder) indexing.add_component("store", document_store) indexing.connect("converter.documents", "splitter.documents") indexing.connect("splitter.documents", "doc_embedder.documents") indexing.connect("doc_embedder.documents", "store.documents") indexing.run({"converter": {"sources": ["docs/manual.txt"]}}) # 2. 查询流水线 query_embedder = SentenceTransformersTextEmbedder( model="sentence-transformers/all-MiniLM-L6-v2" ) retriever = InMemoryEmbeddingRetriever(document_store=document_store, top_k=4) prompt_builder = PromptBuilder(template=""" 请根据下面的资料回答问题,如果资料没有相关内容,请直接说不知道。 资料: {% for doc in documents %} {{ doc.content }} {% endfor %} 问题:{{ query }} """) generator = OpenAIGenerator(model="gpt-4o-mini") rag = Pipeline() rag.add_component("query_embedder", query_embedder) rag.add_component("retriever", retriever) rag.add_component("prompt_builder", prompt_builder) rag.add_component("generator", generator) rag.connect("query_embedder.embedding", "retriever.query_embedding") rag.connect("retriever.documents", "prompt_builder.documents") rag.connect("prompt_builder.prompt", "generator.prompt") result = rag.run({ "query_embedder": {"text": "如何配置网络?"}, "prompt_builder": {"query": "如何配置网络?"}, }) print(result["generator"]["replies"][0])

Haystack 最大的特点在这两份 Pipeline 里表现得淋漓尽致:每个环节的名字、连接关系都写在明面上。索引和查询是完全分开的两条流水线,你可以在中间插入日志、保存检查点、甚至单独测试某个组件。代价是代码量明显更大、Pipeline 概念需要理解。

3.4 代码量背后的自由度取舍

三份代码的差异本质是"默认路径"和"显式控制"的取舍。LangChain 用 LCEL 给了你最多的组合自由度,但自由要付出理解成本;LlamaIndex 用默认配置换来了最快出活速度,深度定制却要求你熟悉它内部的概念体系;Haystack 把控制权放在流水线层面,舍弃了一些"魔法"也换来了极高的可读性和可维护性。

提示:上面的代码是基于 2025 年的主流 API 写法。RAG 框架的接口变动很常见,直接照跑之前一定要去核对对应版本的迁移文档。

另外大家常问的"框架跑得慢不慢"——在真实场景里,三个框架的纯调度开销相对于 embedding 计算、向量库检索和 LLM 生成来说都是微乎其微的。真正影响性能的是你的检索策略、文档切分、向量库选型和模型选择,别在这上面花太多心力。

4. 生产化:可观测性、评估和部署,2026 年选型的真正分水岭

4.1 可观测性:出了问题你能否快速定位

RAG 系统的调试特别烦人:最终回答错了,你很难判断是检索没召回、提示词没写对、还是模型理解偏了。这时候"谁家能让你快速看清中间过程"就成了关键。

LangChain 官方配套的 trace 工具记录非常完整,从 LLM 调用到检索结果都有,还能做数据集、评估和在线监控。但它的完整功能偏云端服务,如果公司在意数据不出内网,你要评估自部署版本的可用性。

LlamaIndex 本身不带全功能观测平台,但社区和第三方工具链很丰富,可以接入多家开源观测平台追踪它的检索节点和生成过程。它也提供简单的调试开关,能打印每步检索到的来源节点。对于独自调试够用,对于团队级可观测需要自己花时间搭。

Haystack 在可观测性上做得最符合企业习惯:从 2.x 开始内置了基于标准协议的能力,Pipeline 的每个组件调用都能被追踪,还提供组件级调用的元数据输出。加上它不是黑盒,自定义组件也可以很方便地打点。这对已有监控体系的团队很友好。

4.2 评估:没有评测集,优化就是盲人摸象

2026 年做 RAG,如果不配评估集,项目基本等于裸奔。这里说的评估有两层:一是对检索质量的评估(召回率、命中率、重排效果),二是对最终生成质量的评估(忠实度、相关性、有用性)。

三家的态度区别在于:LangChain 把评估作为官方配套的一部分,同时生态里有大量第三方评估库可以集成;LlamaIndex 内置了评估模块,可以直接对查询引擎输出跑评分,上手很快;Haystack 本体侧重检索组件,最终生成效果评估更多靠外部工具,但它清晰的流水线结构方便你构建"检索结果快照"用于离线评估。

从我的经验看,无论选哪家,团队都应该从项目第一天就建一个一百到三百条问题的评测集,覆盖真实的用户问法、边界情况和"文档里没有答案"的误导性问题。框架可以换,评测集是长期资产。

4.3 部署形态与周边服务

  • LangChain 大多数时候只是个代码库,你用它构建完应用逻辑后,要自己用 Web 框架包成服务,或用官方平台做云端部署。灵活性高,工作量也大。
  • LlamaIndex 同样需要自建服务层,官方云产品更偏数据和索引管理。很多团队的做法是用 LlamaIndex 做数据处理和检索组件,外面再套一个 Web 服务或直接把它作为内部的 RAG 工具库。
  • Haystack 在这方面最省心:官方提供服务化能力,流水线可以被封装成可调用的 API。它在"把 RAG 变成别人可以调用的服务"这件事上走得最早也最顺。

4.4 长期维护:接口稳定性和技术债

接口稳定性直接影响长期维护成本。Haystack 自从 2.x 以来核心 API 非常稳定,组件化设计让升级多数时候是"组件内部变化",内置集成也相对克制,技术债较少。

LangChain 历史上因为接口变动频繁被吐槽很多,但这两年已经大幅收敛,核心概念也不再三天两头改名。LlamaIndex 的迭代节奏依然偏快,重要升级常伴随一些行为变化,但官方迁移文档相对清晰。我的建议是:无论选择哪家,项目一开始就把框架版本锁死、把框架依赖与其他业务代码隔离,否则你会不断花时间为接口变动买单。

注意:如果公司有明确的私有化部署和数据合规要求,建议在选型阶段就把"框架自身的云端组件/付费服务"和"开源自托管部分"的边界摸清楚,这点往往比框架本身的 API 还重要。

5. 2026 年生态格局:社区热度、维护节奏与周边整合

5.1 Star 数只是入场券,不是选型依据

三家的代码仓库热度差距明显:LangChain 一直是 LLM 应用框架里最热门的,LlamaIndex 紧随其后,Haystack 相对小而美。但实际深入社区你会发现,热门程度和使用体验并不线性相关。LangChain 的教程和问答最多,遇到问题容易搜到答案;LlamaIndex 的中长文深度文章很多,原理讲得透;Haystack 虽然不是最热,但在生产环境的口碑稳定,真实企业案例质量很高。

我还注意到最近一两年的趋势:三家都在向"一站式"靠拢。LangChain 把 LangGraph 作为 Agent 运行时推广,LlamaIndex 推出了自己的 Workflow 和整套数据管线工具,Haystack 也在强化 AgentPipeline 和内置组件库。边界模糊是好事也是坏事——好事是选 A 之后也能借用 B 的思路;坏事是如果你只看了三家的宣传材料,会越来越难看出实质区别。

5.2 周边生态的差异化竞争点

RAG 框架的价值很大一部分来自"周边配套"而不是核心代码:

  • 数据连接器:LlamaIndex 的连接器覆盖面最广,配合文档解析服务形成从解析到索引的完整链条;LangChain 的 Loader 多但质量不均;Haystack 的转换器少而精。
  • 可观测与评估:LangChain 官方配套最全但偏云端;Haystack 以标准协议为基础,最适合已有监控体系的团队;LlamaIndex 则依靠第三方生态组合。
  • Agent 能力:LangGraph 的状态图模型在复杂 Agent 场景里几乎没有对手;LlamaIndex 的 Workflow 和 Agent 适合"以数据为中心的轻量 Agent";Haystack 的 AgentPipeline 定位在企业级受控编排。

5.3 我的生态判断

我认为 2026 年三家都不会掉队,但它们分化会更明显。LangChain 会继续做"大而全"的应用层平台,LlamaIndex 继续深耕"数据侧"的深度能力,Haystack 则坚守"生产管线"的心智。对使用者的建议是:别等"生态统一"的那天,它永远不太可能到来;你真正需要的是认清自己项目的短板,然后让框架的长板去补它。

我自己也会混用,比如用 LlamaIndex 做复杂的 PDF 解析和信息抽取,把产出的结构化数据交给 LangChain 的 Agent 流程做后续任务编排。但这种混用会同时引入两套概念体系,新人上手成本会翻倍,所以我一般只在"单框架实在做得痛苦"时推荐,团队小于五人时尽量只选一家。

6. 选型决策:按团队形态和场景需求画一张决策图

6.1 先回答四个问题再选框架

我不建议一上来比对功能清单。闭着眼想清楚下面几个问题,答案自己就出来了:

  1. 你的数据形态是什么?是几十种异构数据源、批量文档、数据库还是一些网页?如果数据清洗和解析工作量大,LlamaIndex 的数据侧能力省力最明显。
  2. 你要做的是"标准问答"还是"复杂任务"?如果最终形态是围绕知识库的 Agent,需要不断调用工具、做多步推理,LangChain 生态优势大。
  3. 团队会对这套系统长期维护吗?如果会,你要考虑接口稳定性和可观测性。Haystack 在这两项上综合得分很高。
  4. 公司对部署方式有要求吗?纯私有化、离线部署、或者要求服务可监管可回滚?这会直接排除掉一些重度依赖云产品的方案。

6.2 按场景的推荐矩阵

场景首选框架理由
复杂 Agent、多工具调用、工作流编排LangChain + LangGraph编排能力最强,生态最全
多格式文档知识库、快速原型LlamaIndex数据解析和索引最省心
企业级搜索问答、服务化交付Haystack稳定、可观测、部署顺
已有团队熟悉某框架沿用原框架迁移成本往往高于框架收益
图 RAG、多跳推理LlamaIndex属性图索引相对完善
从零开始且团队经验不足首选社区教程最多的可搜到的资料决定排错速度

6.3 换框架的真实成本

如果有人建议你从 A 换到 B,先算一笔账:重写连接器、重调切分参数、迁移评测集、团队重新学习心智模型,这些成本远比"把某个 API 调用改一下"大。除非现有框架在某环节确实卡死了(比如某个数据源只有另一个框架有成熟连接器),否则我不建议为了框架的新特性频繁迁移。

我做过的实际迁移记录里,最值得做的不是"换框架",而是"把业务逻辑与框架解耦":把文档处理、检索、生成器分别封装成独立的内部接口,这样即便底层框架更新换代,业务层改动也能控制在一个模块内。

6.4 这些年换来的一套个人标准

用了一圈之后,我现在的选择标准是反过来的:先确定团队最薄弱、最不想自己造的环节,然后看哪个框架把那个环节补得最好。如果你们最头疼的是 PDF 和异构数据解析,LlamaIndex 真的会让你省下大量时间;如果你们要做一个能指挥多个工具干活的内部助手,LangChain 的 Agent 生态你绕不开;如果你们最担心的是线上稳定性和工单响应速度,Haystack 会把你们的排查时间砍半。

最后说一个我反复踩坑后悟出来的经验:不管选谁,第一天就搭一个最小评测集,第二天就接上某种 trace,第三天就把切分参数和检索策略固定下来。RAG 项目的成败,十有八九不在框架本身,而在数据准备、评测习惯和排障工具这三件"框架之外"的事情上——选型只是那件最容易被过度讨论的小事而已。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进