Start including standard tool calling agent
This commit is contained in:
parent
3a28bda490
commit
4d4bf13152
|
@ -33,6 +33,7 @@ from .monitoring import Monitor
|
||||||
from .prompts import (
|
from .prompts import (
|
||||||
CODE_SYSTEM_PROMPT,
|
CODE_SYSTEM_PROMPT,
|
||||||
JSON_SYSTEM_PROMPT,
|
JSON_SYSTEM_PROMPT,
|
||||||
|
TOOL_CALLING_SYSTEM_PROMPT,
|
||||||
PLAN_UPDATE_FINAL_PLAN_REDACTION,
|
PLAN_UPDATE_FINAL_PLAN_REDACTION,
|
||||||
SYSTEM_PROMPT_FACTS,
|
SYSTEM_PROMPT_FACTS,
|
||||||
SYSTEM_PROMPT_FACTS_UPDATE,
|
SYSTEM_PROMPT_FACTS_UPDATE,
|
||||||
|
@ -870,6 +871,119 @@ class JsonAgent(ReactAgent):
|
||||||
log_entry.observations = updated_information
|
log_entry.observations = updated_information
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
class ToolCallingAgent(ReactAgent):
|
||||||
|
"""
|
||||||
|
In this agent, the tool calls will be formulated and parsed using the underlying library, before execution.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
tools: List[Tool],
|
||||||
|
llm_engine: Optional[Callable] = None,
|
||||||
|
system_prompt: Optional[str] = None,
|
||||||
|
tool_description_template: Optional[str] = None,
|
||||||
|
planning_interval: Optional[int] = None,
|
||||||
|
**kwargs,
|
||||||
|
):
|
||||||
|
if llm_engine is None:
|
||||||
|
llm_engine = HfApiEngine()
|
||||||
|
if system_prompt is None:
|
||||||
|
system_prompt = TOOL_CALLING_SYSTEM_PROMPT
|
||||||
|
if tool_description_template is None:
|
||||||
|
tool_description_template = DEFAULT_TOOL_DESCRIPTION_TEMPLATE
|
||||||
|
super().__init__(
|
||||||
|
tools=tools,
|
||||||
|
llm_engine=llm_engine,
|
||||||
|
system_prompt=system_prompt,
|
||||||
|
tool_description_template=tool_description_template,
|
||||||
|
planning_interval=planning_interval,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
def step(self, log_entry: ActionStep) -> Union[None, Any]:
|
||||||
|
"""
|
||||||
|
Perform one step in the ReAct framework: the agent thinks, acts, and observes the result.
|
||||||
|
Returns None if the step is not final.
|
||||||
|
"""
|
||||||
|
agent_memory = self.write_inner_memory_from_logs()
|
||||||
|
|
||||||
|
self.prompt_messages = agent_memory
|
||||||
|
|
||||||
|
# Add new step in logs
|
||||||
|
log_entry.agent_memory = agent_memory.copy()
|
||||||
|
|
||||||
|
if self.verbose:
|
||||||
|
console.print(
|
||||||
|
Group(
|
||||||
|
Rule(
|
||||||
|
"[italic]Calling LLM engine with this last message:",
|
||||||
|
align="left",
|
||||||
|
style="orange",
|
||||||
|
),
|
||||||
|
Text(str(self.prompt_messages[-1])),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
llm_output = self.llm_engine(
|
||||||
|
self.prompt_messages,
|
||||||
|
)
|
||||||
|
log_entry.llm_output = llm_output
|
||||||
|
except Exception as e:
|
||||||
|
raise AgentGenerationError(f"Error in generating llm_engine output: {e}.")
|
||||||
|
|
||||||
|
if self.verbose:
|
||||||
|
console.print(
|
||||||
|
Group(
|
||||||
|
Rule(
|
||||||
|
"[italic]Output message of the LLM:",
|
||||||
|
align="left",
|
||||||
|
style="orange",
|
||||||
|
),
|
||||||
|
Text(llm_output),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
log_entry.tool_call = ToolCall(tool_name=tool_name, tool_arguments=arguments)
|
||||||
|
|
||||||
|
# Execute
|
||||||
|
console.print(Rule("Agent thoughts:", align="left"), Text(rationale))
|
||||||
|
console.print(
|
||||||
|
Panel(Text(f"Calling tool: '{tool_name}' with arguments: {arguments}"))
|
||||||
|
)
|
||||||
|
if tool_name == "final_answer":
|
||||||
|
if isinstance(arguments, dict):
|
||||||
|
if "answer" in arguments:
|
||||||
|
answer = arguments["answer"]
|
||||||
|
else:
|
||||||
|
answer = arguments
|
||||||
|
else:
|
||||||
|
answer = arguments
|
||||||
|
if (
|
||||||
|
isinstance(answer, str) and answer in self.state.keys()
|
||||||
|
): # if the answer is a state variable, return the value
|
||||||
|
answer = self.state[answer]
|
||||||
|
log_entry.action_output = answer
|
||||||
|
return answer
|
||||||
|
else:
|
||||||
|
if arguments is None:
|
||||||
|
arguments = {}
|
||||||
|
observation = self.execute_tool_call(tool_name, arguments)
|
||||||
|
observation_type = type(observation)
|
||||||
|
if observation_type in [AgentImage, AgentAudio]:
|
||||||
|
if observation_type == AgentImage:
|
||||||
|
observation_name = "image.png"
|
||||||
|
elif observation_type == AgentAudio:
|
||||||
|
observation_name = "audio.mp3"
|
||||||
|
# TODO: observation naming could allow for different names of same type
|
||||||
|
|
||||||
|
self.state[observation_name] = observation
|
||||||
|
updated_information = f"Stored '{observation_name}' in memory."
|
||||||
|
else:
|
||||||
|
updated_information = str(observation).strip()
|
||||||
|
log_entry.observations = updated_information
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class CodeAgent(ReactAgent):
|
class CodeAgent(ReactAgent):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -277,6 +277,113 @@ Now Begin! If you solve the task correctly, you will receive a reward of $1,000,
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
TOOL_CALLING_SYSTEM_PROMPT = """You are an expert assistant who can solve any task using tool calls. You will be given a task to solve as best you can.
|
||||||
|
To do so, you have been given access to the following tools: {{tool_names}}
|
||||||
|
|
||||||
|
The tool call you write is an action: after the tool is executed, you will get the result of the tool call as an "observation".
|
||||||
|
This Action/Observation can repeat N times, you should take several steps when needed.
|
||||||
|
|
||||||
|
You can use the result of the previous action as input for the next action.
|
||||||
|
The observation will always be a string: it can represent a file, like "image_1.jpg".
|
||||||
|
Then you can use it as input for the next action. You can do it for instance as follows:
|
||||||
|
|
||||||
|
Observation: "image_1.jpg"
|
||||||
|
|
||||||
|
Action:
|
||||||
|
{
|
||||||
|
"action": "image_transformer",
|
||||||
|
"action_input": {"image": "image_1.jpg"}
|
||||||
|
}
|
||||||
|
|
||||||
|
To provide the final answer to the task, use an action blob with "action": "final_answer" tool. It is the only way to complete the task, else you will be stuck on a loop. So your final output should look like this:
|
||||||
|
Action:
|
||||||
|
{
|
||||||
|
"action": "final_answer",
|
||||||
|
"action_input": {"answer": "insert your final answer here"}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Here are a few examples using notional tools:
|
||||||
|
---
|
||||||
|
Task: "Generate an image of the oldest person in this document."
|
||||||
|
|
||||||
|
Action:
|
||||||
|
{
|
||||||
|
"action": "document_qa",
|
||||||
|
"action_input": {"document": "document.pdf", "question": "Who is the oldest person mentioned?"}
|
||||||
|
}
|
||||||
|
Observation: "The oldest person in the document is John Doe, a 55 year old lumberjack living in Newfoundland."
|
||||||
|
|
||||||
|
Action:
|
||||||
|
{
|
||||||
|
"action": "image_generator",
|
||||||
|
"action_input": {"prompt": "A portrait of John Doe, a 55-year-old man living in Canada."}
|
||||||
|
}
|
||||||
|
Observation: "image.png"
|
||||||
|
|
||||||
|
Action:
|
||||||
|
{
|
||||||
|
"action": "final_answer",
|
||||||
|
"action_input": "image.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
Task: "What is the result of the following operation: 5 + 3 + 1294.678?"
|
||||||
|
|
||||||
|
Action:
|
||||||
|
{
|
||||||
|
"action": "python_interpreter",
|
||||||
|
"action_input": {"code": "5 + 3 + 1294.678"}
|
||||||
|
}
|
||||||
|
Observation: 1302.678
|
||||||
|
|
||||||
|
Action:
|
||||||
|
{
|
||||||
|
"action": "final_answer",
|
||||||
|
"action_input": "1302.678"
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
Task: "Which city has the highest population , Guangzhou or Shanghai?"
|
||||||
|
|
||||||
|
Action:
|
||||||
|
{
|
||||||
|
"action": "search",
|
||||||
|
"action_input": "Population Guangzhou"
|
||||||
|
}
|
||||||
|
Observation: ['Guangzhou has a population of 15 million inhabitants as of 2021.']
|
||||||
|
|
||||||
|
|
||||||
|
Action:
|
||||||
|
{
|
||||||
|
"action": "search",
|
||||||
|
"action_input": "Population Shanghai"
|
||||||
|
}
|
||||||
|
Observation: '26 million (2019)'
|
||||||
|
|
||||||
|
Action:
|
||||||
|
{
|
||||||
|
"action": "final_answer",
|
||||||
|
"action_input": "Shanghai"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Above example were using notional tools that might not exist for you. You only have access to these tools:
|
||||||
|
|
||||||
|
{{tool_descriptions}}
|
||||||
|
|
||||||
|
{{managed_agents_descriptions}}
|
||||||
|
|
||||||
|
Here are the rules you should always follow to solve your task:
|
||||||
|
1. ALWAYS provide a tool call, else you will fail.
|
||||||
|
2. Always use the right arguments for the tools. Never use variable names as the action arguments, use the value instead.
|
||||||
|
3. Call a tool only when needed: do not call the search agent if you do not need information, try to solve the task yourself.
|
||||||
|
If no tool call is needed, use final_answer tool to return your answer.
|
||||||
|
4. Never re-do a tool call that you previously did with the exact same parameters.
|
||||||
|
|
||||||
|
Now Begin! If you solve the task correctly, you will receive a reward of $1,000,000.
|
||||||
|
"""
|
||||||
|
|
||||||
CODE_SYSTEM_PROMPT = """You are an expert assistant who can solve any task using code blobs. You will be given a task to solve as best you can.
|
CODE_SYSTEM_PROMPT = """You are an expert assistant who can solve any task using code blobs. You will be given a task to solve as best you can.
|
||||||
To do so, you have been given access to a list of tools: these tools are basically Python functions which you can call with code.
|
To do so, you have been given access to a list of tools: these tools are basically Python functions which you can call with code.
|
||||||
To solve the task, you must plan forward to proceed in a series of steps, in a cycle of 'Thought:', 'Code:', and 'Observation:' sequences.
|
To solve the task, you must plan forward to proceed in a series of steps, in a cycle of 'Thought:', 'Code:', and 'Observation:' sequences.
|
||||||
|
|
Loading…
Reference in New Issue