MACHINE LEARNING · LANGCHAIN · 编排 LLM 应用

LangChain:把 LLM 拼成真正的应用

单独调一次模型 API 谁都会,难的让它查资料、调工具、记住上下文。这页按 LangChain 1.x 现行 API(2025 年 10 月发布 v1 之后的主线)带你从一行调用走到一个能检索问答的小 RAG。

zsh — ~/rag-demo
$ pip install -U langchain langchain-openai
Successfully installed langchain-1.4.9 langchain-openai-1.x langgraph-1.x
$ export OPENAI_API_KEY=sk-**** # key 走环境变量,别写进代码
$ python rag_demo.py "LangChain 1.x 用什么构建智能体?"
[检索] 命中 2 段知识库文本 → 作为上下文交给模型
答:create_agent() —— 1.x 的核心入口,底层由 LangGraph 驱动。
本页目录

01

LangChain 是什么:LLM 应用开发框架

直接用 OpenAI、Anthropic 的官方 SDK,你能完成「发一段话、拿回一段回答」。但真实的应用要做的远不止这些:让模型调用你的函数查库存、检索文档再回答、记住前几轮对话、按步骤走完一个多环节流程。LangChain 把这些通用件做成了标准组件——你负责拼装,而不是手写循环、解析工具调用、管理状态。

2025 年 10 月发布的 v1.0 是一次大重写:核心入口收敛到 create_agent(构建智能体)和 init_chat_model(初始化任意厂商的模型),旧版的 LLMChain、AgentExecutor 等全部退场。如果你看过 0.x 时代的老教程,先默认它过时,以官方文档为准。

落到场景上:客服与文档问答(RAG)、让模型调用内部接口干活的自动化流、从非结构化文本里抽取字段(结构化输出)、给已有产品加一个「会查资料的助手」——这些是 LangChain 的主场。反过来,如果只是一次性问答或文本处理,直接调 SDK 反而更轻。

当前主线
langchain 1.x(写本页时最新 1.4.9,2026-11 查 PyPI)
1.0 发布
2025-10(API 大版本重写)
语言
Python / JavaScript(本页讲 Python)
协议
MIT
Python 要求
≥ 3.10
核心入口
create_agent / init_chat_model
智能体运行时
LangGraph(持久化、流式、human-in-the-loop)
0.x 旧 API
已移出主包,搬进 langchain-classic
生态分工一张图:langchain 是编排主包(create_agent、中间件);langchain-core 是抽象层(消息、向量库接口等基础类型);langgraph 负责复杂状态图与多智能体;各厂商模型走独立集成包 langchain-openai、langchain-anthropic 等。装主包时这些依赖会自动带上,但你得知道谁是谁,报错才好定位。

02

安装:两个包 + 一把钥匙

主包和模型集成包一起装,再把 API 密钥配进环境变量,就绪。建议先建一个干净的虚拟环境。

Terminal
# 主包 + OpenAI 集成一起装(会自动带上 langchain-core、langgraph)
pip install -U langchain langchain-openai

# 把密钥写进环境变量(当前终端生效)
export OPENAI_API_KEY=sk-...        # macOS / Linux
setx OPENAI_API_KEY "sk-..."        # Windows(新开终端生效)
密钥从各厂商控制台申请。写成环境变量而不是硬编码在代码里,是避免把 key 提交进 Git 的第一道保险。
密钥安全:不要把 API key 写进源码、Notebook 或提交到仓库。用环境变量或 .env 文件(配 python-dotenv 的 load_dotenv()),并把 .env 加进 .gitignore。泄露的 key 会被扫库脚本秒捡,账单是真的。

03

快速上手:先调通模型,再让它动手

Python · hello_lc.py
# 第一步:用 init_chat_model 拿到模型,「厂商:模型名」一个字符串就够
# 模型名换成你账号可用的任何型号即可,以各服务商控制台为准
from langchain.chat_models import init_chat_model

model = init_chat_model("openai:gpt-5.5", temperature=0)
print(model.invoke("用一句话说明什么是 LLM 应用编排").text)

能跑通上面三行,说明包和密钥都没问题。第二步,把一个会调工具的智能体立起来——这是 LangChain 1.x 的主角 create_agent:

Python · 第一个智能体
from langchain.agents import create_agent

