一、教程整体概览
本教程从LangChain零基础入门,逐步推进至企业级ReAct Agent实战,全程以「可运行代码+核心知识点」为核心,覆盖LangChain生态核心功能,最终实现整合「多轮记忆+RAG知识库+工具调用+LangGraph流程编排」的完整智能体。
学习路线:Day1(LangChain核心)→ Day2(多轮对话记忆)→ Day3(RAG文本切分)→ Day4(完整RAG)→ Day5(RAG+记忆)→ Day6(工具调用入门)→ Day7(完整工具调用)→ Day8-9(LangGraph入门)→ 完整版Agent(企业级)
二、核心依赖包说明(必装+用途)
| 依赖包名称 | 安装命令 | 核心用途 | 关联功能 |
| langchain | uv add langchain | LangChain核心框架,提供流水线(LCEL)、基础链、工具基类等核心能力 | 所有LangChain相关开发,是基础依赖 |
| langchain-openai | uv add langchain-openai | 对接OpenAI格式大模型(通义千问、DeepSeek、豆包等均兼容),提供聊天模型、嵌入模型 | 大模型调用、文本向量化(Embedding) |
| python-dotenv | uv add python-dotenv | 读取.env配置文件,存储API_KEY、BASE_URL等敏感信息,避免硬编码 | 所有需要配置密钥的场景(大模型调用、工具调用) |
| langchain-text-splitters | uv add langchain-text-splitters | 提供文本切分工具,将长文本拆分为语义完整的小块(RAG核心步骤) | RAG文档处理、知识库构建 |
| langchain-community | uv add langchain-community | 第三方工具集合,包含向量数据库(Chroma)、对话历史存储、文档加载等 | RAG向量库、多轮对话记忆、文档加载 |
| langgraph | uv add langgraph | LangChain生态中用于构建Agent工作流的框架,基于状态机实现节点、边的编排 | ReAct Agent、多步骤任务规划 |
三、核心模块详细说明(import+用途+代码示例)
模块1:大模型调用(langchain-openai)
1.1 核心导入
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
1.2 各导入用途
-
ChatOpenAI:创建大模型客户端,用于调用聊天模型(核心AI大脑),支持异步/同步调用,兼容所有OpenAI格式模型(通义千问、DeepSeek等)。
-
OpenAIEmbeddings:将文本转换为向量(向量化工具),用于RAG中向量库的构建和语义检索。
1.3 代码示例
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from dotenv import load_dotenv
import os
load_dotenv() # 加载.env配置
# 1. 创建大模型
llm = ChatOpenAI(
api_key=os.getenv("API_KEY"), # 从.env读取密钥
base_url=os.getenv("BASE_URL"),# 模型接口地址
model=os.getenv("MODEL"), # 模型名称(如qwen-turbo)
temperature=0.7 # 回答随机性(0~1,越小越严谨)
)
# 2. 创建向量化工具
embeddings = OpenAIEmbeddings(
api_key=os.getenv("API_KEY"),
base_url=os.getenv("BASE_URL")
)
模块2:提示词模板(langchain-core)
2.1 核心导入
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
2.2 各导入用途
-
ChatPromptTemplate:构造聊天格式的提示词模板,支持传入变量(如用户问题、上下文),实现提示词的复用和动态填充。
-
MessagesPlaceholder:提示词中的“占位符”,用于自动填充对话历史(多轮记忆的核心),避免手动拼接历史对话。
2.3 代码示例
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
# 1. 基础提示词模板(带变量)
prompt = ChatPromptTemplate.from_messages([
("system", "你是专业的AI助手,回答简洁准确。"), # 系统角色设定
("user", "{question}") # 变量占位符,后续传入用户问题
])
# 2. 带记忆的提示词模板(多轮对话用)
prompt_with_memory = ChatPromptTemplate.from_messages([
("system", "你是记忆超强的AI助手,会记住对话历史。"),
MessagesPlaceholder(variable_name="history"), # 对话历史占位符
("user", "{input}") # 用户输入占位符
])
模块3:多轮对话记忆(langchain-core + langchain-community)
3.1 核心导入
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
3.2 各导入用途
-
ChatMessageHistory:内存级对话历史存储工具,用于保存单个用户的对话记录(如用户提问、AI回答),支持增删查操作。
-
RunnableWithMessageHistory:给LangChain流水线(chain)添加记忆功能,自动读取、保存对话历史,实现多轮对话上下文连贯。
3.3 代码示例
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
# 1. 对话历史存储(字典,key为session_id,区分不同用户)
store = {}
def get_session_history(session_id: str):
if session_id not in store:
store[session_id] = ChatMessageHistory() # 为新用户创建对话历史
return store[session_id]
# 2. 给流水线添加记忆(假设chain是已定义的prompt | llm)
chat_bot = RunnableWithMessageHistory(
chain, # 已有的流水线
get_session_history, # 对话历史获取函数
input_messages_key="input", # 用户输入的key(对应prompt中的{input})
history_messages_key="history" # 对话历史的key(对应MessagesPlaceholder)
)
模块4:RAG知识库(langchain-text-splitters + langchain-community)
4.1 核心导入
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
4.2 各导入用途
-
RecursiveCharacterTextSplitter:最常用的文本切分工具,按“换行→句号→逗号→空格”的优先级切分长文本,保证语义完整,避免文本过长无法被模型读取。
-
Chroma:轻量级内存向量数据库,用于存储文本向量(向量化后的chunks),支持语义相似度检索(RAG的核心检索工具)。
4.3 代码示例
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
# 1. 准备长文本(知识库内容)
knowledge = "公司员工手册:1. 上班时间9:00-18:00;2. 每月10号发工资..."
# 2. 文本切分
splitter = RecursiveCharacterTextSplitter(
chunk_size=150, # 每块最大长度(字符数)
chunk_overlap=30 # 块之间的重叠长度(保证语义连贯)
)
chunks = splitter.split_text(knowledge) # 切分后的文本块
# 3. 构建向量库(存入切分后的文本向量)
embeddings = OpenAIEmbeddings(...) # 已定义的向量化工具
db = Chroma.from_texts(chunks, embeddings)
# 4. 语义检索(根据用户问题找最相关的文本块)
docs = db.similarity_search("工作3年有几天年假?", k=2) # k=2表示取前2个最相关的块
context = "\n".join([d.page_content for d in docs]) # 拼接检索到的上下文
模块5:工具调用(langchain-core)
5.1 核心导入
from langchain_core.tools import tool
from langchain_core.messages import HumanMessage, ToolMessage
5.2 各导入用途
-
@tool 装饰器:将普通Python函数转换为LangChain可识别的工具,模型通过函数注释理解工具的用途和参数。
-
HumanMessage:表示用户的消息(用于传递用户问题给模型)。
-
ToolMessage:表示工具执行的结果(用于将工具返回值传递给模型,让模型整理成自然语言回答)。
5.3 代码示例
from langchain_core.tools import tool
from langchain_core.messages import HumanMessage, ToolMessage
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(...) # 已定义的大模型
# 1. 定义工具(用@tool装饰)
@tool
def add(a: int, b: int) -> int:
"""加法计算器,用于计算两个整数的和。a:第一个整数;b:第二个整数。"""
return a + b
@tool
def get_weather(city: str) -> str:
"""获取城市天气,city:城市名称。"""
return f"{city} 今日晴,25℃"
tools = [add, get_weather] # 工具列表
llm_with_tools = llm.bind_tools(tools) # 给模型绑定工具
# 2. 工具调用流程
def chat(question: str):
# 第一步:模型判断是否调用工具
response = llm_with_tools.invoke([HumanMessage(content=question)])
# 无工具调用,直接返回回答
if not response.tool_calls:
return response.content
# 有工具调用,执行工具并获取结果
tool_outputs = []
for call in response.tool_calls:
tool = next(t for t in tools if t.name == call["name"])
result = tool.invoke(call["args"]) # 执行工具
tool_outputs.append(ToolMessage(tool_call_id=call["id"], content=str(result)))
# 第二步:模型根据工具结果生成最终回答
final = llm.invoke([HumanMessage(question), response] + tool_outputs)
return final.content
模块6:LangGraph Agent(langgraph)
6.1 核心导入
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
6.2 各导入用途
-
TypedDict:用于定义Agent的状态(State),明确状态中包含的数据(如问题、对话历史、工具结果等),实现类型约束。
-
StateGraph:LangGraph的核心类,用于构建Agent的工作流(状态机),管理节点和边的关系。
-
START / END:工作流的起始节点和结束节点,用于定义流程的入口和出口。
6.3 代码示例
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(...) # 已定义的大模型
tools = [add, get_weather] # 已定义的工具
llm_with_tools = llm.bind_tools(tools)
# 1. 定义Agent状态(存储全局数据)
class AgentState(TypedDict):
question: str # 用户问题
tool_result: str # 工具执行结果
answer: str # 最终回答
# 2. 定义节点(每个节点做一件事)
def think_node(state: AgentState):
# 思考节点:判断是否调用工具
res = llm_with_tools.invoke(state["question"])
if res.tool_calls:
tool = next(t for t in tools if t.name == res.tool_calls[0]["name"])
tool_result = tool.invoke(res.tool_calls[0]["args"])
return {"tool_result": str(tool_result)}
return {"answer": res.content}
def answer_node(state: AgentState):
# 回答节点:整理结果生成最终回答
if state["tool_result"]:
final = llm.invoke(f"整理结果:{state['tool_result']}")
return {"answer": final.content}
return state
# 3. 构建工作流
builder = StateGraph(AgentState)
builder.add_node("think", think_node) # 添加思考节点
builder.add_node("answer", answer_node) # 添加回答节点
# 连线:定义流程顺序
builder.add_edge(START, "think") # 起始→思考
builder.add_edge("think", "answer") # 思考→回答
builder.add_edge("answer", END) # 回答→结束
# 编译工作流,生成可运行的Agent
agent = builder.compile()
# 测试Agent
result = agent.invoke({
"question": "33+66等于多少?",
"tool_result": "",
"answer": ""
})
print(result["answer"])
四、企业级完整版Agent整合代码(全模块复用)
from dotenv import load_dotenv
import os
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_core.tools import tool
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
# 1. 加载配置
load_dotenv()
# 2. 大模型 & 向量化工具
llm = ChatOpenAI(
api_key=os.getenv("API_KEY"),
base_url=os.getenv("BASE_URL"),
model=os.getenv("MODEL"),
)
embeddings = OpenAIEmbeddings(
api_key=os.getenv("API_KEY"),
base_url=os.getenv("BASE_URL"),
)
# 3. RAG知识库构建
knowledge = """
员工规则:
1. 上班时间 9:00-18:00
2. 每月10号发工资
3. 满1年5天年假,满5年10天
"""
splitter = RecursiveCharacterTextSplitter(chunk_size=150)
chunks = splitter.split_text(knowledge)
db = Chroma.from_texts(chunks, embeddings)
# 4. 工具定义
@tool
def add(a: int, b: int) -> int:
"""加法计算"""
return a + b
@tool
def query_company_info(question: str) -> str:
"""查询公司内部规则、员工手册"""
docs = db.similarity_search(question)
return "\n".join([d.page_content for d in docs])
tools = [add, query_company_info]
llm_with_tools = llm.bind_tools(tools)
# 5. 多轮记忆配置
store = {}
def get_session_history(session_id: str):
if session_id not in store:
store[session_id] = ChatMessageHistory()
return store[session_id]
# 6. Agent状态定义
class AgentState(TypedDict):
question: str
history: list
tool_result: str
answer: str
# 7. 节点定义
def think_node(state: AgentState):
print("\n🤖 Agent 思考中...")
res = llm_with_tools.invoke(state["question"])
if not res.tool_calls:
return {"answer": res.content}
tool_call = res.tool_calls[0]
tool = next(t for t in tools if t.name == tool_call["name"])
tool_result = tool.invoke(tool_call["args"])
return {"tool_result": str(tool_result)}
def answer_node(state: AgentState):
print("\n📝 生成最终回答...")
if state["tool_result"]:
prompt = f"根据结果整理成人话回答:{state['tool_result']}"
final = llm.invoke(prompt)
return {"answer": final.content}
return state
# 8. 构建LangGraph工作流
builder = StateGraph(AgentState)
builder.add_node("think", think_node)
builder.add_node("answer", answer_node)
builder.add_edge(START, "think")
builder.add_edge("think", "answer")
builder.add_edge("answer", END)
agent = builder.compile()
# 9. 测试
if __name__ == "__main__":
print("="*60)
print(" 企业级 ReAct Agent 已启动")
print("="*60)
# 测试1:计算
res1 = agent.invoke({
"question": "12+34等于多少?",
"history": [],
"tool_result": "",
"answer": ""
})
print("用户:12+34等于多少?")
print("AI:", res1["answer"])
# 测试2:查知识库
res2 = agent.invoke({
"question": "工作3年有几天年假?",
"history": [],
"tool_result": "",
"answer": ""
})
print("用户:工作3年有几天年假?")
print("AI:", res2["answer"])
五、关键知识点总结
5.1 LCEL流水线(核心语法)
chain = A | B,表示“数据从A流向B”,A的输出作为B的输入,可无限扩展(如:prompt | llm | 格式化输出),是LangChain的核心设计。
5.2 RAG核心流程(必记)
准备文档 → 文本切分(RecursiveCharacterTextSplitter)→ 向量化(OpenAIEmbeddings)→ 存入向量库(Chroma)→ 语义检索 → 模型生成回答。
5.3 多轮记忆核心
通过ChatMessageHistory存储对话历史,RunnableWithMessageHistory给流水线添加记忆,session_id区分不同用户,实现上下文连贯。
5.4 工具调用核心
@tool装饰器定义工具 → llm.bind_tools绑定工具 → 模型返回tool_calls → 执行工具 → ToolMessage传递结果 → 模型整理回答。
5.5 LangGraph Agent核心
State(存数据)→ Node(做任务)→ Edge(定流程),通过状态机实现Agent的自主思考、多步骤执行,是企业级Agent的主流架构。
六、常见问题解决
-
模型调用失败:检查.env文件中API_KEY、BASE_URL、MODEL是否正确,确保模型支持OpenAI格式。
-
RAG检索不到相关内容:调整chunk_size和chunk_overlap,确保文本切分语义完整;检查向量化工具是否和模型匹配。
-
多轮记忆失效:确认RunnableWithMessageHistory的input_messages_key和history_messages_key与prompt中的占位符一致;检查session_id是否正确。
-
工具调用失败:检查工具函数的注释是否清晰(模型靠注释理解工具);确保工具参数类型和模型返回的args一致。