LangChain Agent 学习文档(基于 LangChain 1.0)

LangChain Agent 学习文档(基于 LangChain 1.0)

一、Agent 核心概述

1.1 什么是 Agent?

LangChain Agent 是结合语言模型(LLM)与工具(Tools)的智能系统,能通过推理分析任务目标、动态选择工具、迭代执行步骤,直至满足停止条件(生成最终答案或达到迭代上限)。其核心价值是突破 LLM 静态响应的局限,实现"思考-行动-反馈"的闭环。

1.2 核心实现:create_agent

create_agent 是 LangChain 提供的生产级 Agent 构建函数,基于 LangGraph 实现"图结构"运行时(节点=步骤,边=流程连接),支持模型、工具、中间件的灵活集成。

二、Agent 核心组件

2.1 Model(推理引擎)

Model 是 Agent 的"大脑",负责决策与推理,支持静态和动态两种配置方式。

类型 特点 适用场景
静态 Model 初始化时固定,全程不变 多数简单场景(需求稳定)
动态 Model 运行时根据状态/上下文切换 复杂场景(成本优化、长对话)
2.1.1 静态 Model 配置
  • 方式1:通过模型标识符快速初始化(自动推断提供商)

    python 复制代码
    from langchain.agents import create_agent
    
    # "gpt-4o" 自动推断为 "openai:gpt-4o"
    agent = create_agent(
        model="openai:gpt-4o",
        tools=tools  # 后续定义的工具列表
    )
  • 方式2:通过模型实例精细化配置(支持温度、超时等参数)

    python 复制代码
    from langchain.agents import create_agent
    from langchain_openai import ChatOpenAI
    
    # 配置模型细节(温度=0.1:输出更确定;超时=30s)
    model = ChatOpenAI(
        model="openai:gpt-4o",
        temperature=0.1,
        max_tokens=1000,
        timeout=30
    )
    
    agent = create_agent(model=model, tools=tools)
2.1.2 动态 Model 配置

通过 @wrap_model_call 中间件,根据运行时状态(如对话长度)切换模型,实现成本与效果的平衡:

python 复制代码
from langchain_openai import ChatOpenAI
from langchain.agents import create_agent
from langchain.agents.middleware import wrap_model_call, ModelRequest, ModelResponse

# 定义基础模型和高级模型
basic_model = ChatOpenAI(model="gpt-4o-mini")  # 低成本
advanced_model = ChatOpenAI(model="gpt-4o")    # 高效果

# 动态模型选择中间件
@wrap_model_call
def dynamic_model_selection(request: ModelRequest, handler) -> ModelResponse:
    # 对话消息数 > 10 时,切换为高级模型
    message_count = len(request.state["messages"])
    if message_count > 10:
        request.model = advanced_model
    else:
        request.model = basic_model
    return handler(request)

# 初始化 Agent 时注入中间件
agent = create_agent(
    model=basic_model,  # 默认模型
    tools=tools,
    middleware=[dynamic_model_selection]
)

2.2 Tools(行动能力)

Tools 是 Agent 与外部世界交互的"手脚",支持多轮调用、并行执行、错误重试等能力。

2.2.1 定义 Tools

通过 @tool 装饰器快速定义工具(需指定输入参数和功能描述):

python 复制代码
from langchain.tools import tool
from langchain.agents import create_agent

# 工具1:搜索功能
@tool
def search(query: str) -> str:
    """Search for real-time or external information (e.g., news, stock prices)."""
    return f"Search results for '{query}': [simulated data]"

# 工具2:天气查询功能
@tool
def get_weather(location: str) -> str:
    """Get current weather of a specific location (e.g., city name)."""
    return f"Weather in {location}: Sunny, 25°C"

# 初始化 Agent 时传入工具列表
agent = create_agent(model="openai:gpt-4o", tools=[search, get_weather])
2.2.2 Tool 错误处理

通过 @wrap_tool_call 中间件自定义错误逻辑,避免 Agent 因工具异常中断:

python 复制代码
from langchain.agents.middleware import wrap_tool_call
from langchain_core.messages import ToolMessage

# 工具错误处理中间件
@wrap_tool_call
def handle_tool_errors(request, handler):
    try:
        return handler(request)  # 正常执行工具
    except Exception as e:
        # 自定义错误消息,返回给模型
        return ToolMessage(
            content=f"Tool Error: {str(e)} (please check your input, e.g., location format)",
            tool_call_id=request.tool_call["id"]
        )

# 注入错误处理中间件
agent = create_agent(
    model="openai:gpt-4o",
    tools=[search, get_weather],
    middleware=[handle_tool_errors]
)
2.2.3 Tool 与 ReAct 循环

Agent 遵循 ReAct(Reasoning + Acting)模式,交替执行"推理"和"工具调用":

  1. 推理 :分析任务是否需要工具(如"实时天气"需调用 get_weather);
  2. 行动:调用工具获取观察结果(Observation);
  3. 反馈:将观察结果代入下一轮推理,直至生成最终答案。

