Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

return agent intermediate steps #309

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 97 additions & 21 deletions docs/getting_started/agents.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -118,40 +118,40 @@
"name": "stdout",
"output_type": "stream",
"text": [
"What is the age of Olivia Wilde's boyfriend raised to the 0.23 power?\n",
"Thought:\u001b[32;1m\u001b[1;3m I need to find the age of Olivia Wilde's boyfriend\n",
"Action: Search\n",
"Action Input: \"Olivia Wilde's boyfriend\"\u001b[0m\n",
"Observation: \u001b[36;1m\u001b[1;3mOlivia Wilde started dating Harry Styles after ending her years-long engagement to Jason Sudeikis — see their relationship timeline.\u001b[0m\n",
"Thought:\u001b[32;1m\u001b[1;3m I need to find the age of Harry Styles\n",
"\n",
"\n",
"\u001b[1m> Entering new ZeroShotAgent chain...\u001b[0m\n",
"How old is Olivia Wilde's boyfriend? What is that number raised to the 0.23 power?\n",
"Thought:\u001b[32;1m\u001b[1;3m I need to find out how old Olivia Wilde's boyfriend is, and then use a calculator to calculate the power.\n",
"Action: Search\n",
"Action Input: \"Harry Styles age\"\u001b[0m\n",
"Observation: \u001b[36;1m\u001b[1;3m28 years\u001b[0m\n",
"Thought:\u001b[32;1m\u001b[1;3m I need to calculate 28 to the 0.23 power\n",
"Action Input: Olivia Wilde's boyfriend age\u001b[0m\n",
"Observation: \u001b[36;1m\u001b[1;3mWhile Wilde, 37, and Styles, 27, have both kept a low profile when it comes to talking about their relationship, Wilde did address their ...\u001b[0m\n",
"Thought:\u001b[32;1m\u001b[1;3m Olivia Wilde's boyfriend is 27 years old.\n",
"Action: Calculator\n",
"Action Input: 28^0.23\u001b[0m\n",
"Action Input: 27^0.23\u001b[0m\n",
"\n",
"\u001b[1m> Entering new chain...\u001b[0m\n",
"28^0.23\u001b[32;1m\u001b[1;3m\n",
"\u001b[1m> Entering new LLMMathChain chain...\u001b[0m\n",
"27^0.23\u001b[32;1m\u001b[1;3m\n",
"\n",
"```python\n",
"print(28**0.23)\n",
"import math\n",
"print(math.pow(27, 0.23))\n",
"```\n",
"\u001b[0m\n",
"Answer: \u001b[33;1m\u001b[1;3m2.1520202182226886\n",
"Answer: \u001b[33;1m\u001b[1;3m2.1340945944237553\n",
"\u001b[0m\n",
"\u001b[1m> Finished chain.\u001b[0m\n",
"\u001b[1m> Finished LLMMathChain chain.\u001b[0m\n",
"\n",
"Observation: \u001b[33;1m\u001b[1;3mAnswer: 2.1520202182226886\n",
"Observation: \u001b[33;1m\u001b[1;3mAnswer: 2.1340945944237553\n",
"\u001b[0m\n",
"Thought:\u001b[32;1m\u001b[1;3m I now know the final answer\n",
"Final Answer: 2.1520202182226886\u001b[0m"
"Thought:\n",
"\u001b[1m> Finished ZeroShotAgent chain.\u001b[0m\n"
]
},
{
"data": {
"text/plain": [
"'2.1520202182226886'"
"'2.1340945944237553'"
]
},
"execution_count": 4,
Expand All @@ -165,10 +165,86 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 5,
"id": "2f0852ff",
"metadata": {},
"outputs": [],
"source": [
"# We can also return the intermediate steps\n",
"llm = OpenAI(temperature=0)\n",
"agent = initialize_agent(tools, llm, agent=\"zero-shot-react-description\", verbose=True, return_intermediate_steps=True)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "837211e8",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\n",
"\u001b[1m> Entering new ZeroShotAgent chain...\u001b[0m\n",
"How old is Olivia Wilde's boyfriend? What is that number raised to the 0.23 power?\n",
"Thought:\u001b[32;1m\u001b[1;3m I need to find out how old Olivia Wilde's boyfriend is, and then use a calculator to calculate the power.\n",
"Action: Search\n",
"Action Input: Olivia Wilde's boyfriend age\u001b[0m\n",
"Observation: \u001b[36;1m\u001b[1;3mWhile Wilde, 37, and Styles, 27, have both kept a low profile when it comes to talking about their relationship, Wilde did address their ...\u001b[0m\n",
"Thought:\u001b[32;1m\u001b[1;3m Olivia Wilde's boyfriend is 27 years old.\n",
"Action: Calculator\n",
"Action Input: 27^0.23\u001b[0m\n",
"\n",
"\u001b[1m> Entering new LLMMathChain chain...\u001b[0m\n",
"27^0.23\u001b[32;1m\u001b[1;3m\n",
"\n",
"```python\n",
"import math\n",
"print(math.pow(27, 0.23))\n",
"```\n",
"\u001b[0m\n",
"Answer: \u001b[33;1m\u001b[1;3m2.1340945944237553\n",
"\u001b[0m\n",
"\u001b[1m> Finished LLMMathChain chain.\u001b[0m\n",
"\n",
"Observation: \u001b[33;1m\u001b[1;3mAnswer: 2.1340945944237553\n",
"\u001b[0m\n",
"Thought:\n",
"\u001b[1m> Finished ZeroShotAgent chain.\u001b[0m\n"
]
},
{
"data": {
"text/plain": [
"{'input': \"How old is Olivia Wilde's boyfriend? What is that number raised to the 0.23 power?\",\n",
" 'output': '2.1340945944237553',\n",
" 'intermediate_steps': [{'log': \" I need to find out how old Olivia Wilde's boyfriend is, and then use a calculator to calculate the power.\\nAction: Search\\nAction Input: Olivia Wilde's boyfriend age\",\n",
" 'tool': 'Search',\n",
" 'tool_input': \"Olivia Wilde's boyfriend age\",\n",
" 'observation': 'While Wilde, 37, and Styles, 27, have both kept a low profile when it comes to talking about their relationship, Wilde did address their ...'},\n",
" {'log': \" Olivia Wilde's boyfriend is 27 years old.\\nAction: Calculator\\nAction Input: 27^0.23\",\n",
" 'tool': 'Calculator',\n",
" 'tool_input': '27^0.23',\n",
" 'observation': 'Answer: 2.1340945944237553\\n'}]}"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"agent({\"input\":\"How old is Olivia Wilde's boyfriend? What is that number raised to the 0.23 power?\"})"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9256ff6b",
"metadata": {},
"outputs": [],
"source": []
}
],
Expand All @@ -188,7 +264,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.6"
"version": "3.10.8"
}
},
"nbformat": 4,
Expand Down
21 changes: 15 additions & 6 deletions langchain/agents/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Agent(Chain, BaseModel, ABC):
prompt: ClassVar[BasePromptTemplate]
llm_chain: LLMChain
tools: List[Tool]
return_intermediate_steps: bool = False
input_key: str = "input" #: :meta private:
output_key: str = "output" #: :meta private:

