Adds final answer tool for all agents (#31703)
* Adds final answer tool for all agents * Typo * Add clarification in doc * Put final_answer tool adition in agent for clarity
This commit is contained in:
@@ -50,7 +50,7 @@ We implement two versions of ReactJsonAgent:
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
For example, here is how a ReAct agent would work its way through the following question.
|
For example, here is how a ReAct Code agent would work its way through the following question.
|
||||||
|
|
||||||
```py3
|
```py3
|
||||||
>>> agent.run(
|
>>> agent.run(
|
||||||
@@ -188,7 +188,7 @@ You can still authorize additional imports by passing the authorized modules as
|
|||||||
>>> from transformers import ReactCodeAgent
|
>>> from transformers import ReactCodeAgent
|
||||||
|
|
||||||
>>> agent = ReactCodeAgent(tools=[], additional_authorized_imports=['requests', 'bs4'])
|
>>> agent = ReactCodeAgent(tools=[], additional_authorized_imports=['requests', 'bs4'])
|
||||||
>>>agent.run("Could you get me the title of the page at url 'https://huggingface.co/blog'?")
|
>>> agent.run("Could you get me the title of the page at url 'https://huggingface.co/blog'?")
|
||||||
|
|
||||||
(...)
|
(...)
|
||||||
'Hugging Face – Blog'
|
'Hugging Face – Blog'
|
||||||
@@ -256,6 +256,13 @@ agent = ReactJsonAgent(tools=[PythonInterpreterTool()], system_prompt="{your_cus
|
|||||||
> Please make sure to define the `<<tool_descriptions>>` string somewhere in the `template` so the agent is aware
|
> Please make sure to define the `<<tool_descriptions>>` string somewhere in the `template` so the agent is aware
|
||||||
of the available tools.
|
of the available tools.
|
||||||
|
|
||||||
|
|
||||||
|
### Inspecting an agent run
|
||||||
|
|
||||||
|
Here are a few useful attributes to inspect what happened after a run:
|
||||||
|
- `agent.logs` stores the fine-grained logs of the agent. At every step of the agent's run, everything gets stored in a dictionary that then is appended to `agent.logs`.
|
||||||
|
- Running `agent.write_inner_memory_from_logs()` creates an inner memory of the agent's logs for the LLM to view, as a list of chat messages. This method goes over each step of the log and only stores what it's interested in as a message: for instance, it will save the system prompt and task in separate messages, then for each step it will store the LLM output as a message, and the tool call output as another message. Use this if you want a higher-level view of what has happened - but not every log will be transcripted by this method.
|
||||||
|
|
||||||
## Tools
|
## Tools
|
||||||
|
|
||||||
A tool is an atomic function to be used by an agent.
|
A tool is an atomic function to be used by an agent.
|
||||||
@@ -379,7 +386,7 @@ And the output:
|
|||||||
`"The most downloaded model for the 'text-to-video' task is ByteDance/AnimateDiff-Lightning."`
|
`"The most downloaded model for the 'text-to-video' task is ByteDance/AnimateDiff-Lightning."`
|
||||||
|
|
||||||
|
|
||||||
### Manage agent toolbox
|
### Manage your agent's toolbox
|
||||||
|
|
||||||
If you have already initialized an agent, it is inconvenient to reinitialize it from scratch with a tool you want to use. With Transformers, you can manage an agent's toolbox by adding or replacing a tool.
|
If you have already initialized an agent, it is inconvenient to reinitialize it from scratch with a tool you want to use. With Transformers, you can manage an agent's toolbox by adding or replacing a tool.
|
||||||
|
|
||||||
|
|||||||
@@ -337,6 +337,7 @@ class Agent:
|
|||||||
self._toolbox.add_base_tools(add_python_interpreter=(self.__class__ == ReactJsonAgent))
|
self._toolbox.add_base_tools(add_python_interpreter=(self.__class__ == ReactJsonAgent))
|
||||||
else:
|
else:
|
||||||
self._toolbox = Toolbox(tools, add_base_tools=add_base_tools)
|
self._toolbox = Toolbox(tools, add_base_tools=add_base_tools)
|
||||||
|
self._toolbox.add_tool(FinalAnswerTool())
|
||||||
|
|
||||||
self.system_prompt = format_prompt_with_tools(
|
self.system_prompt = format_prompt_with_tools(
|
||||||
self._toolbox, self.system_prompt_template, self.tool_description_template
|
self._toolbox, self.system_prompt_template, self.tool_description_template
|
||||||
@@ -631,8 +632,6 @@ class ReactAgent(Agent):
|
|||||||
tool_description_template=tool_description_template,
|
tool_description_template=tool_description_template,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
if "final_answer" not in self._toolbox.tools:
|
|
||||||
self._toolbox.add_tool(FinalAnswerTool())
|
|
||||||
|
|
||||||
def provide_final_answer(self, task) -> str:
|
def provide_final_answer(self, task) -> str:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ class PythonInterpreterTool(Tool):
|
|||||||
|
|
||||||
class FinalAnswerTool(Tool):
|
class FinalAnswerTool(Tool):
|
||||||
name = "final_answer"
|
name = "final_answer"
|
||||||
description = "Provides a final answer to the given problem"
|
description = "Provides a final answer to the given problem."
|
||||||
inputs = {"answer": {"type": "text", "description": "The final answer to the problem"}}
|
inputs = {"answer": {"type": "text", "description": "The final answer to the problem"}}
|
||||||
output_type = "any"
|
output_type = "any"
|
||||||
|
|
||||||
|
|||||||
@@ -52,8 +52,9 @@ DEFAULT_CODE_SYSTEM_PROMPT = """You will be given a task to solve, your job is t
|
|||||||
To help you, I will give you access to a set of tools that you can use. Each tool is a Python function and has a description explaining the task it performs, the inputs it expects and the outputs it returns.
|
To help you, I will give you access to a set of tools that you can use. Each tool is a Python function and has a description explaining the task it performs, the inputs it expects and the outputs it returns.
|
||||||
You should first explain which tool you will use to perform the task and for what reason, then write the code in Python.
|
You should first explain which tool you will use to perform the task and for what reason, then write the code in Python.
|
||||||
Each instruction in Python should be a simple assignment. You can print intermediate results if it makes sense to do so.
|
Each instruction in Python should be a simple assignment. You can print intermediate results if it makes sense to do so.
|
||||||
|
In the end, use tool 'final_answer' to return your answer, its argument will be what gets returned.
|
||||||
You can use imports in your code, but only from the following list of modules: <<authorized_imports>>
|
You can use imports in your code, but only from the following list of modules: <<authorized_imports>>
|
||||||
Be sure to provide a 'Code:' token, else the system will be stuck in a loop.
|
Be sure to provide a 'Code:' token, else the run will fail.
|
||||||
|
|
||||||
Tools:
|
Tools:
|
||||||
<<tool_descriptions>>
|
<<tool_descriptions>>
|
||||||
@@ -68,7 +69,7 @@ Code:
|
|||||||
translated_question = translator(question=question, src_lang="French", tgt_lang="English")
|
translated_question = translator(question=question, src_lang="French", tgt_lang="English")
|
||||||
print(f"The translated question is {translated_question}.")
|
print(f"The translated question is {translated_question}.")
|
||||||
answer = image_qa(image=image, question=translated_question)
|
answer = image_qa(image=image, question=translated_question)
|
||||||
print(f"The answer is {answer}")
|
final_answer(f"The answer is {answer}")
|
||||||
```<end_action>
|
```<end_action>
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -80,6 +81,7 @@ Code:
|
|||||||
answer = document_qa(document, question="What is the oldest person?")
|
answer = document_qa(document, question="What is the oldest person?")
|
||||||
print(f"The answer is {answer}.")
|
print(f"The answer is {answer}.")
|
||||||
image = image_generator(answer)
|
image = image_generator(answer)
|
||||||
|
final_answer(image)
|
||||||
```<end_action>
|
```<end_action>
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -89,6 +91,7 @@ I will use the following tool: `image_generator` to generate an image.
|
|||||||
Code:
|
Code:
|
||||||
```py
|
```py
|
||||||
image = image_generator(prompt=caption)
|
image = image_generator(prompt=caption)
|
||||||
|
final_answer(image)
|
||||||
```<end_action>
|
```<end_action>
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -100,6 +103,7 @@ Code:
|
|||||||
summarized_text = summarizer(text)
|
summarized_text = summarizer(text)
|
||||||
print(f"Summary: {summarized_text}")
|
print(f"Summary: {summarized_text}")
|
||||||
audio_summary = text_reader(summarized_text)
|
audio_summary = text_reader(summarized_text)
|
||||||
|
final_answer(audio_summary)
|
||||||
```<end_action>
|
```<end_action>
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -111,6 +115,7 @@ Code:
|
|||||||
answer = text_qa(text=text, question=question)
|
answer = text_qa(text=text, question=question)
|
||||||
print(f"The answer is {answer}.")
|
print(f"The answer is {answer}.")
|
||||||
image = image_generator(answer)
|
image = image_generator(answer)
|
||||||
|
final_answer(image)
|
||||||
```<end_action>
|
```<end_action>
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -120,10 +125,11 @@ I will use the following tool: `image_captioner` to generate a caption for the i
|
|||||||
Code:
|
Code:
|
||||||
```py
|
```py
|
||||||
caption = image_captioner(image)
|
caption = image_captioner(image)
|
||||||
|
final_answer(caption)
|
||||||
```<end_action>
|
```<end_action>
|
||||||
|
|
||||||
---
|
---
|
||||||
Above example were using tools that might not exist for you. You only have access to those Tools:
|
Above example were using tools that might not exist for you. You only have acces to those Tools:
|
||||||
<<tool_names>>
|
<<tool_names>>
|
||||||
|
|
||||||
Remember to make sure that variables you use are all defined.
|
Remember to make sure that variables you use are all defined.
|
||||||
@@ -250,7 +256,7 @@ Action:
|
|||||||
}<end_action>
|
}<end_action>
|
||||||
|
|
||||||
|
|
||||||
Above example were using notional tools that might not exist for you. You only have access to those tools:
|
Above example were using notional tools that might not exist for you. You only have acces to those tools:
|
||||||
<<tool_descriptions>>
|
<<tool_descriptions>>
|
||||||
|
|
||||||
Here are the rules you should always follow to solve your task:
|
Here are the rules you should always follow to solve your task:
|
||||||
@@ -357,7 +363,9 @@ Here are the rules you should always follow to solve your task:
|
|||||||
4. Take care to not chain too many sequential tool calls in the same code block, especially when the output format is unpredictable. For instance, a call to search has an unpredictable return format, so do not have another tool call that depends on its output in the same block: rather output results with print() to use them in the next block.
|
4. Take care to not chain too many sequential tool calls in the same code block, especially when the output format is unpredictable. For instance, a call to search has an unpredictable return format, so do not have another tool call that depends on its output in the same block: rather output results with print() to use them in the next block.
|
||||||
5. Call a tool only when needed, and never re-do a tool call that you previously did with the exact same parameters.
|
5. Call a tool only when needed, and never re-do a tool call that you previously did with the exact same parameters.
|
||||||
6. Don't name any new variable with the same name as a tool: for instance don't name a variable 'final_answer'.
|
6. Don't name any new variable with the same name as a tool: for instance don't name a variable 'final_answer'.
|
||||||
7. You can use imports in your code, but only from the following list of modules: <<authorized_imports>>
|
7. Never create any notional variables in our code, as having these in your logs might derail you from the true variables.
|
||||||
|
8. You can use imports in your code, but only from the following list of modules: <<authorized_imports>>
|
||||||
|
9. Don't give up! You're in charge of solving the task, not providing directions to solve it.
|
||||||
|
|
||||||
Now Begin! If you solve the task correctly, you will receive a reward of $1,000,000.
|
Now Begin! If you solve the task correctly, you will receive a reward of $1,000,000.
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -650,7 +650,6 @@ TASK_MAPPING = {
|
|||||||
"text-to-speech": "TextToSpeechTool",
|
"text-to-speech": "TextToSpeechTool",
|
||||||
"translation": "TranslationTool",
|
"translation": "TranslationTool",
|
||||||
"python_interpreter": "PythonInterpreterTool",
|
"python_interpreter": "PythonInterpreterTool",
|
||||||
"final_answer": "FinalAnswerTool",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user