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 提供 Agent 与模型/工具集成;LangGraph 提供有状态编排运行时 | 面向私有数据的上下文工程、索引、检索、查询与工作流 |
| 主要抽象 | Model、Tool、Middleware、Agent;State、Node、Edge | Document、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 → 上下文组装 → 有依据生成
→ 引用校验/拒答 → 响应
持续闭环:
真实问题 + 标注集 → 检索评测 → 生成评测 → 线上监控 → 失败样本回流
只画“文档 → Embedding → 向量库 → LLM”会漏掉生产中最容易出错的部分:文档版本、访问控制、查询改写、关键词召回、重排、上下文预算、引用映射、拒答和评测。
1. 数据摄取:先保证证据正确
RAG 的上限首先由数据决定。PDF 解析不能只抽取连续文本:标题层级、页码、表格单元格、图注、脚注和阅读顺序都可能影响答案。扫描件需要 OCR,复杂版式可以选择 LlamaParse、Unstructured 或经过验证的专用解析器,但必须用自己的文档集比较字段完整率和版面恢复率。
每份文档至少保留:稳定 document_id、来源、租户、权限标签、版本、生效时间、更新时间、标题层级、页码/锚点和内容哈希。删除或更新文档时,要能精确删除旧 chunks,而不是让向量库永久积累幽灵内容。
摄取流程应当幂等、可重放、可观测。解析器、切块器和 Embedding 模型都要记录版本;变更其中任一步时,应知道哪些文档需要重建。
2. Chunking:不存在通用的 512-1024
固定 token 窗口可以作为基线,但不能把 512-1024 tokens + 10%-20% overlap 当成最佳答案。合适粒度取决于文档结构、查询类型、Embedding 模型和生成上下文。
更可靠的策略是:
- 优先按标题、段落、列表、代码块和表格等语义边界切分;
- chunk 保留父文档、章节路径、页码和相邻关系;
- 用小块提高召回精度,再按父章节或邻居块扩展生成上下文;
- 表格、代码和 FAQ 使用专门切分规则,不强行套统一长度;
- 在真实问题集上对 chunk size、overlap 和 parent-child 策略做消融实验。
Overlap 能缓解边界断裂,但会增加索引、召回重复和上下文浪费。只有评测证明有收益时才扩大 overlap。
3. Embedding 与索引:语义检索不是唯一通道
Embedding 模型要按语言、领域、维度、成本和部署方式评估。BGE-M3 等多语言模型可以作为候选,但不能只凭排行榜决定。应建立包含中英文、缩写、产品名、编号、长尾表达和困难负样本的检索集,测 Recall@K、MRR 或 NDCG。
索引通常至少包含两路:
- 稠密向量检索处理语义相似和口语表达;
- BM25/关键词检索处理精确术语、编号、人名、错误码和稀有实体。
两路结果可以用 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 割裂、类型转换和调试成本。先保持最小系统,等数据层与编排层都出现独立复杂度后再拆分。
最终选择建议
- 固定知识库问答、复杂文档和高级检索占主导:优先 LlamaIndex。
- 多工具 Agent、条件分支、循环、持久状态和人工审批占主导:优先 LangChain + LangGraph。
- 简单 2-Step RAG:两者都可以,甚至可以直接使用模型 SDK + 搜索服务。
- 复杂数据 Agent:LlamaIndex 管数据与检索,LangGraph 管任务生命周期,是清晰但并非强制的组合。
框架选择只决定开发体验,不决定 RAG 质量。真正决定上线效果的是证据质量、权限边界、召回与重排、拒答策略、评测集和持续观测。先把这些工程契约定义清楚,再选择最贴合主要复杂度的框架。