LangChain 从入门到实践:由浅入深 + DeepAgent 实战#

一份面向开发者的完整教程。从"什么是 LLM 应用"讲起,逐步覆盖 LangChain 核心组件与实战代码,最后深入官方 DeepAgent(deepagents) 框架,教你构建能规划、能读写文件、能调度子代理、拥有长期记忆的生产级智能体。

适用对象:有 Python 基础、想用大模型做真实应用的工程师。 技术栈版本基线:LangChain 0.3.x / LangGraph 0.2.x / deepagents 0.6+(API 与老版本 0.1 差异较大,请按本教程版本安装)。


目录#

  1. 前言:为什么需要 LangChain
  2. LangChain 生态全景:LangChain / LangGraph / LangSmith / DeepAgent
  3. 环境准备与第一个程序
  4. 核心概念一:Model I/O(模型、提示词、输出解析)
  5. 核心概念二:链(Chains)与 LCEL 表达式语言
  6. 核心概念三:记忆(Memory)与多轮对话
  7. 核心概念四:检索增强(RAG / Indexes)
  8. 核心概念五:工具(Tools)、MCP 与基础 Agent(含 8.3 用 MCP、8.4 写 MCP Server)
  9. 进阶:LangGraph 图式工作流
  10. 深入:DeepAgent(deepagents)官方智能体框架 + MCP 接入
  11. 融合实战:用 DeepAgent 串起前面所有能力
  12. 生产化与最佳实践
  13. 综合项目:私有文档智能分析 + 自动报告生成
  14. 附录:常见问题、版本迁移、学习资源

1. 前言:为什么需要 LangChain#

大语言模型(LLM)很强,但直接 curl 一个 API 只能做"一次性问答"。真实应用需要:

  • 把模型接入你的数据和工具(数据库、搜索引擎、内部 API);
  • 把多步逻辑编排成流程(先检索、再推理、后校验);
  • 记住上下文(多轮对话、长期记忆);
  • 可观测、可调试、可评估(知道每一步发生了什么);
  • 可靠地跑复杂任务(规划、委派、人在回路)。

LangChain 就是为解决这些问题而生的应用开发框架:它把"模型调用 / 提示词 / 检索 / 工具 / 记忆 / Agent"等能力封装成标准化、可组合的模块,让你像搭积木一样构建 LLM 应用。


2. LangChain 生态全景#

很多人混淆 LangChain / LangGraph / LangSmith / DeepAgent 的关系,这里一次讲清:

组件定位一句话
LangChain框架(核心构建块)提供 Models、Prompts、Chains、Retrievers、Tools 等基础组件
LangGraph运行时 / 编排引擎用"图"描述有状态、可循环、可中断的多步流程,是 Agent 的运行底座
LangSmith可观测平台追踪、调试、评估 LLM 应用(非必需,强烈推荐)
DeepAgent (deepagents)Agent 框架(harness)在 LangChain 核心组件 + LangGraph 运行时之上,开箱即用的"能规划、读写文件、调度子代理、有长期记忆"的智能体

关系链:DeepAgent 构建于 LangChain 核心组件 + LangGraph 运行时之上;LangSmith 贯穿三者做可观测。

关键认知:DeepAgent 不是另一个框架,而是 LangChain 生态里的"智能体高阶封装"。它复用了你前面学到的所有 LangChain 组件(模型、工具、提示词),只是替你把"规划 / 文件系统 / 子代理 / 记忆 / 人在回路"这些难做的工程活默认实现了。


3. 环境准备与第一个程序#

3.1 安装#

# 建议使用虚拟环境
python -m venv .venv && source .venv/bin/activate   # Windows: .venv\Scripts\activate

pip install -U langchain langchain-openai langchain-community langgraph
pip install -U deepagents            # DeepAgent(第 10 章使用)
pip install -U python-dotenv         # 管理密钥
pip install -U faiss-cpu             # 轻量向量库(RAG 用,可选 chroma)

3.2 配置密钥#

创建 .env 文件:

OPENAI_API_KEY=sk-xxxx
# 如使用 LangSmith 可观测:
LANGSMITH_TRACING=true
LANGSMITH_API_KEY=lsv2_xxxx
LANGSMITH_PROJECT=langchain-tutorial

3.3 第一个程序#

# hello_langchain.py
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI

load_dotenv()

# 1) 创建模型(Model)
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

