Skip to main content

处理解析错误

有时候LLM无法确定应该采取什么步骤,因为它输出的格式不正确,无法被输出解析器处理。在这种情况下,默认情况下代理会报错。但是你可以通过handle_parsing_errors轻松控制这个功能!让我们来探索一下。

设置

from langchain import (
OpenAI,
LLMMathChain,
SerpAPIWrapper,
SQLDatabase,
SQLDatabaseChain,
)
from langchain.agents import initialize_agent, Tool
from langchain.agents import AgentType
from langchain.chat_models import ChatOpenAI
from langchain.agents.types import AGENT_TO_CLASS

search = SerpAPIWrapper()
tools = [
Tool(
name="Search",
func=search.run,
description="当你需要回答关于当前事件的问题时很有用。你应该提出有针对性的问题",
),
]

API参考:

错误

在这种情况下,代理会报错(因为它无法输出一个Action字符串)

mrkl = initialize_agent(
tools,
ChatOpenAI(temperature=0),
agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
)

mrkl.run("Who is Leo DiCaprio's girlfriend? No need to add Action")
> 进入新的AgentExecutor链...

---------------------------------------------------------------------------
IndexError Traceback (most recent call last)

~/workplace/langchain/langchain/agents/chat/output_parser.py:21 in ChatOutputParser.parse(self, text)
20 try:
---> 21 action = text.split("```")[1]
22 response = json.loads(action.strip())

IndexError: list index out of range

During handling of the above exception, another exception occurred:

OutputParserException Traceback (most recent call last)

Cell In[4], line 1
----> 1 mrkl.run("Who is Leo DiCaprio's girlfriend? No need to add Action")

~/workplace/langchain/langchain/chains/base.py:236 in Chain.run(self, callbacks, *args, **kwargs)
234 if len(args) != 1:
235 raise ValueError("`run` supports only one positional argument.")
--> 236 return self(args[0], callbacks=callbacks)[self.output_keys[0]]
238 if kwargs and not args:
239 return self(kwargs, callbacks=callbacks)[self.output_keys[0]]

~/workplace/langchain/langchain/chains/base.py:140 in Chain.__call__(self, inputs, return_only_outputs, callbacks)
138 except (KeyboardInterrupt, Exception) as e:
139 run_manager.on_chain_error(e)
--> 140 raise e
141 run_manager.on_chain_end(outputs)
142 return self.prep_outputs(inputs, outputs, return_only_outputs)

~/workplace/langchain/langchain/chains/base.py:134 in Chain.__call__(self, inputs, return_only_outputs, callbacks)
128 run_manager = callback_manager.on_chain_start(
129 {"name": self.__class__.__name__},
130 inputs,
131 )
132 try:
133 outputs = (
--> 134 self._call(inputs, run_manager=run_manager)
135 if new_arg_supported
136 else self._call(inputs)
137 )
138 except (KeyboardInterrupt, Exception) as e:
139 run_manager.on_chain_error(e)

~/workplace/langchain/langchain/agents/agent.py:947 in AgentExecutor._call(self, inputs, run_manager)
945 # We now enter the agent loop (until it returns something).
946 while self._should_continue(iterations, time_elapsed):
--> 947 next_step_output = self._take_next_step(
948 name_to_tool_map,
949 color_mapping,
950 inputs,
951 intermediate_steps,
952 run_manager=run_manager,
953 )
954 if isinstance(next_step_output, AgentFinish):
955 return self._return(
956 next_step_output, intermediate_steps, run_manager=run_manager
957 )

~/workplace/langchain/langchain/agents/agent.py:773 in AgentExecutor._take_next_step(self, name_to_tool_map, color_mapping, inputs, intermediate_steps, run_manager)
771 raise_error = False
772 if raise_error:
--> 773 raise e
774 text = str(e)
775 if isinstance(self.handle_parsing_errors, bool):

