Improving inner prompts

This commit is contained in:
João Moura
2024-02-20 17:53:30 -03:00
parent 7b7d714109
commit 0593d52b91
7 changed files with 38 additions and 38 deletions

View File

@@ -261,7 +261,7 @@ class Agent(BaseModel):
self, self,
intermediate_steps: List[Tuple[AgentAction, str]], intermediate_steps: List[Tuple[AgentAction, str]],
observation_prefix: str = "Result: ", observation_prefix: str = "Result: ",
llm_prefix: str = "Thought: ", llm_prefix: str = "",
) -> str: ) -> str:
"""Construct the scratchpad that lets the agent continue its thought process.""" """Construct the scratchpad that lets the agent continue its thought process."""
thoughts = "" thoughts = ""

View File

@@ -3,7 +3,6 @@ from typing import Any, Dict, Iterator, List, Optional, Tuple, Union
from langchain.agents import AgentExecutor from langchain.agents import AgentExecutor
from langchain.agents.agent import ExceptionTool from langchain.agents.agent import ExceptionTool
from langchain.agents.tools import InvalidTool
from langchain.callbacks.manager import CallbackManagerForChainRun from langchain.callbacks.manager import CallbackManagerForChainRun
from langchain_core.agents import AgentAction, AgentFinish, AgentStep from langchain_core.agents import AgentAction, AgentFinish, AgentStep
from langchain_core.exceptions import OutputParserException from langchain_core.exceptions import OutputParserException
@@ -147,7 +146,7 @@ class CrewAgentExecutor(AgentExecutor):
observation = f"\n{str(e.observation)}" observation = f"\n{str(e.observation)}"
text = str(e.llm_output) text = str(e.llm_output)
else: else:
observation = "Invalid or incomplete response" observation = ""
elif isinstance(self.handle_parsing_errors, str): elif isinstance(self.handle_parsing_errors, str):
observation = f"\n{self.handle_parsing_errors}" observation = f"\n{self.handle_parsing_errors}"
elif callable(self.handle_parsing_errors): elif callable(self.handle_parsing_errors):
@@ -206,15 +205,8 @@ class CrewAgentExecutor(AgentExecutor):
]: ]:
observation = tool_usage.use(tool_calling, agent_action.log) observation = tool_usage.use(tool_calling, agent_action.log)
else: else:
tool_run_kwargs = self.agent.tool_run_logging_kwargs() observation = self._i18n.errors("wrong_tool_name").format(
observation = InvalidTool().run( tool=tool_calling.tool_name,
{ tools=", ".join([tool.name for tool in self.tools]),
"requested_tool_name": tool_calling.tool_name,
"available_tool_names": list(name_to_tool_map.keys()),
},
verbose=self.verbose,
color=None,
callbacks=run_manager.get_child() if run_manager else None,
**tool_run_kwargs,
) )
yield AgentStep(action=agent_action, observation=observation) yield AgentStep(action=agent_action, observation=observation)

View File

