使用LangChain预置的Agent类型(Zero-shot ReAct等)

核心知识点讲解

LangChain预置的Agent类型

LangChain提供了多种预置的Agent类型,每种类型都针对不同的使用场景进行了优化:

Agent类型 特点 适用场景
Zero-shot ReAct 基于描述选择工具,结合推理和行动 通用场景,需要工具使用
Conversational React 优化的对话式智能体 对话场景,需要记忆功能
Structured Chat 结构化输出,支持多轮对话 复杂任务,需要清晰的输出格式
ReAct 原始的ReAct实现 需要显式推理步骤的场景
Self-Ask with Search 通过自问自答获取信息 信息检索任务
Plan and Execute 先规划后执行 复杂的多步骤任务
OpenAI Functions 使用OpenAI的函数调用 OpenAI模型,需要结构化输出

Agent执行流程

大多数LangChain Agent的执行流程如下:

  1. 接收输入:获取用户的问题或指令
  2. 分析输入:理解用户需求,确定需要的工具
  3. 选择工具:基于工具描述选择合适的工具
  4. 执行工具:调用选定的工具并获取结果
  5. 处理结果:分析工具执行结果,决定下一步行动
  6. 生成回答:基于所有信息生成最终回答

Agent配置选项

使用LangChain Agent时,可以配置以下选项:

  • 工具列表:智能体可以使用的工具
  • 语言模型:用于推理和决策的语言模型
  • 记忆系统:用于存储对话历史
  • 停止条件:最大迭代次数、超时时间等
  • 输出格式:如何格式化最终回答

实用案例分析

案例1:使用Zero-shot ReAct Agent

from langchain.agents import initialize_agent, AgentType
from langchain.llms import OpenAI
from langchain.tools import Tool
from langchain.utilities import SerpAPIWrapper, Calculator

# 1. 初始化工具
search = SerpAPIWrapper()
calculator = Calculator()

tools = [
    Tool(
        name="Search",
        func=search.run,
        description="用于搜索网络信息"
    ),
    Tool(
        name="Calculator",
        func=calculator.run,
        description="用于进行数学计算"
    )
]

# 2. 初始化语言模型
llm = OpenAI(temperature=0.7)

# 3. 初始化Zero-shot ReAct Agent
agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True,
    max_iterations=5
)

# 4. 运行Agent
result = agent.run("2023年世界杯冠军是谁?这个国家的人口大约是多少?")
print(f"最终答案: {result}")

案例2:使用Conversational React Agent

from langchain.agents import initialize_agent, AgentType
from langchain.chat_models import ChatOpenAI
from langchain.tools import Tool
from langchain.utilities import SerpAPIWrapper
from langchain.memory import ConversationBufferMemory

# 1. 初始化工具
search = SerpAPIWrapper()

tools = [
    Tool(
        name="Search",
        func=search.run,
        description="用于搜索网络信息"
    )
]

# 2. 初始化聊天模型
chat_model = ChatOpenAI(temperature=0.7)

# 3. 初始化记忆系统
memory = ConversationBufferMemory(
    memory_key="chat_history",
    return_messages=True
)

# 4. 初始化Conversational React Agent
agent = initialize_agent(
    tools=tools,
    llm=chat_model,
    agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True,
    memory=memory
)

# 5. 运行Agent(多轮对话)
print("=== 第一轮对话 ===")
result1 = agent.run("北京今天的天气如何?")
print(f"回答: {result1}")

print("\n=== 第二轮对话 ===")
result2 = agent.run("上海呢?")
print(f"回答: {result2}")

print("\n=== 第三轮对话 ===")
result3 = agent.run("这两个城市的天气有什么不同?")
print(f"回答: {result3}")

案例3:使用Structured Chat Agent

from langchain.agents import initialize_agent, AgentType
from langchain.chat_models import ChatOpenAI
from langchain.tools import Tool
from langchain.utilities import SerpAPIWrapper, Calculator
from langchain.memory import ConversationBufferMemory

# 1. 初始化工具
search = SerpAPIWrapper()
calculator = Calculator()

tools = [
    Tool(
        name="Search",
        func=search.run,
        description="用于搜索网络信息"
    ),
    Tool(
        name="Calculator",
        func=calculator.run,
        description="用于进行数学计算"
    )
]