~/workplace/langchain/langchain/agents/agent.py:762 in AgentExecutor._take_next_step(self, name_to_tool_map, color_mapping, inputs, intermediate_steps, run_manager)
756 """Take a single step in the thought-action-observation loop.
757
758 Override this to take control of how the agent makes and acts on choices.
759 """
760 try:
761 # Call the LLM to see what to do.
--> 762 output = self.agent.plan(
763 intermediate_steps,
764 callbacks=run_manager.get_child() if run_manager else None,
765 **inputs,
766 )
767 except OutputParserException as e:
768 if isinstance(self.handle_parsing_errors, bool):

~/workplace/langchain/langchain/agents/agent.py:444 in Agent.plan(self, intermediate_steps, callbacks, **kwargs)
442 full_inputs = self.get_full_inputs(intermediate_steps, **kwargs)
443 full_output = self.llm_chain.predict(callbacks=callbacks, **full_inputs)
--> 444 return self.output_parser.parse(full_output)

~/workplace/langchain/langchain/agents/chat/output_parser.py:26 in ChatOutputParser.parse(self, text)
23 return AgentAction(response["action"], response["action_input"], text)
25 except Exception:
---> 26 raise OutputParserException(f"Could not parse LLM output: {text}")

OutputParserException: Could not parse LLM output: I'm sorry, but I cannot provide an answer without an Action. Please provide a valid Action in the format specified above.

默认错误处理

使用Invalid or incomplete response处理错误

mrkl = initialize_agent(
tools,
ChatOpenAI(temperature=0),
agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
handle_parsing_errors=True,
)

mrkl.run("Who is Leo DiCaprio's girlfriend? No need to add Action")
> 进入新的AgentExecutor链...

Observation: Invalid or incomplete response
Thought:
Observation: Invalid or incomplete response
Thought:Search for Leo DiCaprio's current girlfriend
Action:
{
"action": "Search",
"action_input": "Leo DiCaprio current girlfriend"
}
Observation: Just Jared on Instagram: “Leonardo DiCaprio & girlfriend Camila Morrone couple up for a lunch date!
Thought:Camila Morrone is currently Leo DiCaprio's girlfriend
Final Answer: Camila Morrone

> 完成链。

自定义错误消息

你可以轻松自定义解析错误时使用的消息

mrkl = initialize_agent(
tools,
ChatOpenAI(temperature=0),
agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
handle_parsing_errors="Check your output and make sure it conforms!",
)

mrkl.run("Who is Leo DiCaprio's girlfriend? No need to add Action")
> 进入新的AgentExecutor链...

Observation: Could not parse LLM output: I'm sorry, but I canno
Thought:I need to use the Search tool to find the answer to the question.
Action:
{
"action": "Search",
"action_input": "Who is Leo DiCaprio's girlfriend?"
}
Observation: DiCaprio broke up with girlfriend Camila Morrone, 25, in the summer of 2022, after dating for four years. He's since been linked to another famous supermodel – Gigi Hadid. The power couple were first supposedly an item in September after being spotted getting cozy during a party at New York Fashion Week.
Thought:The answer to the question is that Leo DiCaprio's current girlfriend is Gigi Hadid.
Final Answer: Gigi Hadid.

> 完成链。

自定义错误函数

你还可以将错误自定义为一个接受错误并输出字符串的函数。

def _handle_error(error) -> str:
return str(error)[:50]

mrkl = initialize_agent(
tools,
ChatOpenAI(temperature=0),
agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
handle_parsing_errors=_handle_error,
)

mrkl.run("Who is Leo DiCaprio's girlfriend? No need to add Action")
> 进入新的AgentExecutor链...

Observation: Could not parse LLM output: I'm sorry, but I canno
Thought:I need to use the Search tool to find the answer to the question.
Action:
{
"action": "Search",
"action_input": "Who is Leo DiCaprio's girlfriend?"
}
Observation: DiCaprio broke up with girlfriend Camila Morrone, 25, in the summer of 2022, after dating for four years. He's since been linked to another famous supermodel – Gigi Hadid. The power couple were first supposedly an item in September after being spotted getting cozy during a party at New York Fashion Week.
Thought:The current girlfriend of Leonardo DiCaprio is Gigi Hadid.
Final Answer: Gigi Hadid.

> 完成链。