def get_word_count(text: str) -> int:
    """统计一段文本去掉空格后的字数。"""
    return len(text.replace(" ", ""))

agent = create_agent(
    model="openai:gpt-5.5",          # 也能传 init_chat_model 的返回值
    tools=[get_word_count],           # 函数列表,模型自己决定何时调用
    system_prompt="你是文字助手,需要统计字数时调用工具。",
)

result = agent.invoke(
    {"messages": [{"role": "user", "content": "数一数这句有多少字:大模型应用落地"}]}
)
print(result["messages"][-1].text)    # 取最后一条消息,就是最终回答
  • 01

    配好密钥再跑

    首次运行最常见的报错就是没读到 API key。先 export(或写 .env),确认当前终端能 echo $OPENAI_API_KEY 打印出来。

  • 02

    用「厂商:模型名」换模型

    init_chat_model("anthropic:claude-sonnet-4-6")、"ollama:llama3.3"——换厂商只换字符串和对应集成包,业务代码不动。

  • 03

    工具就是带 docstring 的函数

    模型靠 docstring 判断这个工具干什么、什么时候用。描述写得越清楚,调用越准。

  • 04

    结果从 messages 里取

    agent.invoke 返回完整消息历史,最后一条是回答;想看过程就把整个列表打出来,能看到模型的工具调用记录。

模型名是唯一「会过时」的参数:不同账号可用的型号不同,报 model not found 就去服务商控制台核对,别照抄别人的代码。

04

核心概念:消息、工具、RAG 与记忆

消息与角色:对话的通用语言

一切交互都是消息列表,角色只有几种:system(设定人设与规则)、user(用户输入)、assistant / AI(模型回答)、tool(工具执行结果)。1.x 里消息类统一从 langchain.messages 导入,也支持直接传 OpenAI 风格的字典。

Python · 消息
from langchain.messages import SystemMessage, HumanMessage, AIMessage, ToolMessage

messages = [
    SystemMessage("你是一名严谨的技术编辑。"),
    HumanMessage("用一句话解释什么是 RAG。"),
]
reply = model.invoke(messages)   # 返回 AIMessage
print(reply.text)                # .text 是纯文本
print(reply.content_blocks)      # 标准化内容块,兼容各厂商的推理/引用等信息

结构化输出与工具调用

两个高频需求:让模型返回程序能用的对象(接数据库、接表单),以及让模型决定调用你的函数。前者用 with_structured_output 套一个 Pydantic 模型;后者最低层是 bind_tools,最高层就是 create_agent 帮你把「调用—执行—回填」的循环全包了。

Python · 结构化输出
from pydantic import BaseModel

class BookReview(BaseModel):
    title: str
    score: int        # 1-10
    reason: str

review = model.with_structured_output(BookReview).invoke(
    "给《三体》写一条 30 字短评"
)
print(review.title, review.score)    # 已经是 Python 对象,不是字符串
Python · 工具定义与绑定
from langchain.tools import tool

@tool
def get_weather(city: str) -> str:
    """查询一个城市今天的天气。"""
    return f"{city}:晴,26°C"       # 真实项目里换成调用天气 API

resp = model.bind_tools([get_weather]).invoke("北京天气怎么样?")
print(resp.tool_calls)   # 模型说:想调 get_weather,参数是……执行权在你手上

RAG 三件套:加载、切分、检索

模型不知道你的私有资料,RAG 的思路是「先检索、后生成」:把文档加载进来,切分成小块并向量化存进向量库,提问时按相似度捞出最相关的几段,塞进提示词交给模型。组件全部可替换——换 loader 不动切分,换向量库不动业务逻辑。

Python · RAG 三件套
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_core.vectorstores import InMemoryVectorStore

docs = TextLoader("notes.txt", encoding="utf-8").load()
chunks = RecursiveCharacterTextSplitter(
    chunk_size=500, chunk_overlap=50,
).split_documents(docs)

store = InMemoryVectorStore.from_documents(chunks, OpenAIEmbeddings())
print(store.similarity_search("部署要点", k=3))   # 直接检索试一下
retriever = store.as_retriever(search_kwargs={"k": 3})  # 或包成检索器接进链里

记忆、会话与 LangSmith 观测

