🦜⛓️ LangChain 完全学习手册:看完就能上手

本文基于 LangChain v1.x,包含 LCEL、RAG、Agent 等核心内容,代码均可直接运行。适合有 Python 基础、想动手做 AI 应用的开发者。


目录

  • 一、LangChain 是什么
  • 二、环境安装与配置
  • 三、六大核心概念详解
  • 四、RAG 实战:让 AI 回答你的私有文档
  • 五、Agent:让 AI 自主使用工具
  • 六、生产环境最佳实践
  • 七、完整项目:智能客服系统
  • 八、速查手册

一、LangChain 是什么

1.1 它解决的问题

在 LangChain 出现之前,做一个 AI 应用需要手写大量基础代码:

  • 每接一个 LLM(OpenAI、Anthropic、Google…),都要单独写对接逻辑
  • 对话历史要自己拼,每次都要手动处理上下文
  • Prompt 写死在代码里,根本没法复用
  • 想让 AI 调工具、查数据库?从零实现调度逻辑
  • RAG 完整流程要写几百行胶水代码

结果 80% 时间在搞基础设施,真正的 AI 逻辑只占 20%。

LangChain 把这些通用模式全都抽象成了可复用的组件,你只需要关心自己的业务逻辑。

1.2 核心能力一览

功能

解决的问题

统一模型接口

换 GPT-4、Claude、Gemini、本地 Llama,只改一行配置

Prompt 模板系统

像写函数一样写 Prompt,支持变量、Few-shot

链式调用(LCEL)

用 | 管道符串联组件,清晰可读

内置记忆管理

自动管理对话历史,多种策略开箱即用

RAG 全套工具

文档加载、切割、向量化、检索一条龙

Agent 框架

让 AI 自主调用工具、搜索、执行代码

类比一下:LangChain 之于 AI 开发,就像 Django 之于 Web 开发——不是语言,是让你更快出活儿的框架。

1.3 LangChain 生态

现在 LangChain 已经是个完整生态,三个主要产品:

产品

定位

什么时候用

🦜 LangChain

核心框架

快速构建 LLM 应用、RAG、简单 Agent

🕸 LangGraph

Agent 编排引擎

复杂多步骤 Agent、状态机工作流

🔭 LangSmith

调试与监控

线上 Trace 记录、质量评估

本文专注核心框架,LangGraph 和 LangSmith 单独成文。


二、环境安装与配置

2.1 安装

LangChain 是模块化的,按需安装:

bash

# 核心框架(必装)

pip install langchain

# 按你用的模型选一个

pip install langchain-openai # GPT 系列

pip install langchain-anthropic # Claude 系列

pip install langchain-google-genai # Gemini 系列

pip install langchain-ollama # 本地模型

# RAG 相关

pip install langchain-community # 社区扩展,含大量文档加载器

pip install chromadb # 本地向量数据库

# 环境变量

pip install python-dotenv

2.2 配置 API Key

项目根目录建一个 .env 文件:

ini

OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxx

ANTHROPIC_API_KEY=sk-ant-xxxxxxxx

记得把 .env 加进 .gitignore,别把 Key 传上去。

代码里加载:

csharp

from dotenv import load_dotenv

load_dotenv()

2.3 跑通第一个程序

python

from dotenv import load_dotenv

from langchain_openai import ChatOpenAI

from langchain_core.messages import HumanMessage

load_dotenv()

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

response = llm.invoke([HumanMessage(content="用一句话解释什么是 LangChain")])

print(response.content)

看到 AI 回复就说明环境 OK 了。

想换 Claude?只需改两行,其他完全不动:

ini

from langchain_anthropic import ChatAnthropic

llm = ChatAnthropic(model="claude-opus-4-5")

# 后面代码一模一样

这就是统一接口的价值。


三、六大核心概念详解

3.1 模型(Models)

现在用的几乎都是 ChatModel,接受消息列表,返回 AI 消息。

ini

from langchain_openai import ChatOpenAI

from langchain_anthropic import ChatAnthropic

from langchain_ollama import ChatOllama

gpt = ChatOpenAI(

model="gpt-4o-mini",

temperature=0.7, # 0=确定,1=有创意

max_tokens=1000,

)

