技术札记

LangChain 与 LlamaIndex:如何选择,以及如何构建生产级 RAG

从框架定位、真实应用场景到完整 RAG 链路,系统比较 LangChain、LangGraph 与 LlamaIndex,并梳理解析、切块、混合检索、重排、引用、评测和权限治理。

HOUHUIYANG.COM

扫码继续阅读

正在生成…

LangChain 与 LlamaIndex:如何选择,以及如何构建生产级 RAG

houhuiyang.com/zh/notes/langchain-vs-llamaindex-production-rag

LangChain 和 LlamaIndex 经常被放在一起比较,因为两者都能连接模型、向量数据库和外部工具,也都能构建 RAG 与 Agent。但“LangChain 做 Agent,LlamaIndex 做 RAG”只是一个粗略起点,不能作为完整的技术结论。

今天的 LangChain 更接近面向 Agent 的高层框架:提供模型、工具、中间件和预构建 Agent 循环;复杂、有状态、可恢复的编排由底层 LangGraph 承担。LlamaIndex 则以数据为中心:围绕 Document、Node、Ingestion Pipeline、Index、Retriever、Query Engine 建立完整抽象,同时也提供 Workflows、FunctionAgent、ReActAgent 和多 Agent 能力。

真正的选择题不是“哪个框架更强”,而是:系统最难的部分是数据进入、检索与证据组织,还是工具决策、状态流转与长任务编排?

LangChain、LangGraph 与 LlamaIndex 的能力边界

一张更准确的对比表

维度LangChain / LangGraphLlamaIndex
核心定位LangChain 提供 Agent 与模型/工具集成;LangGraph 提供有状态编排运行时面向私有数据的上下文工程、索引、检索、查询与工作流
主要抽象Model、Tool、Middleware、Agent;State、Node、EdgeDocument、Node、Transformation、Index、Retriever、Query Engine、Workflow
RAG支持加载、切块、向量库、Retriever、2-Step/Agentic/Hybrid RAG数据摄取、元数据、索引、检索、合成和评测抽象更集中
Agent高层 create_agent,底层 LangGraph 支持持久化、流式、人机协同与恢复FunctionAgent、ReActAgent、AgentWorkflow 与事件驱动 Workflows
适合的复杂度工具选择、条件分支、循环、审批、长任务状态异构数据接入、复杂检索、文档关系、查询引擎与数据 Agent
可观测性LangSmith 与 LangGraph 状态轨迹集成紧密Callback/Instrumentation,并可接入多种观测平台
使用建议业务流程和 Agent 行为是系统核心时优先私有数据质量和检索链路是系统核心时优先

这里最重要的是避免两个误区。

第一,LlamaIndex 不等于“向量索引工具”。它覆盖数据摄取、转换、存储、查询、响应合成、评测和 Agent 工作流。第二,LangChain 不等于早期的“Chain 拼接库”。LangChain 1.x 的 Agent 运行在 LangGraph 之上,LangGraph 才是需要精细控制状态、循环、持久化和恢复时的低层入口。

用场景而不是功能清单做选择

场景一:企业知识库与制度问答

核心难点通常是 PDF/Office 解析、版本管理、权限过滤、章节结构、混合检索、引用定位和检索评测。此时优先使用 LlamaIndex 往往更自然,因为它的数据与检索抽象集中,Ingestion Pipeline 还能处理转换缓存、去重和增量更新。

但如果只是一个固定的“检索一次再回答”流程,原生代码或 LangChain、LlamaIndex 中任意一个都能完成。不要为了框架而框架化。

场景二:多工具业务 Agent

例如一个售后 Agent 需要查询订单、读取知识库、判断退款条件、发起审批、等待人工确认、调用支付系统并记录结果。难点是状态机、工具权限、循环上限、失败恢复和 Human-in-the-loop。此时 LangChain Agent + LangGraph 更贴合问题结构。

场景三:数据研究与报告生成

Agent 需要先判断问题,调用文档检索、SQL、Web API,再迭代补证据并生成带引用报告。可以用 LlamaIndex 构建高质量检索工具,用 LangGraph 管理研究步骤、状态、审批和恢复。混用是合理的,但必须保持边界:LlamaIndex 暴露稳定 Retriever/Query Engine 接口,编排层只消费结构化结果,不直接操作索引内部对象。

场景四:检索本身就是产品

当产品提供按租户、时间、类别和权限组合过滤,支持多索引路由、父子块检索、Graph RAG 或多模态文档时,数据层复杂度远高于 Agent。优先围绕 LlamaIndex 或独立搜索服务建设检索平台,再把它作为工具提供给任意 Agent 框架。

RAG 不是一条箭头,而是两条生命周期

一个完整 RAG 系统包含离线摄取和在线回答两条链路,并由评测反馈闭环连接。

离线摄取:
数据源 → 解析/OCR → 清洗与结构恢复 → 元数据/权限 → 切块
      → Embedding + 关键词索引 → 版本化存储 → 质量检查

在线回答:
问题 → 安全与权限 → 查询理解/改写 → 路由 → 混合召回
    → 融合/去重 → Rerank → 上下文组装 → 有依据生成
    → 引用校验/拒答 → 响应

持续闭环:
真实问题 + 标注集 → 检索评测 → 生成评测 → 线上监控 → 失败样本回流

生产级 RAG 的端到端链路

只画“文档 → Embedding → 向量库 → LLM”会漏掉生产中最容易出错的部分:文档版本、访问控制、查询改写、关键词召回、重排、上下文预算、引用映射、拒答和评测。

1. 数据摄取:先保证证据正确