默认情况下每次 invoke 都是失忆的。给 agent 配一个 checkpointer(存档器),再用 thread_id 区分会话,它就能记住同一会话里说过的内容——这是 LangGraph 提供的能力,1.x 的 create_agent 直接暴露了参数。调试阶段强烈建议打开 LangSmith:官方观测平台,每次调用的提示词、工具轨迹、token 花费全部可查。

Python · 会话记忆
from langgraph.checkpoint.memory import InMemorySaver

agent = create_agent(
    model="openai:gpt-5.5",
    tools=[get_weather],
    system_prompt="你是可靠的助手。",
    checkpointer=InMemorySaver(),     # 生产可换持久化实现
)
cfg = {"configurable": {"thread_id": "user-42"}}   # 同一个 id = 同一个会话
agent.invoke({"messages": [{"role": "user", "content": "我叫小林"}]}, cfg)
agent.invoke({"messages": [{"role": "user", "content": "我叫什么?"}]}, cfg)
Terminal · 打开 LangSmith 记录
export LANGSMITH_TRACING=true
export LANGSMITH_API_KEY=lsv2_...
# 之后所有调用自动上报到 smith.langchain.com,先注册拿 key

05

速查表:1.x 高频 API 与生态包

下面这块表格能搜。忘了某个 API 叫什么,直接搜 agent、检索、结构化 之类的词。

API作用
init_chat_model("openai:gpt-5.5")按「厂商:模型名」字符串初始化对话模型,参数如 temperature 透传
init_chat_model(m, model_provider="google-genai")模型名不带前缀时,显式指定厂商
from langchain.chat_modelsinit_chat_model 所在模块
model.invoke(messages)单次调用,传字符串、字典列表或消息对象都行
model.stream(...)流式输出,逐段拿结果
model.bind_tools([fn])低层工具绑定:模型返回 tool_calls,执行循环自己写
model.with_structured_output(Schema)按 Pydantic 模型返回结构化对象
create_agent(model=, tools=)1.x 核心入口:构建会自动调工具的智能体,另支持 system_prompt、checkpointer、middleware
from langchain.agentscreate_agent 所在模块
agent.invoke({"messages": [...]})运行智能体,返回完整消息历史
result["messages"][-1]取最后一条消息即最终回答,.text 拿纯文本
agent.stream(...)流式执行,逐步产出中间与最终状态
@tool把普通函数变成工具,docstring 就是给模型看的说明书
create_agent(checkpointer=...)接入会话记忆,配合 thread_id 区分会话

06

实战:30 行的最小 RAG 问答

不建数据库、不跑服务:知识库就是几段文本,向量库用内存版,检索出来的片段拼进提示词再调模型。整个脚本 30 多行,跑通后把它换成真实文档就是能用的原型。需要有效的 OPENAI_API_KEY,会产生少量调用费用。

第 1 步:建知识库并入库

Python · rag_demo.py(上)
# 运行前:pip install -U langchain langchain-openai
# 密钥:export OPENAI_API_KEY=sk-...
from langchain_core.vectorstores import InMemoryVectorStore
from langchain_openai import OpenAIEmbeddings

texts = [
    "LangChain 1.x 的核心入口是 create_agent,智能体底层由 LangGraph 驱动。",
    "init_chat_model 用「厂商:模型名」字符串初始化任意厂商的对话模型。",
    "RAG 三件套:文档加载、切分、向量库与检索器,检索结果作为上下文交给模型。",
    "LangSmith 是官方观测平台,设置 LANGSMITH_TRACING=true 即可记录每次调用。",
]

# 向量化并写入内存向量库;真实项目里 texts 换成 loader 读出的文档切分结果
store = InMemoryVectorStore.from_texts(texts, embedding=OpenAIEmbeddings())

第 2 步:组装「检索 → 填模板 → 生成」的链

Python · rag_demo.py(中)
from langchain.chat_models import init_chat_model
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough

retriever = store.as_retriever(search_kwargs={"k": 2})   # 每次取最相关的 2 段
llm = init_chat_model("openai:gpt-5.5", temperature=0)

prompt = ChatPromptTemplate.from_template(
    "仅根据下面的资料回答问题;资料里没有的就直说不知道。\n\n"
    "资料:\n{context}\n\n问题:{question}"
)

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

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

