解决大模型 5 大痛点:LangChain 核心组件全解析

26 阅读13分钟

第一性原理分析:LangChain


第一步:问题是什么?

假设你已经掌握了提示词工程,能够通过精心设计的提示词让大模型完成各种任务。但你很快会发现几个新的问题:

问题 1:单次对话有长度限制 你有一本 500 页的 PDF,想让它总结核心内容。但大模型的上下文窗口有限(比如 128K tokens),放不下一整本书。你需要一种方法处理超出上下文窗口的内容

问题 2:模型没有长期记忆 你和 AI 聊了半小时,它记得刚才说过什么。但明天你再回来,它忘得一干二净。你需要一种方法让 AI 记住跨会话的信息

问题 3:模型不能主动采取行动 你想让 AI 帮你查今天的天气、订餐厅、发邮件。它说"好的,我帮你查",但实际上它只是生成文字,不会真的调用天气 API、不会真的操作你的邮箱。你需要一种方法让 AI 能调用外部工具

问题 4:复杂任务需要多步协作 你想让 AI 写一份市场分析报告:先搜资料、再分析数据、然后写报告、最后检查格式。单个提示词搞不定,你需要把多个步骤串联起来

问题 5:同样的事要反复做 你每天都要处理类似的文档:读 PDF、提取要点、翻译成英文、保存到数据库。每次写提示词太累,你需要把流程固定下来,重复使用

所以问题来了:如何把大模型的能力从"单次对话"扩展成"可组合、可记忆、可行动、可重复的应用程序"? 这就是 LangChain 要解决的问题。


第二步:从零设计,我们需要什么?

假设我们要从零设计一个框架,把大模型变成真正的应用开发平台,从最基本的需求推导:

需求 1:模型抽象(Model Abstraction)

不同的大模型(OpenAI、Claude、LLaMA)有不同的 API、不同的参数、不同的定价。我们不能让应用代码直接依赖某个具体模型,需要统一接口,想换模型时只需改一行配置。

需求 2:提示词管理(Prompt Management)

提示词会变得越来越长、越来越复杂:

  • 系统提示词(角色设定)
  • 用户输入(动态内容)
  • 示例(少样本学习)
  • 格式指令(输出格式)

我们需要一种结构化组织提示词的方式,而不是用字符串拼接。

需求 3:记忆机制(Memory)

应用需要记住对话历史:

  • 短期记忆:当前对话的上下文
  • 长期记忆:跨会话的用户偏好、历史记录
  • 向量记忆:把历史信息存成向量,需要时检索相关部分

需求 4:链式组合(Chaining)

复杂任务需要多个步骤:

  • 步骤1:检索相关信息
  • 步骤2:基于信息生成答案
  • 步骤3:检查答案质量
  • 步骤4:格式化输出

我们需要一种把多个组件串成流水线的方式。

需求 5:工具调用(Tools)

AI 需要能与外部世界交互:

  • 调用 API(天气、搜索、数据库)
  • 执行代码(Python 解释器)
  • 操作文件(读写、转换)
  • 发送通知(邮件、消息)

我们需要让 AI 能决定何时调用什么工具,并处理返回结果

需求 6:文档处理(Document Loaders)

AI 经常需要处理各种格式的外部文档:

  • PDF、Word、Excel
  • 网页、数据库
  • 音视频(转录)

我们需要统一加载和分割文档的方式。

需求 7:检索增强生成(RAG)

当模型不知道答案时,需要从外部知识库检索相关信息:

  • 把文档切成小块
  • 转成向量存入数据库
  • 根据问题检索相关块
  • 把检索结果作为上下文交给模型

这是解决"模型知识有限"和"处理超长文档"的核心方法。

需求 8:智能体(Agent)

有时候你不知道任务需要几步完成。让 AI 自己决定:

  • 分析任务
  • 决定需要什么工具
  • 调用工具获取信息
  • 基于结果决定下一步

我们需要让 AI 拥有自主决策能力


第三步:LangChain 的核心设计原理

基于以上需求,LangChain 的设计思路就很清晰了:

核心原理 1:组件化(Modularity)- 一切皆可组合

LangChain 把 AI 应用拆解成最基本的组件,每个组件解决一个单一问题:

