LangChain中不同Agent类型使用实操

LangChain中SingleAction Agent与ReAct Agent

一、核心概念对比

1. SingleAction Agent (单动作代理)

特点

  • 每次只执行一个动作(调用一个工具或直接返回LLM响应)
  • 不进行多步推理循环
  • 轻量级实现,适合简单任务

典型架构

输入 → 决策(选择工具或直接响应)→ 执行 → 输出

2. ReAct Agent (推理+动作代理)

特点

  • 结合推理(Reasoning)和动作(Acting)的循环过程
  • 支持多步决策和工具链调用
  • 适合复杂任务处理

典型架构

思考 → 决定动作 → 执行 → 观察结果 → 循环直到完成任务

二、详细对比表

特性 SingleAction Agent ReAct Agent
执行方式 单步执行 多步循环执行
复杂度 简单任务 复杂任务
工具支持 0-1个工具 多个工具协同
历史记忆 默认无 部分类型支持
资源消耗 较高
典型应用 简单查询、直接响应 数学计算、搜索、多步问题分解
实现类 LLMSingleActionAgent ZeroShotReactDescription

三、SingleAction Agent实现示例

from langchain.agents import Tool, LLMSingleActionAgent, AgentExecutor
from langchain.chains import LLMChain
from langchain_openai import ChatOpenAI
import os

# 1. 准确定义工具(名称和描述要清晰)
def get_word_length(word: str) -> int:
    return len(word)

tools = [
    Tool(
        name="字符串长度计算",  # 工具名称必须唯一且明确
        func=get_word_length,
        description="计算英文单词的长度,输入一个单词,返回它的字符数"
    )
]
# 2. 重构Prompt模板(强制要求Final Answer)


# ========== ReAct风格Prompt与Parser ===========
from langchain.prompts import StringPromptTemplate

REACT_AGENT_TMPL = """你是一个帮助用户解决问题的助手。

你可以使用以下工具:

{tools}

按照以下格式回答问题:
---
Question: 用户的问题
Thought: 我需要思考如何回答这个问题
Action: 工具名称
Action Input: 工具的输入
Observation: 工具返回的结果
...(这个思考/行动/行动输入/观察可以重复几次)
Thought: 现在我知道答案了
Final Answer: 给用户的最终答案
---

注意:
1. 回答要专业、简洁、准确
2. 如果需要调用工具请严格按照格式输出,否则直接输出Final Answer

Question: {input}
{agent_scratchpad}
"""
class ReActPromptTemplate(StringPromptTemplate):
    """
    :function: ReActPromptTemplate
    :param template: 模板字符串
    :param tools: 工具列表
    :return: 格式化后的prompt
    """
    template: str
    tools: list

    def format(self, **kwargs) -> str:
        intermediate_steps = kwargs.pop("intermediate_steps")
        thoughts = ""
        for action, observation in intermediate_steps:
            thoughts += action.log
            thoughts += f"\nObservation: {
     
     observation}\nThought: "
        kwargs["agent_scratchpad"] = thoughts
        kwargs["tools"] = "\n".join([f"{
     
     tool.name}: {
     
     tool.description}" for tool in self.tools])
        return self.template.format(**kwargs)

prompt = ReActPromptTemplate(
    template=REACT_AGENT_TMPL,
    tools=tools,
    input_variables=["input", "intermediate_steps"]
)


import re
from langchain.agents import AgentOutputParser
from langchain.schema import AgentAction, AgentFinish
class ReActOutputParser(AgentOutputParser):
    """
    :function: ReActOutputParser
    :param text: LLM输出
    :return: AgentAction 或 AgentFinish
    """
    def parse(self, text: str):
        # 检查Final Answer
        if "Final Answer:" in text:
            return AgentFinish(
                return_values={
   
   "output": text.split("Final Answer:")[-1].strip()},
                log=text,
            )
        # 尝试解析Action结构
        match = re.search(r"Action\s*:(.*?)\nAction Input\s*:(.*)", text, re.DOTALL)
        if match:
            action = match.group(1).strip()
            action_input = match.group(2).strip()
            return AgentAction(tool=action, tool_input=action_input, log=text)
        # 兜底:直接输出
        return AgentFinish(return_values={
   
   "output": text.strip()}, log=text)


# 3. 创建llm
BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
MODEL = "qwen-turbo"
API_KEY = os.getenv('DASHSCOPE_API_KEY')
llm = ChatOpenAI(
    model= MODEL,  # 默认的大模型为GPT-3.5-turbo,比较便宜
    openai_api_base= BASE_URL,
    openai_api_key= API_KEY
)


#4. Create LLMChain first
llm_chain = LLMChain(llm=llm, prompt=prompt)


# 5. Create output parser

output_parser = ReActOutputParser()
# 6. 定义的工具名称
tool_names = [tool.name for tool in tools]

# 7. 定义SingleActionAgent
agent = LLMSingleActionAgent(
    llm_chain=llm_chain,
    output_parser=output_parser,
    allowed_tools=tool_names,
    stop=["\nObservation:"]
)

# 8. 执行时传入工具描述
agent_executor = AgentExecutor.from_agent_and_tools(
    agent=agent,
    tools=tools,
    verbose=True,
    max_iterations=5,

)

# 9. 运行(确保输入格式正确)
try:
    result = agent_executor.run("单词'hello'的长度是多少?")
    
    print(f"执行结果: {
     
     result}")

except Exception as e:
    print(f"执行过程中出现错误: {
     
     str(e)}")  

运行输出结果如下

> Entering new AgentExecutor chain...
---
Thought: 我需要计算单词'hello'的长度。
Action: 字符串长度计算
Action Input: hello

Observation:5
我现在知道答案了。

Final Answer: 单词'hello'的长度是5。

> Finished chain.
执行结果: 单词'hello'的长度是5。

四、ReAct Agent类型及示例

1. 用agent = ZeroShotAgent 定义agent.

特点:零样本学习,不保留历史
适用场景:单轮任务,不需要上下文记忆,但实际经过对memory的配置和prompt配合,也能实现上下文记忆。

示例程序总结:注意定义agent = ZeroShotAgent,需要定义llm_chain,prompt和tools这几个参数。

agent = ZeroShotAgent(
    llm_chain=LLMChain(llm=llm, prompt=PromptTemplate.from_template(prefix + suffix)),
    tools=tools,
    verbose=True
)

完整示例,可成功执行

from langchain.agents import Tool, ZeroShotAgent, AgentExecutor
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
import os

# 1. 定义一个简单的加法计算器工具
def simple_add(expression: str) -> str:
    """简单的加法计算器"""
    try:
        # 移除所有空格和引号
        expression = expression.strip().strip('"\'')
        # 分割数字
        numbers = expression.split('+')
        # 转换为整数并求和
        result = sum(int(num.strip()) for num in numbers)
        return str(result)
    except Exception as e:
        return f"计算失败:{
     
     str(e)}"