# 2) 调用(自动处理消息格式)
response = llm.invoke("用一句话解释什么是 LangChain?")
print(response.content)

运行:python hello_langchain.py

要点

  • ChatOpenAI 属于 langchain-openai(独立包,遵循"一个厂商一个包"的设计)。
  • responseAIMessage 对象,response.content 是文本。
  • 模型返回的是消息对象,不是裸字符串——这是后面所有组合的基础。

4. 核心概念一:Model I/O#

LangChain 把"模型交互"抽象为三段式 Model I/O

Prompt(提示词) ──▶ Model(模型) ──▶ Output Parser(输出解析)

4.1 PromptTemplate:把提示词模板化#

from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个乐于助人的翻译员,只输出翻译结果,不要解释。"),
    ("user", "把下面这句话翻译成英文:\n{text}"),
])

# 渲染模板(得到可发给模型的消息列表)
messages = prompt.format_prompt(text="今天天气真好").to_messages()
print(messages)

4.2 Output Parser:把模型输出结构化#

from langchain_core.output_parsers import StrOutputParser, CommaSeparatedListOutputParser

# 字符串解析(最常用)
str_parser = StrOutputParser()

# 列表解析
list_parser = CommaSeparatedListOutputParser()
print(list_parser.parse("苹果, 香蕉, 橙子"))  # ['苹果', '香蕉', '橙子']

4.3 实战:迷你翻译器#

# translator.py
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4o-mini")
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是翻译员,只输出译文,不解释。目标语言:{language}"),
    ("user", "{text}"),
])
parser = StrOutputParser()

chain = prompt | llm | parser   # 这就是"链"(下一章详讲)

result = chain.invoke({"language": "English", "text": "LangChain 让构建大模型应用变得简单。"})
print(result)
# -> "LangChain makes building LLM applications simple."

5. 核心概念二:链(Chains)与 LCEL#

5.1 什么是链#

链(Chain)= 把多个组件用管道(pipe)串起来,前一个的输出是后一个的输入。LangChain 用 LCEL(LangChain Expression Language)| 操作符描述:

chain = prompt | llm | parser

这行代码本身就是一条链,可读、可组合、可流式、可批量。

5.2 LCEL 的核心优势#

  • 可组合:链可以再被 | 成更大的链。
  • 原生支持流式chain.stream(...)
  • 原生支持批量chain.batch([...])
  • 原生支持异步await chain.ainvoke(...)
  • 可观测:接入 LangSmith 自动追踪每一步。

5.3 实战:带结构化输出的"产品评论分析器"#

# review_analyzer.py
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field

# 用 Pydantic 定义结构化输出
class ReviewAnalysis(BaseModel):
    sentiment: str = Field(description="正面 / 负面 / 中性")
    score: float = Field(description="情感评分,0~1,越高越正面")
    keywords: list[str] = Field(description="关键观点词")

llm = ChatOpenAI(model="gpt-4o-mini")
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是电商评论分析专家,严格按 schema 输出 JSON。"),
    ("user", "分析这条评论:\n{review}"),
])

# with_structured_output 让模型直接返回结构化对象
structured_llm = llm.with_structured_output(ReviewAnalysis)
chain = prompt | structured_llm

result = chain.invoke({"review": "快递太慢了,等了一周才到,但产品质量还行。"})
print(result.sentiment, result.score, result.keywords)

5.4 组合更复杂的链#

# 先翻译,再分析(链中套链)
translate_chain = (
    ChatPromptTemplate.from_template("翻译成英文:{text}")
    | ChatOpenAI(model="gpt-4o-mini")
)

analyze_chain = translate_chain | structured_llm
print(analyze_chain.invoke({"text": "这家店服务态度很差。"}))

6. 核心概念三:记忆(Memory)与多轮对话#

真实对话要记住历史。LangChain 用 RunnableWithMessageHistory 把"历史"注入链。

# memory_chatbot.py
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.chat_history import InMemoryChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4o-mini")
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个友好的助手。"),
    MessagesPlaceholder("history"),   # 历史消息插入点
    ("user", "{input}"),
])

chain = prompt | llm

# 用 session_id 区分不同用户/会话
store = {}  # 生产环境换成 Redis / 数据库
def get_history(session_id):
    return store.setdefault(session_id, InMemoryChatMessageHistory())

