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 的图结构运行时。

相关推荐
奋进的芋圆14 小时前
DataSyncManager 详解与 Spring Boot 迁移指南
java·spring boot·后端
计算机程序设计小李同学14 小时前
个人数据管理系统
java·vue.js·spring boot·后端·web安全
Echo娴15 小时前
Spring的开发步骤
java·后端·spring
追逐时光者15 小时前
TIOBE 公布 C# 是 2025 年度编程语言
后端·.net
Victor35615 小时前
Hibernate(32)什么是Hibernate的Criteria查询?
后端
Victor35615 小时前
Hibernate(31)Hibernate的原生SQL查询是什么?
后端
_UMR_16 小时前
springboot集成Jasypt实现配置文件启动时自动解密-ENC
java·spring boot·后端
程序员小假16 小时前
我们来说说 Cookie、Session、Token、JWT
java·后端