claude = ChatAnthropic(model="claude-opus-4-5", temperature=0)

# 本地模型(需要先装并运行 Ollama)

local = ChatOllama(model="llama3.2")

# 三个用法完全一样

result = gpt.invoke("你好")

print(result.content) # .content 拿到文本

3.2 Prompt 模板

别把 Prompt 写死在字符串里,用模板:

makefile

from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_messages([

("system", "你是一名专业的 {language} 开发专家。"),

("human", "请解释 {topic} 的概念,并给出代码示例。"),

])

# 填充变量

messages = prompt.invoke({

"language": "Python",

"topic": "装饰器",

})

response = llm.invoke(messages)

print(response.content)

好处很直接:变量可以动态传入,Prompt 可以复用,单测也好写。

3.3 LCEL 链式调用(重点)

LCEL(LangChain Expression Language)是最核心的设计,用 | 管道符把组件串起来:

ini

from langchain_openai import ChatOpenAI

from langchain_core.prompts import ChatPromptTemplate

from langchain_core.output_parsers import StrOutputParser

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

prompt = ChatPromptTemplate.from_template("请用中文简洁介绍:{topic}")

parser = StrOutputParser() # 把 AIMessage 转成纯字符串

# 组合成链:输入 → Prompt → LLM → 解析

chain = prompt | llm | parser

# 单次调用

result = chain.invoke({"topic": "量子计算"})

# 批量处理

results = chain.batch([

{"topic": "机器学习"},

{"topic": "深度学习"},

{"topic": "强化学习"},

])

# 流式输出(打字机效果)

for chunk in chain.stream({"topic": "神经网络"}):

print(chunk, end="", flush=True)

链中每个组件都有 invoke / batch / stream 方法,可以自由组合。

3.4 输出解析器

AI 默认输出文本,解析器把它转成 Python 对象:

python

from langchain_core.pydantic_v1 import BaseModel, Field

from langchain.output_parsers import PydanticOutputParser

from langchain_openai import ChatOpenAI

from langchain_core.prompts import ChatPromptTemplate

# 定义你想要的结构

class MovieReview(BaseModel):

title: str = Field(description="电影名")

score: int = Field(description="评分 1-10")

summary: str = Field(description="一句话评价")

parser = PydanticOutputParser(pydantic_object=MovieReview)

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

prompt = ChatPromptTemplate.from_messages([

("system", "你是影评专家。请按要求格式输出。\n{format_instructions}"),

("human", "评价电影:{movie}"),

])

chain = prompt | llm | parser

review = chain.invoke({

"movie": "星际穿越",

"format_instructions": parser.get_format_instructions()

})

print(review.title) # 星际穿越

print(review.score) # 9(整数,不是字符串)

print(review.summary) # 震撼人心的科幻巨作...

3.5 记忆(Memory)

默认每次 invoke() 是独立的,AI 不记得上文。加记忆的最简单方式是手动维护历史列表:

ini

from langchain_openai import ChatOpenAI

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

from langchain_core.messages import HumanMessage, AIMessage

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

prompt = ChatPromptTemplate.from_messages([

("system", "你是一个友好的 AI 助手。"),

MessagesPlaceholder(variable_name="history"), # 历史消息插入点

("human", "{input}"),

])

chain = prompt | llm

history = []

def chat(user_input):

response = chain.invoke({"input": user_input, "history": history})

history.append(HumanMessage(content=user_input))

history.append(AIMessage(content=response.content))

return response.content

print(chat("我叫小明")) # 你好,小明!...

print(chat("你还记得我叫什么?")) # 当然,你叫小明!

3.6 检索器(Retrievers)

RAG 的核心组件,根据问题找相关文档:

ini

from langchain_community.vectorstores import Chroma

from langchain_openai import OpenAIEmbeddings

from langchain_core.documents import Document

docs = [

Document(page_content="LangChain 是构建 AI 应用的框架"),

Document(page_content="LCEL 使用 | 管道符组合组件"),

Document(page_content="向量数据库存储文本的数学表示"),

]

# 自动向量化并存入数据库

vectorstore = Chroma.from_documents(docs, OpenAIEmbeddings())

retriever = vectorstore.as_retriever(search_kwargs={"k": 2})