组件类型作用例子
Models与大模型交互的统一接口OpenAI、Claude、LLaMA
Prompts管理和结构化提示词PromptTemplate、ChatPromptTemplate
Memory存储和检索对话历史BufferMemory、VectorStoreMemory
Chains把多个组件串联起来LLMChain、SequentialChain
ToolsAI 可调用的外部功能SearchTool、CalculatorTool
Agents自主决策使用哪些工具ReActAgent、PlanAndExecuteAgent
Document Loaders加载各种格式的文档PDFLoader、WebBaseLoader
Vector Stores存储和检索向量Chroma、FAISS、Pinecone
Output Parsers解析和格式化模型输出JSONParser、PydanticParser

这些组件像乐高积木,你可以自由组合,构建复杂的应用。

核心原理 2:提示词模板化(Prompt Templating)- 结构化提示词

与其用字符串拼接,LangChain 提供结构化的提示词模板:

# 不好的方式:字符串拼接
prompt = f"你是一个{role}。请回答这个问题:{question}"

# LangChain 的方式:结构化模板
from langchain.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个{role},擅长用{style}的风格回答问题。"),
    ("human", "我的问题是:{question}"),
    ("ai", "让我思考一下..."),
    ("human", "请直接回答,不需要思考过程"),
])

# 使用时传入变量
formatted_prompt = prompt.format_messages(
    role="历史老师",
    style="生动有趣",
    question="解释一下工业革命的影响"
)

为什么有效?

  • 把提示词结构从代码中分离出来,易于维护
  • 支持多轮对话的结构化表达
  • 变量注入清晰,避免字符串拼接错误

核心原理 3:链式组合(Chaining)- 把组件串成流水线

LangChain 的核心概念是"链"(Chain):一个链可以包含多个步骤,每个步骤的输出是下一个步骤的输入。

from langchain.chains import LLMChain, SimpleSequentialChain

# 链1:生成一个笑话
chain1 = LLMChain(
    llm=llm,
    prompt=PromptTemplate.from_template("讲一个关于{topic}的笑话")
)

# 链2:评价这个笑话
chain2 = LLMChain(
    llm=llm,
    prompt=PromptTemplate.from_template("评价这个笑话:{joke}。给出 1-10 的评分并解释。")
)

# 串联起来
overall_chain = SimpleSequentialChain(chains=[chain1, chain2])
result = overall_chain.run("程序员")

为什么有效?

  • 把复杂任务分解成简单步骤
  • 每个步骤可以单独测试和优化
  • 支持多种组合方式(顺序、条件、映射)

核心原理 4:记忆抽象(Memory Abstraction)- 多种记忆方式

LangChain 提供多种记忆实现,适应不同场景:

# 1. 缓冲区记忆:记住最近几轮对话
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory(k=5)  # 记住最近5轮

# 2. 向量存储记忆:把历史存入向量库,检索相关部分
from langchain.memory import VectorStoreRetrieverMemory
memory = VectorStoreRetrieverMemory(retriever=retriever)

# 3. 摘要记忆:把历史总结成摘要
from langchain.memory import ConversationSummaryMemory
memory = ConversationSummaryMemory(llm=llm)

# 4. 组合记忆:多种记忆方式结合
from langchain.memory import CombinedMemory
memory = CombinedMemory(memories=[buffer_memory, summary_memory])

为什么有效? 不同的应用需要不同的记忆方式:

  • 客服机器人:需要记住最近几轮对话(缓冲区)
  • 个人助手:需要记住用户偏好(向量检索)
  • 长对话:需要摘要来压缩信息(摘要记忆)

核心原理 5:检索增强生成(RAG)- 让模型"先查后答"

这是 LangChain 最强大的功能之一:当模型不知道答案时,从外部知识库检索相关信息。

# 1. 加载文档
loader = PDFLoader("manual.pdf")
documents = loader.load()

# 2. 分割文档
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000)
docs = text_splitter.split_documents(documents)

# 3. 创建向量存储
vectorstore = Chroma.from_documents(docs, embeddings_model)

# 4. 创建检索器
retriever = vectorstore.as_retriever()

# 5. 创建 RAG 链
from langchain.chains import RetrievalQA
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",  # 把检索到的文档"塞"进提示词
    retriever=retriever
)

# 6. 提问
answer = qa_chain.run("如何设置用户权限?")

