【LangChain】代理(Agents):语言模型(LLM)通过动态推理和工具调用来处理复杂任务

在 LangChain 中,代理(Agents) 是一种高级组件,允许语言模型(LLM)通过动态推理和工具调用来处理复杂任务。代理通过结合语言模型的自然语言理解能力和外部工具(如搜索、计算、数据库查询等)的执行能力,能够根据用户输入自主选择合适的操作路径,执行多步骤任务并生成最终结果。代理是 LangChain 生态中实现交互性和智能自动化任务的核心模块,特别适合需要动态决策的场景。

以下是对 LangChain 代理的详细介绍,涵盖其定义、工作原理、类型、实现方式、应用场景、代码示例、优化建议以及与生态系统的结合。


1. 什么是 LangChain 的代理?

代理是一个智能系统,结合语言模型和工具,通过推理决定如何处理用户输入。它的核心功能是:

  • 理解输入:解析用户查询,提取意图和任务要求。
  • 动态决策:根据任务选择合适的工具或操作序列。
  • 工具调用:执行外部功能(如搜索、计算)以获取数据或完成任务。
  • 生成响应:整合工具结果和语言模型的推理,输出最终答案。

代理与 链(Chains) 的区别在于:

  • 链是预定义的、固定的工作流,执行顺序确定。
  • 代理是动态的,通过推理选择工具和操作路径,适合开放性任务。

代理的核心组件:

  • 语言模型(LLM):提供推理和语言生成能力。
  • 工具(Tools):提供外部功能(如搜索、数据库查询)。
  • 代理执行器(AgentExecutor):管理推理循环,协调模型和工具的交互。

2. 代理的工作原理

代理的工作流程可以分为以下步骤:

  1. 输入解析:语言模型分析用户输入,理解任务目标。
  2. 推理规划
    • 使用推理框架(如 ReAct)生成操作计划。
    • 决定是否调用工具、调用哪些工具以及调用顺序。
  3. 工具调用
    • 根据推理计划调用工具,传递输入并获取结果。
    • 工具结果反馈给语言模型。
  4. 迭代推理
    • 语言模型根据工具结果更新推理,可能触发更多工具调用。
    • 循环直到任务完成或达到终止条件。
  5. 输出生成
    • 语言模型综合所有信息,生成最终答案。

代理通常基于以下推理框架:

  • ReAct(Reasoning + Acting):结合推理和行动,模型在每次迭代中思考(生成推理)并执行(调用工具)。
  • OpenAI Functions:利用 OpenAI 的函数调用能力,结构化工具调用。
  • Plan-and-Execute:先规划完整步骤,再逐一执行。

3. LangChain 代理的类型

LangChain 提供了多种代理类型,基于不同的推理框架和语言模型特性。以下是主要类型的详细介绍:

(1) Zero-shot ReAct

  • 功能:基于 ReAct 框架,通过零样本提示(Zero-shot Prompting)推理和调用工具。
  • 特点
    • 无需训练,直接根据工具描述选择工具。
    • 适合通用任务,灵活性高。
    • 依赖语言模型的推理能力。
  • 适用场景
    • 通用问答。
    • 动态任务处理(如搜索后计算)。
  • 示例
    from langchain_openai import ChatOpenAI
    from langchain.agents import initialize_agent, AgentType
    from langchain_community.tools import DuckDuckGoSearchRun
    
    llm = ChatOpenAI(api_key="your-openai-key")
    tools = [DuckDuckGoSearchRun()]
    agent = initialize_agent(
        tools=tools,
        llm=llm,
        agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
        verbose=True
    )
    result = agent.invoke("量子计算的最新进展是什么?")
    print(result)
    

