| import json |
| import re |
| from typing import Pattern, Union |
|
|
| from langchain_core.agents import AgentAction, AgentFinish |
| from langchain_core.exceptions import OutputParserException |
|
|
| from langchain.agents.agent import AgentOutputParser |
| from langchain.agents.chat.prompt import FORMAT_INSTRUCTIONS |
|
|
| FINAL_ANSWER_ACTION = "Final Answer:" |
|
|
|
|
| class ChatOutputParser(AgentOutputParser): |
| """Output parser for the chat agent.""" |
|
|
| format_instructions: str = FORMAT_INSTRUCTIONS |
| """Default formatting instructions""" |
|
|
| pattern: Pattern = re.compile(r"^.*?`{3}(?:json)?\n(.*?)`{3}.*?$", re.DOTALL) |
| """Regex pattern to parse the output.""" |
|
|
| def get_format_instructions(self) -> str: |
| """Returns formatting instructions for the given output parser.""" |
| return self.format_instructions |
|
|
| def parse(self, text: str) -> Union[AgentAction, AgentFinish]: |
| """Parse the output from the agent into |
| an AgentAction or AgentFinish object. |
| |
| Args: |
| text: The text to parse. |
| |
| Returns: |
| An AgentAction or AgentFinish object. |
| |
| Raises: |
| OutputParserException: If the output could not be parsed. |
| ValueError: If the action could not be found. |
| """ |
|
|
| includes_answer = FINAL_ANSWER_ACTION in text |
| try: |
| found = self.pattern.search(text) |
| if not found: |
| |
| raise ValueError("action not found") |
| action = found.group(1) |
| response = json.loads(action.strip()) |
| includes_action = "action" in response |
| if includes_answer and includes_action: |
| raise OutputParserException( |
| "Parsing LLM output produced a final answer " |
| f"and a parse-able action: {text}" |
| ) |
| return AgentAction( |
| response["action"], response.get("action_input", {}), text |
| ) |
|
|
| except Exception as exc: |
| if not includes_answer: |
| raise OutputParserException( |
| f"Could not parse LLM output: {text}" |
| ) from exc |
| output = text.split(FINAL_ANSWER_ACTION)[-1].strip() |
| return AgentFinish({"output": output}, text) |
|
|
| @property |
| def _type(self) -> str: |
| return "chat" |
|
|