chat = RunnableWithMessageHistory(
    chain,
    get_history,
    input_messages_key="input",
    history_messages_key="history",
)

cfg = {"configurable": {"session_id": "user-1"}}
print(chat.invoke({"input": "我叫小明。"}, config=cfg).content)
print(chat.invoke({"input": "我刚才说我叫什么?"}, config=cfg).content)  # 能记住"小明"

要点

  • MessagesPlaceholder("history") 是插入历史的位置。
  • get_history 决定历史存哪(内存 / Redis / LangGraph store)。
  • 生产环境务必把 store 换成持久化存储,否则重启即失忆。

7. 核心概念四:检索增强(RAG)#

RAG(Retrieval-Augmented Generation)= 先检索相关文档,再让模型基于检索内容回答,解决"模型不知道你的私有数据"的问题。

7.1 RAG 四步流水线#

文档加载(Loader) → 切分(Splitter) → 向量化+存储(Embeddings+VectorStore) → 检索+生成(Retriever+Chain)

7.2 实战:基于本地文档的问答#

# rag_demo.py
from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import FAISS
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser

# 1) 加载
docs = TextLoader("company_faq.txt", encoding="utf-8").load()

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

# 3) 向量化 + 入库
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(splits, embeddings)
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})

# 4) 检索 + 生成
llm = ChatOpenAI(model="gpt-4o-mini")
prompt = ChatPromptTemplate.from_template(
    "根据上下文回答。如果不知道就说不知道。\n上下文:{context}\n问题:{question}"
)

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

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

print(rag_chain.invoke("你们的退款政策是什么?"))

要点retriever | format_docs 表示"先检索,再把结果拼成文本",LCEL 让数据流动一目了然。


8. 核心概念五:工具(Tools)与基础 Agent#

8.1 Tool:让模型能"动手"#

from langchain_core.tools import tool

@tool
def get_weather(city: str) -> str:
    """获取指定城市的天气(示例,返回模拟数据)。"""
    return f"{city}:晴,26°C,微风。"

@tool
def calculator(expression: str) -> str:
    """计算一个数学表达式,如 '23 * 45 + 1'。"""
    return str(eval(expression))

@tool 装饰器自动从函数签名和 docstring 生成模型的"工具说明"。docstring 写得越清楚,模型越会用对

8.2 基础 Agent:ReAct(让模型自己决定调用哪个工具)#

# basic_agent.py
from langchain.agents import create_react_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4o-mini")
tools = [get_weather, calculator]

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个能用工具的助手,思考后再行动。"),
    ("user", "{input}"),
    ("assistant", "{agent_scratchpad}"),  # Agent 的中间思考记录
])

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

print(executor.invoke({"input": "北京现在多少度?如果温度乘 2 再加 10 是多少?"})["output"])

局限create_react_agent 适合简单场景,但缺乏文件系统、子代理、长期记忆、人在回路等能力——这正是 DeepAgent 要解决的。

8.3 MCP:用标准协议接入任意工具(进阶必读)#

前面我们用 @tool 手写工具。但真实世界里,大量能力(数据库、GitHub、文件系统、各种 SaaS API)已经有人做成了 MCP 服务器。如果每次都自己写 @tool 包装,重复劳动且难维护。

MCP(Model Context Protocol,模型上下文协议) 是 Anthropic 主导的开放标准,被戏称为"AI 的 USB-C 接口":它定义了一套统一协议,让任何 AI 应用都能通过标准接口连上任意 MCP 服务器,自动获得该服务器暴露的所有工具——无需为 each 服务写定制集成代码。

你的 Agent  ──标准协议(MCP)──▶  MCP 服务器A(数据库)
                              ├─▶  MCP 服务器B(文件系统)
                              └─▶  MCP 服务器C(GitHub/各种API)

在 LangChain 中接 MCP:用官方适配器 langchain-mcp-adapters,核心两步——

  1. MultiServerMCPClient 连接一个或多个 MCP 服务器;
  2. await client.get_tools() 把服务器上的工具自动转换为 LangChain 工具,之后可在任意 Agent / 链中使用。

安装

pip install langchain-mcp-adapters
# stdio 方式拉起本地服务器需要 Node 环境(npx)
# 例如官方文件系统服务器:npx -y @modelcontextprotocol/server-filesystem /tmp/workspace

