Agent构建总结(LangChain)

跑通Agent的过程其实主要是在让LLM跑通以下链条:

有什么工具 → 当前需要用什么工具 → 结构化返回工具和参数 → 本地调用对应工具 → 得到最终结果

上述链条所有的实现均离不开prompt,因此我们可以将链条转换为以下两个问题:

  • 问题一:如何在prompt中告知LLM可用工具及工具用途?
  • 问题二:如何在prompt中约束LLM结构化返回工具和参数?

完成上述两个问题后Agent其实就可以完成单一工具的问题了,此时将会有一个新的问题:

  • 问题三:如何在prompt中约束LLM有次序的选择工具完成复杂任务?

本篇文章将针对上述问题进行简单总结

注意:出于简洁便于理解的意图,本篇文章中大面积结合 LangChain 实现。

一. 如何在prompt中告知LLM可用工具及工具用途?

利用LangChain我们可以先将工具及其信息生成一个工具对象,这及便于管理也便于后续对工具的调用,如下:

from langchain.tools import StructuredTool

tool = StructuredTool.from_function(
    func=func,
    name="ToolName",
    description="xxx",
)

参数解析:

  • func 传入我们已经实现的工具函数
  • name= 对该工具的命名
  • description 对该工具用途的描述

之后我们在写prompt的同时便可将工具及其信息一同写入,该步骤同样可用LangChain的接口实现。

from langchain_core.tools import render_text_description