为什么有效?

  • 解决知识局限:模型只能记住训练时的知识,RAG 让它能访问最新文档
  • 解决长度限制:把长文档切成小块,只检索相关部分
  • 可追溯:你知道模型是基于哪些文档回答的,减少幻觉

核心原理 6:工具调用(Tool Calling)- 让 AI 能动手做事

LangChain 让 AI 可以调用外部工具:

from langchain.agents import Tool, AgentExecutor, create_react_agent

# 定义工具
tools = [
    Tool(
        name="Search",
        func=search_api.search,
        description="搜索互联网获取最新信息"
    ),
    Tool(
        name="Calculator",
        func=lambda x: eval(x),
        description="计算数学表达式"
    ),
    Tool(
        name="Weather",
        func=weather_api.get_weather,
        description="查询天气"
    )
]

# 创建智能体
agent = create_react_agent(llm, tools, prompt)

# 执行
agent_executor = AgentExecutor(agent=agent, tools=tools)
result = agent_executor.invoke({
    "input": "北京今天天气怎么样?顺便帮我算一下 25 的平方根是多少?"
})

为什么有效?

  • 扩展能力:AI 不再只是"说话",而是能"行动"
  • 实时信息:通过搜索工具获取最新信息
  • 精确计算:通过计算器工具避免数学错误

核心原理 7:智能体(Agent)- 让 AI 自主决策

智能体是 LangChain 最复杂的组件:它不是按固定流程执行,而是让 AI 自己决定下一步做什么。

from langchain.agents import create_react_agent
from langchain.agents import AgentExecutor

# ReAct 模式:Reason + Act
# 1. 思考:我需要查天气
# 2. 行动:调用天气工具
# 3. 观察:得到天气数据
# 4. 思考:还需要查航班吗?
# 5. 行动:调用航班工具
# 6. 思考:信息够了,可以回答

agent = create_react_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

result = agent_executor.invoke({
    "input": "我明天要去北京开会,帮我看看天气适合穿什么,再查一下最近的航班"
})

为什么有效?

  • 灵活性:不需要预先定义所有步骤
  • 适应性:根据中间结果调整后续行动
  • 解决复杂问题:多步推理+工具调用结合

核心原理 8:回调系统(Callbacks)- 可观测性

LangChain 提供完整的回调系统,让你能监控每一步的执行:

from langchain.callbacks import StdOutCallbackHandler, FileCallbackHandler

# 控制台输出
handler = StdOutCallbackHandler()

# 文件日志
file_handler = FileCallbackHandler("execution.log")

# 执行时可传入回调
chain.run(input="问题", callbacks=[handler, file_handler])

可以看到:

  • 调用了什么模型?花了多少 token?
  • 检索了哪些文档?相似度分数?
  • 智能体想了什么?调了什么工具?
  • 每一步花了多长时间?

为什么有效? 调试 AI 应用比传统应用更难,因为是非确定性的。回调系统让你能追踪执行过程,理解 AI 为什么这样回答。


第四步:用简单比喻理解 LangChain

想象 LangChain 是一个智能厨房

  • Models:你的厨师(可以是中国厨师、法国厨师、素食厨师,但他们都用同样的方式听你指令)
  • Prompts:菜谱(不是随口说"做道菜",而是有步骤、有配料的完整菜谱)
  • Memory:厨师的记忆力(记得你上次喜欢什么口味,记得今天已经做过什么菜)
  • Chains:烹饪流程(洗菜→切菜→炒菜→装盘,每一步有先后顺序)
  • Tools:厨房工具(刀、锅、烤箱、秤,厨师需要时会用)
  • Agents:自主厨师(你只说"做一顿健康的晚餐",他决定做什么菜、用什么工具、按什么顺序)
  • Document Loaders:食材采购员(去不同地方采购:菜市场、超市、网上)
  • Vector Stores:食材冷库(把食材切好分类存放,需要时快速取出)
  • RAG:先查菜谱再做菜(不确定的菜先翻菜谱书,找到相关步骤再动手)

你可以自己决定:

  • 只用厨师(直接调用模型)
  • 给厨师菜谱(提示词模板)
  • 给厨师流程(链)
  • 给厨师工具(工具)
  • 让厨师自己决定(智能体)

LangChain 就是帮你组装这个智能厨房的框架


第五步:LangChain 的本质是什么?