实战:给基础 Agent 接入 MCP 工具(支持 stdio 本地进程 / http 远程服务两种传输)

# mcp_agent.py
import asyncio
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain.agents import create_agent   # 0.3+ 推荐的统一 Agent 工厂

async def main():
    client = MultiServerMCPClient({
        # ① stdio:本地子进程(如官方 filesystem 服务器)
        "filesystem": {
            "command": "npx",
            "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp/workspace"],
            "transport": "stdio",
        },
        # ② http:远程 MCP 服务(Streamable HTTP / SSE)
        "weather": {
            "url": "http://localhost:8000/mcp",
            "transport": "http",
        },
    })

    tools = await client.get_tools()   # 自动拉取所有 MCP 工具并转为 LangChain 工具

    # 与普通 @tool 完全一样喂给 Agent
    agent = create_agent("openai:gpt-4o", tools)
    result = await agent.ainvoke({
        "messages": [{"role": "user", "content": "列出 /tmp/workspace 下的文件,并告诉我天气。"}]
    })
    print(result["messages"][-1].content)
    await client.close()   # 记得关闭,释放子进程

asyncio.run(main())

要点

  • transport 支持 stdio(本地、跨语言子进程)、http/sse(远程服务)等多种方式。
  • 返回的 tools 就是标准 LangChain 工具,可与你自定义的 @tool 混用。
  • MCP 还支持 Resource(资源):把静态知识在启动时注入上下文(区别于运行时实时调用的 Tool),适合"只读背景资料"。
  • 一个 MultiServerMCPClient 可同时管理多台服务器、跨语言、统一编排——这正是 MCP 解耦"工具实现"与"Agent 业务"的价值。

8.4 自己动手写一个 MCP Server(造 MCP)#

会用 MCP 之后,下一步自然是把自己的数据/系统封装成 MCP 服务器,这样任何支持 MCP 的客户端(Claude Desktop、Cursor,以及我们在 8.3 / 10.8 写的 LangChain 与 DeepAgent)都能直接连上你的能力,无需为每个客户端各写一套集成。

官方 Python SDK 的底层写法 boilerplate 很多;社区主流(约七成 MCP 服务器在用)是 FastMCP,用装饰器 + 类型注解即可,JSON Schema、参数校验、传输层全帮你搞定。

安装

pip install fastmcp   # FastMCP 3.x

一个最小可运行的服务器my_server.py)——包含 MCP 的三种核心组件:

# my_server.py
from fastmcp import FastMCP

mcp = FastMCP("My First MCP Server")

# ① Tool:可被模型调用的"动作"(带类型注解 + docstring,自动生成 schema)
@mcp.tool
def add(a: int, b: int) -> int:
    """把两个整数相加。"""
    return a + b

# ② Resource:只读数据源(URI 模板可取参数,适合暴露静态/背景资料)
@mcp.resource("greeting://{name}")
def greeting(name: str) -> str:
    """按名字返回问候语(只读资源)。"""
    return f"Hello, {name}!"

# ③ Prompt:可复用的提示词模板
@mcp.prompt
def review_code(code: str) -> str:
    """生成一段代码审查提示词。"""
    return f"请审查下面这段代码的性能与安全性:\n{code}"

if __name__ == "__main__":
    mcp.run()   # 默认 stdio 传输

运行服务器(两种传输):

# 方式 A:stdio(本地客户端如 Claude Desktop 默认用这种,进程由客户端拉起)
python my_server.py

# 方式 B:HTTP(远程访问,端点为 http://host:port/mcp)
# 改 my_server.py 末行为:mcp.run(transport="streamable-http", host="0.0.0.0", port=8000)
# 或用 CLI:fastmcp run my_server.py:mcp --transport http --port 8000

本地调试fastmcp dev my_server.py 会启动 MCP Inspector(可视化 UI),可手动测试 Tool / Resource / Prompt。

闭环验证:这个服务器可以直接被我们前面写的代码消费——

# stdio 方式接入(对应 8.3 / 10.8 的 MultiServerMCPClient)
client = MultiServerMCPClient({
    "myserver": {
        "command": "python",
        "args": ["my_server.py"],   # 指向你刚写的文件
        "transport": "stdio",
    }
})
# 或 HTTP 方式:{"myserver": {"url": "http://localhost:8000/mcp", "transport": "http"}}
tools = await client.get_tools()    # 拿到的就是 add / greeting / review_code