# 2. 初始化聊天模型
chat_model = ChatOpenAI(temperature=0.7)

# 3. 初始化记忆系统
memory = ConversationBufferMemory(
    memory_key="chat_history",
    return_messages=True
)

# 4. 初始化Structured Chat Agent
agent = initialize_agent(
    tools=tools,
    llm=chat_model,
    agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True,
    memory=memory,
    return_intermediate_steps=True
)

# 5. 运行Agent
result = agent({
    "input": "2023年中国的GDP是多少?比2022年增长了多少百分比?"
})

print(f"最终答案: {result['output']}")
print("\n中间步骤:")
for step in result['intermediate_steps']:
    print(f"- {step}")

案例4:使用Plan and Execute Agent

from langchain.agents import initialize_agent, AgentType
from langchain.chat_models import ChatOpenAI
from langchain.tools import Tool
from langchain.utilities import SerpAPIWrapper, Calculator

# 1. 初始化工具
search = SerpAPIWrapper()
calculator = Calculator()

tools = [
    Tool(
        name="Search",
        func=search.run,
        description="用于搜索网络信息"
    ),
    Tool(
        name="Calculator",
        func=calculator.run,
        description="用于进行数学计算"
    )
]

# 2. 初始化语言模型(Plan and Execute需要更强大的模型)
llm = ChatOpenAI(temperature=0.7, model_name="gpt-4")

# 3. 初始化Plan and Execute Agent
agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.PLAN_AND_EXECUTE,
    verbose=True,
    max_execution_time=60
)

# 4. 运行Agent(复杂任务)
result = agent.run(
    "规划一个从北京到上海的3天2晚旅行,包括交通、住宿、景点和美食推荐," 
    "并计算大致的旅行费用"
)
print(f"最终答案: {result}")

案例5:使用OpenAI Functions Agent

from langchain.agents import initialize_agent, AgentType
from langchain.chat_models import ChatOpenAI
from langchain.tools import Tool
from langchain.utilities import SerpAPIWrapper
from langchain.tools import StructuredTool
from pydantic import BaseModel, Field

# 1. 定义工具输入模型
class WeatherInput(BaseModel):
    location: str = Field(description="城市或地区名称")

# 2. 定义天气工具
def get_weather(location: str) -> str:
    """获取指定地点的天气信息"""
    # 这里使用模拟数据,实际应用中应调用真实的天气API
    return f"{location}的天气晴朗,温度25°C,湿度60%"

# 3. 初始化工具
search = SerpAPIWrapper()
weather_tool = StructuredTool(
    name="GetWeather",
    func=get_weather,
    description="获取指定地点的天气信息",
    args_schema=WeatherInput
)

tools = [
    Tool(
        name="Search",
        func=search.run,
        description="用于搜索网络信息"
    ),
    weather_tool
]

# 4. 初始化语言模型
llm = ChatOpenAI(temperature=0.7, model_name="gpt-3.5-turbo-0613")

# 5. 初始化OpenAI Functions Agent
agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.OPENAI_FUNCTIONS,
    verbose=True
)

# 6. 运行Agent
result = agent.run("北京和上海今天的天气如何?")
print(f"最终答案: {result}")

代码解析

案例1:Zero-shot ReAct Agent

  1. 工具配置:配置了搜索和计算工具
  2. Agent初始化:使用AgentType.ZERO_SHOT_REACT_DESCRIPTION
  3. 核心特点
    • 基于工具描述选择工具
    • 结合推理和行动
    • 适用于通用场景
  4. 运行过程
    • 分析问题,确定需要搜索2023年世界杯冠军
    • 执行搜索获取冠军信息
    • 分析结果,确定需要搜索该国家的人口
    • 执行搜索获取人口信息
    • 综合信息生成最终答案

案例2:Conversational React Agent

  1. 记忆系统:使用ConversationBufferMemory存储对话历史
  2. 聊天模型:使用ChatOpenAI模型
  3. 核心特点
    • 优化的对话体验
    • 支持多轮对话
    • 能够参考之前的对话内容
  4. 运行过程
    • 第一轮:获取北京天气
    • 第二轮:获取上海天气(智能体理解"上海呢?"指的是上海的天气)
    • 第三轮:比较两个城市的天气差异(基于之前的对话内容)