RAG 的上限首先由数据决定。PDF 解析不能只抽取连续文本:标题层级、页码、表格单元格、图注、脚注和阅读顺序都可能影响答案。扫描件需要 OCR,复杂版式可以选择 LlamaParse、Unstructured 或经过验证的专用解析器,但必须用自己的文档集比较字段完整率和版面恢复率。

每份文档至少保留:稳定 document_id、来源、租户、权限标签、版本、生效时间、更新时间、标题层级、页码/锚点和内容哈希。删除或更新文档时,要能精确删除旧 chunks,而不是让向量库永久积累幽灵内容。

摄取流程应当幂等、可重放、可观测。解析器、切块器和 Embedding 模型都要记录版本;变更其中任一步时,应知道哪些文档需要重建。

2. Chunking:不存在通用的 512-1024

固定 token 窗口可以作为基线,但不能把 512-1024 tokens + 10%-20% overlap 当成最佳答案。合适粒度取决于文档结构、查询类型、Embedding 模型和生成上下文。

更可靠的策略是:

Overlap 能缓解边界断裂,但会增加索引、召回重复和上下文浪费。只有评测证明有收益时才扩大 overlap。

3. Embedding 与索引:语义检索不是唯一通道

Embedding 模型要按语言、领域、维度、成本和部署方式评估。BGE-M3 等多语言模型可以作为候选,但不能只凭排行榜决定。应建立包含中英文、缩写、产品名、编号、长尾表达和困难负样本的检索集,测 Recall@K、MRR 或 NDCG。

索引通常至少包含两路:

两路结果可以用 Reciprocal Rank Fusion 等稳定方法融合。元数据过滤应尽可能在召回前执行,尤其是租户、ACL、生效时间和数据类型;不要先召回无权内容再在 Prompt 前删除。

4. 查询理解与路由

用户问题未必适合直接 Embedding。多轮对话需要把代词和省略信息改写成独立查询;复杂问题可能需要拆解;明确的编号查询应提高关键词权重;涉及结构化事实时应路由到 SQL 或 API,而不是强行向量搜索。

查询改写必须保留原始约束,不能为了“更容易检索”而改变用户意图。高风险系统应记录原问题、改写结果、路由决定和模型版本,方便追踪错误发生在哪一步。

5. 召回、融合与 Rerank

第一阶段召回追求覆盖率,可以从多个通道取较大的候选集;第二阶段用 cross-encoder 或专用 reranker 按 query-document 相关性精排,再选取进入上下文的证据。

Top-K = 3-5 不是固定最佳实践。最终数量取决于证据密度、文档重复度、上下文窗口和问题是否需要多来源综合。更好的做法是:先召回较多候选,重排和去重,再按 token 预算、分数阈值与证据覆盖动态截断。

Reranker 解决相关性排序,不负责权限、时效和业务资格。确定性约束必须由过滤规则执行。

6. 上下文组装:把证据变成可消费输入

上下文不是把 Top-K 直接拼接。组装器需要:去重、恢复标题路径、合并相邻块、保留来源编号、控制单一文档占比,并避免在 token 截断时切掉关键结论。

建议为每个证据块分配稳定引用 ID,并携带标题、URL/文件、页码、更新时间和权限安全的片段。Prompt 应明确要求只依据证据回答、区分事实与推断、证据不足时拒答,并输出可解析的引用结构。

但 Prompt 不能真正消除幻觉。“文档中未找到”必须由检索置信度、证据覆盖和生成后引用校验共同支持,而不是只写一句系统提示。

7. 生成、引用与拒答

生成阶段至少区分三种结果:有充分证据并回答;证据部分充分,回答已知部分并说明缺口;证据不足,拒绝作答并建议澄清或转人工。

引用校验应检查:每个关键结论是否有引用、引用片段是否真的支持结论、引用是否仍在授权范围内。高风险场景还需要规则校验、结构化输出验证或人工审批。

答案不是 RAG 的唯一输出。调试和审计所需的 retrieval trace、候选分数、过滤原因、模型版本与延迟,应进入内部观测系统,但不能向终端用户泄露敏感元数据。

8. 评测:先分层,才能知道改哪里

至少建立四层指标:

层级关键指标回答的问题
解析/切块字段完整率、结构保真、chunk 覆盖正确证据有没有进入索引
检索Recall@K、MRR、NDCG、过滤正确率正确证据有没有被找到并排在前面
生成Faithfulness、引用正确率、完整性、拒答准确率答案是否真正被证据支持
系统P50/P95 延迟、成本、失败率、缓存命中、权限违规系统是否可稳定、安全地运行

离线评测集应来自真实问题,并包含无答案问题、模糊问题、跨文档问题、版本冲突和权限隔离案例。线上反馈不能只看点赞率:还应分析改写率、重复提问、转人工率和引用点击。

什么时候混用,什么时候不要混用

混用的合理边界是:LlamaIndex 作为独立的摄取与检索模块,向 LangGraph 暴露一个带结构化输入输出的检索工具;LangGraph 负责决定何时检索、是否补充查询、是否调用其他工具,以及如何处理审批和恢复。

LangGraph / LangChain Agent
  ├─ KnowledgeSearchTool → LlamaIndex Retriever / Query Engine
  ├─ SQLTool
  ├─ BusinessAPITool
  └─ HumanApproval

不要混用的情况也很明确:一个固定的 2-Step RAG 如果单框架几十行代码就能完成,加入两套抽象只会增加版本冲突、Tracing 割裂、类型转换和调试成本。先保持最小系统,等数据层与编排层都出现独立复杂度后再拆分。

最终选择建议

框架选择只决定开发体验,不决定 RAG 质量。真正决定上线效果的是证据质量、权限边界、召回与重排、拒答策略、评测集和持续观测。先把这些工程契约定义清楚,再选择最贴合主要复杂度的框架。

参考资料

返回技术札记