对 DeepAgent 同样适用:把这些 tools 传给 create_deep_agent(tools=...) 即可(见 10.8)。你造的 MCP Server,被你自己学的 LangChain / DeepAgent 直接吃掉——这就是完整的"用 MCP → 造 MCP → 接入智能体"闭环。

开发注意事项

  • 函数类型注解 + docstring 直接决定工具 schema 与模型可见描述,写得清晰模型才用得对(与 @tool 同理)。
  • stdio 模式禁止向 stdout 打印调试信息(stdout 是 MCP 传输通道,会被污染);用 logging 或 stderr。
  • 返回值必须是可 JSON 序列化的类型(dict / list / str / int 等),不要返回自定义类实例。
  • MCP 本身不替你做鉴权;HTTP 部署要加 OAuth / 网关,敏感动作在工具内部做权限校验。

9. 进阶:LangGraph 图式工作流#

当流程需要分支、循环、状态、人工审批时,用 LangGraph 把步骤画成"图"。

# langgraph_demo.py
from typing import TypedDict
from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4o-mini")

class State(TypedDict):
    topic: str
    draft: str

def write(state: State):
    resp = llm.invoke(f"写一段关于 {state['topic']} 的简短介绍")
    return {"draft": resp.content}

def decide(state: State) -> str:
    # 简单规则:含敏感词则退回重写
    return "end" if "机密" not in state["draft"] else "rewrite"

graph = StateGraph(State)
graph.add_node("write", write)
graph.add_conditional_edges("write", decide, {"end": END, "rewrite": "write"})
graph.set_entry_point("write")
app = graph.compile()

print(app.invoke({"topic": "人工智能"}))

要点:LangGraph 的核心是"状态(State)+ 节点(Node)+ 边(Edge,可条件化)"。DeepAgent 内部正是基于这个运行时。


10. 深入:DeepAgent(deepagents)官方智能体框架#

这是本教程的重点结合部分。DeepAgent 是 LangChain 官方出品的"智能体框架(harness)",构建在 LangChain 核心组件 + LangGraph 运行时之上,开箱即用地提供:

能力说明
任务规划内置 write_todos,复杂任务自动拆解为步骤并跟踪进度
文件系统read_file / write_file / edit_file / ls / glob / grep,把大上下文卸载到文件,避免窗口溢出
代码执行沙箱后端下可 execute 运行 shell / 解释器
子代理委派task 工具生成专用子代理,隔离上下文、并行处理
长期记忆跨会话持久化记忆(LangGraph store)
人在回路敏感操作前中断,要求人工审批
技能(Skills)可复用的工作流与领域知识

10.1 安装#

pip install -U deepagents langchain-openai
# 可选:代码解释器(v0.6+)
pip install -U "deepagents[quickjs]"   # Python

10.2 实战 1:最小 DeepAgent#

# deepagent_minimal.py
from deepagents import create_deep_agent

def get_weather(city: str) -> str:
    """获取指定城市的天气。"""
    return f"{city}:晴,26°C。"

agent = create_deep_agent(
    model="openai:gpt-4o",          # 模型字符串格式:厂商:模型名
    tools=[get_weather],
    system_prompt="你是一个有用的助手。",
)

result = agent.invoke({
    "messages": [{"role": "user", "content": "旧金山的天气怎么样?"}]
})
print(result["messages"][-1].content)

与第 8 章对比:同样是"带天气工具",DeepAgent 不用你手写 ReAct 提示词和 agent_scratchpad,规划/工具调度/上下文管理都已内置。

10.3 实战 2:文件系统 + 研究任务(DeepAgent 的杀手锏)#

# deepagent_research.py
from deepagents import create_deep_agent

agent = create_deep_agent(
    model="openai:gpt-4o",
    system_prompt="你是一个研究助手。请使用文件工具保存中间结果。",
)

# 让 Agent 自己规划、检索、写文件
result = agent.invoke({
    "messages": [{
        "role": "user",
        "content": "调研 'LangGraph 是什么',把要点写入 research.md,并附上 3 个关键结论。",
    }]
})

# 文件系统后端可用 FilesystemBackend 指定落盘路径(见 10.6)

DeepAgent 会:① 写 write_todos 规划;② 调搜索/读取工具;③ 把长内容写入 research.md 避免撑爆上下文;④ 自动总结历史。