示例流程

  • 用户请求:"What's the weather in Beijing? Is it suitable for outdoor activities?"
    1. 推理:"需要北京天气数据 → 调用 get_weather";
    2. 行动:调用 get_weather(location="Beijing"),返回 Weather in Beijing: Rainy, 18°C
    3. 推理:"有天气数据 → 无需再调用工具 → 生成建议";
    4. 最终答案:"Beijing is rainy today (18°C), so it's not suitable for outdoor activities."

2.3 System Prompt(引导规则)

System Prompt 定义 Agent 的"行为准则",支持静态固定和动态生成两种方式。

2.3.1 静态 System Prompt

直接通过 system_prompt 参数传入固定提示:

python 复制代码
agent = create_agent(
    model="openai:gpt-4o",
    tools=tools,
    system_prompt="You are a concise assistant. Answer in 2 sentences max, no jargon."
)
2.3.2 动态 System Prompt

通过 @dynamic_prompt 中间件,根据运行时上下文(如用户角色)生成提示,是 Agent 灵活性的核心:

python 复制代码
from typing import TypedDict
from langchain.agents.middleware import dynamic_prompt, ModelRequest

# 1. 定义上下文结构(必须是 TypedDict,LangChain 1.0 强制要求)
class Context(TypedDict):
    user_role: str  # 上下文字段:用户角色(expert/beginner/user)

# 2. 动态提示生成函数(被 @dynamic_prompt 装饰)
@dynamic_prompt
def user_role_prompt(request: ModelRequest) -> str:
    # 从上下文获取用户角色(默认值:user)
    user_role = request.runtime.context.get("user_role", "user")
    base_prompt = "You are a helpful assistant."

    # 根据角色生成不同提示
    if user_role == "expert":
        return f"{base_prompt} Provide technical details (e.g., algorithms, parameters)."
    elif user_role == "beginner":
        return f"{base_prompt} Explain with examples, no technical terms."
    return base_prompt

# 3. 初始化 Agent 时注入中间件和上下文 schema
agent = create_agent(
    model="openai:gpt-4o",
    tools=[search],
    middleware=[user_role_prompt],  # 注入动态提示逻辑
    context_schema=Context          # 绑定上下文结构
)

# 4. 调用时传入上下文,触发动态提示
result = agent.invoke(
    {"messages": [{"role": "user", "content": "Explain machine learning"}]},
    context={"user_role": "beginner"}  # 切换为"新手视角"提示
)

三、Agent 调用与流式输出

3.1 基础调用:agent.invoke()

通过 invoke() 传入用户请求和上下文,获取最终结果:

python 复制代码
# 调用 Agent(传入用户消息和上下文)
result = agent.invoke(
    {
        "messages": [{"role": "user", "content": "Search AI news today"}]  # 用户请求
    },
    context={"user_role": "expert"}  # 上下文(可选)
)

# 输出结果(result 包含完整状态,重点关注 messages 最后一条)
print(result["messages"][-1]["content"])

3.2 流式输出:agent.stream()

对于多步骤任务,通过流式输出实时反馈中间过程(如工具调用、推理步骤):

python 复制代码
# 流式获取 Agent 执行过程
for chunk in agent.stream(
    {"messages": [{"role": "user", "content": "Search AI news and summarize"}]},
    stream_mode="values"  # 按"完整状态块"返回
):
    # 获取最新消息
    latest_msg = chunk["messages"][-1]
    # 区分"工具调用"和"文本回答"
    if latest_msg.get("tool_calls"):
        print(f"[Tool Calling] {[tc['name'] for tc in latest_msg['tool_calls']]}")
    elif latest_msg["content"]:
        print(f"[Agent Response] {latest_msg['content']}")

四、高级概念

4.1 Structured Output(结构化输出)

强制 Agent 按指定格式返回结果(如 JSON、自定义类),支持两种策略:

策略 原理 适用场景
ToolStrategy 利用模型的工具调用能力生成结构化数据 所有支持工具调用的模型
ProviderStrategy 利用模型提供商原生结构化能力(如 OpenAI) 特定提供商(兼容性有限)
示例:用 ToolStrategy 提取联系人信息
python 复制代码
from pydantic import BaseModel
from langchain.agents.structured_output import ToolStrategy

# 1. 定义结构化输出格式(Pydantic 模型)
class ContactInfo(BaseModel):
    name: str
    email: str
    phone: str

# 2. 初始化 Agent 时指定输出策略
agent = create_agent(
    model="openai:gpt-4o-mini",
    tools=[search],
    response_format=ToolStrategy(ContactInfo)  # 绑定结构化格式
)

# 3. 调用并获取结构化结果
result = agent.invoke({
    "messages": [{"role": "user", "content": "Extract contact: John Doe, john@x.com, 123-4567"}]
})

# 4. 访问结构化结果(result["structured_response"])
print(result["structured_response"])
# Output: ContactInfo(name='John Doe', email='john@x.com', phone='123-4567')