with open(path, "r", encoding="utf-8") as f:
	main_prompt = ChatPromptTemplate.from_messages(
	    [
	        HumanMessagePromptTemplate.from_template
<think>我们正在讨论LangChain构建Agent的方法和步骤。根据引用内容,LangChain提供了构建传统Agent的工具,而LangGraph则用于更复杂的场景(如单/多Agent系统)[^1]。对于小型功能,使用LangGraph可能过于复杂。因此,我们将重点放在LangChainAgent构建上。 在LangChain中,构建一个Agent通常涉及以下步骤: 1. 定义工具(Tools):Agent可以使用的功能函数。 2. 创建Agent执行器(AgentExecutor):将工具、语言模型(LLM)和Agent类型组合起来。 3. 选择Agent类型:如Zero-shot ReAct、Conversational等。 4. 运行Agent:通过执行器调用Agent。 引用[2]中提供了几个工具定义的例子,如文本字数计算工具、CSV代理和Python代理。这些工具将被集成到Agent中。 下面,我们将详细说明每个步骤。 ### 步骤1: 定义工具(Tools) 工具是Agent可以调用的函数。每个工具需要定义名称(name)、描述(description)和运行函数(_run)。例如: ```python from langchain.agents import tool @tool def text_length(text: str) -> int: """计算文本的字数(当你需要计算文本包含的字数时,使用此工具)""" return len(text) ``` 或者使用类的方式(如引用[2]所示): ```python from langchain.tools import BaseTool class TextLengthTool(BaseTool): name = "文本字数计算工具" description = "当你需要计算文本包含的字数时,使用此工具" def _run(self, text: str) -> int: return len(text) ``` ### 步骤2: 创建Agent执行器(AgentExecutor) Agent执行器负责调用Agent,管理工具调用和状态。我们可以使用`initialize_agent`函数来创建执行器。 首先,需要准备以下组件: - 工具列表(tools) - 语言模型(llm) - Agent类型(agent) 例如,使用OpenAI模型和预定义的文本工具: ```python from langchain.agents import initialize_agent, AgentType from langchain.llms import OpenAI # 实例化模型 llm = OpenAI(temperature=0) # 工具列表 tools = [TextLengthTool()] # 或者 [text_length] 如果使用了装饰器 # 创建Agent执行器 agent_executor = initialize_agent( tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, # 使用Zero-shot ReAct代理 verbose=True # 打印详细日志 ) ``` ### 步骤3: 选择Agent类型 LangChain支持多种Agent类型,常见的有: - `AgentType.ZERO_SHOT_REACT_DESCRIPTION`:零样本ReAct代理,根据工具描述决定动作。 - `AgentType.CONVERSATIONAL_REACT_DESCRIPTION`:适用于多轮对话的代理。 - `AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION`:支持结构化输入的代理。 选择哪种代理取决于具体任务。例如,如果任务需要多轮对话,则选择`CONVERSATIONAL_REACT_DESCRIPTION`。 ### 步骤4: 运行Agent 通过执行器的`run`方法调用Agent: ```python result = agent_executor.run("请计算'Hello, world!'的字数") print(result) # 输出: 13 ``` ### 完整示例:构建一个包含多个工具的Agent 假设我们有两个工具:文本字数计算和当前日期获取。 ```python from langchain.agents import tool, initialize_agent, AgentType from langchain.llms import OpenAI from datetime import datetime @tool def get_current_time() -> str: """获取当前日期和时间(当你需要知道当前时间时使用此工具)""" return datetime.now().strftime("%Y-%m-%d %H:%M:%S") @tool def text_length(text: str) -> int: """计算文本的字数(当你需要计算文本包含的字数时,使用此工具)""" return len(text) # 初始化模型和工具 llm = OpenAI(temperature=0) tools = [text_length, get_current_time] # 创建Agent执行器 agent = initialize_agent( tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True ) # 运行Agent agent.run("今天的日期是什么?然后计算'Hello'的字数") ``` ### 高级功能:自定义代理 如果需要更复杂的控制,可以自定义代理。这通常涉及: 1. 定义提示模板(Prompt Template) 2. 自定义输出解析器(Output Parser) 3. 组合工具、模型和代理逻辑 例如,自定义一个ReAct风格的代理: ```python from langchain.agents import Agent, Tool, AgentExecutor from langchain import LLMChain # 自定义提示模板 template = """...""" # 这里定义提示模板 prompt = PromptTemplate( template=template, input_variables=["input", "tools", "tool_names", "agent_scratchpad"] ) # 创建LLM链 llm_chain = LLMChain(llm=llm, prompt=prompt) # 定义工具 tools = [ ... ] # 创建自定义代理 agent = Agent( llm_chain=llm_chain, output_parser=output_parser, # 需要自定义输出解析器 tools=tools ) # 创建执行器 agent_executor = AgentExecutor.from_agent_and_tools( agent=agent, tools=tools, verbose=True ) ``` ### 总结 在LangChain构建Agent的核心步骤包括: 1. **定义工具**:使用`@tool`装饰器或继承`BaseTool`类 2. **初始化Agent执行器**:使用`initialize_agent`函数,指定工具、模型和代理类型 3. **选择代理类型**:根据任务需求选择合适的代理类型 4. **运行代理**:通过执行器的`run`方法执行任务 对于简单任务,使用预定义的代理类型(如`ZERO_SHOT_REACT_DESCRIPTION`)即可;对于复杂任务,可能需要自定义代理逻辑[^1][^2]。 §§相关问题§§ 1. LangChain 中如何自定义工具(Tools)? 2. 如何为LangChain Agent添加记忆(Memory)功能? 3. LangChain 支持哪些类型的Agent? 4. 如何处理LangChain Agent执行过程中的错误?</think>### LangChain 构建 Agent 的方法与步骤 在 LangChain构建 Agent 的核心是通过 **工具组合+推理引擎** 实现自主决策能力。以下是详细构建流程(基于引用[1][2]): --- #### 一、基础组件准备 1. **定义工具(Tools)** 创建 Agent 可调用的功能模块,需明确 `name` 和 `description`(关键!Agent 靠描述选择工具): ```python from langchain.tools import BaseTool class TextLengthTool(BaseTool): name = "文本字数计算工具" description = "计算文本字数时使用" # ✅ 清晰描述触发条件 def _run(self, text: str) -> int: return len(text) # 实际功能逻辑 class CSVTool(BaseTool): name = "CSV数据分析工具" description = "分析CSV文件时使用" ... ``` 2. **初始化语言模型(LLM)** 选择支撑推理的核心模型: ```python from langchain.llms import OpenAI llm = OpenAI(temperature=0) # 低随机性保证稳定性 ``` --- #### 二、Agent 组装 3. **创建 Agent 执行器** 使用 `initialize_agent` 集成工具和模型: ```python from langchain.agents import initialize_agent, AgentType # 工具列表 tools = [TextLengthTool(), CSVTool(), PythonREPLTool()] # 构建 Agent agent = initialize_agent( tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, # ✅ 零样本推理代理 verbose=True # 打印执行过程 ) ``` 4. **选择 Agent 类型(关键决策)** | **Agent 类型** | **适用场景** | 特点 | |-----------------------------------|----------------------------------|--------------------------| | `AgentType.ZERO_SHOT_REACT_DESCRIPTION` | 简单任务 | 无记忆,每次独立推理[^1] | | `AgentType.STRUCTURED_CHAT_ZERO_SHOT` | 多工具复杂任务 | 结构化决策 | | `AgentType.CONVERSATIONAL_REACT_DESCRIPTION` | 多轮对话场景 | 带对话记忆 | --- #### 三、执行与优化 5. **运行 Agent** ```python response = agent.run("分析house_price.csv并计算房价中位数") print(response) # 输出: "CSV数据分析结果:中位数为$450,000" ``` 6. **高级控制技巧** - **工具描述优化**: ```python description = "在需要处理CSV文件时使用,输入必须是文件路径" # ✨ 精确描述提升调用准确率 ``` - **自定义提示模板**: 覆盖默认提示,强化任务理解: ```python from langchain.agents import ZeroShotAgent prompt = ZeroShotAgent.create_prompt( tools, prefix="你是一个数据分析专家,请用专业术语回答" ) ``` --- ### 完整工作流示例 ```python # 步骤1:定义工具 class StatsTool(BaseTool): name = "统计计算工具" description = "执行均值/中位数计算时使用" def _run(self, data: list) -> float: import numpy as np return np.median(data) # 步骤2:初始化模型和工具 llm = OpenAI(temperature=0) tools = [CSVTool(), StatsTool()] # 步骤3:创建Agent agent = initialize_agent( tools, llm, agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT, # 结构化任务代理 verbose=True ) # 步骤4:执行复杂任务 task = """ 1. 加载house_price.csv 2. 提取"price"列 3. 计算中位数 """ result = agent.run(task) # ✅ 自动调用CSVTool和StatsTool ``` --- ### 关键设计原则 1. **工具描述即API**:Agent 仅通过 `description` 理解工具功能,需用自然语言精确描述触发条件[^2] 2. **LLM 作为调度器**:语言模型负责解析问题→选择工具→生成输入参数 3. **递归执行机制**: ```mermaid graph LR A[用户输入] --> B(LLM推理) B --> C{需调用工具?} C -- 是 --> D[执行工具] D --> B C -- 否 --> E[返回最终结果] ``` --- ### 常见问题解决 - **工具选择错误**:优化 `description` 加入排除条件,如 *"非文本分析勿用此工具"* - **参数格式错误**:在描述中明确输入格式,如 *"输入必须是字符串列表"* - **复杂任务分解**:使用 `AgentType.STRUCTURED_CHAT_ZERO_SHOT` 支持多步骤规划 > 提示:对于轻量级任务直接用 `AgentExecutor`;复杂工作流(如多Agent协作)才需 LangGraph[^1]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值