10.4 实战 3:子代理并行委派#

# deepagent_subagents.py
from deepagents import create_deep_agent

agent = create_deep_agent(
    model="openai:gpt-4o",
    system_prompt="遇到可并行的子问题,用 task 工具委派给子代理。",
)

result = agent.invoke({
    "messages": [{
        "role": "user",
        "content": "分别调研 '向量数据库'、'RAG'、'Agent 评估' 三个主题,各写一段总结,合并到 report.md。",
    }]
})

task 工具会 spawn 出隔离上下文窗口的子代理并行工作,主代理上下文保持干净——这是处理"又长又杂"任务的关键。

10.5 实战 4:长期记忆持久化#

# deepagent_memory.py
from deepagents import create_deep_agent

agent = create_deep_agent(
    model="openai:gpt-4o",
    system_prompt="记住用户的偏好,并在后续对话中使用。",
)

# 第一次
agent.invoke({"messages": [{"role": "user", "content": "我喜欢用中文,且关注成本优化。"}]})
# 后续新会话(基于 LangGraph store 持久化)
agent.invoke({"messages": [{"role": "user", "content": "帮我选个模型。"}]})  # 会记得你的偏好

10.6 实战 5:人在回路(Human-in-the-loop)#

# deepagent_hitl.py
from deepagents import create_deep_agent
from langgraph.checkpoint.memory import InMemorySaver

# 让删除/发送等敏感工具在执行前中断审批
agent = create_deep_agent(
    model="openai:gpt-4o",
    system_prompt="对不可逆操作必须先征求用户同意。",
)
checkpointer = InMemorySaver()
app = agent.with_config({"recursion_limit": 50})

# 运行到需要人工审批时,LangGraph 会 interrupt,等待人类 resume

安全原则(官方强调):DeepAgent 遵循"信任模型、边界在工具/沙箱层"的设计。敏感权限务必在工具或沙箱层面强制,而非指望模型自律。

10.7 实战 6:把 LangChain 工具/链接入 DeepAgent(融合点)#

你第 4–8 章写的所有 LangChain 组件,都能直接喂给 DeepAgent

# deepagent_integrate.py
from deepagents import create_deep_agent
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate

# 复用第 8 章的工具
@tool
def get_weather(city: str) -> str:
    """获取城市天气。"""
    return f"{city}:晴。"

# 复用第 5 章的链,包成工具
translate_chain = (
    ChatPromptTemplate.from_template("翻译成英文:{text}")
    | ChatOpenAI(model="gpt-4o-mini")
)

@tool
def translate(text: str) -> str:
    """把中文翻译成英文。"""
    return translate_chain.invoke({"text": text})

# 全部交给 DeepAgent 统一编排
agent = create_deep_agent(
    model="openai:gpt-4o",
    tools=[get_weather, translate],
    system_prompt="你是一个全能助手,合理使用工具完成任务。",
)

agent.invoke({"messages": [{"role": "user", "content": "把'北京天气不错'翻译成英文,并查北京的天气。"}]})

这就是"由浅入深"的闭环:基础组件 → 链 → 工具 → 基础 Agent → 最终用 DeepAgent 把它们组织成可靠的生产级智能体。

10.8 实战 7:让 DeepAgent 原生接入 MCP 服务器#

这是 DeepAgent 与 MCP 结合的最强力用法。DeepAgent 对 MCP 是一等公民支持:你只需用 MultiServerMCPClient 拉取 MCP 工具,直接传给 create_deep_agent(tools=...),MCP 工具就会和 DeepAgent 内置的 harness 工具(write_todos / read_file / task 等)、你的自定义 @tool 共存并协同工作

# deepagent_mcp.py
import asyncio
from langchain_mcp_adapters.client import MultiServerMCPClient
from deepagents import create_deep_agent

async def main():
    # 1) 连接 MCP 服务器(数据库 / API / 文件系统皆可)
    client = MultiServerMCPClient({
        "my_server": {
            "transport": "http",
            "url": "http://localhost:8000/mcp",
        }
    })
    tools = await client.get_tools()   # 转为 LangChain 工具

    # 2) 直接喂给 DeepAgent;MCP 工具 + 内置 harness 工具 + 自定义工具自动融合
    agent = create_deep_agent(
        model="openai:gpt-4o",
        tools=tools,
    )

    # 3) 运行(thread_id 用于记忆隔离,详见 10.5)
    result = await agent.ainvoke(
        {"messages": [{"role": "user", "content": "用 MCP 服务器帮我查一下数据库里最近的 5 笔订单,并整理成表格。"}]},
        config={"configurable": {"thread_id": "1"}},
    )
    print(result["messages"][-1].content)
    await client.close()