4.2 Memory(状态管理)

Agent 通过"状态(State)"维护对话历史和自定义信息(如用户偏好),LangChain 1.0 强制要求自定义状态必须用 TypedDict(弃用 Pydantic 模型和 dataclasses)。

4.2.1 定义状态的两种方式
方式 特点 适用场景
中间件(Middleware) 状态与中间件绑定,逻辑更内聚 状态需被特定中间件/工具访问
state_schema 参数 全局状态,简化配置 状态仅用于工具调用
方式1:通过 Middleware 定义状态
python 复制代码
from langchain.agents import AgentState, AgentMiddleware
from typing import Any

# 1. 定义自定义状态(继承 AgentState,必须是 TypedDict)
class CustomState(AgentState):
    user_preferences: dict  # 自定义字段:用户偏好(如回答风格)

# 2. 定义中间件,绑定状态
class PreferenceMiddleware(AgentMiddleware):
    state_schema = CustomState  # 关联自定义状态
    tools = [search]            # 该中间件关联的工具

    # 模型调用前处理状态(如注入用户偏好到提示)
    def before_model(self, state: CustomState, runtime) -> dict[str, Any] | None:
        print(f"User Preference: {state['user_preferences']}")
        return None

# 3. 初始化 Agent
agent = create_agent(
    model="openai:gpt-4o",
    tools=tools,
    middleware=[PreferenceMiddleware()]  # 注入中间件
)

# 4. 调用时传入自定义状态
result = agent.invoke({
    "messages": [{"role": "user", "content": "Explain AI"}],
    "user_preferences": {"style": "technical", "verbosity": "low"}  # 自定义状态
})
方式2:通过 state_schema 定义状态
python 复制代码
from langchain.agents import AgentState

# 1. 定义自定义状态
class CustomState(AgentState):
    user_preferences: dict

# 2. 初始化 Agent 时指定 state_schema
agent = create_agent(
    model="openai:gpt-4o",
    tools=tools,
    state_schema=CustomState  # 全局绑定状态
)

# 3. 调用时传入状态
result = agent.invoke({
    "messages": [{"role": "user", "content": "Explain AI"}],
    "user_preferences": {"style": "simple"}
})

4.3 Middleware(中间件)

Middleware 是 Agent 的"插件系统",用于在执行流程中插入自定义逻辑(如日志、权限校验、状态修改),核心作用是解耦核心逻辑与扩展功能

常用 Middleware 装饰器
装饰器 作用 示例场景
@wrap_model_call 拦截模型调用(如动态切换模型) 成本优化、长对话升级模型
@wrap_tool_call 拦截工具调用(如错误处理、日志) 工具异常捕获、调用记录
@dynamic_prompt 动态生成系统提示 按用户角色切换回答风格
@before_model 模型调用前处理状态(如注入上下文) 补充用户偏好到提示

五、核心注意事项(LangChain 1.0 变更)

  1. 自定义状态强制用 TypedDict :弃用 Pydantic 模型和 dataclasses,需继承 AgentState(如 class CustomState(AgentState): ...);
  2. 结构化输出需显式指定策略 :不再支持直接传入 Pydantic 模型,需用 ToolStrategyProviderStrategy
  3. 模型实例避免预绑定工具 :动态模型选择时,模型不可用 bind_tools() 预绑定工具,否则结构化输出会失效。

六、总结

LangChain Agent 的核心逻辑是"模型推理 + 工具行动 + 状态管理 ",通过 create_agent 可快速构建生产级系统。学习重点:

  1. 掌握 Model/Tools/System Prompt 三大核心组件的配置;
  2. 理解动态模型、动态提示的中间件逻辑(灵活性关键);
  3. 遵守 LangChain 1.0 规范(如 TypedDict 状态),避免兼容性问题。

建议结合官方 v1 迁移指南LangGraph 文档,深入理解 Agent 的图结构运行时。

相关推荐
不一样的少年_3 小时前
老板问我:AI真能一键画广州旅游路线图?我用 MCP 现场开图
前端·人工智能·后端
qq_5470261793 小时前
SpringCloud--Sleuth 分布式链路追踪
后端·spring·spring cloud
JohnYan3 小时前
微软验证器-验证ID功能初体验
后端·算法·安全
海边夕阳20063 小时前
数据源切换的陷阱:Spring Boot中@Transactional与@DS注解的冲突博弈与破局之道
java·数据库·spring boot·后端·架构
干翻秋招3 小时前
MySQL知识点复习
后端
扎瓦斯柯瑞迫4 小时前
Cursor 提示"Too Many Accounts"?一行命令重置机器码
前端·javascript·后端
又过一个秋4 小时前
dpdk-3.hash表CURD
后端·c
Data_Adventure4 小时前
从 TypeScript 视角读懂 Java 和 TS 类中 new 自己的区别
后端
起这个名字4 小时前
Langchain4j Rag 知识库教程
java·后端