LangChain从0到企业级Agent完整教程(详细文档)

5 阅读10分钟

一、教程整体概览

本教程从LangChain零基础入门,逐步推进至企业级ReAct Agent实战,全程以「可运行代码+核心知识点」为核心,覆盖LangChain生态核心功能,最终实现整合「多轮记忆+RAG知识库+工具调用+LangGraph流程编排」的完整智能体。

学习路线:Day1(LangChain核心)→ Day2(多轮对话记忆)→ Day3(RAG文本切分)→ Day4(完整RAG)→ Day5(RAG+记忆)→ Day6(工具调用入门)→ Day7(完整工具调用)→ Day8-9(LangGraph入门)→ 完整版Agent(企业级)

二、核心依赖包说明(必装+用途)

依赖包名称安装命令核心用途关联功能
langchainuv add langchainLangChain核心框架,提供流水线(LCEL)、基础链、工具基类等核心能力所有LangChain相关开发,是基础依赖
langchain-openaiuv add langchain-openai对接OpenAI格式大模型(通义千问、DeepSeek、豆包等均兼容),提供聊天模型、嵌入模型大模型调用、文本向量化(Embedding)
python-dotenvuv add python-dotenv读取.env配置文件,存储API_KEY、BASE_URL等敏感信息,避免硬编码所有需要配置密钥的场景(大模型调用、工具调用)
langchain-text-splittersuv add langchain-text-splitters提供文本切分工具,将长文本拆分为语义完整的小块(RAG核心步骤)RAG文档处理、知识库构建
langchain-communityuv add langchain-community第三方工具集合,包含向量数据库(Chroma)、对话历史存储、文档加载等RAG向量库、多轮对话记忆、文档加载
langgraphuv add langgraphLangChain生态中用于构建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一致。