一、双雄并立:一个管数据,一个管流程

在2026年的大模型应用开发生态中,LangChain和LlamaIndex已经形成了明确的分工格局。两者并非“非此即彼”的替代关系,而是各有所长的互补伙伴。

先一句话说清两者的核心定位:LlamaIndex是让LLM读懂私有数据的“知识引擎”,LangChain是给LLM配上手脚和流程的“编排中枢”

维度 LlamaIndex LangChain
核心能力 文档加载、分块、向量索引、语义检索 模型封装、提示工程、工作流编排、工具调用
擅长领域 私有数据接入与检索优化 多组件串联与Agent自主决策
关键动作 “数据→分块→建索引→精准检索” “调用工具→处理结果→生成回答”

打个形象的比方:LlamaIndex是给LLM配了个“专属图书管理员”,能在海量私有文档中快速找到你要的那一页;LangChain则是给LLM配了个“工作助理”,让它会用计算器、查数据库、按步骤完成多任务。

两者的协同逻辑可概括为:LlamaIndex负责“找什么”,LangChain负责“怎么做”——前者检索出相关上下文,后者将上下文与用户问题组装成提示模板,再调用大模型生成答案。


二、技术实现:三种混合调度模式

2.1 模式一:LlamaIndex检索 + LangChain问答链

这是最基础也是最常用的集成方式。LlamaIndex负责构建索引和检索,LangChain的RetrievalQA链负责调用LLM生成回答。

from llama_index import VectorStoreIndex, SimpleDirectoryReader
from llama_index.core import Settings
from langchain.chains import RetrievalQA
from langchain.chat_models import ChatOpenAI
from llama_index.langchain_helpers.retrievers import VectorIndexRetriever

# Step 1: LlamaIndex构建文档索引
documents = SimpleDirectoryReader("./docs").load_data()
index = VectorStoreIndex.from_documents(documents)

# Step 2: 将LlamaIndex检索器包装为LangChain检索器
retriever = VectorIndexRetriever(index=index, similarity_top_k=3)

# Step 3: LangChain构建问答链
llm = ChatOpenAI(temperature=0)
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    retriever=retriever,
    chain_type="stuff"
)

# Step 4: 执行问答
response = qa_chain.run("文档中提到的核心观点是什么?")

关键点VectorIndexRetriever是官方提供的适配器,将LlamaIndex的查询引擎无缝转换为LangChain的Retriever接口。


2.2 模式二:多查询引擎 + Agent智能路由

当你有多个知识库(如不同年份的财报、不同部门的文档),可以让LangChain Agent根据问题内容,自动判断调用哪个LlamaIndex查询引擎。

from llama_index.core.tools import QueryEngineTool, ToolMetadata
from langchain.agents import initialize_agent, AgentExecutor
from langchain.tools import Tool
from llama_index.core import load_index_from_storage, StorageContext

# 构建多个查询引擎(以Uber和Lyft财报为例)
lyft_engine = load_index_from_storage(
    StorageContext.from_defaults(persist_dir="./storage/lyft")
).as_query_engine(similarity_top_k=3)

uber_engine = load_index_from_storage(
    StorageContext.from_defaults(persist_dir="./storage/uber")
).as_query_engine(similarity_top_k=3)

# 将查询引擎转为LangChain工具
tools = [
    QueryEngineTool(
        query_engine=lyft_engine,
        metadata=ToolMetadata(
            name="lyft_10k",
            description="查询Lyft公司2021年财务数据"
        )
    ).to_langchain_tool(),
    QueryEngineTool(
        query_engine=uber_engine,
        metadata=ToolMetadata(
            name="uber_10k",
            description="查询Uber公司2021年财务数据"
        )
    ).to_langchain_tool()
]

# 还可追加外部搜索工具
from langchain.tools import DuckDuckGoSearchRun
tools.append(Tool(
    name="WebSearch",
    func=DuckDuckGoSearchRun().run,
    description="当需要查询实时信息或工具无法提供的内容时使用"
))

# 创建Agent
agent = initialize_agent(
    tools, 
    llm, 
    agent="zero-shot-react-description", 
    verbose=True
)

# Agent会自动判断:问Lyft用第一个工具,问Uber用第二个,问超出范围则走搜索
response = agent.run("Uber在2021年是否盈利?")

技术要点

  • QueryEngineTool将LlamaIndex查询引擎包装为LangChain工具
  • .to_langchain_tool()方法实现格式转换
  • Agent通过工具描述来判断调用哪个引擎,实现“智能路由”

2.3 模式三:索引持久化 + 增量加载(生产必备)

生产环境中,索引构建耗时长(尤其是大量文档),必须实现“一次构建、多次加载”。

import os
from llama_index.core import (
    VectorStoreIndex, 
    SimpleDirectoryReader,
    StorageContext,
    load_index_from_storage
)

def build_or_load_index(doc_dir: str = "./docs", index_dir: str = "./storage"):
    """索引管理:存在则加载,不存在则构建并持久化"""
    if not os.path.exists(index_dir):
        # 首次运行:构建索引
        documents = SimpleDirectoryReader(
            input_dir=doc_dir, 
            recursive=True
        ).load_data()
        index = VectorStoreIndex.from_documents(documents)
        # 持久化到本地
        index.storage_context.persist(persist_dir=index_dir)
        print(f"索引已构建并保存至 {index_dir}")
    else:
        # 后续运行:从本地加载
        storage_context = StorageContext.from_defaults(persist_dir=index_dir)
        index = load_index_from_storage(storage_context)
        print(f"索引已从 {index_dir} 加载")
    return index

# 使用
index = build_or_load_index()
retriever = index.as_retriever(similarity_top_k=3)

配置优化建议:分块参数直接影响检索质量,建议根据文档类型定制:

from llama_index.core.node_parser import SimpleNodeParser

parser = SimpleNodeParser.from_defaults(
    chunk_size=512,        # 每块大小
    chunk_overlap=50       # 重叠量,保持上下文连贯性
)

三、混合架构的工程化要点

3.1 分层职责清晰

在混合架构中,必须明确各层边界:

层级 职责 使用框架
数据层 文档加载、分块、向量化、索引管理 LlamaIndex
编排层 提示模板、模型调用、输出解析、工具集成 LangChain
流程层(进阶) 复杂状态管理、多智能体协作、循环重试 LangGraph

3.2 避坑指南

常见问题 解决方案
索引重复构建耗时 使用storage_context.persist()持久化,后续load_index_from_storage()加载
检索结果不精准 调整similarity_top_k,或启用混合检索(向量+关键词)
上下文超出token限制 限制历史轮数(10~20轮),或使用ConversationSummaryMemory压缩记忆
多工具调用混乱 为每个QueryEngineTool写好description,Agent依赖描述决策

四、总结:何时双轨并行?

推荐双轨并行的典型场景

  • 企业知识库问答:LlamaIndex处理海量内部文档,LangChain负责对话管理与多轮交互
  • 多数据源聚合查询:多个LlamaIndex查询引擎作为工具,由LangChain Agent统一调度
  • 需要工具调用的RAG应用:LlamaIndex提供检索能力,LangChain集成外部API(搜索、计算、数据库等)

单纯选择一方的场景

  • 只需简单文档问答 → 单用LlamaIndex即可
  • 需大量工具集成但检索简单 → 单用LangChain更轻量

LlamaIndex管好“数据”,LangChain管好“流程”,两者各司其职,才能构建出真正稳定、可扩展的大模型应用。

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