@@ -8,7 +8,7 @@ from crewai.utilities import I18N
TOOL_USAGE_SECTION = "Use Tool:" TOOL_USAGE_SECTION = "Use Tool:"
FINAL_ANSWER_ACTION = "Final Answer:" FINAL_ANSWER_ACTION = "Final Answer:"
FINAL_ANSWER_AND_TOOL_ERROR_MESSAGE = "You are trying to use a tool and give a final answer at the same time, choose only one." FINAL_ANSWER_AND_TOOL_ERROR_MESSAGE = "I tried to use a tool and give a final answer at the same time, I must choose only one."
class CrewAgentParser(ReActSingleInputOutputParser): class CrewAgentParser(ReActSingleInputOutputParser):
@@ -50,9 +50,8 @@ class CrewAgentParser(ReActSingleInputOutputParser):
{"output": text.split(FINAL_ANSWER_ACTION)[-1].strip()}, text {"output": text.split(FINAL_ANSWER_ACTION)[-1].strip()}, text
) )
error = self._i18n.errors("unexpected_format")
format = self._i18n.slice("format_without_tools") format = self._i18n.slice("format_without_tools")
error = f"{error}\n{format}" error = f"{format}"
raise OutputParserException( raise OutputParserException(
error, error,
observation=error, observation=error,

View File

@@ -42,11 +42,16 @@ class AgentTools(BaseModel):
def _execute(self, agent, task, context): def _execute(self, agent, task, context):
"""Execute the command.""" """Execute the command."""
agent = [ try:
available_agent agent = [
for available_agent in self.agents available_agent
if available_agent.role.strip().lower() == agent.strip().lower() for available_agent in self.agents
] if available_agent.role.strip().lower() == agent.strip().lower()
]
except:
return self.i18n.errors("agent_tool_unexsiting_coworker").format(
coworkers="\n".join([f"- {agent.role}" for agent in self.agents])
)
if not agent: if not agent:
return self.i18n.errors("agent_tool_unexsiting_coworker").format( return self.i18n.errors("agent_tool_unexsiting_coworker").format(

View File

@@ -82,7 +82,7 @@ class ToolUsage:
error = getattr(e, "message", str(e)) error = getattr(e, "message", str(e))
self._printer.print(content=f"\n\n{error}\n", color="red") self._printer.print(content=f"\n\n{error}\n", color="red")
return error return error
return f"{self._use(tool_string=tool_string, tool=tool, calling=calling)}\n{self._i18n.slice('final_answer_format')}" return f"{self._use(tool_string=tool_string, tool=tool, calling=calling)}\n\n{self._i18n.slice('final_answer_format')}"
def _use( def _use(
self, self,
@@ -121,10 +121,13 @@ class ToolUsage:
self._run_attempts += 1 self._run_attempts += 1
if self._run_attempts > self._max_parsing_attempts: if self._run_attempts > self._max_parsing_attempts:
self._telemetry.tool_usage_error(llm=self.llm) self._telemetry.tool_usage_error(llm=self.llm)
error_message = self._i18n.errors("tool_usage_exception").format(
error=e
)
error = ToolUsageErrorException( error = ToolUsageErrorException(
f'{self._i18n.errors("tool_usage_exception").format(error=e)}.\n{self._i18n.slice("format").format(tool_names=self.tools_names)}' f'\n{error_message}.\nMoving one then. {self._i18n.slice("format").format(tool_names=self.tools_names)}'
).message ).message
self._printer.print(content=f"\n\n{error}\n", color="red") self._printer.print(content=f"\n\n{error_message}\n", color="red")
return error return error
return self.use(calling=calling, tool_string=tool_string) return self.use(calling=calling, tool_string=tool_string)
@@ -196,7 +199,7 @@ class ToolUsage:
instructor = Instructor( instructor = Instructor(
llm=self.llm, llm=self.llm,
model=InstructorToolCalling, model=InstructorToolCalling,
content=f"Tools available:\n\n{self._render()}\n\nReturn a valid schema for the tool, the tool name must be equal one of the options, use this text to inform a valid ouput schema:\n{tool_string}```", content=f"Tools available:\n###\n{self._render()}\n\nReturn a valid schema for the tool, the tool name must be equal one of the options, use this text to inform a valid ouput schema:\n{tool_string}```",
instructions=dedent( instructions=dedent(
"""\ """\
The schema should have the following structure, only two keys: The schema should have the following structure, only two keys:
@@ -204,7 +207,7 @@ class ToolUsage:
- arguments: dict (with all arguments being passed) - arguments: dict (with all arguments being passed)
Example: Example:
{"tool_name": "tool_name", "arguments": {"arg_name1": "value", "arg_name2": 2}} {"tool_name": "tool name", "arguments": {"arg_name1": "value", "arg_name2": 2}}
""" """
), ),
) )

View File

@@ -6,23 +6,24 @@
}, },
"slices": { "slices": {
"observation": "\nResult", "observation": "\nResult",
"task": "Begin! This is VERY important to you, your job depends on it!\n\nCurrent Task: {input}", "task": "\n\nCurrent Task: {input}\n\n Begin! This is VERY important to you, your job depends on it!\n\n",
"memory": "This is the summary of your work so far:\n{chat_history}", "memory": "This is the summary of your work so far:\n{chat_history}",
"role_playing": "You are {role}.\n{backstory}\n\nYour personal goal is: {goal}", "role_playing": "You are {role}.\n{backstory}\n\nYour personal goal is: {goal}",
"tools": "You have access to ONLY the following tools, use one at time:\n\n{tools}\n\nTo use a tool you MUST use the exact following format:\n\n```\nUse Tool: the tool you wanna use, should be one of [{tool_names}] and absolute all relevant input and context for using the tool, you must use only one tool at once.\nResult: [result of the tool]\n```\n\nTo complete the task you MUST follow the format:\n\n```\nFinal Answer: [THE MOST COMPLETE ANSWE WITH ALL CONTEXT, DO NOT LEAVE ANYTHING OUT]\n``` You must use these formats, my life depends on it.", "tools": "You have access to ONLY the following tools, use one at time:\n\n{tools}\n\nTo use a tool you MUST use the exact following format:\n\n```\nUse Tool: the tool you wanna use, should be one of [{tool_names}] and absolute all relevant input and context for using the tool, you must use only one tool at once.\nResult: [result of the tool]\n```\n\nTo give your final answer use the exact following format:\n\n```\nFinal Answer: [THE MOST COMPLETE ANSWE WITH ALL CONTEXT, DO NOT LEAVE ANYTHING OUT]\n```\nI MUST use these formats, my jobs depends on it!",
"no_tools": "To complete the task you MUST follow the format:\n\n```\nFinal Answer: [your most complete final answer goes here]\n``` You must use these formats, my life depends on it.", "no_tools": "To give your final answer use the exact following format:\n\n```\nFinal Answer: [entire content of your most complete final answer goes here]\n```\nI MUST use these formats, my jobs depends on it!",
"format": "To use a tool you MUST use the exact following format:\n\n```\nUse Tool: the tool you wanna use, should be one of [{tool_names}] and absolute all relevant input and context for using the tool, you must use only one tool at once.\nResult: [result of the tool]\n```\n\nTo complete the task you MUST follow the format:\n\n```\nFinal Answer: [your most complete final answer goes here]\n``` You must use these formats, my life depends on it.", "format": "You MUST either use a tool (use one at time) OR give your best final answer. To use a tool you MUST use the exact following format:\n\n```\nUse Tool: the tool you wanna use, should be one of [{tool_names}] and absolute all relevant input and context for using the tool, you must use only one tool at once.\nResult: [result of the tool]\n```\n\nTo give your final answer use the exact following format:\n\n```\nFinal Answer: [your most complete final answer goes here]\n```\nI MUST use these formats, my jobs depends on it!",
"final_answer_format": "If you don't need to use any more tools, use the correct format for your final answer:\n\n```Final Answer: [your most complete final answer goes here]```", "final_answer_format": "If you don't need to use any more tools, make sure use the correct format to give your final answer:\n\n```Final Answer: [entire content of your most complete final answer goes here]```\n You MUST use these formats, your jobs depends on it!",
"format_without_tools": "To use a tool you MUST use the exact following format:\n\n```\nUse Tool: the tool you wanna use, and absolute all relevant input and context for using the tool, you must use only one tool at once.\nResult: [result of the tool]\n```\n\nTo complete the task you MUST follow the format:\n\n```\nFinal Answer: [your most complete final answer goes here]\n``` You must use these formats, my life depends on it.", "format_without_tools": "ERROR: I didn't use the right format. I MUST either use a tool (use one at time) OR give my best final answer.\n\n```\nUse Tool: the tool you wanna use, and absolute all relevant input and context for using the tool, you must use only one tool at once.\nResult: [result of the tool]\n```\nOR\n```\nFinal Answer: [entire content of your most complete final answer goes here]\n```",
"task_with_context": "{task}\nThis is the context you're working with:\n{context}", "task_with_context": "{task}\nThis is the context you're working with:\n{context}",
"expected_output": "Your final answer must be: {expected_output}" "expected_output": "Your final answer must be: {expected_output}"
}, },
"errors": { "errors": {
"unexpected_format": "You didn't use the expected format, you MUST use a tool or give your best final answer.", "unexpected_format": "ERROR: I didn't use the expected format, I MUST either use a tool (use one at time) OR give my best final answer.\n",
"force_final_answer": "Actually, I used too many tools, so I'll stop now and give you my absolute BEST Final answer NOW, using exaclty the expected format bellow:\n\n```\nFinal Answer: [your most complete final answer goes here]\n``` You must use these formats, my life depends on it.", "force_final_answer": "Actually, I used too many tools, so I'll stop now and give you my absolute BEST Final answer NOW, using exaclty the expected format bellow:\n\n```\nFinal Answer: [your most complete final answer goes here]\n```\nI MUST use these formats, my jobs depends on it!",
"agent_tool_unexsiting_coworker": "\nError executing tool. Co-worker mentioned on the Action Input not found, it must to be one of the following options:\n{coworkers}.\n", "agent_tool_unexsiting_coworker": "\nError executing tool. Co-worker mentioned not found, it must to be one of the following options:\n{coworkers}\n",
"task_repeated_usage": "I already used the {tool} tool with input {tool_input}. So I already know that and must stop using it with same input. \nI could give my best complete final answer if I'm ready, using exaclty the expected format bellow:\n\n```\nFinal Answer: [your most complete final answer goes here]\n``` You must use these formats, my life depends on it.", "task_repeated_usage": "I already used the {tool} tool with input {tool_input}. So I already know that and must stop using it with same input. \nI could give my best complete final answer if I'm ready, using exaclty the expected format bellow:\n\n```\nFinal Answer: [entire content of your most complete final answer goes here]\n```\nI MUST use these formats, my jobs depends on it!",
"tool_usage_error": "It seems we encountered an unexpected error while trying to use the tool.", "tool_usage_error": "It seems we encountered an unexpected error while trying to use the tool.",
"wrong_tool_name": "You tried to use the tool {tool}, but it doesn't exist. You must use one of the following tools, use one at time: {tools}.",
"tool_usage_exception": "It seems we encountered an unexpected error while trying to use the tool. This was the error: {error}" "tool_usage_exception": "It seems we encountered an unexpected error while trying to use the tool. This was the error: {error}"
}, },
"tools": { "tools": {

View File

@@ -51,7 +51,7 @@ def test_delegate_work_to_wrong_agent():
assert ( assert (
result result
== "\nError executing tool. Co-worker mentioned on the Action Input not found, it must to be one of the following options:\n- researcher.\n" == "\nError executing tool. Co-worker mentioned not found, it must to be one of the following options:\n- researcher\n"
) )
@@ -64,5 +64,5 @@ def test_ask_question_to_wrong_agent():
assert ( assert (
result result
== "\nError executing tool. Co-worker mentioned on the Action Input not found, it must to be one of the following options:\n- researcher.\n" == "\nError executing tool. Co-worker mentioned not found, it must to be one of the following options:\n- researcher\n"
) )