(2) OpenAI Functions

  • 功能:利用 OpenAI 的函数调用能力,结构化工具调用。
  • 特点
    • 适合 OpenAI 模型(如 GPT-4)。
    • 工具调用更可靠,输出结构化(JSON)。
    • 适合复杂任务,需要明确工具参数。
  • 适用场景
    • 结构化任务(如 API 调用)。
    • 需要高可靠性工具调用。
  • 示例
    from langchain_openai import ChatOpenAI
    from langchain.agents import initialize_agent, AgentType
    from langchain_core.tools import Tool
    
    def calculator(expression: str) -> str:
        return str(eval(expression))
    
    tools = [Tool(name="Calculator", func=calculator, description="执行数学计算")]
    llm = ChatOpenAI(api_key="your-openai-key")
    agent = initialize_agent(
        tools=tools,
        llm=llm,
        agent_type=AgentType.OPENAI_FUNCTIONS,
        verbose=True
    )
    result = agent.invoke("计算 5 + 3")
    print(result)
    

(3) Conversational Agent

  • 功能:专为对话场景设计,结合记忆(Memory)维护上下文。
  • 特点
    • 支持多轮对话,记录历史。
    • 基于 ReAct 框架,适合交互式任务。
  • 适用场景
    • 聊天机器人。
    • 持续交互的任务。
  • 示例
    from langchain_openai import ChatOpenAI
    from langchain.agents import initialize_agent, AgentType
    from langchain.memory import ConversationBufferMemory
    from langchain_community.tools import DuckDuckGoSearchRun
    
    llm = ChatOpenAI(api_key="your-openai-key")
    memory = ConversationBufferMemory(memory_key="chat_history")
    tools = [DuckDuckGoSearchRun()]
    agent = initialize_agent(
        tools=tools,
        llm=llm,
        agent_type=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
        memory=memory,
        verbose=True
    )
    result = agent.invoke("量子计算是什么?")
    result = agent.invoke("有哪些最新进展?")
    print(result)
    

(4) Self-Ask with Search

  • 功能:通过分解问题并使用搜索工具回答复杂问题。
  • 特点
    • 适合需要分步推理的知识性问题。
    • 依赖搜索工具(如 Google、DuckDuckGo)。
  • 适用场景
    • 回答复杂的事实性问题。
    • 需要外部知识的场景。
  • 示例
    from langchain_openai import ChatOpenAI
    from langchain.agents import initialize_agent, AgentType
    from langchain_community.tools import DuckDuckGoSearchRun
    
    llm = ChatOpenAI(api_key="your-openai-key")
    tools = [DuckDuckGoSearchRun()]
    agent = initialize_agent(
        tools=tools,
        llm=llm,
        agent_type=AgentType.SELF_ASK_WITH_SEARCH,
        verbose=True
    )
    result = agent.invoke("量子计算的最新进展是什么?")
    print(result)
    

(5) Structured Chat

  • 功能:支持结构化工具调用,结合对话记忆。
  • 特点
    • 适合需要多轮对话和复杂工具调用的场景。
    • 支持结构化输入(如 JSON Schema)。
  • 适用场景
    • 复杂交互式任务。
    • 需要严格输入格式的工具调用。
  • 示例
    from langchain_openai import ChatOpenAI
    from langchain.agents import initialize_agent, AgentType
    from langchain_core.tools import StructuredTool
    from pydantic import BaseModel
    
    class CalcInput(BaseModel):
        a: float
        b: float
    
    def add_numbers(input: CalcInput) -> float:
        return input.a + input.b
    
    tools = [StructuredTool.from_function(
        func=add_numbers,
        name="Adder",
        description="将两个数字相加"
    )]
    llm = ChatOpenAI(api_key="your-openai-key")
    agent = initialize_agent(
        tools=tools,
        llm=llm,
        agent_type=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,
        verbose=True
    )
    result = agent.invoke("将 5 和 3 相加")
    print(result)
    