asyncio.run(main())

为什么这套组合特别强

  • DeepAgent 拿到 MCP 工具后,会自动规划该不该调、何时调、调哪个;
  • 调完的结果可以写入文件系统write_file)做上下文卸载,避免窗口溢出;
  • 复杂查询还能委派子代理task)并行处理;
  • 全程享有人在回路审批与长期记忆

一句话:MCP 负责"连得上、拿得到工具",DeepAgent 负责"规划好、用得稳"。把第 8.3 章的 MCP 能力直接喂给第 10 章的 DeepAgent,你就拥有了"既能用标准协议接遍全网工具、又能可靠跑复杂任务"的生产级智能体。

完整 MCP 配置(stdio 服务器、OAuth 鉴权、工具过滤、有状态会话等)参见官方 MCP 指南:https://docs.langchain.com/oss/python/langchain/mcp


11. 融合实战:用 DeepAgent 串起前面所有能力#

把 RAG(第 7 章)+ 工具(第 8 章)+ DeepAgent(第 10 章)组合成一个"能读私有文档、能联网、能写报告的智能研究助理":

# deepagent_full.py
from deepagents import create_deep_agent
from langchain_core.tools import tool
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings

# 1) 准备私有知识库(RAG 检索器)
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.load_local("my_kb", embeddings, allow_dangerous_deserialization=True)
retriever = vectorstore.as_retriever(k=3)

@tool
def search_knowledge_base(query: str) -> str:
    """在公司私有知识库中检索相关信息。"""
    docs = retriever.invoke(query)
    return "\n\n".join(d.page_content for d in docs)

@tool
def save_report(content: str) -> str:
    """把最终报告保存到 report.md。"""
    with open("report.md", "w", encoding="utf-8") as f:
        f.write(content)
    return "已保存 report.md"

# 2) 交给 DeepAgent 统一规划与执行
agent = create_deep_agent(
    model="openai:gpt-4o",
    tools=[search_knowledge_base, save_report],
    system_prompt="你是一个研究助理:先检索内部知识库,再整理成报告并保存。",
)

agent.invoke({
    "messages": [{
        "role": "user",
        "content": "基于内部知识库,整理一份'2026 产品规划要点'报告并保存。",
    }]
})

12. 生产化与最佳实践#

12.1 可观测:接入 LangSmith#

# 设置环境变量后,所有链/图自动追踪
os.environ["LANGSMITH_TRACING"] = "true"
os.environ["LANGSMITH_API_KEY"] = "lsv2_xxx"
os.environ["LANGSMITH_PROJECT"] = "prod-agents"

在 LangSmith 控制台能看到每一步的输入/输出、token 消耗、延迟、错误——调试 Agent 的必备。

12.2 流式输出(提升体验)#

# LCEL 链
for chunk in chain.stream({"input": "介绍一下 RAG"}):
    print(chunk, end="", flush=True)

# DeepAgent(v0.6+ 统一事件流)
stream = agent.stream_events(
    {"messages": [{"role": "user", "content": "研究 LangChain 流式"}]},
    version="v3",
)
for msg in stream.messages:
    for delta in msg.text:
        print(delta, end="", flush=True)

12.3 错误处理与重试#

# 给模型调用加重试与降级
llm_with_retry = llm.with_retry(retry_if_exception_type=Exception, stop_after_attempt=3)

12.4 成本与性能优化#

  • 模型分层:简单任务用 gpt-4o-mini,复杂推理才上 gpt-4o;DeepAgent 支持开源/低成本模型(如 GLM、DeepSeek)。
  • 提示词缓存:长 system prompt 启用缓存,降低重复计费。
  • 减少不必要检索:先判断是否需要 RAG,再调用。

12.5 安全与合规#

  • 工具层做权限白名单(尤其 execute/文件写)。
  • 敏感数据脱敏后再进模型。
  • 不可逆操作配置人在回路审批。

13. 综合项目:私有文档智能分析 + 自动报告生成#