这条链的读法:输入的问题一路透传;同时 retriever 拿回文档、format_docs 拼成一段文本;两路汇进模板填空,最后交给模型。LCEL 用 | 把组件串成管道,每一段都能单独测试。

第 3 步:提问运行

Python · rag_demo.py(下)
if __name__ == "__main__":
    while True:
        q = input("\n问题(直接回车退出)> ").strip()
        if not q:
            break
        print(chain.invoke(q).text)
Terminal
$ python rag_demo.py

问题(直接回车退出)> 1.x 用什么构建智能体?
1.x 通过 create_agent() 构建智能体,底层由 LangGraph 驱动,支持持久化与流式。

第 4 步:把原型换成真实知识库

骨架不动,只换两处:texts 换成 loader 读出的切分结果,内存库换成可持久化的向量库:

Python · 只换入库这一段
# pip install langchain-community langchain-chroma
from langchain_community.document_loaders import PyPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_chroma import Chroma

docs = PyPDFLoader("handbook.pdf").load()          # 换 loader
chunks = RecursiveCharacterTextSplitter(
    chunk_size=500, chunk_overlap=50,
).split_documents(docs)

store = Chroma.from_documents(                       # 换向量库,落盘
    chunks, OpenAIEmbeddings(), persist_directory="./db"
)
retriever = store.as_retriever(search_kwargs={"k": 2})
# 下面的 prompt、chain 原样复用——组件可替换正是分层的好处
下一步把原型变真:texts 换成 TextLoader/WebBaseLoader 读真实文档;InMemoryVectorStore 换成 Chroma 等持久向量库;再用第 05 节的生态包表对照升级。结构不用变,只换组件。

07

避坑:四个最常见的坑

坑一:照 0.x 老教程写,import 直接报错

v1 是破坏性重写。from langchain.chains import LLMChain、AgentExecutor、initialize_agent 在主包里都没有了;网上 2024 年及更早的教程基本全是旧写法。对照检查:create_agent(替代 create_react_agent / AgentExecutor)在 langchain.agents,消息从 langchain.messages 导入。确需维护旧项目,官方提供了 langchain-classic 包收容旧 API。

判断教程新旧的最快方法:看到 LLMChain、AgentExecutor、create_react_agent 这几个词,直接关掉,找以 create_agent 开头的资料,或只看 docs.langchain.com。

坑二:AuthenticationError / model not found

九成是密钥没配对或模型名写错。排查顺序:当前终端 echo $OPENAI_API_KEY 有值吗?key 是不是对应厂商的?模型字符串里的厂商前缀和型号在服务商控制台存在吗?

Terminal · 三连检查
echo $OPENAI_API_KEY            # 有输出才算配上了
pip show langchain langchain-openai | grep -E 'Name|Version'
python -c "from dotenv import load_dotenv; load_dotenv(); import os; print(bool(os.getenv('OPENAI_API_KEY')))"

用 .env 文件时,load_dotenv() 必须在构造模型之前执行;export 只对当前终端会话生效,换窗口要重配。

坑三:RAG 答非所问,先怪检索再怪模型

检索增强类应用不准,问题大多出在检索端:切分太大(一片塞进多个主题)、没有 overlap(句子被拦腰切断)、取的 k 太小。先脱离模型单独测,人眼看捞回来的片段对不对——检索不对,调提示词是白费劲。中文语料记得给切分器留意标点,必要时换按句子切分的策略。

Python · 检索体检:不经过模型直接看结果
hits = store.similarity_search("1.x 用什么构建智能体?", k=2)
for d in hits:
    print("---")
    print(d.page_content[:120])      # 捞回来的片段对不对,肉眼判断

坑四:什么时候不该上框架

LangChain 是编排工具,不是必需品。判断标准很简单:只是一次问答——用 init_chat_model 甚至厂商官方 SDK 就够;要模型反复调工具、走多步流程——用 create_agent;多个角色协作、复杂状态机、要人工审批节点——上 LangGraph。给 hello world 套全家桶,只会让调试链路变长。

08

进阶方向与资源

学完本页去哪:把第 06 节的 RAG 接上你自己的文档(PDF、网页都行),再给 create_agent 加两三个真实业务工具(查库、发请求、写文件)。两个都稳了,去 LangGraph 学状态图——那是从「会用」到「能设计」的分水岭。

09

收尾:照着勾一遍

0 / 5

已复制