(6) Custom Agent

  • 功能:开发者可以自定义代理逻辑,适配特定推理框架或工具。
  • 特点
    • 继承 BaseAgent 或使用 LangGraph 实现。
    • 高度灵活,适合复杂场景。
  • 适用场景
    • 特定任务的定制推理逻辑。
    • 集成非标准工具或工作流。
  • 示例(简单自定义代理):
    from langchain.agents import AgentExecutor, BaseSingleActionAgent
    from langchain_core.tools import Tool
    from langchain_openai import ChatOpenAI
    
    class CustomAgent(BaseSingleActionAgent):
        def plan(self, intermediate_steps, **kwargs):
            return {"tool": "Calculator", "tool_input": kwargs["input"]}
    
        def parse_output(self, output):
            return output
    
    def calculator(expression: str) -> str:
        return str(eval(expression))
    
    tools = [Tool(name="Calculator", func=calculator, description="执行数学计算")]
    llm = ChatOpenAI(api_key="your-openai-key")
    agent = CustomAgent()
    executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
    result = executor.invoke({"input": "2 + 2"})
    print(result)
    

4. 代理的应用场景

代理在以下场景中广泛应用:

  1. 开放性问答
    • 回答需要外部数据的问题(如“今天的天气”)。
    • 示例:结合 SerpAPIDuckDuckGoSearch
  2. 多步骤任务
    • 执行复杂任务(如“搜索最新论文并总结”)。
    • 示例:结合 Arxiv 和语言模型。
  3. 交互式对话
    • 构建聊天机器人,维护上下文并调用工具。
    • 示例:使用 Conversational Agent
  4. 自动化工作流
    • 触发外部操作(如发送邮件、更新数据库)。
    • 示例:结合 ZapierToolkit
  5. 数学与计算
    • 解决数学或编程问题。
    • 示例:使用 PythonREPLTool
  6. 研究与分析
    • 收集和处理外部数据。
    • 示例:结合 WebResearchRetrieverWikipedia

5. 代理的实现与代码示例

综合示例:多工具代理

以下是一个代理结合搜索和计算工具的示例:

from langchain_openai import ChatOpenAI
from langchain.agents import initialize_agent, AgentType
from langchain_core.tools import Tool
from langchain_community.tools import DuckDuckGoSearchRun
from langchain_core.callbacks import StdOutCallbackHandler

# 自定义计算工具
def calculator(expression: str) -> str:
    return str(eval(expression))

calc_tool = Tool(
    name="Calculator",
    func=calculator,
    description="执行数学计算,输入为数学表达(如 '2 + 2')。"
)

# 搜索工具
search_tool = DuckDuckGoSearchRun()

# 工具列表
tools = [calc_tool, search_tool]

# 初始化代理
llm = ChatOpenAI(api_key="your-openai-key")
agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True,
    callbacks=[StdOutCallbackHandler()]
)

# 执行任务
result = agent.invoke("计算 5 + 3 并搜索量子计算的最新进展")
print(result["output"])

输出

[AgentExecutor] 正在执行...
[Thought] 需要先计算 5 + 3,然后搜索量子计算的最新进展。
[Action] 使用 Calculator 工具计算 5 + 3
[Tool Output] 8
[Action] 使用 DuckDuckGoSearch 工具搜索量子计算的最新进展
[Tool Output] 量子计算的最新研究...
[Final Answer] 计算结果为 8,量子计算的最新进展包括...

示例:带记忆的对话代理

from langchain_openai import ChatOpenAI
from langchain.agents import initialize_agent, AgentType
from langchain.memory import ConversationBufferMemory
from langchain_community.tools import DuckDuckGoSearchRun

llm = ChatOpenAI(api_key="your-openai-key")
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
tools = [DuckDuckGoSearchRun()]
agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent_type=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
    memory=memory,
    verbose=True
)

# 多轮对话
print(agent.invoke("量子计算是什么?")["output"])
print(agent.invoke("有哪些最新进展?")["output"])

6. 代理的优化建议

