LangChain 与 LlamaIndex 完全指南:LLM 应用框架的实战选型

LangChain 是 2023 年以来 AI 工程界最有争议的框架之一 —— 它把 LLM 应用开发从"裸调 API"提升到"组件化",但也因为过度抽象、文档跟不上、API 频繁改动被开发者抱怨。这篇文章不站队,而是讲清楚 LangChain / LlamaIndex 实际能解决什么问题、什么场景该用、什么场景该绕开,以及 2025 年最稳的使用姿势。

LangChain 到底提供什么

核心是把 LLM 应用拆成可组合的组件:

  • Models:统一接口包装各家 LLM(OpenAI、Anthropic、本地模型),换厂商只改一行。
  • Prompts:模板化的 prompt 管理。
  • Output Parsers:把 LLM 输出解析成结构化对象。
  • Retrievers:统一的检索接口(向量库、Elasticsearch、Web 搜索)。
  • Chains:把多个调用串成一个流程。
  • Agents:基于 ReAct / Plan-and-Execute 的 Agent 框架。
  • Memory:对话历史管理。
  • Callbacks:运行时回调,做监控、日志、缓存。

这套组件抽象在"快速搭原型"时威力很大,几行代码就能搞一个 RAG 或 Agent。

LCEL:LangChain Expression Language

LangChain 0.1+ 引入的声明式管道语法,用 | 操作符串联组件:

from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser

prompt = ChatPromptTemplate.from_template("用 50 字解释什么是 {concept}")
model = ChatOpenAI(model="gpt-4o")
parser = StrOutputParser()

chain = prompt | model | parser

result = chain.invoke({"concept": "websocket"})
# "WebSocket 是一种基于 TCP 的全双工通信协议..."

# 流式输出
for chunk in chain.stream({"concept": "kubernetes"}):
    print(chunk, end="", flush=True)

# 批量
results = chain.batch([{"concept": "redis"}, {"concept": "kafka"}])

# 异步
result = await chain.ainvoke({"concept": "rabbitmq"})

LCEL 的好处:同一个 chain 自动支持同步、异步、流式、批量、并发。不用自己包装 4 种调用方式。

构建 RAG:LangChain 风格

from langchain_community.document_loaders import PyPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough

# 索引
docs = PyPDFLoader("manual.pdf").load()
chunks = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50).split_documents(docs)
vectorstore = Chroma.from_documents(chunks, OpenAIEmbeddings())
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})

# Chain
prompt = ChatPromptTemplate.from_template("""
基于以下资料回答问题。资料中没有的不要编。

资料:
{context}

问题:{question}
""")

def format_docs(docs):
    return "\n\n".join(d.page_content for d in docs)

chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | prompt
    | ChatOpenAI(model="gpt-4o")
    | StrOutputParser()
)

answer = chain.invoke("如何配置 HTTPS?")

20 行实现一个能跑的 RAG。但生产级 RAG 还需要 reranker、混合检索、query 改写 —— LangChain 都有现成组件,堆起来就行。

LlamaIndex:专注数据接入

LlamaIndex(原 GPT-Index)和 LangChain 定位略有不同 —— 它更专注"如何把企业数据接入 LLM":

  • 更多文档加载器(Notion、Slack、Confluence、Jira、Salesforce 等)。
  • 更精细的索引结构(Tree Index、List Index、Knowledge Graph Index、Vector Index)。
  • 更强的 RAG 优化(Auto Retrieval、Sub-Question Query、Sentence Window)。
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding

# 简单到一行
documents = SimpleDirectoryReader("./docs").load_data()
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine(llm=OpenAI(model="gpt-4o"))
response = query_engine.query("如何配置 HTTPS?")

选型:纯 RAG 场景或要接入很多奇怪数据源 → LlamaIndex;复杂 Agent / 工作流 → LangChain / LangGraph。当然两者也可以一起用 —— LlamaIndex 做检索层,LangChain 做编排层。

LangGraph:状态化的 Agent 编排

LangChain 团队 2024 年推出 LangGraph,专门做 Agent / 工作流编排。它把流程建模成有向图,每个节点是 LLM 调用或工具,节点间有条件边:

from langgraph.graph import StateGraph, END
from typing import TypedDict

class State(TypedDict):
    question: str
    docs: list
    answer: str
    needs_more_info: bool

# 节点
def retrieve(state):
    docs = retriever.invoke(state["question"])
    return {"docs": docs}

def grade_docs(state):
    # 用 LLM 判断 docs 是否足够回答
    needed = grade_chain.invoke({"question": state["question"], "docs": state["docs"]})
    return {"needs_more_info": needed}

def transform_query(state):
    new_q = rewrite_chain.invoke({"question": state["question"]})
    return {"question": new_q}

def generate(state):
    answer = answer_chain.invoke({"question": state["question"], "docs": state["docs"]})
    return {"answer": answer}

# 构图
workflow = StateGraph(State)
workflow.add_node("retrieve", retrieve)
workflow.add_node("grade", grade_docs)
workflow.add_node("transform", transform_query)
workflow.add_node("generate", generate)

workflow.set_entry_point("retrieve")
workflow.add_edge("retrieve", "grade")

# 条件边:根据状态决定下一步
workflow.add_conditional_edges(
    "grade",
    lambda state: "transform" if state["needs_more_info"] else "generate",
    {"transform": "transform", "generate": "generate"}
)
workflow.add_edge("transform", "retrieve")     # 循环回检索
workflow.add_edge("generate", END)

app = workflow.compile()
result = app.invoke({"question": "如何配置 HTTPS?"})

这是Self-Correcting RAG(自纠错 RAG)的实现 —— 检索后判断是否够答,不够就改写 query 重新检索。LangGraph 把这种带状态、有循环、有分支的 Agent 流程表达得清晰。

LangSmith:观测性

LangChain 自家的可观测性平台。运行时自动记录每个组件的输入、输出、耗时、token、错误。生产级 LLM 应用必备工具:

import os
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "..."
os.environ["LANGCHAIN_PROJECT"] = "my-app"

# 之后所有 chain 调用自动上传到 LangSmith
result = chain.invoke({"question": "..."})
# 在 LangSmith Web UI 看到完整 trace

LangSmith 还提供数据集管理、自动评估、A/B 测试、提示词版本管理。对生产应用极其有用。竞品:Weave(Weights & Biases)、Helicone、Phoenix。

LangChain 的争议

抱怨 1:过度抽象

很多场景只是想"调一下 OpenAI",LangChain 让你先理解 Runnable、LCEL、Callback、Memory、Tool... 学习曲线陡。

对策:简单调用直接用厂商 SDK(openaianthropic),复杂场景才上 LangChain。

抱怨 2:API 频繁变动

0.0.x → 0.1 → 0.2 → 0.3 几次大改,网上 tutorials 经常和当前版本不一致。

对策:看官方 docs 当下版本的写法,GitHub issues 里搜最近 30 天的讨论。

抱怨 3:性能开销

LangChain 在每个组件外都包了一层,callback、tracing、metadata 收集让简单调用比裸调慢 10-30%。

对策:高 QPS 场景关闭不必要的 callback,或者绕开 LangChain 直接调。

什么时候用,什么时候不用

用 LangChain

  • 需要快速搭原型,组件能拿现成的。
  • 要支持多家 LLM 切换。
  • 需要复杂编排(Multi-Agent、Self-Correcting、并行分支)。
  • 需要 LangSmith 这样的可观测平台。

不用

  • 简单的"调 GPT 写邮件"—— 直接用 openai SDK 更简单。
  • 极致性能场景(实时对话、低延迟)—— 抽象层是瓶颈。
  • 团队成员都不熟 LangChain,引入学习成本超过收益。

替代方案

2024-2025 年出现了不少 LangChain 的"轻量替代":

  • Instructor:专注结构化输出,极简。
  • Marvin:类似 Instructor,把 LLM 当函数调。
  • DSPy(Stanford):把 prompt 当作"可优化代码",自动调优 few-shot 例子。
  • Pydantic AI:Pydantic 团队出品,类型安全 + 简单 API。
  • Vercel AI SDK:前端工程师友好,边缘部署友好。