把全教程串成一个可运行项目 project_report_agent/

project_report_agent/
├── .env                  # 密钥
├── kb/                   # 放入私有文档(.txt/.md/.pdf)
├── main.py               # 入口
├── build_kb.py           # 构建向量库
└── requirements.txt

build_kb.py

from langchain_community.document_loaders import DirectoryLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS

docs = DirectoryLoader("kb", glob="**/*.md").load()
splits = RecursiveCharacterTextSplitter(chunk_size=800, chunk_overlap=80).split_documents(docs)
FAISS.from_documents(splits, OpenAIEmbeddings()).save_local("my_kb")
print("知识库构建完成")

main.py

from deepagents import create_deep_agent
from langchain_core.tools import tool
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings

retriever = FAISS.load_local("my_kb", OpenAIEmbeddings(),
                             allow_dangerous_deserialization=True).as_retriever(k=4)

@tool
def search_kb(query: str) -> str:
    """检索公司私有知识库。"""
    return "\n\n".join(d.page_content for d in retriever.invoke(query))

@tool
def save_report(markdown: str) -> str:
    """保存最终报告到 output.md。"""
    with open("output.md", "w", encoding="utf-8") as f:
        f.write(markdown)
    return "报告已保存"

agent = create_deep_agent(
    model="openai:gpt-4o",
    tools=[search_kb, save_report],
    system_prompt="你是资深分析师:检索→分析→生成结构化 Markdown 报告→保存。",
)

agent.invoke({
    "messages": [{
        "role": "user",
        "content": "基于知识库生成《2026 上半年业务复盘与下半年策略》报告,含数据、风险、行动计划三章。",
    }]
})

运行:python build_kb.py && python main.py。一个能"读你家文档、自动写报告"的生产级智能体就跑起来了。


14. 附录#

14.1 常见问题#

问题解决
ImportError: cannot import name 'ChatOpenAI'忘记装 langchain-openai,或混用了老版 langchain
模型返回空 / 不调用工具检查 @tool 的 docstring 是否清晰,工具签名类型是否标注
RAG 答非所问调小 chunk_size、增大 k、换更强 embedding
DeepAgent 不写文件确认用了支持文件系统的后端(默认内存态),生产用 FilesystemBackend
上下文溢出依赖 DeepAgent 的自动摘要 + 文件卸载,或手动压缩历史

14.2 版本迁移提醒#

  • LangChain 0.2+ 已拆分厂商包(langchain-openai 等),不要再 from langchain.llms import OpenAI
  • ConversationChain 等旧记忆 API 已弃用,统一用 LCEL + RunnableWithMessageHistory
  • Agent 推荐路径:create_react_agent(简单)→ deepagents.create_deep_agent(生产复杂任务)

14.3 学习资源#

  • 官方文档:https://docs.langchain.com (含 DeepAgent 专页)
  • 中文文档:https://langchain-zh.cn
  • deepagents 仓库:https://github.com/langchain-ai/deepagents
  • LangGraph:https://langchain-ai.github.io/langgraph/
  • LangSmith:https://docs.smith.langchain.com
  • 示例库:https://github.com/langchain-ai/langchain/tree/master/libs/community

学习路线小结#

第3章 第一个程序
   ↓
第4章 Model I/O(提示词 / 解析)
   ↓
第5章 链 LCEL(组件组合)
   ↓
第6章 记忆(多轮对话)
   ↓
第7章 RAG(私有数据问答)
   ↓
第8章 工具 + 基础 Agent
   ↓
第9章 LangGraph(图式编排)
   ↓
第10章 DeepAgent(官方智能体框架:规划/文件系统/子代理/记忆/人在回路)
   ↓
第11–13章 融合实战 + 生产化 + 综合项目

核心理念:LangChain 给你"积木",LangGraph 给你"流水线轨道",而 DeepAgent 是把这些积木 + 轨道封装成一辆能自己开、自己修、自己记路的车。从基础组件学起,最终用 DeepAgent 收口,你就能从"会调 API"成长为"能交付可靠 LLM 应用"的工程师。

本教程所有代码基于 LangChain 0.3.x / LangGraph 0.2.x / deepagents 0.6+。运行前请安装对应版本并配置 OPENAI_API_KEY。如需替换为其他模型厂商,只需换对应集成包(如 langchain-anthropiclangchain-google-genai)并调整 model 参数即可。