(1) 提高工具选择准确性

  • 清晰的工具描述
    • 确保工具描述明确功能和输入格式。
    • 示例:description="搜索网页,返回最新信息。输入为查询字符串。"
  • 限制工具数量
    • 通常少于 10 个工具,避免代理选择困难。
  • 结构化工具
    • 使用 StructuredTool 提供明确的输入格式。
    from pydantic import BaseModel
    
    class SearchInput(BaseModel):
        query: str
    
    def search(query: SearchInput) -> str:
        return DuckDuckGoSearchRun().run(query.query)
    

(2) 提高性能

  • 缓存工具结果
    • 使用 LangChain 的缓存机制。
    from langchain.globals import set_llm_cache
    from langchain.cache import SQLiteCache
    
    set_llm_cache(SQLiteCache(database_path="cache.db"))
    
  • 异步工具
    • 实现异步工具以支持高并发。
  • 减少推理循环
    • 设置最大迭代次数(max_iterations)。
    agent = initialize_agent(tools, llm, max_iterations=5)
    

(3) 错误处理

  • 回退机制
    • 为工具或代理配置回退。
    from langchain_core.runnables import RunnableWithFallbacks
    
    search_tool_with_fallback = search_tool.with_fallbacks([DuckDuckGoSearchRun()])
    
  • 异常捕获
    • 在工具中处理异常。
    @tool
    def safe_calculator(expression: str) -> str:
        try:
            return str(eval(expression))
        except Exception as e:
            return f"计算错误:{e}"
    

(4) 监控与调试

  • 回调
    • 使用回调记录代理的推理和工具调用。
    from langchain_core.callbacks import BaseCallbackHandler
    
    class AgentCallback(BaseCallbackHandler):
        def on_agent_action(self, action, **kwargs):
            print(f"代理动作:{action.tool},输入:{action.tool_input}")
    
  • LangSmith
    • 分析代理的性能和工具选择。
    from langsmith import Client
    agent.invoke(input, config={"callbacks": [Client(api_key="your-langsmith-key")]})
    

(5) 上下文管理

  • 记忆优化
    • 使用 ConversationSummaryMemory 压缩对话历史,节省 token。
    from langchain.memory import ConversationSummaryMemory
    
    memory = ConversationSummaryMemory(llm=llm)
    
  • 动态上下文
    • 使用检索器为代理提供外部知识。
    from langchain.chains import ConversationalRetrievalChain
    
    qa_chain = ConversationalRetrievalChain.from_llm(llm, retriever, memory=memory)
    

7. 注意事项

  • 推理能力
    • 代理的性能依赖语言模型的推理能力,选择强大的模型(如 GPT-4)。
    • 弱模型可能导致工具选择错误或推理循环过多。
  • 工具设计
    • 工具描述不清晰可能导致误选。
    • 确保工具输出与代理期望兼容。
  • 性能
    • 多次工具调用可能增加延迟,需优化工具执行。
    • 设置 max_iterationsmax_execution_time 限制循环。
  • 安全性
    • 避免执行不安全的工具(如未沙箱化的 eval)。
    • 限制工具的访问权限。
  • 成本
    • 工具调用(如 SerpAPI)和模型推理可能产生费用。
    • 使用缓存和低成本工具优化。

8. 学习资源


9. 总结

  • 定义:代理结合语言模型和工具,通过动态推理处理复杂任务。
  • 类型
    • Zero-shot ReAct:通用推理。
    • OpenAI Functions:结构化工具调用。
    • Conversational Agent:对话场景。
    • Self-Ask with Search:复杂问题分解。
    • Structured Chat:结构化交互。
    • 自定义代理:特定需求。
  • 工作原理:输入解析 → 推理规划 → 工具调用 → 迭代推理 → 输出生成。
  • 应用场景:问答、多步骤任务、对话、自动化、计算、研究。
  • 优化点:工具选择、性能、错误处理、上下文管理、监控。
  • 注意事项:推理能力、工具设计、性能、安全性、成本。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彬彬侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值