# 语义检索

results = retriever.invoke("什么是管道符?")

for doc in results:

print(doc.page_content)


四、RAG 实战:让 AI 回答你的私有文档

4.1 RAG 是什么

RAG(Retrieval-Augmented Generation)解决的问题:让 AI 回答训练数据之外的内容,比如公司内部文档、最新资料、私人笔记。

流程分两个阶段:

离线索引(只做一次):文档 → 切块 → 向量化 → 存数据库

在线查询(每次问答):用户提问 → 检索相关块 → 连同问题传给 LLM → 得到答案

4.2 完整实现

python

from dotenv import load_dotenv

from langchain_openai import ChatOpenAI, OpenAIEmbeddings

from langchain_community.vectorstores import Chroma

from langchain.text_splitter import RecursiveCharacterTextSplitter

from langchain_core.prompts import ChatPromptTemplate

from langchain_core.output_parsers import StrOutputParser

from langchain_core.runnables import RunnablePassthrough

from langchain_core.documents import Document

load_dotenv()

# 1. 准备文档(实际场景换成 PyPDFLoader 加载 PDF)

documents = [

Document(page_content="""

公司假期政策:

- 年假:入职满一年后 10 天,每加一年 +1 天,最多 15 天

- 病假:每年 10 天,需提供医院证明

- 婚假:3 天(提前 2 周申请)

- 产假:女员工 128 天,男员工陪产假 15 天

""", metadata={"source": "hr_policy.txt"}),

Document(page_content="""

报销流程:

1. 保存所有发票原件

2. 在 OA 系统填写报销申请

3. 直属上级审批(500 元以上需总监审批)

4. 财务审核,5 个工作日内打款

报销上限:差旅费单次最高 5000 元

""", metadata={"source": "expense_policy.txt"}),

]

# 2. 切割文档

splitter = RecursiveCharacterTextSplitter(

chunk_size=500, # 每块最多 500 字符

chunk_overlap=50, # 块间重叠 50 字符,防止语义断裂

)

chunks = splitter.split_documents(documents)

# 3. 向量化并存入数据库

vectorstore = Chroma.from_documents(chunks, OpenAIEmbeddings())

retriever = vectorstore.as_retriever(search_kwargs={"k": 3})

# 4. 构建 RAG Chain

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

prompt = ChatPromptTemplate.from_messages([

("system", """你是公司的 HR 助手,只根据提供的文档回答问题。

如果文档中没有相关信息,直接说「文档中未找到相关信息」,不要编造。

参考文档:

{context}"""),

("human", "{question}"),

])

def format_docs(docs):

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

rag_chain = (

{"context": retriever | format_docs, "question": RunnablePassthrough()}

| prompt

| llm

| StrOutputParser()

)

# 5. 问问题

questions = [

"入职满两年有几天年假?",

"报销超过多少需要总监审批?",

"公司有没有年终奖?", # 文档里没有的

]

for q in questions:

print(f"\n问:{q}")

print(f"答:{rag_chain.invoke(q)}")

4.3 常用文档加载器

加载器

用途

PyPDFLoader

PDF 文件(需 pip install pypdf)

WebBaseLoader

网页内容

TextLoader

纯文本 .txt

CSVLoader

CSV 数据文件

DirectoryLoader

批量加载整个文件夹

UnstructuredWordDocumentLoader

Word 文档

GitLoader

Git 仓库代码文件


五、Agent:让 AI 自主使用工具

5.1 Chain vs Agent

Chain 的执行路径是固定的(A → B → C)。

Agent 不同,它让 LLM 自己决定下一步做什么:要不要调工具、调哪个、拿到结果后怎么处理,一直循环到得出最终答案。

典型的 ReAct 循环:接收问题 → 思考 → 行动(调工具)→ 观察结果 → 继续思考…

5.2 创建带工具的 Agent

python

from dotenv import load_dotenv

from langchain_openai import ChatOpenAI

from langchain_core.tools import tool

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

from langchain.agents import create_tool_calling_agent, AgentExecutor

load_dotenv()

# 定义工具,docstring 是关键——AI 靠它决定用哪个工具

@tool

def get_weather(city: str) -> str:

"""获取指定城市的当前天气。参数:city(城市名,如'北京')"""

data = {

"北京": "晴天,25°C,湿度 40%",

"上海": "多云,28°C,湿度 65%",

"广州": "小雨,30°C,湿度 85%",

}

return data.get(city, f"{city} 暂无数据")

@tool

def calculate(expression: str) -> str:

"""计算数学表达式。参数:expression(如 '2+3*4')"""

try:

return f"{expression} = {eval(expression)}"

except Exception as e:

return f"计算出错:{e}"

# 创建 Agent

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

tools = [get_weather, calculate]

prompt = ChatPromptTemplate.from_messages([

("system", "你是一个有用的助手,可以使用工具帮助用户。"),

("human", "{input}"),

MessagesPlaceholder(variable_name="agent_scratchpad"), # Agent 思考过程

])

agent = create_tool_calling_agent(llm, tools, prompt)

agent_executor = AgentExecutor(

agent=agent,

tools=tools,

verbose=True, # 打印中间过程,调试用

max_iterations=5,

)

result = agent_executor.invoke({

"input": "北京今天天气如何?另外 15 × 23 + 7 等于多少?"

})

print(result["output"])

# Agent 会自动决定调两个工具,然后综合回答

5.3 内置工具

不用自己造轮子,LangChain 有大量现成工具:

工具

功能

DuckDuckGoSearchRun

免费网络搜索,无需 Key

TavilySearchResults

高质量网络搜索(需 Tavily Key)

WikipediaQueryRun

查询维基百科

PythonREPLTool

执行 Python 代码

RequestsGetTool

发起 HTTP 请求

SQLDatabaseTool

查询 SQL 数据库

python

from langchain_community.tools import DuckDuckGoSearchRun

search = DuckDuckGoSearchRun()

print(search.invoke("LangChain 最新版本"))


六、生产环境最佳实践

6.1 容错与 Fallback

ini

from langchain_openai import ChatOpenAI

from langchain_anthropic import ChatAnthropic

# 主模型挂了自动切备用

primary = ChatOpenAI(model="gpt-4o")

backup = ChatAnthropic(model="claude-opus-4-5")

robust_llm = primary.with_fallbacks([backup])

6.2 流式输出

python

chain = prompt | llm | StrOutputParser()

# 同步流式

for chunk in chain.stream({"question": "解释机器学习"}):

print(chunk, end="", flush=True)

# 异步(FastAPI 场景)

async def stream_response(question: str):

async for chunk in chain.astream({"question": question}):

yield chunk

6.3 向量数据库持久化

向量化有费用,做一次存磁盘,下次直接读:

ini

import os

from langchain_community.vectorstores import Chroma

PERSIST_DIR = "./chroma_db"

if not os.path.exists(PERSIST_DIR):

vectorstore = Chroma.from_documents(

documents=chunks,

embedding=OpenAIEmbeddings(),

persist_directory=PERSIST_DIR,

)

else:

# 直接从磁盘加载,无需重新向量化

vectorstore = Chroma(

persist_directory=PERSIST_DIR,

embedding_function=OpenAIEmbeddings(),

)

6.4 开启请求缓存

相同输入不重复调 API,省钱省时间:

python

from langchain.globals import set_llm_cache

from langchain.cache import SQLiteCache

set_llm_cache(SQLiteCache(database_path=".langchain.db"))

# 之后相同的请求直接走缓存

6.5 常见报错

错误

解决方法

AuthenticationError

API Key 未设置或过期,检查 .env 和 load_dotenv()

RateLimitError

请求频率过高,加 time.sleep() 或用指数退避

ContextWindowExceededError

输入 Token 太多,减小 chunk_size,或只保留最近几轮历史

OutputParserException

AI 没按格式输出,Prompt 里加更明确的格式指令

ModuleNotFoundError

缺对应的包,按报错提示 pip install


七、完整项目:智能客服系统

综合前面所有知识,搭一个支持 RAG + 对话记忆 + 流式输出的智能客服:

python

from dotenv import load_dotenv

from langchain_openai import ChatOpenAI, OpenAIEmbeddings

from langchain_community.vectorstores import Chroma

from langchain.text_splitter import RecursiveCharacterTextSplitter

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