案例3:Structured Chat Agent

  1. 结构化输出:支持更清晰的输出格式
  2. 中间步骤:通过return_intermediate_steps=True获取执行过程
  3. 核心特点
    • 结构化的输出格式
    • 更详细的中间步骤
    • 适合复杂任务
  4. 运行过程
    • 分析问题,确定需要搜索2023年中国GDP
    • 执行搜索获取GDP数据
    • 分析结果,确定需要搜索2022年中国GDP
    • 执行搜索获取2022年数据
    • 计算增长率
    • 综合信息生成最终答案

案例4:Plan and Execute Agent

  1. 强大模型:使用GPT-4模型,适合复杂任务
  2. 规划能力:先制定详细计划,再执行
  3. 核心特点
    • 先规划后执行
    • 适合复杂的多步骤任务
    • 能够处理需要多个工具的任务
  4. 运行过程
    • 分析旅行需求,制定详细计划
    • 执行计划,搜索交通、住宿、景点、美食信息
    • 计算旅行费用
    • 综合信息生成最终答案

案例5:OpenAI Functions Agent

  1. 函数调用:使用OpenAI的函数调用能力
  2. 结构化工具:使用StructuredTool和Pydantic模型定义工具输入
  3. 核心特点
    • 使用OpenAI的函数调用API
    • 更精确的工具参数传递
    • 适合需要结构化输入的工具
  4. 运行过程
    • 分析问题,确定需要获取北京和上海的天气
    • 调用天气工具获取北京天气
    • 调用天气工具获取上海天气
    • 综合信息生成最终答案

高级配置

1. 自定义Agent提示词

from langchain.agents import initialize_agent, AgentType
from langchain.llms import OpenAI
from langchain.tools import Tool
from langchain.utilities import SerpAPIWrapper
from langchain.prompts import PromptTemplate

# 初始化工具
search = SerpAPIWrapper()
tools = [
    Tool(
        name="Search",
        func=search.run,
        description="用于搜索网络信息"
    )
]

# 自定义提示词
custom_prompt = PromptTemplate(
    template="""你是一个专业的AI助手,能够通过思考和行动来解决问题。

可用工具:
{tools}

请按照以下格式回答:

问题: {input}

思考: [分析问题,决定使用什么工具]
行动: [工具名称[参数]]
观察: [工具执行结果]
... (重复思考-行动-观察步骤)
思考: [总结所有信息]
回答: [你的最终答案]

开始回答:
""",
    input_variables=["input", "tools"]
)

# 初始化Agent
llm = OpenAI(temperature=0.7)
agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True,
    agent_kwargs={
        "prompt": custom_prompt
    }
)

# 运行Agent
result = agent.run("2023年诺贝尔物理学奖获得者是谁?")
print(f"最终答案: {result}")

2. 自定义记忆系统

from langchain.agents import initialize_agent, AgentType
from langchain.chat_models import ChatOpenAI
from langchain.tools import Tool
from langchain.utilities import SerpAPIWrapper
from langchain.memory import ConversationSummaryMemory

# 初始化工具
search = SerpAPIWrapper()
tools = [
    Tool(
        name="Search",
        func=search.run,
        description="用于搜索网络信息"
    )
]

# 初始化语言模型
llm = ChatOpenAI(temperature=0.7)

# 初始化摘要记忆系统
memory = ConversationSummaryMemory(
    memory_key="chat_history",
    return_messages=True,
    llm=llm
)

# 初始化Agent
agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True,
    memory=memory
)

# 运行Agent(多轮对话)
print("=== 第一轮对话 ===")
result1 = agent.run("什么是人工智能?")
print(f"回答: {result1}")

print("\n=== 第二轮对话 ===")
result2 = agent.run("它有哪些应用领域?")
print(f"回答: {result2}")

print("\n=== 第三轮对话 ===")
result3 = agent.run("刚才我们讨论了什么?")
print(f"回答: {result3}")

3. 多Agent协作

from langchain.agents import initialize_agent, AgentType
from langchain.chat_models import ChatOpenAI
from langchain.tools import Tool
from langchain.utilities import SerpAPIWrapper, Calculator

# 初始化工具
search = SerpAPIWrapper()
calculator = Calculator()