不同场景选不同工具。LangChain 适合"大而全",这些替代品适合"专而精"。

工程心得

1. Prompt 和 Chain 分离

# 不好:prompt 写死在代码里
prompt = ChatPromptTemplate.from_template("用 50 字回答 {q}")

# 好:prompt 集中管理,可以版本化
from langchain_core.prompts import load_prompt
prompt = load_prompt("./prompts/answer_v3.yaml")

2. 给 chain 起名字

chain = (prompt | model | parser).with_config({"run_name": "answer_chain"})
# LangSmith 里能看到这个名字,debug 更清晰

3. 错误处理

chain = (prompt | model | parser).with_retry(stop_after_attempt=3)

# 或者 fallback 到备用模型
chain = primary_chain.with_fallbacks([backup_chain])

LangChain 之外:Vercel AI SDK

2025 年前端工程师用得最多的 LLM 工具包之一。专注 streaming、React/Next.js 集成、边缘部署:

// API 路由
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';

export async function POST(req) {
    const { messages } = await req.json();
    const result = await streamText({
        model: openai('gpt-4o'),
        messages,
        tools: {
            getWeather: {
                description: '查询天气',
                parameters: z.object({ city: z.string() }),
                execute: async ({ city }) => { /* ... */ }
            }
        }
    });
    return result.toDataStreamResponse();
}

// React 组件
import { useChat } from 'ai/react';

export default function Chat() {
    const { messages, input, handleSubmit } = useChat();
    return (
        <form onSubmit={handleSubmit}>
            {messages.map(m => <div key={m.id}>{m.content}</div>)}
            <input value={input} />
        </form>
    );
}

Vercel AI SDK 的卖点是"类型安全 + 流式 + 边缘友好",写聊天应用比 LangChain 简单得多。但纯后端复杂业务还是 LangChain / LlamaIndex 更全。

DSPy:把 Prompt 当代码自动优化

Stanford 出品的革命性框架。核心理念:你定义"任务签名"(输入 / 输出 / 步骤),DSPy 自动生成和优化 prompt

import dspy

# 定义任务签名
class QA(dspy.Signature):
    """根据上下文回答问题"""
    context = dspy.InputField()
    question = dspy.InputField()
    answer = dspy.OutputField(desc="简洁的回答")

# 定义流程
class RAG(dspy.Module):
    def __init__(self):
        self.retrieve = dspy.Retrieve(k=3)
        self.generate = dspy.ChainOfThought(QA)

    def forward(self, question):
        context = self.retrieve(question).passages
        return self.generate(context=context, question=question)

# 自动优化:DSPy 会用 few-shot 示例和评估指标自动调 prompt
optimizer = dspy.BootstrapFewShot(metric=accuracy_metric)
optimized = optimizer.compile(RAG(), trainset=train_data)

DSPy 解决的痛点:prompt 调参太靠玄学。它把这个过程数据化、可优化。学习成本略高,但对长期维护的 LLM 应用非常有价值。

写在最后

LangChain / LlamaIndex / LangGraph 这套生态,代表了"把 LLM 当组件"的工程化思路。它有抽象成本,但当你的应用真的开始处理"多模型、多工具、多步骤、多分支、长会话"时,这些抽象省下来的开发时间会让你回头感谢它。

给一个判断标准:项目的复杂度 = 框架引入的合理性。一两天的 demo 不需要 LangChain,几个月的 SaaS 产品几乎必须用。具体到选型,2025 年的现状:结构化输出用 Instructor,纯 RAG 用 LlamaIndex,复杂 Agent 用 LangGraph,前端集成用 Vercel AI SDK,可观测都用 LangSmith。这套组合在大多数场景下都够用且不踩坑。

—— 别看了 · 2026
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理 邮箱1846861578@qq.com。
技术教程

AI Agent 完全指南:从 ReAct 到 Multi-Agent 的工程架构

2026-5-15 16:01:23

技术教程

LoRA 与 QLoRA 微调完全指南:让开源大模型变成你的领域专家

2026-5-15 16:01:23

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索