Source code for langchain.agents.xml.base

from typing import Any, List, Sequence, Tuple, Union

from langchain_core._api import deprecated
from langchain_core.agents import AgentAction, AgentFinish
from langchain_core.callbacks import Callbacks
from langchain_core.language_models import BaseLanguageModel
from langchain_core.prompts.base import BasePromptTemplate
from langchain_core.prompts.chat import AIMessagePromptTemplate, ChatPromptTemplate
from langchain_core.runnables import Runnable, RunnablePassthrough
from langchain_core.tools import BaseTool

from langchain.agents.agent import BaseSingleActionAgent
from langchain.agents.format_scratchpad import format_xml
from langchain.agents.output_parsers import XMLAgentOutputParser
from langchain.agents.xml.prompt import agent_instructions
from langchain.chains.llm import LLMChain
from langchain.tools.render import ToolsRenderer, render_text_description


[docs]@deprecated("0.1.0", alternative="create_xml_agent", removal="0.3.0") class XMLAgent(BaseSingleActionAgent): """代理程序使用XML标记。 参数: 工具:代理程序可以选择的工具列表 llm_chain:调用以预测下一步动作的LLMChain 示例: .. code-block:: python from langchain.agents import XMLAgent from langchain 工具 = ... 模型 =""" tools: List[BaseTool] """代理程序可以访问的工具列表。""" llm_chain: LLMChain """用于预测动作的链。""" @property def input_keys(self) -> List[str]: return ["input"]
[docs] @staticmethod def get_default_prompt() -> ChatPromptTemplate: base_prompt = ChatPromptTemplate.from_template(agent_instructions) return base_prompt + AIMessagePromptTemplate.from_template( "{intermediate_steps}" )
[docs] @staticmethod def get_default_output_parser() -> XMLAgentOutputParser: return XMLAgentOutputParser()
[docs] def plan( self, intermediate_steps: List[Tuple[AgentAction, str]], callbacks: Callbacks = None, **kwargs: Any, ) -> Union[AgentAction, AgentFinish]: log = "" for action, observation in intermediate_steps: log += ( f"<tool>{action.tool}</tool><tool_input>{action.tool_input}" f"</tool_input><observation>{observation}</observation>" ) tools = "" for tool in self.tools: tools += f"{tool.name}: {tool.description}\n" inputs = { "intermediate_steps": log, "tools": tools, "question": kwargs["input"], "stop": ["</tool_input>", "</final_answer>"], } response = self.llm_chain(inputs, callbacks=callbacks) return response[self.llm_chain.output_key]
[docs] async def aplan( self, intermediate_steps: List[Tuple[AgentAction, str]], callbacks: Callbacks = None, **kwargs: Any, ) -> Union[AgentAction, AgentFinish]: log = "" for action, observation in intermediate_steps: log += ( f"<tool>{action.tool}</tool><tool_input>{action.tool_input}" f"</tool_input><observation>{observation}</observation>" ) tools = "" for tool in self.tools: tools += f"{tool.name}: {tool.description}\n" inputs = { "intermediate_steps": log, "tools": tools, "question": kwargs["input"], "stop": ["</tool_input>", "</final_answer>"], } response = await self.llm_chain.acall(inputs, callbacks=callbacks) return response[self.llm_chain.output_key]
[docs]def create_xml_agent( llm: BaseLanguageModel, tools: Sequence[BaseTool], prompt: BasePromptTemplate, tools_renderer: ToolsRenderer = render_text_description, *, stop_sequence: Union[bool, List[str]] = True, ) -> Runnable: """创建一个使用XML格式化其逻辑的代理。 参数: llm:LLM,用作代理。 tools:此代理可以访问的工具。 prompt:要使用的提示,必须具有输入键 `tools`:包含每个工具的描述。 `agent_scratchpad`:包含先前代理操作和工具输出。 tools_renderer:控制工具如何转换为字符串,然后传递给LLM。默认为`render_text_description`。 stop_sequence:布尔值或字符串列表。 如果为True,则添加一个停止标记"</tool_input>"以避免产生幻觉。 如果为False,则不添加停止标记。 如果为字符串列表,则使用提供的列表作为停止标记。 默认为True。如果您使用的LLM不支持停止序列,则可以将其设置为False。 返回: 代表代理的可运行序列。它接受与传递的提示相同的所有输入变量。它返回一个AgentAction或AgentFinish。 示例: .. code-block:: python from langchain import hub from langchain_community.chat_models import ChatAnthropic from langchain.agents import AgentExecutor, create_xml_agent prompt = hub.pull("hwchase17/xml-agent-convo") model = ChatAnthropic(model="claude-3-haiku-20240307") tools = ... agent = create_xml_agent(model, tools, prompt) agent_executor = AgentExecutor(agent=agent, tools=tools) agent_executor.invoke({"input": "hi"}) # 与聊天历史一起使用 from langchain_core.messages import AIMessage, HumanMessage agent_executor.invoke( { "input": "what's my name?", # 请注意,chat_history是一个字符串 # 因为此提示针对LLMs,而不是聊天模型 "chat_history": "Human: My name is Bob\nAI: Hello Bob!", } ) 提示: 提示必须具有以下输入键: * `tools`:包含每个工具的描述。 * `agent_scratchpad`:包含先前代理操作和工具输出的XML字符串。 这里有一个示例: .. code-block:: python from langchain_core.prompts import PromptTemplate template = '''You are a helpful assistant. Help the user answer any questions. You have access to the following tools: {tools} In order to use a tool, you can use <tool></tool> and <tool_input></tool_input> tags. You will then get back a response in the form <observation></observation> For example, if you have a tool called 'search' that could run a google search, in order to search for the weather in SF you would respond: <tool>search</tool><tool_input>weather in SF</tool_input> <observation>64 degrees</observation> When you are done, respond with a final answer between <final_answer></final_answer>. For example: <final_answer>The weather in SF is 64 degrees</final_answer> Begin! Previous Conversation: {chat_history} Question: {input} {agent_scratchpad}''' prompt = PromptTemplate.from_template(template) """ # noqa: E501 missing_vars = {"tools", "agent_scratchpad"}.difference( prompt.input_variables + list(prompt.partial_variables) ) if missing_vars: raise ValueError(f"Prompt missing required variables: {missing_vars}") prompt = prompt.partial( tools=tools_renderer(list(tools)), ) if stop_sequence: stop = ["</tool_input>"] if stop_sequence is True else stop_sequence llm_with_stop = llm.bind(stop=stop) else: llm_with_stop = llm agent = ( RunnablePassthrough.assign( agent_scratchpad=lambda x: format_xml(x["intermediate_steps"]), ) | prompt | llm_with_stop | XMLAgentOutputParser() ) return agent