第15章:LangChain 框架——Agent 开发的瑞士军刀

第15章:LangChain 框架——Agent 开发的瑞士军刀

系列导读:LangChain 是 Agent 开发的主流框架。本章讲框架架构、核心概念和实战决策——“什么时候用 LangChain,什么时候应该甩开它”。


一、LangChain 要解决的问题

手工实现一个 Agent,你需要写:

  • Tool 注册与解析
  • Prompt 模板管理
  • Memory 存储维护
  • Agent 循环逻辑(ReAct / Plan-and-Execute)
  • 错误处理和重试
  • 多 Agent 协作(如果需要)

LangChain 把这些都封装成了可复用的组件和链式工具,让 Agent 开发从"从零搭建"变成"组装积木"。

二、LangChain 核心概念

1. Chain(链)

将多个组件按顺序串起来执行:

chain = prompt_template | llm | output_parser
result = chain.invoke({"input": "分析这份数据"})

每个 | 表示前一个组件的输出经过变换传给下一个组件。

2. Agent

预先封装好的 Agent 循环:

agent = create_react_agent(
    tools=tools,
    llm=llm,
    prompt=prompt
)
agent_executor = AgentExecutor(agent=agent, tools=tools, max_iterations=10)
result = agent_executor.invoke({"input": "帮我查天气"})

预置的 Agent 类型:

  • ReAct Agent:Thought → Action → Observation 循环
  • Plan-and-Execute Agent:先规划计划,再按步骤执行
  • Structured Chat Agent:支持多参数工具调用
  • Conversational Agent:带记忆的对话型 Agent

3. Tool

from langchain.tools import tool

@tool
def get_weather(city: str) -> str:
    """查询指定城市的天气信息。"""
    return f"{city}今天天气晴朗,25度"

tools = [get_weather]

装饰自动提取函数签名和 docstring 作为 tool schema,非常简洁。

4. Memory

from langchain.memory import ConversationBufferMemory

memory = ConversationBufferMemory()
memory.save_context({"input": "我喜欢简洁风格"}, {"output": "好的,我会注意"})
# memory 会自动维护对话历史,在 Agent 调用时作为 context 注入

5. Retriever(检索器)

把 RAG 的检索部分封装好:

retriever = Chroma.from_documents(docs, embeddings).as_retriever()
result = retriever.invoke("什么是 RAG?")

三、LangChain 的优势

  1. 快速原型:组装积木的方式,几小时就能跑通一个 Agent
  2. 生态丰富:内置大量 ready-to-use 的 tools、retrievers、memory 模块
  3. 标准接口:统一的 invoke/stream/batch 接口,切换底层模型无痛
  4. 调试友好:链式调用的中间步骤都能打印出来

四、LangChain 的天坑

坑1:过度封装

LangChain 的链式抽象堆了太多层,理解一个简单调用背后实际发生了什么,需要追踪好几层源码。

坑2:性能问题

链式调用每层都有类型转换、验证、异常捕获,对高频场景来说有不可忽视的 overhead。

坑3:版本迭代快

API 变动频繁,一个用 v0.1 写的项目,几个月后 v0.2 就 break。

坑4:不适合深度定制

你要做一个高度定制的推理流程,LangChain 的约束框架可能碍手碍脚。

五、“什么时候用 LangChain,什么时候手搓?”

场景 推荐方案
快速原型验证 / MVP 用 LangChain
标准 Agent 模式(ReAct、工具调用) 用 LangChain
内部工具/低频应用 用 LangChain
高并发生产服务 手搓核心关键路径
极度定制化的推理流程 手搓
需要极致性能优化 手搓
大规模 Multi-Agent 系统 手搓核心编排,局部用框架

最务实的做法:用 LangChain 快速做出 MVP,验证业务价值后再决定哪些部分需要重写。

六、LangChain 实战:一个完整的 RAG Agent

from langchain import hub
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_chroma import Chroma
from langchain_community.document_loaders import WebBaseLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser

# 1. 加载文档
loader = WebBaseLoader("https://docs.python.org/3/")
docs = loader.load()

# 2. 切割
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
splits = text_splitter.split_documents(docs)

# 3. 存入向量库
vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings())
retriever = vectorstore.as_retriever()

# 4. 构建 RAG Chain
prompt = hub.pull("rlm/rag-prompt")
llm = ChatOpenAI(model="gpt-4o")

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

rag_chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

# 5. 使用
response = rag_chain.invoke("Python 的 GIL 是什么?")

七、LangChain 的替代者

框架 特点 适用场景
LangGraph LangChain 官方出的图编排工具,比链更灵活 复杂 Multi-Agent 编排
LlamaIndex 专注 RAG,文档加载和索引更强 知识库/文档问答
CrewAI 专注 Multi-Agent 协作场景 多智能体项目
AutoGen 微软出的 Multi-Agent 对话框架 研究/多轮讨论
直接 SDK 不用框架,直接调 OpenAI/Anthropic SDK 简单/高性能场景

八、本章小结

  • LangChain 是 Agent/RAG 快速开发和原型验证的首选框架
  • 核心概念:Chain、Agent、Tool、Memory、Retriever
  • 优势是组装敏捷和生态丰富,劣势是过度封装和性能开销
  • 选型建议:MVP 用 LangChain,生产级核心路径可重写
  • LlamaIndex(RAG 更强)、CrewAI(Multi-Agent 更强)是重要替代方案

思考题

  1. 你在什么情况下会用 LlamaIndex 而不是 LangChain?两个框架的核心差异在哪?
  2. 如果你的 Agent 需要同时走 “向量检索 + API 调用 + 代码执行 + 最终报告生成” 四条路径,LangChain 的链式抽象够用吗?你会怎么设计架构?