# 创建搜索Agent
search_agent = initialize_agent(
    tools=[Tool(name="Search", func=search.run, description="用于搜索网络信息")],
    llm=ChatOpenAI(temperature=0.7),
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True
)

# 创建计算Agent
math_agent = initialize_agent(
    tools=[Tool(name="Calculator", func=calculator.run, description="用于进行数学计算")],
    llm=ChatOpenAI(temperature=0.7),
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True
)

# 代理Agent,负责分发任务
def task_distributor(question):
    if any(keyword in question for keyword in ["计算", "数学", "等于", "加", "减", "乘", "除"]):
        return math_agent.run(question)
    else:
        return search_agent.run(question)

# 测试多Agent协作
print("=== 测试搜索任务 ===")
result1 = task_distributor("2023年世界杯冠军是谁?")
print(f"回答: {result1}")

print("\n=== 测试计算任务 ===")
result2 = task_distributor("12345的平方根是多少?")
print(f"回答: {result2}")

性能优化

1. 工具选择优化

  • 工具描述:编写清晰、准确的工具描述,帮助智能体更好地选择工具
  • 工具数量:不要提供过多工具,只包含必要的工具
  • 工具分组:将相关工具分组,提高选择效率

2. 模型选择优化

  • 任务复杂度:简单任务使用GPT-3.5,复杂任务使用GPT-4
  • 响应速度:对速度要求高的场景使用GPT-3.5-Turbo
  • 推理能力:对推理要求高的场景使用GPT-4

3. 执行流程优化

  • 最大迭代次数:根据任务复杂度设置合理的最大迭代次数
  • 超时设置:设置适当的超时时间,避免任务无限执行
  • 记忆管理:根据对话长度选择合适的记忆类型

4. 错误处理优化

  • 重试机制:配置工具调用的重试次数
  • 错误提示:提供清晰的错误提示,帮助智能体从错误中恢复
  • 备用方案:当一个工具失败时,提供备用工具或方法

最佳实践

1. 选择合适的Agent类型

场景 推荐Agent类型 理由
通用工具使用 Zero-shot ReAct 基于描述选择工具,适用范围广
对话系统 Conversational React 优化的对话体验,支持多轮对话
复杂任务 Plan and Execute 先规划后执行,适合复杂任务
结构化输出 Structured Chat 清晰的输出格式,详细的中间步骤
OpenAI模型 OpenAI Functions 利用函数调用能力,更精确的工具参数

2. 工具设计最佳实践

  • 描述清晰:工具描述应清晰、准确,说明工具的用途和参数
  • 功能单一:每个工具应专注于单一功能
  • 错误处理:工具应包含适当的错误处理
  • 返回格式:工具返回格式应一致、易于理解

3. 提示词设计最佳实践

  • 清晰指令:提供清晰的任务指令
  • 格式指导:明确指定输出格式
  • 示例引导:对于复杂任务,提供示例
  • 限制说明:说明工具的使用限制

总结

通过本集的学习,我们了解了LangChain中预置的各种Agent类型,包括:

  1. Zero-shot ReAct:基于描述选择工具,适用于通用场景
  2. Conversational React:优化的对话式智能体,支持多轮对话
  3. Structured Chat:结构化输出,适合复杂任务
  4. Plan and Execute:先规划后执行,适合复杂的多步骤任务
  5. OpenAI Functions:使用OpenAI的函数调用,适合需要结构化输入的工具

我们还学习了如何配置和使用这些Agent,以及如何优化它们的性能。选择合适的Agent类型和配置,可以大大提高智能体的效率和可靠性。

在实际应用中,应根据具体任务的特点选择合适的Agent类型,并进行适当的配置和优化。对于复杂任务,可以考虑使用多个Agent协作的方式,充分发挥每个Agent的优势。

课后思考

  1. 如何根据任务类型选择合适的Agent类型?
  2. 如何优化Agent的工具选择能力?
  3. 如何处理Agent执行过程中的错误?
  4. 如何评估不同Agent类型的性能?
  5. 如何设计一个多Agent协作系统?

在下一集中,我们将学习如何控制Agent的停止条件与最大迭代次数,确保智能体能够高效、可靠地完成任务。

« 上一篇 手撕源码:实现一个简单的ReAct智能体 下一篇 » Agent的停止条件与最大迭代次数控制