Expand All @@ -39,7 +40,10 @@ def output_keys(self) -> List[str]:

:meta private:
"""
return [self.output_key]
if self.return_intermediate_steps:
return [self.output_key, "intermediate_steps"]
else:
return [self.output_key]

@root_validator()
def validate_prompt(cls, values: Dict) -> Dict:
Expand Down Expand Up @@ -126,7 +130,7 @@ def get_action(self, thoughts: str, inputs: dict) -> AgentAction:
tool, tool_input = parsed_output
return AgentAction(tool, tool_input, full_output)

def _call(self, inputs: Dict[str, str]) -> Dict[str, str]:
def _call(self, inputs: Dict[str, str]) -> Dict[str, Any]:
"""Run text through and get agent response."""
# Do any preparation necessary when receiving a new input.
self._prepare_for_new_call()
Expand All @@ -142,12 +146,17 @@ def _call(self, inputs: Dict[str, str]) -> Dict[str, str]:
while True:
# Call the LLM to see what to do.
output = self.get_action(chained_input.input, inputs)
# Add the log to the Chained Input.
chained_input.add_action(output, color="green")
# If the tool chosen is the finishing tool, then we end and return.
if output.tool == self.finish_tool_name:
return {self.output_key: output.tool_input}
# Otherwise we lookup the tool
final_output: dict = {self.output_key: output.tool_input}
if self.return_intermediate_steps:
final_output[
"intermediate_steps"
] = chained_input.intermediate_steps
return final_output
# Other we add the log to the Chained Input.
chained_input.add_action(output, color="green")
# And then we lookup the tool
if output.tool in name_to_tool_map:
chain = name_to_tool_map[output.tool]
# We then call the tool on the tool input to get an observation
Expand Down
20 changes: 19 additions & 1 deletion langchain/agents/input.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Input manager for agents."""
from typing import Optional
from typing import List, Optional

import langchain
from langchain.schema import AgentAction
Expand All @@ -14,12 +14,29 @@ def __init__(self, text: str, verbose: bool = False):
if self._verbose:
langchain.logger.log_agent_start(text)
self._input = text
self._intermediate_actions: List[AgentAction] = []
self._intermediate_observations: List[str] = []

@property
def intermediate_steps(self) -> List:
"""Return intermediate steps the agent took."""
steps = []
for i, action in enumerate(self._intermediate_actions):
step = {
"log": action.log,
"tool": action.tool,
"tool_input": action.tool_input,
"observation": self._intermediate_observations[i],
}
steps.append(step)
return steps

def add_action(self, action: AgentAction, color: Optional[str] = None) -> None:
"""Add text to input, print if in verbose mode."""
if self._verbose:
langchain.logger.log_agent_action(action, color=color)
self._input += action.log
self._intermediate_actions.append(action)

def add_observation(
self,
Expand All @@ -37,6 +54,7 @@ def add_observation(
llm_prefix=llm_prefix,
)
self._input += f"\n{observation_prefix}{observation}\n{llm_prefix}"
self._intermediate_observations.append(observation)

@property
def input(self) -> str:
Expand Down
2 changes: 1 addition & 1 deletion langchain/chains/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def _call(self, inputs: Dict[str, str]) -> Dict[str, str]:

def __call__(
self, inputs: Union[Dict[str, Any], Any], return_only_outputs: bool = False
) -> Dict[str, str]:
) -> Dict[str, Any]:
"""Run the logic of this chain and add to output if desired.

Args:
Expand Down