云计算百科
云计算领域专业知识百科平台

LangChain框架完全指南(介绍与使用)

LangChain 框架完全指南:从 1.0 重构到 Agent 实战

一句话总结:LangChain 是目前最流行的 LLM 应用开发框架——它不训练模型,而是解决「怎么把大模型接进真实软件」这件事:统一各家模型的调用接口、把提示词/工具/记忆/检索标准化成可组合的组件、并提供一套 Agent 运行时(循环调用模型 → 执行工具 → 再调用)。2025 年 10 月它发布了 1.0,把框架大幅收缩:旧的 LLMChain、AgentExecutor 全部移出主包,新核心只剩一个函数 create_agent,外加一套中间件机制。这意味着网上 2024 年的教程基本全部失效——本篇按当前 langchain 1.4.2 的实际接口写,并专门给了一节「老教程排错对照表」。


📋 目录

  • LangChain 是什么,它到底解决什么问题
  • ⚠️ 最重要的一件事:1.0 把旧教程全废了
  • 生态全景:一张图看懂七个包的分工
  • 核心概念:四个词吃透 LangChain
  • 安装与环境准备(含国内 DeepSeek 方案)
  • 第一个 Agent:10 行代码跑通
  • 逐项拆解:LangChain 的六项核心能力
  • LCEL 与 Runnable:底层协议
  • RAG 实战:三种架构与完整代码
  • 什么时候该用 LangGraph
  • LangSmith:可观测性与评测
  • 常见问题 FAQ(含老教程报错排查)
  • 总结

  • 一、LangChain 是什么,它到底解决什么问题

    1.1 一句话定位

    LangChain 不训练模型,也不提供模型。 它是一层「胶水 + 骨架」,把大模型和你的代码、数据、工具连起来。

    用一句话概括它的价值:让你不用为每一个模型供应商、每一种数据源、每一套重试/流式/日志逻辑重复造轮子。

    1.2 没有框架时,你会遇到什么问题

    假设你想做一个「企业知识库问答」:

    # 直接用官方 SDK 的写法(示意)
    import openai

    resp = openai.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": f"根据以下资料回答问题:\\n{context}\\n\\n问题:{question}"}],
    )
    answer = resp.choices[0].message.content

    这段代码能跑。但一旦要做成产品,你会立刻撞上这堆问题:

    问题手写要处理什么
    换模型 每家 SDK 的调用方式、参数名、返回结构都不同,换一家要重写一遍
    流式输出 前端要一个字一个字出,得自己处理 SSE、分块拼接、异常中断
    并发批处理 100 条数据要并发跑,得自己写 asyncio / 线程池和限流
    工具调用 模型要调用外部 API,得自己写 JSON Schema、解析工具调用、处理失败重试
    多轮记忆 会话历史要自己存、自己裁剪、自己控制 token 预算
    RAG 检索 文档切分、向量化、入库、召回、重排,每步都是一套独立逻辑
    可观测性 一次请求经过 7 个步骤,出错了根本不知道死在哪
    重试与降级 主模型挂了要切备用模型,要自己写 fallback

    LangChain 的做法是把这些抽象成统一的「组件协议」:

    #mermaid-svg-j7u0AQx2w870s6N3{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-j7u0AQx2w870s6N3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-j7u0AQx2w870s6N3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-j7u0AQx2w870s6N3 .error-icon{fill:#552222;}#mermaid-svg-j7u0AQx2w870s6N3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-j7u0AQx2w870s6N3 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-j7u0AQx2w870s6N3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-j7u0AQx2w870s6N3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-j7u0AQx2w870s6N3 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-j7u0AQx2w870s6N3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-j7u0AQx2w870s6N3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-j7u0AQx2w870s6N3 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-j7u0AQx2w870s6N3 .marker.cross{stroke:#333333;}#mermaid-svg-j7u0AQx2w870s6N3 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-j7u0AQx2w870s6N3 p{margin:0;}#mermaid-svg-j7u0AQx2w870s6N3 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-j7u0AQx2w870s6N3 .cluster-label text{fill:#333;}#mermaid-svg-j7u0AQx2w870s6N3 .cluster-label span{color:#333;}#mermaid-svg-j7u0AQx2w870s6N3 .cluster-label span p{background-color:transparent;}#mermaid-svg-j7u0AQx2w870s6N3 .label text,#mermaid-svg-j7u0AQx2w870s6N3 span{fill:#333;color:#333;}#mermaid-svg-j7u0AQx2w870s6N3 .node rect,#mermaid-svg-j7u0AQx2w870s6N3 .node circle,#mermaid-svg-j7u0AQx2w870s6N3 .node ellipse,#mermaid-svg-j7u0AQx2w870s6N3 .node polygon,#mermaid-svg-j7u0AQx2w870s6N3 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-j7u0AQx2w870s6N3 .rough-node .label text,#mermaid-svg-j7u0AQx2w870s6N3 .node .label text,#mermaid-svg-j7u0AQx2w870s6N3 .image-shape .label,#mermaid-svg-j7u0AQx2w870s6N3 .icon-shape .label{text-anchor:middle;}#mermaid-svg-j7u0AQx2w870s6N3 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-j7u0AQx2w870s6N3 .rough-node .label,#mermaid-svg-j7u0AQx2w870s6N3 .node .label,#mermaid-svg-j7u0AQx2w870s6N3 .image-shape .label,#mermaid-svg-j7u0AQx2w870s6N3 .icon-shape .label{text-align:center;}#mermaid-svg-j7u0AQx2w870s6N3 .node.clickable{cursor:pointer;}#mermaid-svg-j7u0AQx2w870s6N3 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-j7u0AQx2w870s6N3 .arrowheadPath{fill:#333333;}#mermaid-svg-j7u0AQx2w870s6N3 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-j7u0AQx2w870s6N3 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-j7u0AQx2w870s6N3 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-j7u0AQx2w870s6N3 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-j7u0AQx2w870s6N3 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-j7u0AQx2w870s6N3 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-j7u0AQx2w870s6N3 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-j7u0AQx2w870s6N3 .cluster text{fill:#333;}#mermaid-svg-j7u0AQx2w870s6N3 .cluster span{color:#333;}#mermaid-svg-j7u0AQx2w870s6N3 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-j7u0AQx2w870s6N3 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-j7u0AQx2w870s6N3 rect.text{fill:none;stroke-width:0;}#mermaid-svg-j7u0AQx2w870s6N3 .icon-shape,#mermaid-svg-j7u0AQx2w870s6N3 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-j7u0AQx2w870s6N3 .icon-shape p,#mermaid-svg-j7u0AQx2w870s6N3 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-j7u0AQx2w870s6N3 .icon-shape .label rect,#mermaid-svg-j7u0AQx2w870s6N3 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-j7u0AQx2w870s6N3 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-j7u0AQx2w870s6N3 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-j7u0AQx2w870s6N3 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    你的业务代码

    LangChain 统一接口

    OpenAI

    Anthropic

    DeepSeek

    Ollama 本地

    Chroma / FAISS

    PostgreSQL / Milvus

    工具 / API / MCP

    换模型 = 改一个字符串。加检索 = 加一个组件。这套抽象就是它的核心卖点。

    1.3 诚实的边界:什么时候不该用 LangChain

    这点很多教程不说,但很重要:

    你的场景建议
    只调用一次 LLM,固定 prompt ❌ 直接用官方 SDK。LangChain 只会增加抽象层和心智负担
    固定的 2–4 步流水线(检索 → 提示 → 模型) ✅ LCEL 很合适
    Agent 循环、工具调用、需要人工审批 ✅✅ 这正是 LangChain / LangGraph 的主场
    极致性能、不需要任何观测 ❌ 直接调 SDK 更快
    需要极复杂的自定义状态机 ✅ 用 LangGraph(LangChain 的底层编排框架)

    🎯 一句话判断标准:如果你在写「胶水代码」超过 50 行,LangChain 就值了;如果只是单次 API 调用,它只会碍事。

    1.4 关键信息一览(数据截至 2026-09)

    项目内容
    当前版本 langchain 1.4.2(2026-09-19 发布)
    核心库 langchain-core 1.6.0(2026-08-19)
    编排框架 langgraph 1.2.12(2026-09-21)
    1.0 GA 时间 2025-10-22(与 LangGraph 1.0 同日)
    Python 要求 3.10 – 3.14
    开源协议 MIT
    GitHub Stars langchain 约 147k;langgraph 约 42.3k
    生态规模 数百个集成包(模型 / 向量库 / 加载器 / 工具)
    商业产品 LangSmith(可观测性)、LangGraph Platform(部署)
    官方课程 LangChain Academy(免费)

    二、⚠️ 最重要的一件事:1.0 把旧教程全废了

    如果你在网上搜到 2024 年的 LangChain 教程,照抄会直接报 ImportError——不是你的环境问题,是 API 真的删了。

    2.1 发生了什么

    #mermaid-svg-5XRgcu1cT5wZEHDD{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5XRgcu1cT5wZEHDD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5XRgcu1cT5wZEHDD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5XRgcu1cT5wZEHDD .error-icon{fill:#552222;}#mermaid-svg-5XRgcu1cT5wZEHDD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5XRgcu1cT5wZEHDD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5XRgcu1cT5wZEHDD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5XRgcu1cT5wZEHDD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5XRgcu1cT5wZEHDD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5XRgcu1cT5wZEHDD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5XRgcu1cT5wZEHDD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5XRgcu1cT5wZEHDD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5XRgcu1cT5wZEHDD .marker.cross{stroke:#333333;}#mermaid-svg-5XRgcu1cT5wZEHDD svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5XRgcu1cT5wZEHDD p{margin:0;}#mermaid-svg-5XRgcu1cT5wZEHDD .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-5XRgcu1cT5wZEHDD .cluster-label text{fill:#333;}#mermaid-svg-5XRgcu1cT5wZEHDD .cluster-label span{color:#333;}#mermaid-svg-5XRgcu1cT5wZEHDD .cluster-label span p{background-color:transparent;}#mermaid-svg-5XRgcu1cT5wZEHDD .label text,#mermaid-svg-5XRgcu1cT5wZEHDD span{fill:#333;color:#333;}#mermaid-svg-5XRgcu1cT5wZEHDD .node rect,#mermaid-svg-5XRgcu1cT5wZEHDD .node circle,#mermaid-svg-5XRgcu1cT5wZEHDD .node ellipse,#mermaid-svg-5XRgcu1cT5wZEHDD .node polygon,#mermaid-svg-5XRgcu1cT5wZEHDD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5XRgcu1cT5wZEHDD .rough-node .label text,#mermaid-svg-5XRgcu1cT5wZEHDD .node .label text,#mermaid-svg-5XRgcu1cT5wZEHDD .image-shape .label,#mermaid-svg-5XRgcu1cT5wZEHDD .icon-shape .label{text-anchor:middle;}#mermaid-svg-5XRgcu1cT5wZEHDD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5XRgcu1cT5wZEHDD .rough-node .label,#mermaid-svg-5XRgcu1cT5wZEHDD .node .label,#mermaid-svg-5XRgcu1cT5wZEHDD .image-shape .label,#mermaid-svg-5XRgcu1cT5wZEHDD .icon-shape .label{text-align:center;}#mermaid-svg-5XRgcu1cT5wZEHDD .node.clickable{cursor:pointer;}#mermaid-svg-5XRgcu1cT5wZEHDD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5XRgcu1cT5wZEHDD .arrowheadPath{fill:#333333;}#mermaid-svg-5XRgcu1cT5wZEHDD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5XRgcu1cT5wZEHDD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5XRgcu1cT5wZEHDD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5XRgcu1cT5wZEHDD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5XRgcu1cT5wZEHDD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5XRgcu1cT5wZEHDD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5XRgcu1cT5wZEHDD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5XRgcu1cT5wZEHDD .cluster text{fill:#333;}#mermaid-svg-5XRgcu1cT5wZEHDD .cluster span{color:#333;}#mermaid-svg-5XRgcu1cT5wZEHDD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5XRgcu1cT5wZEHDD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5XRgcu1cT5wZEHDD rect.text{fill:none;stroke-width:0;}#mermaid-svg-5XRgcu1cT5wZEHDD .icon-shape,#mermaid-svg-5XRgcu1cT5wZEHDD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5XRgcu1cT5wZEHDD .icon-shape p,#mermaid-svg-5XRgcu1cT5wZEHDD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5XRgcu1cT5wZEHDD .icon-shape .label rect,#mermaid-svg-5XRgcu1cT5wZEHDD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5XRgcu1cT5wZEHDD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5XRgcu1cT5wZEHDD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5XRgcu1cT5wZEHDD :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    0.x 时代2022-2025包罗万象的 chain 动物园

    2025-10-22LangChain 1.0 GA大幅收缩 + 稳定承诺

    主包只留四件事agents / models / messages / tools

    其余全部搬到langchain-classic

    两件事比版本号重要得多:

    ① 范围收缩(Scope Cut) langchain 主包不再尝试容纳过去三年所有的 chain 模式,只保留四件事:agents、models、messages、tools。所有旧东西——LLMChain、各种 pre-built chains、AgentExecutor——搬到了一个字面就叫 classic 的包里:

    # 旧代码的新地址
    from langchain_classic.chains import LLMChain

    这个命名很诚实:框架在告诉你,这是博物馆展区。

    ② 稳定性承诺(Stability Promise) 1.0 承诺 在 2.0 之前不做破坏性变更。听起来很无聊,但对一个「每隔几个月就搞崩一次教程」的库来说,这可能是这次发布里最大的功能。

    2.2 为什么收缩:2023 的问题和 2026 的问题不一样

    年份那时的问题那时的答案
    2023 「我怎么把提示词拼起来?」 Chains
    2026 「我怎么让模型在工具循环里安全地跑起来?」 Agents

    Agents 赢了,包结构现在直接承认了这一点。

    2.3 新旧对照表(速查)

    你想做什么老写法(0.x)新写法(1.x)
    调用模型 ChatOpenAI(…) init_chat_model("openai:gpt-5.5")
    拼提示 + 调用 LLMChain(llm=…, prompt=…) prompt | model | parser
    构建 Agent initialize_agent(…) / AgentExecutor create_agent(…)
    ReAct Agent langgraph.prebuilt.create_react_agent 已弃用 → create_agent
    加记忆 ConversationChain / ConversationBufferMemory checkpointer / RunnableWithMessageHistory
    旧 chain 导入 from langchain.chains import … from langchain_classic.chains import …
    文本切分 from langchain.text_splitter import … from langchain_text_splitters import …
    Chroma from langchain_community.vectorstores import Chroma from langchain_chroma import Chroma

    三、生态全景:一张图看懂七个包的分工

    这是理解 LangChain 最容易被绕晕的地方——它不是一个包,是一族包。

    #mermaid-svg-29xA3rNaDeSTS5OD{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-29xA3rNaDeSTS5OD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-29xA3rNaDeSTS5OD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-29xA3rNaDeSTS5OD .error-icon{fill:#552222;}#mermaid-svg-29xA3rNaDeSTS5OD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-29xA3rNaDeSTS5OD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-29xA3rNaDeSTS5OD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-29xA3rNaDeSTS5OD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-29xA3rNaDeSTS5OD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-29xA3rNaDeSTS5OD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-29xA3rNaDeSTS5OD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-29xA3rNaDeSTS5OD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-29xA3rNaDeSTS5OD .marker.cross{stroke:#333333;}#mermaid-svg-29xA3rNaDeSTS5OD svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-29xA3rNaDeSTS5OD p{margin:0;}#mermaid-svg-29xA3rNaDeSTS5OD .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-29xA3rNaDeSTS5OD .cluster-label text{fill:#333;}#mermaid-svg-29xA3rNaDeSTS5OD .cluster-label span{color:#333;}#mermaid-svg-29xA3rNaDeSTS5OD .cluster-label span p{background-color:transparent;}#mermaid-svg-29xA3rNaDeSTS5OD .label text,#mermaid-svg-29xA3rNaDeSTS5OD span{fill:#333;color:#333;}#mermaid-svg-29xA3rNaDeSTS5OD .node rect,#mermaid-svg-29xA3rNaDeSTS5OD .node circle,#mermaid-svg-29xA3rNaDeSTS5OD .node ellipse,#mermaid-svg-29xA3rNaDeSTS5OD .node polygon,#mermaid-svg-29xA3rNaDeSTS5OD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-29xA3rNaDeSTS5OD .rough-node .label text,#mermaid-svg-29xA3rNaDeSTS5OD .node .label text,#mermaid-svg-29xA3rNaDeSTS5OD .image-shape .label,#mermaid-svg-29xA3rNaDeSTS5OD .icon-shape .label{text-anchor:middle;}#mermaid-svg-29xA3rNaDeSTS5OD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-29xA3rNaDeSTS5OD .rough-node .label,#mermaid-svg-29xA3rNaDeSTS5OD .node .label,#mermaid-svg-29xA3rNaDeSTS5OD .image-shape .label,#mermaid-svg-29xA3rNaDeSTS5OD .icon-shape .label{text-align:center;}#mermaid-svg-29xA3rNaDeSTS5OD .node.clickable{cursor:pointer;}#mermaid-svg-29xA3rNaDeSTS5OD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-29xA3rNaDeSTS5OD .arrowheadPath{fill:#333333;}#mermaid-svg-29xA3rNaDeSTS5OD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-29xA3rNaDeSTS5OD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-29xA3rNaDeSTS5OD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-29xA3rNaDeSTS5OD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-29xA3rNaDeSTS5OD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-29xA3rNaDeSTS5OD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-29xA3rNaDeSTS5OD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-29xA3rNaDeSTS5OD .cluster text{fill:#333;}#mermaid-svg-29xA3rNaDeSTS5OD .cluster span{color:#333;}#mermaid-svg-29xA3rNaDeSTS5OD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-29xA3rNaDeSTS5OD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-29xA3rNaDeSTS5OD rect.text{fill:none;stroke-width:0;}#mermaid-svg-29xA3rNaDeSTS5OD .icon-shape,#mermaid-svg-29xA3rNaDeSTS5OD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-29xA3rNaDeSTS5OD .icon-shape p,#mermaid-svg-29xA3rNaDeSTS5OD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-29xA3rNaDeSTS5OD .icon-shape .label rect,#mermaid-svg-29xA3rNaDeSTS5OD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-29xA3rNaDeSTS5OD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-29xA3rNaDeSTS5OD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-29xA3rNaDeSTS5OD :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    旁路

    底座

    集成层(按需安装)

    高层(开箱即用)

    你的应用

    业务代码

    langchaincreate_agent + models + messages + tools

    langgraphStateGraph / 编排 / 运行时

    langchain-openai

    langchain-anthropic

    langchain-deepseek

    langchain-ollama

    langchain-chroma / -postgres / -milvus …

    langchain-coreRunnable / LCEL / MessagePrompt / OutputParser / 抽象接口

    langchain-classic旧的 chains(博物馆)

    LangSmith可观测性 / 评测(商业)

    包名作用什么时候装
    langchain-core 底座。Runnable 协议、LCEL、消息类型、提示词模板、输出解析器、抽象接口 被依赖,自动装
    langchain 主包。create_agent、模型/消息/工具的核心构建模块 做 Agent 就装
    langgraph 编排框架与运行时。状态图、持久化、流式、人工干预 需要复杂流程时
    langchain-<provider> 集成包。各模型/向量库的具体实现 用到哪个装哪个
    langchain-classic 旧版遗留。LLMChain 等 只在维护老项目时装
    langchain-text-splitters 文本切分器 做 RAG 时装
    langchain-community 社区集成(大量文档加载器等) 按需
    LangSmith 追踪 / 评测 / 提示词管理 可选,商业服务

    💡 关键理解:create_agent 底层跑在 LangGraph 上。 这意味着你不需要会 LangGraph,就能白拿它的:持久化、流式处理、人工干预、时间旅行。 这也解释了为什么 langgraph 会出现在依赖里——高层 API 的收益,来自底层运行时的能力。

    3.1 官方推荐的「分层使用」路径

    官方明确说过:先用高层 API,需要时再下沉——这不是权宜之计,这是设计意图。

    #mermaid-svg-bcX5mh4ECX7ZMoBk{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-bcX5mh4ECX7ZMoBk .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-bcX5mh4ECX7ZMoBk .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-bcX5mh4ECX7ZMoBk .error-icon{fill:#552222;}#mermaid-svg-bcX5mh4ECX7ZMoBk .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-bcX5mh4ECX7ZMoBk .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-bcX5mh4ECX7ZMoBk .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-bcX5mh4ECX7ZMoBk .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-bcX5mh4ECX7ZMoBk .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-bcX5mh4ECX7ZMoBk .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-bcX5mh4ECX7ZMoBk .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-bcX5mh4ECX7ZMoBk .marker{fill:#333333;stroke:#333333;}#mermaid-svg-bcX5mh4ECX7ZMoBk .marker.cross{stroke:#333333;}#mermaid-svg-bcX5mh4ECX7ZMoBk svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-bcX5mh4ECX7ZMoBk p{margin:0;}#mermaid-svg-bcX5mh4ECX7ZMoBk .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-bcX5mh4ECX7ZMoBk .cluster-label text{fill:#333;}#mermaid-svg-bcX5mh4ECX7ZMoBk .cluster-label span{color:#333;}#mermaid-svg-bcX5mh4ECX7ZMoBk .cluster-label span p{background-color:transparent;}#mermaid-svg-bcX5mh4ECX7ZMoBk .label text,#mermaid-svg-bcX5mh4ECX7ZMoBk span{fill:#333;color:#333;}#mermaid-svg-bcX5mh4ECX7ZMoBk .node rect,#mermaid-svg-bcX5mh4ECX7ZMoBk .node circle,#mermaid-svg-bcX5mh4ECX7ZMoBk .node ellipse,#mermaid-svg-bcX5mh4ECX7ZMoBk .node polygon,#mermaid-svg-bcX5mh4ECX7ZMoBk .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-bcX5mh4ECX7ZMoBk .rough-node .label text,#mermaid-svg-bcX5mh4ECX7ZMoBk .node .label text,#mermaid-svg-bcX5mh4ECX7ZMoBk .image-shape .label,#mermaid-svg-bcX5mh4ECX7ZMoBk .icon-shape .label{text-anchor:middle;}#mermaid-svg-bcX5mh4ECX7ZMoBk .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-bcX5mh4ECX7ZMoBk .rough-node .label,#mermaid-svg-bcX5mh4ECX7ZMoBk .node .label,#mermaid-svg-bcX5mh4ECX7ZMoBk .image-shape .label,#mermaid-svg-bcX5mh4ECX7ZMoBk .icon-shape .label{text-align:center;}#mermaid-svg-bcX5mh4ECX7ZMoBk .node.clickable{cursor:pointer;}#mermaid-svg-bcX5mh4ECX7ZMoBk .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-bcX5mh4ECX7ZMoBk .arrowheadPath{fill:#333333;}#mermaid-svg-bcX5mh4ECX7ZMoBk .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-bcX5mh4ECX7ZMoBk .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-bcX5mh4ECX7ZMoBk .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-bcX5mh4ECX7ZMoBk .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-bcX5mh4ECX7ZMoBk .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-bcX5mh4ECX7ZMoBk .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-bcX5mh4ECX7ZMoBk .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-bcX5mh4ECX7ZMoBk .cluster text{fill:#333;}#mermaid-svg-bcX5mh4ECX7ZMoBk .cluster span{color:#333;}#mermaid-svg-bcX5mh4ECX7ZMoBk div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-bcX5mh4ECX7ZMoBk .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-bcX5mh4ECX7ZMoBk rect.text{fill:none;stroke-width:0;}#mermaid-svg-bcX5mh4ECX7ZMoBk .icon-shape,#mermaid-svg-bcX5mh4ECX7ZMoBk .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-bcX5mh4ECX7ZMoBk .icon-shape p,#mermaid-svg-bcX5mh4ECX7ZMoBk .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-bcX5mh4ECX7ZMoBk .icon-shape .label rect,#mermaid-svg-bcX5mh4ECX7ZMoBk .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-bcX5mh4ECX7ZMoBk .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-bcX5mh4ECX7ZMoBk .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-bcX5mh4ECX7ZMoBk :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    第一步create_agent(10 行跑通)

    第二步加 middleware(治理/审批/摘要)

    第三步显式 LangGraph 图(自定义状态转移/长时任务)


    四、核心概念:四个词吃透 LangChain

    4.1 Model(模型):用字符串描述模型

    1.0 最重要的便利之一:用 provider:model 字符串指定模型。

    from langchain.chat_models import init_chat_model

    model = init_chat_model("openai:gpt-5.5", temperature=0.5)
    # 换 Claude 就改这一行
    model = init_chat_model("anthropic:claude-sonnet-4-6")
    # 换 DeepSeek(国内常用)
    model = init_chat_model("deepseek:deepseek-chat")
    # 换本地 Ollama
    model = init_chat_model("ollama:llama3.1")

    这个设计最实际的好处:拿本地小模型试你的 Agent,只需要改一行字符串。

    4.2 Message(消息):统一的对话载体

    所有模型交互都归结为消息列表。1.0 新增的 content_blocks 属性是关键改进——跨供应商统一读取推理过程、引用、工具调用:

    response = model.invoke("法国首都是什么?")

    for block in response.content_blocks:
    if block["type"] == "reasoning":
    print("模型推理:", block["reasoning"])
    elif block["type"] == "text":
    print("回答:", block["text"])
    elif block["type"] == "tool_call":
    print("工具调用:", block["name"], block["args"])

    ⚠️ 目前 content_blocks 支持这些集成:langchain-anthropic、langchain-aws、langchain-openai、langchain-google-genai、langchain-ollama。

    4.3 Tool(工具):一个装饰器就够了

    在 LangChain 里,工具就是「一个带好的 docstring 的普通 Python 函数」。

    from langchain.tools import tool

    @tool
    def get_weather(city: str) –> str:
    """Get weather for a given city."""
    return f"It's always sunny in {city}!"

    🎯 为什么 docstring 这么重要? 官方文档写得很直白:工具的名字、描述、参数名,会直接变成模型提示词的一部分。 也就是说——你写给模型的「说明书」质量,决定了它会不会正确调用这个工具。 这不是注释,这是 prompt。

    4.4 Agent(智能体):一个循环

    create_agent 的内部其实非常简单,就一个循环:

    #mermaid-svg-mydZxusiuwXXafg5{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-mydZxusiuwXXafg5 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-mydZxusiuwXXafg5 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-mydZxusiuwXXafg5 .error-icon{fill:#552222;}#mermaid-svg-mydZxusiuwXXafg5 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-mydZxusiuwXXafg5 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-mydZxusiuwXXafg5 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-mydZxusiuwXXafg5 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-mydZxusiuwXXafg5 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-mydZxusiuwXXafg5 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-mydZxusiuwXXafg5 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-mydZxusiuwXXafg5 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-mydZxusiuwXXafg5 .marker.cross{stroke:#333333;}#mermaid-svg-mydZxusiuwXXafg5 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-mydZxusiuwXXafg5 p{margin:0;}#mermaid-svg-mydZxusiuwXXafg5 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-mydZxusiuwXXafg5 .cluster-label text{fill:#333;}#mermaid-svg-mydZxusiuwXXafg5 .cluster-label span{color:#333;}#mermaid-svg-mydZxusiuwXXafg5 .cluster-label span p{background-color:transparent;}#mermaid-svg-mydZxusiuwXXafg5 .label text,#mermaid-svg-mydZxusiuwXXafg5 span{fill:#333;color:#333;}#mermaid-svg-mydZxusiuwXXafg5 .node rect,#mermaid-svg-mydZxusiuwXXafg5 .node circle,#mermaid-svg-mydZxusiuwXXafg5 .node ellipse,#mermaid-svg-mydZxusiuwXXafg5 .node polygon,#mermaid-svg-mydZxusiuwXXafg5 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-mydZxusiuwXXafg5 .rough-node .label text,#mermaid-svg-mydZxusiuwXXafg5 .node .label text,#mermaid-svg-mydZxusiuwXXafg5 .image-shape .label,#mermaid-svg-mydZxusiuwXXafg5 .icon-shape .label{text-anchor:middle;}#mermaid-svg-mydZxusiuwXXafg5 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-mydZxusiuwXXafg5 .rough-node .label,#mermaid-svg-mydZxusiuwXXafg5 .node .label,#mermaid-svg-mydZxusiuwXXafg5 .image-shape .label,#mermaid-svg-mydZxusiuwXXafg5 .icon-shape .label{text-align:center;}#mermaid-svg-mydZxusiuwXXafg5 .node.clickable{cursor:pointer;}#mermaid-svg-mydZxusiuwXXafg5 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-mydZxusiuwXXafg5 .arrowheadPath{fill:#333333;}#mermaid-svg-mydZxusiuwXXafg5 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-mydZxusiuwXXafg5 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-mydZxusiuwXXafg5 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mydZxusiuwXXafg5 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-mydZxusiuwXXafg5 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mydZxusiuwXXafg5 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-mydZxusiuwXXafg5 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-mydZxusiuwXXafg5 .cluster text{fill:#333;}#mermaid-svg-mydZxusiuwXXafg5 .cluster span{color:#333;}#mermaid-svg-mydZxusiuwXXafg5 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-mydZxusiuwXXafg5 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-mydZxusiuwXXafg5 rect.text{fill:none;stroke-width:0;}#mermaid-svg-mydZxusiuwXXafg5 .icon-shape,#mermaid-svg-mydZxusiuwXXafg5 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mydZxusiuwXXafg5 .icon-shape p,#mermaid-svg-mydZxusiuwXXafg5 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-mydZxusiuwXXafg5 .icon-shape .label rect,#mermaid-svg-mydZxusiuwXXafg5 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mydZxusiuwXXafg5 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-mydZxusiuwXXafg5 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-mydZxusiuwXXafg5 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    有

    没有

    用户消息

    调用模型

    模型输出有工具调用吗?

    执行工具结果作为 tool message 追加

    输出最终回答

    就这样。 没有魔法。所谓「Agent」,本质就是**「模型自己决定下一步做什么」的 while 循环**。


    五、安装与环境准备

    5.1 安装

    # 推荐用 uv(官方推荐)
    uv python pin 3.11
    uv add langchain

    # 或者用 pip
    pip install -U langchain

    按需安装集成包:

    # 国内常用:DeepSeek(性价比高、中文强、兼容 OpenAI 接口)
    pip install langchain-deepseek

    # 常见组合
    pip install langchain-openai # OpenAI
    pip install langchain-anthropic # Claude
    pip install langchain-ollama # 本地模型
    pip install langchain-chroma # Chroma 向量库
    pip install langchain-text-splitters # 文本切分器(RAG 用)

    注意 langchain 自带一堆可选依赖组(PyPI 上列出的 extras): anthropic、aws、azure-ai、baseten、community、deepseek、fireworks、google-genai、google-vertexai、groq、huggingface、mcp、meta、mistralai、ollama、openai、perplexity、together、xai

    所以你也可以这样装:

    pip install "langchain[openai,deepseek]"

    5.2 配置 API Key

    永远不要把 Key 写死在代码里。 用一个 .env 文件:

    # .env
    DEEPSEEK_API_KEY=sk-your-key-here
    # OPENAI_API_KEY=sk-…
    # ANTHROPIC_API_KEY=sk-…

    from dotenv import load_dotenv
    load_dotenv() # 自动读取 .env 中的环境变量

    SDK 会自动从环境变量读取对应的 Key——ChatDeepSeek 会自动读 DEEPSEEK_API_KEY,并自动使用 api.deepseek.com 作为 base_url,不需要你手写 base_url。

    5.3 国内开发者的推荐配置

    项建议
    模型 DeepSeek(便宜 + 中文强 + 兼容 OpenAI 协议)
    加载器/向量库 Chroma(本地、零部署)或 pgvector(已有 PostgreSQL 的话)
    Embedding 优先国内厂商的 embedding 接口;本地可用 Ollama + nomic-embed-text
    网络 若直连不稳,考虑国内云厂商的 OpenAI 兼容端点
    LangSmith 海外服务,跨境数据传输需自行评估合规

    六、第一个 Agent:10 行代码跑通

    这是官方 quickstart 的形状,当前接口下这就是完整可跑的代码:

    from langchain.agents import create_agent

    def get_weather(city: str) –> str:
    """Get weather for a given city."""
    return f"It's always sunny in {city}!"

    agent = create_agent(
    model="openai:gpt-5.5",
    tools=[get_weather],
    system_prompt="You are a helpful assistant",
    )

    result = agent.invoke(
    {"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]}
    )
    print(result["messages"][–1].content_blocks)

    跑之前有一件代码本身不会提醒你的事:先导出你所用供应商的 API Key(OPENAI_API_KEY / ANTHROPIC_API_KEY / DEEPSEEK_API_KEY……),否则 Agent 没有凭据可用。

    create_agent 就是全部。 你交给它三样东西:

    参数说明
    model 「供应商:模型名」字符串,或一个模型对象
    tools 一串普通 Python 函数(可以是裸函数,也可以是 @tool 包装的)
    system_prompt 系统提示词

    换成 DeepSeek 版本(国内读者可直接用):

    from dotenv import load_dotenv
    from langchain.agents import create_agent

    load_dotenv()

    def get_weather(city: str) –> str:
    """查询指定城市的天气。"""
    return f"{city} 今天晴,25℃。"

    agent = create_agent(
    model="deepseek:deepseek-chat",
    tools=[get_weather],
    system_prompt="你是一个乐于助人的中文助手。",
    )

    result = agent.invoke({"messages": [{"role": "user", "content": "北京天气怎么样?"}]})
    print(result["messages"][–1].content_blocks)


    七、逐项拆解:LangChain 的六项核心能力

    7.1 模型调用:init_chat_model

    from langchain.chat_models import init_chat_model

    model = init_chat_model(
    "deepseek:deepseek-chat",
    temperature=0.5,
    timeout=300,
    max_tokens=25000,
    )

    两种改参数的姿势:

    方式写法特点
    bind() model.bind(temperature=2).invoke(messages) 一次调用临时改参数,最直接
    configurable_fields init_chat_model(…, configurable_fields=("model","temperature")) 运行时通过 config 切换,更灵活

    # 用法示例:运行时切换 model 与 temperature
    configurable_model = init_chat_model(
    "deepseek:deepseek-chat",
    configurable_fields=("model", "model_provider", "temperature"),
    )

    result = configurable_model.invoke(
    messages,
    config={"configurable": {"temperature": 1}},
    )

    多轮对话就是传消息列表:

    from langchain.messages import HumanMessage, SystemMessage

    messages = [
    SystemMessage(content="你是一个乐于助人的中文助手"),
    HumanMessage(content="1+1 等于几?"),
    ]
    print(model.invoke(messages).content)

    7.2 工具:@tool 详解

    from langchain.tools import tool

    @tool
    def search_flights(origin: str, destination: str, date: str) –> str:
    """查询指定日期从出发地到目的地的航班。

    Args:
    origin: 出发城市,如 "北京"
    destination: 目的城市,如 "上海"
    date: 日期,格式 YYYY-MM-DD
    """
    return "CA1501 08:00-10:15 ¥1200"

    三条硬规则:

  • 函数名 = 工具名,模型靠它调用。用 search_flights 而不是 func1。
  • docstring = 工具描述,直接进 prompt。写清楚「什么时候该用」比写清楚「它能做什么」更重要。
  • 类型注解是必需的,LangChain 靠它生成参数的 JSON Schema。Pydantic 模型也可以用。
  • @tool 还支持通过 ToolRuntime 参数做运行时注入(比如把用户 ID、数据库连接传进工具,而不让模型看到这些参数)。

    7.3 结构化输出

    Agent 也能直接吐结构化数据——而且是集成在主循环里的,不需要额外一次 LLM 调用:

    from langchain.agents import create_agent
    from langchain.agents.structured_output import ToolStrategy
    from pydantic import BaseModel

    class Weather(BaseModel):
    temperature: float
    condition: str

    def weather_tool(city: str) –> str:
    """查询城市天气。"""
    return f"{city} 天气晴,70°F"

    agent = create_agent(
    "openai:gpt-4o-mini",
    tools=[weather_tool],
    response_format=ToolStrategy(Weather),
    )

    result = agent.invoke({"messages": [{"role": "user", "content": "旧金山天气如何?"}]})
    print(result["structured_response"])

    💡 1.0 的三点改进:① 结构化输出在主循环内生成,无需额外 LLM 调用;② 模型可选择调用工具或使用提供商侧的结构化输出;③ 直接省钱。

    7.4 中间件(Middleware):1.0 真正的亮点 ⭐

    create_agent 拿到了发布公告的全部注意力,但日常开发中更重要的是中间件。

    在 1.0 之前,想控制 Agent 循环的「中间过程」,你要么用 callback handlers,要么继承子类,要么 fork 一个 prebuilt graph——大多数教程干脆跳过了这个问题。

    现在有了明确的「缝」,而且命名就写明了它切在哪里:

    Hook执行时机典型用例
    before_agent 调用 Agent 前 加载记忆、校验输入
    before_model 每次 LLM 调用前 更新提示词、修剪消息、控制预算
    wrap_model_call 包裹每次 LLM 调用 拦截并修改请求/响应
    wrap_tool_call 包裹每次工具调用 拦截并修改工具执行
    after_model 每次 LLM 响应后 校验输出、应用安全护栏
    after_agent Agent 完成后 保存结果、清理资源

    内置中间件(开箱即用,覆盖了最常见的三类需求):

    from langchain.agents import create_agent
    from langchain.agents.middleware import (
    PIIMiddleware,
    SummarizationMiddleware,
    HumanInTheLoopMiddleware,
    )

    agent = create_agent(
    model="anthropic:claude-sonnet-4-5",
    tools=[read_email, send_email],
    middleware=[
    # ① 发送给模型前屏蔽敏感信息
    PIIMiddleware(patterns=["email", "phone", "ssn"]),
    # ② 对话过长时自动摘要,控制 token 预算
    SummarizationMiddleware(
    model="anthropic:claude-sonnet-4-5",
    max_tokens_before_summary=500,
    ),
    # ③ 敏感工具调用需人工审批
    HumanInTheLoopMiddleware(
    interrupt_on={
    "send_email": {"allowed_decisions": ["approve", "edit", "reject"]}
    }
    ),
    ],
    )

    自定义中间件(写成类,实现 wrap_model_call):

    from dataclasses import dataclass
    from typing import Callable

    from langchain.agents import create_agent
    from langchain.agents.middleware import AgentMiddleware, ModelRequest
    from langchain.agents.middleware.types import ModelResponse
    from langchain_openai import ChatOpenAI

    @dataclass
    class Context:
    user_expertise: str = "beginner"

    class ExpertiseBasedToolMiddleware(AgentMiddleware):
    """按用户专业度动态换模型、换工具集"""

    def wrap_model_call(
    self,
    request: ModelRequest,
    handler: Callable[[ModelRequest], ModelResponse],
    ) –> ModelResponse:
    user_level = request.runtime.context.user_expertise

    if user_level == "expert":
    request.model = ChatOpenAI(model="openai:gpt-5")
    request.tools = [advanced_search, data_analysis]
    else:
    request.model = ChatOpenAI(model="openai:gpt-5-nano")
    request.tools = [simple_search, basic_calculator]

    return handler(request)

    agent = create_agent(
    model="anthropic:claude-sonnet-4-5",
    tools=[simple_search, advanced_search, basic_calculator, data_analysis],
    middleware=[ExpertiseBasedToolMiddleware()],
    context_schema=Context,
    )

    🎯 这个模式的威力:新手用便宜的小模型 + 简单工具,专家用旗舰模型 + 高级工具。 一套代码,两种成本曲线。这道以前要 fork 源码才能做的题,现在是一个类。

    7.5 记忆与持久化

    因为 create_agent 跑在 LangGraph 上,持久化是白拿的:

    from langgraph.checkpoint.memory import InMemorySaver

    checkpointer = InMemorySaver()

    agent = create_agent(
    model="deepseek:deepseek-chat",
    tools=[get_weather],
    checkpointer=checkpointer, # ← 加上这行就有了记忆
    )

    # 用 thread_id 区分会话
    config = {"configurable": {"thread_id": "user-001"}}

    agent.invoke({"messages": [{"role": "user", "content": "我叫小明"}]}, config)
    result = agent.invoke({"messages": [{"role": "user", "content": "我叫什么?"}]}, config)
    print(result["messages"][–1].content) # 会记得你叫小明

    ⚠️ InMemorySaver 只适合开发——进程一重启就没了。生产环境必须换成持久化 checkpointer(存到数据库)。

    从 LangGraph 自动继承的四个能力:

    能力说明
    持久化 会话间对话自动保存
    流式处理 实时传输 token、工具调用与推理轨迹
    人工干预 敏感操作前暂停 Agent 等审批
    时间旅行 回溯对话历史,探索不同分支

    八、LCEL 与 Runnable:底层协议

    langchain-core 里最核心的东西是 Runnable 协议。它定义了「任何一个可组合的工作单元」必须提供的接口:

    from langchain_core.runnables import Runnable

    class MyRunnable(Runnable[str, str]):
    def invoke(self, input: str, config=None) –> str: ...
    async def ainvoke(self, input: str, config=None) –> str: ...
    def stream(self, input: str, config=None): ...
    async def astream(self, input: str, config=None): ...
    def batch(self, inputs: list[str], config=None) –> list[str]: ...

    内置的 Runnable 包括:每个聊天模型、每个输出解析器、每个提示词模板、每个检索器、每个工具。

    LCEL(LangChain Expression Language)就是用 | 把它们串起来:

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

    model = ChatOpenAI(model="gpt-4o")
    prompt = ChatPromptTemplate.from_template("用一句话解释 {topic}。")
    parser = StrOutputParser()

    chain = prompt | model | parser

    result = chain.invoke({"topic": "光合作用"}) # 阻塞式,返回完整结果
    # chain.stream({"topic": "光合作用"}) # 流式,逐块返回
    # chain.batch([{"topic": "A"}, {"topic": "B"}]) # 批量
    # await chain.ainvoke(…) # 异步

    官方设计目标:一次定义组合,batch / async / stream 不用重写代码。

    8.1 三个必须知道的细节

    ① | 是惰性的。 prompt | model | parser 只是定义,不会执行。不调用 .invoke() / .stream() / .batch() / .astream(),什么都不会发生。代码「跑了但没反应」,先检查是不是忘了调。

    ② 组合类型

    写法得到的类型语义
    a | b | c RunnableSequence 串行,前一个的输出是后一个的输入
    {"x": a, "y": b} RunnableParallel 并行 fan-out,同一份输入喂给多个分支

    RAG 的经典组合(一眼就能看出来它在干嘛):

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

    ③ 流式和并发的两个坑

    现象原因解法
    stream() 只出最后一大段 中间某步用了 .invoke 而非 .stream,或某个非 LLM 的 Runnable 没实现 stream 用 astream_events(input, version="v2") 看哪个环节没有 on_chat_model_stream 事件
    batch 比 for 循环还慢 并发度没上去 chain.batch(inputs, config={"max_concurrency": 8})

    生产环境还要加:

    # 降级:主模型挂了自动切备用
    model_with_fallback = model.with_fallbacks([backup_model])

    # 重试
    from tenacity import stop_after_attempt
    reliable = model.with_retry(stop_after_attempt=3)

    # 追踪(LangSmith 靠 config 传播)
    chain.invoke({"q": "…"}, config={"tags": ["prod", "faq"], "metadata": {"user_id": "u1"}})


    九、RAG 实战:三种架构与完整代码

    RAG(检索增强生成)是 LangChain 最主流的落地场景。它解决 LLM 的两个硬伤:上下文有限、知识静态(训练数据冻结在某个时间点)。

    9.1 三种 RAG 架构怎么选

    官方把 RAG 分成三类,选择的关键是「你需要多少可控性」:

    架构说明控制力灵活性延迟典型场景
    2-Step RAG 检索总是发生在生成之前 ✅ 高 ❌ 低 ⚡ 快且可预测 FAQ、文档机器人
    Agentic RAG Agent 自己决定何时、如何检索 ❌ 低 ✅ 高 ⏳ 可变 能访问多个工具的研究助手
    Hybrid RAG 两者结合,加校验步骤 ⚖️ 中 ⚖️ 中 ⏳ 可变 需要质量校验的领域问答

    💡 延迟这点很关键:2-Step RAG 的最大 LLM 调用次数是已知且有上限的,所以延迟更可预测。

    9.2 有现成知识库的话,不要重建

    官方特别提醒:如果你已经有知识库(SQL、文档库、CRM、内部文档系统),不需要重建它。 直接:

  • 当成工具接给 Agent(Agentic RAG)
  • 查询后把结果作为 context 喂给 LLM(2-Step RAG)
  • 9.3 完整代码:2-Step RAG

    """最小可运行的 RAG 示例"""
    from dotenv import load_dotenv
    from langchain_community.document_loaders import PyPDFLoader, TextLoader, DirectoryLoader
    from langchain_text_splitters import RecursiveCharacterTextSplitter
    from langchain_chroma import Chroma
    from langchain_openai import ChatOpenAI, OpenAIEmbeddings
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_core.output_parsers import StrOutputParser
    from langchain_core.runnables import RunnablePassthrough

    load_dotenv()

    # ———- ① 加载文档 ———-
    loader = PyPDFLoader("docs/manual.pdf")
    docs = loader.load()

    # 也可以用目录加载器批量读 Markdown
    # loader = DirectoryLoader("./knowledge_base", glob="**/*.md", loader_cls=TextLoader)
    # docs = loader.load()

    # ———- ② 切分 ———-
    splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=200,
    separators=["\\n\\n", "\\n", "。", "!", "?", ".", " ", ""],
    )
    chunks = splitter.split_documents(docs)
    print(f"切分出 {len(chunks)} 个块")

    # ———- ③ 向量化 + 入库 ———-
    embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
    vectorstore = Chroma.from_documents(
    documents=chunks,
    embedding=embeddings,
    persist_directory="./chroma_db",
    )

    # ———- ④ 构造检索器 ———-
    retriever = vectorstore.as_retriever(
    search_type="mmr", # 用 MMR 兼顾相关性与多样性
    search_kwargs={"k": 5, "fetch_k": 20},
    )

    # ———- ⑤ 组装 RAG 链 ———-
    prompt = ChatPromptTemplate.from_template(
    """你是一个严谨的助手。请**只**根据下面提供的资料回答问题。
    如果资料中不含答案,直接说「资料中没有相关信息」,不要编造。

    资料:
    {context}

    问题:{question}

    回答:"""
    )

    model = ChatOpenAI(model="gpt-4o-mini", temperature=0)

    def format_docs(docs):
    return "\\n\\n—\\n\\n".join(
    f"[来源: {d.metadata.get('source', '未知')}]\\n{d.page_content}"
    for d in docs
    )

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

    # ———- ⑥ 提问 ———-
    answer = rag_chain.invoke("文档里讲了哪些核心概念?")
    print(answer)

    9.4 完整代码:Agentic RAG

    给 Agent 一个「能取外部知识」的工具即可:

    import requests
    from langchain.tools import tool
    from langchain.agents import create_agent

    @tool
    def fetch_url(url: str) –> str:
    """Fetch text content from a URL"""
    response = requests.get(url, timeout=10.0)
    response.raise_for_status()
    return response.text

    system_prompt = """\\
    需要从网页获取信息时请使用 fetch_url;回答时引用相关原文片段。
    """

    agent = create_agent(
    model="claude-sonnet-4-6",
    tools=[fetch_url], # ← 一个检索工具就够开启 RAG 行为
    system_prompt=system_prompt,
    )

    🎯 注意这句官方原话:「一个 Agent 要实现 RAG 行为,唯一需要的就是访问一个或多个能取外部知识的工具。」 也就是说,Agentic RAG 不需要任何专门的 RAG 代码——RAG 退化成「给 Agent 一个检索工具」这一个动作。

    9.5 调参经验

    参数建议原因
    chunk_size 256–512 token(中文约 300–600 字) 太大 → 语义被噪声稀释;太小 → 丢失必要上下文
    chunk_overlap chunk_size 的 10–20% 避免句子正好被切断在边界
    search_type "mmr" 优于默认 similarity 纯 top-k 常召回 5 条内容雷同的块;MMR 兼顾相关性 + 多样性
    separators 中文要加 。!? 默认分隔符是英文标点,中文会切得很难看
    结构化文档 用 MarkdownHeaderTextSplitter / HTMLHeaderTextSplitter 尊重文档结构,能显著提升检索精度

    十、什么时候该用 LangGraph

    create_agent 覆盖不了的场景,就是要下沉到 LangGraph 的时候。

    需求用 create_agent用 LangGraph
    标准工具循环 ✅ —
    自定义状态转移、条件分支 ❌ ✅
    持久化 checkpoints(生产级) ⚠️ 基础够用 ✅ 完全控制
    复杂路由 / 长时运行循环 ❌ ✅
    细粒度执行控制(每步耗时) ❌ ✅
    多 Agent 协同 ⚠️ 部分 ✅
    人工审批、重试、护栏 ✅ 用 middleware 就行 ✅

    💡 重要澄清:人工审批、重试、护栏,以及一部分多 Agent 交接,用高层 middleware 和 interrupt 就能实现,不需要定义图。 「先用高层,需要时再下沉」是官方指定的路径,不是绕路。

    LangGraph 的定位:它是一个低层编排框架与运行时,用于构建长时间运行、有状态的 Agent。它受 Pregel 和 Apache Beam 启发,公开接口借鉴了 NetworkX。

    它解决的正是 LangChain 撞到的天花板:

    • 原 AgentExecutor 过于独断、难以定制
    • 组合多个 Agent 需要各种 workaround
    • 跨轮次的状态是你自己的问题

    这就是团队为什么要造 LangGraph,并把所有严肃的 Agent 工作都指向那里。

    用 LangGraph 写一个最小图(示意):

    from langgraph.graph import StateGraph, MessagesState
    from langgraph.checkpoint.memory import InMemorySaver

    builder = StateGraph(MessagesState)

    builder.add_node("agent", call_model)
    builder.add_node("tools", tool_node)

    builder.add_edge("__start__", "agent")
    builder.add_conditional_edges("agent", should_continue, {"tools": "tools", "end": "__end__"})
    builder.add_edge("tools", "agent") # ← 这里形成了循环

    graph = builder.compile(checkpointer=InMemorySaver())

    LangGraph 已经被 Klarna、Replit、Elastic 等公司用于生产。


    十一、LangSmith:可观测性与评测

    没有追踪,调多步 Agent 就像在没有日志的情况下调分布式系统——能做,但没必要的难。

    LangSmith 是一个托管平台,提供:追踪(tracing)、评测(evaluation)、提示词管理、监控。

    它把 LangChain 内置的 callbacks 和埋点,包装成统一的界面。 一条 trace 可以把多次模型调用、工具调用、检索步骤、中间件执行、中间输出归并成一条可调试的记录。

    #mermaid-svg-iw7GoGbhtZgXMHca{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-iw7GoGbhtZgXMHca .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-iw7GoGbhtZgXMHca .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-iw7GoGbhtZgXMHca .error-icon{fill:#552222;}#mermaid-svg-iw7GoGbhtZgXMHca .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-iw7GoGbhtZgXMHca .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-iw7GoGbhtZgXMHca .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-iw7GoGbhtZgXMHca .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-iw7GoGbhtZgXMHca .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-iw7GoGbhtZgXMHca .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-iw7GoGbhtZgXMHca .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-iw7GoGbhtZgXMHca .marker{fill:#333333;stroke:#333333;}#mermaid-svg-iw7GoGbhtZgXMHca .marker.cross{stroke:#333333;}#mermaid-svg-iw7GoGbhtZgXMHca svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-iw7GoGbhtZgXMHca p{margin:0;}#mermaid-svg-iw7GoGbhtZgXMHca .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-iw7GoGbhtZgXMHca .cluster-label text{fill:#333;}#mermaid-svg-iw7GoGbhtZgXMHca .cluster-label span{color:#333;}#mermaid-svg-iw7GoGbhtZgXMHca .cluster-label span p{background-color:transparent;}#mermaid-svg-iw7GoGbhtZgXMHca .label text,#mermaid-svg-iw7GoGbhtZgXMHca span{fill:#333;color:#333;}#mermaid-svg-iw7GoGbhtZgXMHca .node rect,#mermaid-svg-iw7GoGbhtZgXMHca .node circle,#mermaid-svg-iw7GoGbhtZgXMHca .node ellipse,#mermaid-svg-iw7GoGbhtZgXMHca .node polygon,#mermaid-svg-iw7GoGbhtZgXMHca .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-iw7GoGbhtZgXMHca .rough-node .label text,#mermaid-svg-iw7GoGbhtZgXMHca .node .label text,#mermaid-svg-iw7GoGbhtZgXMHca .image-shape .label,#mermaid-svg-iw7GoGbhtZgXMHca .icon-shape .label{text-anchor:middle;}#mermaid-svg-iw7GoGbhtZgXMHca .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-iw7GoGbhtZgXMHca .rough-node .label,#mermaid-svg-iw7GoGbhtZgXMHca .node .label,#mermaid-svg-iw7GoGbhtZgXMHca .image-shape .label,#mermaid-svg-iw7GoGbhtZgXMHca .icon-shape .label{text-align:center;}#mermaid-svg-iw7GoGbhtZgXMHca .node.clickable{cursor:pointer;}#mermaid-svg-iw7GoGbhtZgXMHca .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-iw7GoGbhtZgXMHca .arrowheadPath{fill:#333333;}#mermaid-svg-iw7GoGbhtZgXMHca .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-iw7GoGbhtZgXMHca .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-iw7GoGbhtZgXMHca .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-iw7GoGbhtZgXMHca .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-iw7GoGbhtZgXMHca .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-iw7GoGbhtZgXMHca .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-iw7GoGbhtZgXMHca .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-iw7GoGbhtZgXMHca .cluster text{fill:#333;}#mermaid-svg-iw7GoGbhtZgXMHca .cluster span{color:#333;}#mermaid-svg-iw7GoGbhtZgXMHca div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-iw7GoGbhtZgXMHca .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-iw7GoGbhtZgXMHca rect.text{fill:none;stroke-width:0;}#mermaid-svg-iw7GoGbhtZgXMHca .icon-shape,#mermaid-svg-iw7GoGbhtZgXMHca .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-iw7GoGbhtZgXMHca .icon-shape p,#mermaid-svg-iw7GoGbhtZgXMHca .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-iw7GoGbhtZgXMHca .icon-shape .label rect,#mermaid-svg-iw7GoGbhtZgXMHca .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-iw7GoGbhtZgXMHca .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-iw7GoGbhtZgXMHca .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-iw7GoGbhtZgXMHca :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    一次用户请求

    中间件

    模型调用 1

    工具调用

    检索

    模型调用 2

    一条完整 Trace

    三个主要能力:

    能力说明
    Tracing 端到端看到每一步的输入输出、耗时、token
    Prompt 版本管理 比较改动、回滚到旧版本
    评测 在数据集上跑评测,对发布做基准、检测回归

    顺带一提:LangSmith 还能在可用信息足够时,按 trace / 模型 / 会话 / 打标用户估算模型成本。

    11.1 但要说清楚它的边界

    ① 它不是商业智能系统。 它不会替代你的计费数据库、财务软件或营收看板。营收、基础设施成本、客户级毛利——这些仍然要你自己的账单与分析管道。

    ② 它不是 MIT 协议的。 LangSmith Cloud 是专有商业服务。企业客户有 BYOC 和完全自托管选项(含数据驻留、私有网络、气隙环境)。

    ③ 它不是必须的。 你可以用结构化日志、OpenTelemetry、自建系统,或这些替代品:Langfuse、Helicone、Arize Phoenix(用之前请自行核对各自的许可证)。

    🎯 判断标准:当「无法解释的失败」的代价,超过「引入另一个托管服务」的代价时,LangSmith 就值了。


    十二、常见问题 FAQ

    老教程报错排查(最常被问的一类)

    Q1:ImportError: cannot import name 'LLMChain' from 'langchain.chains' → LLMChain 已移出主包。迁移到 LCEL(推荐),或改从遗留包导入:

    from langchain_classic.chains import LLMChain # 需要 pip install langchain-classic

    Q2:ImportError: cannot import name 'create_react_agent' → langgraph.prebuilt.create_react_agent 已弃用。改用:

    from langchain.agents import create_agent

    Q3:AgentExecutor 相关代码全报错 → 已弃用。新项目请直接用 create_agent,或直接上 LangGraph。

    Q4:No module named 'langchain.text_splitter' → 切分器已独立成包:

    from langchain_text_splitters import RecursiveCharacterTextSplitter # pip install langchain-text-splitters

    Q5:No module named 'langchain_community' / Chroma 导入失败 → 按需安装对应集成包,并优先用专用包:

    pip install langchain-chroma

    from langchain_chroma import Chroma # 替代 langchain_community.vectorstores.Chroma

    Q6:ConversationChain / ConversationBufferMemory 找不到 → 用 checkpointer 或 RunnableWithMessageHistory 替代。1.0 的推荐做法就是给 create_agent 传 checkpointer。

    Q7:AttributeError: 'ChatOpenAI' object has no attribute 'chain' → 0.x 时代的 .chain() 写法已不存在。改用 | 组合。


    概念与使用类

    Q8:create_agent 和 LangGraph 是什么关系?必须学 LangGraph 吗? → create_agent 底层就是 LangGraph。基础用法完全不需要学 LangGraph,但你会白拿它的持久化、流式、人工干预、时间旅行。需要复杂编排时再下沉。

    Q9:model="anthropic:claude-sonnet-4-6" 这种字符串是怎么识别的? → LangChain 按 provider:model 前缀自动路由到对应集成包。前提是对应包已安装(如 langchain-anthropic),且 API Key 在环境变量里。用 langchain[anthropic] 一次装好。

    Q10:chain = prompt | model | parser 为什么跑起来没反应? → | 是惰性的,只是定义,不执行。 必须调用 .invoke() / .stream() / .batch() / .astream() 之一。这是最高频的误解。

    Q11:.batch() 为什么比 for 循环还慢? → .batch() 默认不是你想象的并行。 需要显式提高并发度:

    chain.batch(inputs, config={"max_concurrency": 8})

    要真正的异步并行,用 .abatch()。

    Q12:流式输出为什么只出最后一大段? → 中间某一环没有流式。常见原因:某步用了 .invoke(),或某个自定义 Runnable 没实现 stream。用 astream_events(…, version="v2") 看哪个环节缺少 on_chat_model_stream 事件,这是生产调试的首选手段。

    Q13:怎么知道该用 create_agent 还是 LangGraph? → 一句话:标准工具循环用 create_agent;一旦你需要「自定义状态 + 条件跳转 + 长时任务」,就下沉到 LangGraph。

    Q14:LangChain 会不会又搞破坏性更新? → 1.0 承诺在 2.0 之前不做破坏性变更。 这也意味着你现在学的 1.x 核心 API 能稳定用一段时间——这对一个以前每隔几个月就崩一次教程的库来说,是最大的改进。

    Q15:我可以只装 langchain-core 吗? → 可以。如果你只想用 LCEL / Runnable / 消息类型,不涉及 Agent,装 langchain-core + 对应的集成包即可。langchain-core 现在还拆出了 langchain-protocol 等更细的包,依赖结构在持续细化。


    十三、总结

    三句话概括 LangChain 的现状

  • 它已经不是一个「链式调用工具库」,而是一个「Agent 框架」。 1.0 的范围收缩不是减法,是定位澄清——2023 年要解决「怎么拼提示词」,2026 年要解决「怎么让模型在工具循环里安全地跑」。
  • 核心只有一个函数 create_agent,外加一套 middleware。 前者让你 10 行跑通,后者让你在 Agent 循环的六个「缝」上做治理。
  • 它在向 LangGraph 分层:高层开箱即用,低层完全可控。 官方明确说「先用高层,需要时再下沉」是设计意图,不是权宜之计。
  • ✅ 应该做的

  • 新项目直接上 langchain >= 1.4,不要从 0.x 开始
  • 用 init_chat_model("provider:model") 获得最大的换模型灵活性
  • 把工具的 docstring 当成 prompt 来写——它会直接进模型的提示词
  • 生产和开发用不同的 checkpointer:InMemorySaver 只是玩具,生产必须持久化
  • 优先用 middleware 解决问题,不要急着 fork 或写自定义图
  • 给 LCEL 链配上 astream_events 调试,否则流式问题会让你怀疑人生
  • 上线前先问自己:真的需要 LangChain 吗? 单次调用用官方 SDK 更好
  • ❌ 不要做的

  • 不要照抄 2024 年的教程——LLMChain、AgentExecutor、create_react_agent 都已废弃或移出
  • 不要把 langchain 当成一个包——它是 core + 主包 + 几十个集成包
  • 不要在生产用 InMemorySaver
  • 不要忘了调用 .invoke() 就开始怀疑环境
  • 不要为了「用框架」而用框架——胶水代码不到 50 行,裸 SDK 更清爽
  • 不要假设 .batch() 一定并行,显式设置 max_concurrency
  • 🎯 最后一句

    LangChain 的价值不在于它「能做什么」,而在于它「帮你省掉了什么」。 它省掉的是:为每种模型重写调用代码、自己实现流式与并发、自己搭工具调用协议、自己设计 Agent 循环、自己拼可观测性。这些事你都能自己做,但做完之后你会发现,你写的就是一个更差的 LangChain。 ——而它的边界同样清晰:单次调用别用它,超复杂状态机用 LangGraph。


    📚 参考资料与数据说明

    • 官方文档:https://docs.langchain.com/oss/python/langchain/overview
    • API Reference:https://reference.langchain.com/python/langchain/langchain/
    • LangChain v1 新特性(中文):https://langchain-doc.cn/v1/python/langchain/releases/langchain-v1.html
    • 官方 Quickstart:https://docs.langchain.com/oss/python/langchain/quickstart
    • LangGraph 文档:https://docs.langchain.com/oss/python/langgraph/overview
    • Retrieval / RAG 文档:https://docs.langchain.com/oss/python/langchain/retrieval
    • PyPI:langchain / langchain-core / langgraph
    • GitHub:https://github.com/langchain-ai/langchain、https://github.com/langchain-ai/langgraph
    • 官方免费课程:LangChain Academy https://academy.langchain.com/

    版本与数据说明:本文版本号、依赖信息与 Star 数取自 PyPI 与 GitHub 于 2026-09-21 至 2026-09-26 的数据: langchain 1.4.2(2026-09-19)、langchain-core 1.6.0(2026-08-19)、langgraph 1.2.12(2026-09-21)。 LangChain 处于快速迭代期,本文代码基于 1.x 接口编写,但部分集成包的导入路径可能随版本微调,落地前请以官方文档为准。示例中的模型名(如 gpt-5.5、claude-sonnet-4-6)来自官方文档示例,请替换为你账号实际可用的模型。


    如果这篇指南对你有帮助,欢迎点赞 + 收藏。需要的话我可以继续拆解 LangGraph 状态管理实战、LangChain + MCP 工具接入,或者 基于 LangChain 的本地知识库完整项目——评论区告诉我你想先看哪个。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » LangChain框架完全指南(介绍与使用)
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!