用第一性原理来看,LangChain 的本质是:一个用于构建基于大语言模型应用的组件化编排框架。

这个定义包含几个关键点:

1. 组件化

它不重新发明轮子,而是把 AI 应用开发中反复出现的模式抽象成可复用的组件:

  • 模型调用
  • 提示词管理
  • 记忆存储
  • 文档处理
  • 工具调用
  • 决策逻辑

2. 编排

它的核心不是组件本身,而是如何把这些组件组合起来

  • 链式编排:固定流程
  • 智能体编排:动态决策
  • 回调编排:可观测性

3. 框架

它提供的是骨架和规范,不是完整的应用:

  • 定义了组件接口
  • 提供了标准实现
  • 允许自定义扩展
  • 处理了通用问题(如 token 计数、重试、错误处理)

4. 大语言模型为中心

所有设计都围绕一个核心:让大模型更好地集成到应用中

  • 模型是"大脑"
  • 工具是"手脚"
  • 记忆是"短期/长期记忆"
  • 检索是"外部知识库"
  • 链是"思考流程"

所以,LangChain 不是"又一个 AI 工具",而是AI 应用开发的操作系统

  • 它提供了标准 API(就像操作系统提供文件系统、网络接口)
  • 它管理资源(token、内存、工具)
  • 它协调组件间的通信(链式调用、数据传递)
  • 它提供扩展机制(自定义组件、回调)

第六步:一个完整的 LangChain 应用示例

把以上原理综合起来,一个真实的 LangChain 应用可能长这样:

# 一个智能客服系统
from langchain import ...

# 1. 加载产品文档
loader = DirectoryLoader("./product_docs/", glob="**/*.pdf")
docs = loader.load()
splitter = RecursiveCharacterTextSplitter(chunk_size=1000)
chunks = splitter.split_documents(docs)

# 2. 创建向量库
vectorstore = Chroma.from_documents(chunks, embeddings)
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})

# 3. 设置记忆(记住用户历史)
memory = ConversationSummaryMemory(llm=llm, memory_key="chat_history")

# 4. 定义工具(查订单、退货、咨询人工)
tools = [
    Tool(name="OrderStatus", func=api.get_order_status, description="查询订单状态"),
    Tool(name="ReturnPolicy", func=db.get_return_policy, description="获取退货政策"),
    Tool(name="HumanHandoff", func=lambda x: "转接人工客服", description="转接人工")
]

# 5. 创建提示词模板
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是智能客服助手,基于产品文档回答问题。如果不知道,可以说需要转人工。"),
    ("human", "用户问题:{input}"),
    ("ai", "让我看看相关文档...")
])

# 6. 创建 RAG 链(先检索后回答)
rag_chain = RetrievalQA.from_chain_type(
    llm=llm,
    retriever=retriever,
    chain_type="stuff"
)

# 7. 创建智能体(能决定用 RAG 还是工具)
agent = create_react_agent(
    llm=llm,
    tools=tools + [Tool(name="RAG", func=rag_chain.run, description="检索产品文档")],
    prompt=prompt
)

# 8. 执行
agent_executor = AgentExecutor(agent=agent, tools=tools, memory=memory)
response = agent_executor.invoke({"input": "我的订单延迟了,能退货吗?"})

这个例子展示了:

  • 文档加载与分割
  • 向量检索(RAG)
  • 记忆管理
  • 工具定义
  • 提示词模板
  • 智能体决策
  • 链式组合

总结:LangChain 的三大价值

用第一性原理推导,LangChain 提供了三大核心价值:

价值一:抽象化(Abstraction) 把复杂的大模型交互抽象成简单一致的接口。你不用关心不同模型的 API 差异,不用手动处理 token 计数,不用重复实现记忆机制。

价值二:组合化(Composition) 把 AI 应用拆解成可组合的积木块。你可以像搭乐高一样,把检索、记忆、工具、提示词组合成复杂的应用流程。

价值三:自动化(Automation) 把固定的 AI 交互流程变成可重复执行的程序。从"每次写提示词"到"写一次代码,反复运行",从"手动操作"到"智能体自主决策"。

掌握了 LangChain,你就掌握了把大模型从聊天机器人升级为真正的应用程序的方法。它不只是工具,更是思维框架:如何用组件化的方式思考 AI 应用开发。