from langchain_core.output_parsers import StrOutputParser

from langchain_core.runnables import RunnablePassthrough

from langchain_core.messages import HumanMessage, AIMessage

from langchain_core.documents import Document

load_dotenv()

# 初始化知识库

product_docs = [

Document(page_content="超级充电宝 ProMax:20000mAh,65W 快充,380g,299 元,保修 1 年"),

Document(page_content="退换货:7 天无理由退货,30 天内质量问题免费换新,保留原包装"),

Document(page_content="使用注意:避免高温,不可拆卸,禁止飞机托运"),

]

chunks = RecursiveCharacterTextSplitter(chunk_size=300, chunk_overlap=30).split_documents(product_docs)

vectorstore = Chroma.from_documents(chunks, OpenAIEmbeddings())

retriever = vectorstore.as_retriever(search_kwargs={"k": 2})

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

prompt = ChatPromptTemplate.from_messages([

("system", """你是智能客服。严格基于以下文档回答,文档中没有的内容回复「请联系人工客服」。

产品文档:

{context}"""),

MessagesPlaceholder(variable_name="history"),

("human", "{question}"),

])

chat_history = []

rag_chain = (

{

"context": retriever | (lambda docs: "\n".join(d.page_content for d in docs)),

"question": RunnablePassthrough(),

"history": lambda _: chat_history,

}

| prompt | llm | StrOutputParser()

)

# 对话循环

print("智能客服已启动(输入 quit 退出)")

while True:

user_input = input("\n你:").strip()

if user_input.lower() == "quit":

break

print("客服:", end="")

full_response = ""

for chunk in rag_chain.stream(user_input):

print(chunk, end="", flush=True)

full_response += chunk

print()

chat_history.append(HumanMessage(content=user_input))

chat_history.append(AIMessage(content=full_response))

# 只保留最近 6 轮,防止 Token 超限

if len(chat_history) > 12:

chat_history = chat_history[-12:]

这个项目可以继续扩展:

  • 把知识库换成真实 PDF(PyPDFLoader)
  • Chroma 换成云端向量库(Pinecone / Weaviate)
  • 包成 FastAPI 接口对外提供服务
  • 接 LangSmith 监控线上效果

八、速查手册

常用 Import

python

# 模型

from langchain_openai import ChatOpenAI, OpenAIEmbeddings

from langchain_anthropic import ChatAnthropic

from langchain_ollama import ChatOllama

# Prompt

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

# 输出解析

from langchain_core.output_parsers import StrOutputParser, JsonOutputParser

from langchain.output_parsers import PydanticOutputParser

# 消息

from langchain_core.messages import HumanMessage, AIMessage, SystemMessage

# Runnables

from langchain_core.runnables import RunnablePassthrough, RunnableLambda

# 文档处理

from langchain_core.documents import Document

from langchain.text_splitter import RecursiveCharacterTextSplitter

# 向量库

from langchain_community.vectorstores import Chroma, FAISS

# 文档加载器

from langchain_community.document_loaders import PyPDFLoader, WebBaseLoader, TextLoader

# Agent

from langchain_core.tools import tool

from langchain.agents import create_tool_calling_agent, AgentExecutor

模型参数

参数

说明

temperature

0~2,越低越确定,越高越有创意。问答用 0,写作用 0.7+

max_tokens

最大输出 Token 数

model

模型名,如 gpt-4o-mini / claude-opus-4-5

streaming

True 开启流式输出

timeout

请求超时秒数

max_retries

自动重试次数,默认 2

TextSplitter 参数

参数

说明

chunk_size

每块最大字符数,Q&A 场景 500-1000

chunk_overlap

块间重叠字符,建议 chunk_size 的 10%

separators

切割优先级,默认 ['\n\n', '\n', ' ', '']

推荐学习路径

  • Week 1:读完本文 → 跑通所有示例 → 独立实现简单 RAG
  • Week 2:实现带记忆的对话 → 自定义工具 → 第一个 Agent
  • Week 3:深入 LangGraph(复杂 Agent)→ 接入 LangSmith
  • Week 4:完整项目 → 部署 API(FastAPI + LangServe)


原文链接:https://juejin.cn/post/7618949119742132251

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