tools = [
    Tool(
        name="SimpleAdd",
        func=simple_add,
        description="简单的加法计算器,输入格式为'数字+数字',例如:1+2"
    )
]

# 2. 创建ZeroShotAgent的提示模板
prefix = """你是一个帮助用户解决问题的助手。你可以使用以下工具:

{tools}

请使用以下格式:

Question: 输入的问题
Thought: 你需要思考如何解决这个问题
Action: 要使用的工具名称
Action Input: 工具的输入
Observation: 工具的输出
... (这个思考/行动/观察可以重复多次)
Thought: 我现在知道最终答案
Final Answer: 对原始输入问题的最终答案

现在开始:

Question: {input}
"""

suffix = """
{agent_scratchpad}
"""

# 创建llm
BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
MODEL = "qwen-turbo"
API_KEY = os.getenv('DASHSCOPE_API_KEY')
llm = ChatOpenAI(
    model= MODEL,  # 默认的大模型为GPT-3.5-turbo,比较便宜
    openai_api_base= BASE_URL,
    openai_api_key= API_KEY
)

# 创建agent
agent = ZeroShotAgent(
    llm_chain=LLMChain(llm=llm, prompt=PromptTemplate.from_template(prefix + suffix)),
    tools=tools,
    verbose=True
)

# 执行
agent_executor = AgentExecutor.from_agent_and_tools(
    agent=agent,
    tools=tools,
    verbose=True,
    max_iterations=10
)

