LangChain 框架完全指南:从 1.0 重构到 Agent 实战
一句话总结:LangChain 是目前最流行的 LLM 应用开发框架——它不训练模型,而是解决「怎么把大模型接进真实软件」这件事:统一各家模型的调用接口、把提示词/工具/记忆/检索标准化成可组合的组件、并提供一套 Agent 运行时(循环调用模型 → 执行工具 → 再调用)。2025 年 10 月它发布了 1.0,把框架大幅收缩:旧的 LLMChain、AgentExecutor 全部移出主包,新核心只剩一个函数 create_agent,外加一套中间件机制。这意味着网上 2024 年的教程基本全部失效——本篇按当前 langchain 1.4.2 的实际接口写,并专门给了一节「老教程排错对照表」。
📋 目录
一、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 新旧对照表(速查)
| 调用模型 | 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"
三条硬规则:
@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——大多数教程干脆跳过了这个问题。
现在有了明确的「缝」,而且命名就写明了它切在哪里:
| 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、内部文档系统),不需要重建它。 直接:
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 的时候。
| 标准工具循环 | ✅ | — |
| 自定义状态转移、条件分支 | ❌ | ✅ |
| 持久化 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 的现状
✅ 应该做的
❌ 不要做的
🎯 最后一句
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 的本地知识库完整项目——评论区告诉我你想先看哪个。
网硕互联帮助中心





评论前必须登录!
注册