LangChain中不同Agent类型使用实操二
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)), 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"]) # 测试字符串长度计算 result = agent_executor.invoke({ "input": "单词'hello'的长度是多少?", "tools": "\n".join([f"{tool.name}: {tool.description}" for tool in tools]) }) print("\n最终输出:", 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。 > Entering new AgentExecutor chain... Thought: 我需要计算单词'hello'的长度,这可以通过WordLength工具来实现。 Action: WordLength Action Input: 'hello' Observation: 5 Thought:我现在知道最终答案 Final Answer: 单词'hello'的长度是5个字符。 > Finished chain. 最终输出: 单词'hello'的长度是5个字符。
继续在此基础上,提出问题“请计算单词’hello’和’world’的长度之和是多少?”,它能自动选择工具,自动选择步骤,自动选择变量,自动选择答案。
#根据问题“请计算单词'hello'和'world'的长度之和是多少?”,自动选择工具,自动选择步骤,自动选择变量,自动选择答案。 #无需记忆历史对话,因此未用到memory。 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: 对原始输入问题的最终答案 重要提示: 1. 如果问题涉及多个步骤,你需要一步步思考 2. 可以使用一个工具的输出作为另一个工具的输入 3. 在得到所有需要的结果后,给出最终答案 现在开始: 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": "请计算单词'hello'和'world'的长度之和是多少?", "tools": "\n".join([f"{tool.name}: {tool.description}" for tool in tools]) }) print("最终输出:", result["output"])
输出结果如下
> Entering new AgentExecutor chain... Thought: 我需要分别计算两个单词的长度,然后将它们相加。 Action: WordLength Action Input: 'hello' Observation: 5 Thought:现在我需要计算第二个单词'world'的长度。 Action: WordLength Action Input: 'world' Observation: 5 Thought:我现在知道两个单词的长度分别是5,它们的总长度是10。 Final Answer: 单词'hello'和'world'的长度之和是10。 > Finished chain. 最终输出: 单词'hello'和'world'的长度之和是10。