# 运行
result = agent_executor.invoke({
   
   
    "input": "计算 1 + 2 等于多少?",
    "tools": "\n".join([f"{
     
     tool.name}: {
     
     tool.description}" for tool in tools])
})

print("最终输出:", result["output"]) 

输出结果如下:

> Entering new AgentExecutor chain...
Thought: 这是一个简单的加法计算,我可以直接使用SimpleAdd工具来计算。
Action: SimpleAdd
Action Input: 1+2
Observation: 3
Thought:我现在知道最终答案。
Final Answer: 1 + 2 等于 3> Finished chain.
最终输出: 1 + 2 等于 3
在此基础上,我增加了工具,使其可以自行选择合适的工具进行处理
from langchain.agents import Tool, ZeroShotAgent, AgentExecutor
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
import os

# 1. 定义工具函数
def simple_add(expression: str) -> str:
    """简单的加法计算器"""
    try:
        # 移除所有空格和引号
        expression = expression.strip().strip('"\'')
        # 分割数字
        numbers = expression.split('+')
        # 转换为整数并求和
        result = sum(int(num.strip()) for num in numbers)
        return str(result)
    except Exception as e:
        return f"计算失败:{
     
     str(e)}"

def get_word_length(word: str) -> str:
    """计算字符串长度"""
    try:
        # 移除所有空格和引号
        word = word.strip().strip('"\'')
        return str(len(word))
    except Exception as e:
        return f"计算失败:{
     
     str(e)}"

# 2. 创建工具列表
tools = [
    Tool(
        name="SimpleAdd",
        func=simple_add,
        description="简单的加法计算器,输入格式为'数字+数字',例如:1+2"
    ),
    Tool(
        name="WordLength",
        func=get_word_length,
        description="计算字符串长度,输入一个字符串,返回它的字符数,例如:'hello'"
    )
]

# 3. 创建ZeroShotAgent的提示模板
prefix = """你是一个帮助用户解决问题的助手。你可以使用以下工具:

{tools}

请使用以下格式:

Question: 输入的问题
Thought: 你需要思考如何解决这个问题
Action: 要使用的工具名称
Action Input: 工具的输入
Observation: 工具的输出
... (这个思考/行动/观察可以重复多次)
Thought: 我现在知道最终答案
Final Answer: 对原始输入问题的最终答案

现在开始:

Question: {input}
"""

suffix = """
{agent_scratchpad}
"""

# 创建llm
BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
MODEL = "qwen-turbo"
API_KEY = os.getenv('DASHSCOPE_API_KEY')
llm = ChatOpenAI(
    model= MODEL,  # 默认的大模型为GPT-3.5-turbo,比较便宜
    openai_api_base= BASE_URL,
    openai_api_key= API_KEY
)

# 创建agent
agent = ZeroShotAgent(
    llm_chain=LLMChain(llm=llm, prompt=PromptTemplate.from_template(prefix + suffix
### 如何在 LangChain使用 Agent DeepSeek #### 配置环境 为了能够在 LangChain 中集成并使用 Agent DeepSeek,需先安装必要的依赖库。这通常涉及 Python 的虚拟环境设置以及特定包的安装。 ```bash pip install langchain deepseek-oaspy ``` 确保已正确设置了 PostgreSQL 或者 pgvector 向量数据库来支持 LangChain 所需的数据存储需求[^3]。 #### 初始化 Agent 初始化一个基于 DeepSeek 大模型的 Agent 可以通过 LangChain 提供的功能实现: ```python from langchain.agents import initialize_agent, Tool from langchain.llms import DeepSeek deepseek_llm = DeepSeek() # 创建 DeepSeek 实例 tools = [ Tool( name="DeepSeek Search", func=deepseek_llm.run, description="Useful for when you need to answer questions using knowledge from the web." ) ] agent = initialize_agent(tools, llm=deepseek_llm, agent_type='react-description') ``` 这段代码创建了一个名为 `DeepSeek Search` 的工具,并将其与 DeepSeek LLM 结合起来形成一个新的 Agent[^1]。 #### 运行查询 有了上述配置之后,可以通过简单的函数调用来执行具体的任务或提问解答操作: ```python response = agent.run("What is the capital of France?") print(response) ``` 此命令会触发 Agent 使用 DeepSeek 模型去寻找关于法国首都的信息并返回结果。 #### 解决常见问题 当遇到无法获取预期响应或其他异常情况时,考虑以下几个方面来进行排查: - **网络连接状态**:确认是否有稳定的互联网访问权限以便于在线资源检索。 - **API 密钥验证**:如果 DeepSeek API 要求身份认证,则应检查所提供的密钥是否有效。 - **版本兼容性**:确保所使用的各个组件之间的版本相互匹配,避免因不兼容而导致错误发生。 - **日志记录分析**:启用详细的日志输出可以帮助定位具体的问题所在位置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

alpha xu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值