ReAct Agent - 一个简单的介绍和计算器工具¶
这是一个展示ReAct代理的笔记本,其中展示了非常简单的计算器工具(没有花哨的RAG管道或API调用)。
我们展示了它如何逐步推理不同工具,以实现最终目标。
如果您在colab上打开这个笔记本,您可能需要安装LlamaIndex 🦙。
In [ ]:
Copied!
%pip install llama-index-llms-openai
%pip install llama-index-llms-openai
In [ ]:
Copied!
!pip install llama-index
!pip install llama-index
In [ ]:
Copied!
from llama_index.core.agent import ReActAgent
from llama_index.llms.openai import OpenAI
from llama_index.core.llms import ChatMessage
from llama_index.core.tools import BaseTool, FunctionTool
from llama_index.core.agent import ReActAgent
from llama_index.llms.openai import OpenAI
from llama_index.core.llms import ChatMessage
from llama_index.core.tools import BaseTool, FunctionTool
[nltk_data] Downloading package stopwords to /Users/jerryliu/Programmi [nltk_data] ng/gpt_index/.venv/lib/python3.10/site- [nltk_data] packages/llama_index/legacy/_static/nltk_cache... [nltk_data] Unzipping corpora/stopwords.zip. [nltk_data] Downloading package punkt to /Users/jerryliu/Programming/g [nltk_data] pt_index/.venv/lib/python3.10/site- [nltk_data] packages/llama_index/legacy/_static/nltk_cache... [nltk_data] Unzipping tokenizers/punkt.zip.
定义函数工具¶
我们设置了一些简单的multiply
和add
工具。请注意,您可以定义任意函数并将其传递给FunctionTool
(它将处理文档字符串和参数签名)。
In [ ]:
Copied!
def multiply(a: int, b: int) -> int:
"""将两个整数相乘并返回结果整数"""
return a * b
multiply_tool = FunctionTool.from_defaults(fn=multiply)
def multiply(a: int, b: int) -> int:
"""将两个整数相乘并返回结果整数"""
return a * b
multiply_tool = FunctionTool.from_defaults(fn=multiply)
In [ ]:
Copied!
def add(a: int, b: int) -> int:
"""对两个整数进行相加,并返回结果整数"""
return a + b
add_tool = FunctionTool.from_defaults(fn=add)
def add(a: int, b: int) -> int:
"""对两个整数进行相加,并返回结果整数"""
return a + b
add_tool = FunctionTool.from_defaults(fn=add)
In [ ]:
Copied!
llm = OpenAI(model="gpt-3.5-turbo-instruct")
agent = ReActAgent.from_tools([multiply_tool, add_tool], llm=llm, verbose=True)
llm = OpenAI(model="gpt-3.5-turbo-instruct")
agent = ReActAgent.from_tools([multiply_tool, add_tool], llm=llm, verbose=True)
In [ ]:
Copied!
response = agent.chat("What is 20+(2*4)? Calculate step by step ")
response = agent.chat("What is 20+(2*4)? Calculate step by step ")
Thought: I need to use a tool to help me answer the question.
Action: multiply
Action Input: {"a": 2, "b": 4}
Observation: 8
Thought: I need to use a tool to help me answer the question.
Action: add
Action Input: {"a": 20, "b": 8}
Observation: 28
Thought: I can answer without using any more tools.
Answer: 28
In [ ]:
Copied!
response_gen = agent.stream_chat("What is 20+2*4? Calculate step by step")
response_gen.print_response_stream()
response_gen = agent.stream_chat("What is 20+2*4? Calculate step by step")
response_gen.print_response_stream()
28
GPT-4 是 OpenAI 推出的第四代通用预训练模型。它是一种基于人工智能的语言模型,可以用于生成文本、回答问题和执行其他自然语言处理任务。GPT-4 在语言理解和生成方面取得了显著的进展,被认为是当前最先进的语言模型之一。
In [ ]:
Copied!
llm = OpenAI(model="gpt-4")
agent = ReActAgent.from_tools([multiply_tool, add_tool], llm=llm, verbose=True)
llm = OpenAI(model="gpt-4")
agent = ReActAgent.from_tools([multiply_tool, add_tool], llm=llm, verbose=True)
In [ ]:
Copied!
response = agent.chat("What is 2+2*4")
print(response)
response = agent.chat("What is 2+2*4")
print(response)
Thought: I need to use the tools to help me answer the question. According to the order of operations in mathematics (BIDMAS/BODMAS), multiplication should be done before addition. So, I will first multiply 2 and 4, and then add the result to 2. Action: multiply Action Input: {'a': 2, 'b': 4} Observation: 8 Thought: Now that I have the result of the multiplication, I need to add this result to 2. Action: add Action Input: {'a': 2, 'b': 8} Observation: 10 Thought: I can answer without using any more tools. Answer: 10 10
In [ ]:
Copied!
llm = OpenAI(model="gpt-4")
agent = ReActAgent.from_tools([multiply_tool, add_tool], llm=llm, verbose=True)
llm = OpenAI(model="gpt-4")
agent = ReActAgent.from_tools([multiply_tool, add_tool], llm=llm, verbose=True)
In [ ]:
Copied!
prompt_dict = agent.get_prompts()
for k, v in prompt_dict.items():
print(f"Prompt: {k}\n\nValue: {v.template}")
prompt_dict = agent.get_prompts()
for k, v in prompt_dict.items():
print(f"Prompt: {k}\n\nValue: {v.template}")
Prompt: agent_worker:system_prompt Value: You are designed to help with a variety of tasks, from answering questions to providing summaries to other types of analyses. ## Tools You have access to a wide variety of tools. You are responsible for using the tools in any sequence you deem appropriate to complete the task at hand. This may require breaking the task into subtasks and using different tools to complete each subtask. You have access to the following tools: {tool_desc} ## Output Format To answer the question, please use the following format. ``` Thought: I need to use a tool to help me answer the question. Action: tool name (one of {tool_names}) if using a tool. Action Input: the input to the tool, in a JSON format representing the kwargs (e.g. {{"input": "hello world", "num_beams": 5}}) ``` Please ALWAYS start with a Thought. Please use a valid JSON format for the Action Input. Do NOT do this {{'input': 'hello world', 'num_beams': 5}}. If this format is used, the user will respond in the following format: ``` Observation: tool response ``` You should keep repeating the above format until you have enough information to answer the question without using any more tools. At that point, you MUST respond in the one of the following two formats: ``` Thought: I can answer without using any more tools. Answer: [your answer here] ``` ``` Thought: I cannot answer the question with the provided tools. Answer: Sorry, I cannot answer your query. ``` ## Current Conversation Below is the current conversation consisting of interleaving human and assistant messages.
自定义提示¶
为了好玩,让我们尝试指示代理以项目符号的形式输出答案以及推理过程。请参阅“## 附加规则”部分。
In [ ]:
Copied!
from llama_index.core import PromptTemplate
react_system_header_str = """\
您被设计用于帮助完成各种任务,从回答问题到提供摘要再到其他类型的分析。
## 工具
您可以访问各种各样的工具。您负责根据需要使用任何顺序的工具来完成手头的任务。这可能需要将任务分解为子任务,并使用不同的工具来完成每个子任务。
您可以访问以下工具:
{tool_desc}
## 输出格式
为了回答问题,请使用以下格式。
思考:我需要使用一个工具来帮助我回答问题。
操作:如果使用工具,请使用工具名称(其中之一为{tool_names})。
操作输入:工具的输入,以JSON格式表示kwargs(例如{{"input": "hello world", "num_beams": 5}})。
请始终从一个思考开始。
请对操作输入使用有效的JSON格式。不要这样做{{'input': 'hello world', 'num_beams': 5}}。
如果使用此格式,用户将以以下格式回复:
观察:工具响应
您应该一直重复上述格式,直到您获得足够的信息来回答问题而无需再使用任何工具。在那时,您必须以以下两种格式之一做出回应:
思考:我可以在不再使用任何工具的情况下回答。
答案:[您的答案在这里]
思考:我无法使用提供的工具回答问题。
答案:抱歉,我无法回答您的查询。
## 附加规则
- 答案必须包含一系列项目符号,解释您是如何得出答案的。这可以包括以前的对话历史的方面。
- 您必须遵守每个工具的函数签名。如果函数需要参数,请不要传递任何参数。
## 当前对话
以下是由人类和助手消息交替组成的当前对话。
"""
react_system_prompt = PromptTemplate(react_system_header_str)
from llama_index.core import PromptTemplate
react_system_header_str = """\
您被设计用于帮助完成各种任务,从回答问题到提供摘要再到其他类型的分析。
## 工具
您可以访问各种各样的工具。您负责根据需要使用任何顺序的工具来完成手头的任务。这可能需要将任务分解为子任务,并使用不同的工具来完成每个子任务。
您可以访问以下工具:
{tool_desc}
## 输出格式
为了回答问题,请使用以下格式。
思考:我需要使用一个工具来帮助我回答问题。
操作:如果使用工具,请使用工具名称(其中之一为{tool_names})。
操作输入:工具的输入,以JSON格式表示kwargs(例如{{"input": "hello world", "num_beams": 5}})。
请始终从一个思考开始。
请对操作输入使用有效的JSON格式。不要这样做{{'input': 'hello world', 'num_beams': 5}}。
如果使用此格式,用户将以以下格式回复:
观察:工具响应
您应该一直重复上述格式,直到您获得足够的信息来回答问题而无需再使用任何工具。在那时,您必须以以下两种格式之一做出回应:
思考:我可以在不再使用任何工具的情况下回答。
答案:[您的答案在这里]
思考:我无法使用提供的工具回答问题。
答案:抱歉,我无法回答您的查询。
## 附加规则
- 答案必须包含一系列项目符号,解释您是如何得出答案的。这可以包括以前的对话历史的方面。
- 您必须遵守每个工具的函数签名。如果函数需要参数,请不要传递任何参数。
## 当前对话
以下是由人类和助手消息交替组成的当前对话。
"""
react_system_prompt = PromptTemplate(react_system_header_str)
In [ ]:
Copied!
agent.get_prompts()
agent.get_prompts()
Out[ ]:
{'agent_worker:system_prompt': PromptTemplate(metadata={'prompt_type': <PromptType.CUSTOM: 'custom'>}, template_vars=['tool_desc', 'tool_names'], kwargs={}, output_parser=None, template_var_mappings=None, function_mappings=None, template='\nYou are designed to help with a variety of tasks, from answering questions to providing summaries to other types of analyses.\n\n## Tools\nYou have access to a wide variety of tools. You are responsible for using\nthe tools in any sequence you deem appropriate to complete the task at hand.\nThis may require breaking the task into subtasks and using different tools\nto complete each subtask.\n\nYou have access to the following tools:\n{tool_desc}\n\n## Output Format\nTo answer the question, please use the following format.\n\n```\nThought: I need to use a tool to help me answer the question.\nAction: tool name (one of {tool_names}) if using a tool.\nAction Input: the input to the tool, in a JSON format representing the kwargs (e.g. {{"input": "hello world", "num_beams": 5}})\n```\n\nPlease ALWAYS start with a Thought.\n\nPlease use a valid JSON format for the Action Input. Do NOT do this {{\'input\': \'hello world\', \'num_beams\': 5}}.\n\nIf this format is used, the user will respond in the following format:\n\n```\nObservation: tool response\n```\n\nYou should keep repeating the above format until you have enough information\nto answer the question without using any more tools. At that point, you MUST respond\nin the one of the following two formats:\n\n```\nThought: I can answer without using any more tools.\nAnswer: [your answer here]\n```\n\n```\nThought: I cannot answer the question with the provided tools.\nAnswer: Sorry, I cannot answer your query.\n```\n\n## Current Conversation\nBelow is the current conversation consisting of interleaving human and assistant messages.\n\n')}
In [ ]:
Copied!
agent.update_prompts({"agent_worker:system_prompt": react_system_prompt})
agent.update_prompts({"agent_worker:system_prompt": react_system_prompt})
In [ ]:
Copied!
agent.reset()
response = agent.chat("What is 5+3+2")
print(response)
agent.reset()
response = agent.chat("What is 5+3+2")
print(response)
Thought: I need to use the add tool to help me answer the question. Action: add Action Input: {'a': 5, 'b': 3} Observation: 8 Thought: Now I need to add the result from the previous operation to 2. Action: add Action Input: {'a': 8, 'b': 2} Observation: 10 Thought: I can answer without using any more tools. Answer: The result of 5+3+2 is 10. - I first added 5 and 3 using the add tool, which resulted in 8. - Then I added the result (8) to 2 using the add tool again, which resulted in 10. The result of 5+3+2 is 10. - I first added 5 and 3 using the add tool, which resulted in 8. - Then I added the result (8) to 2 using the add tool again, which resulted in 10.