-
Notifications
You must be signed in to change notification settings - Fork 2.9k
/
XMLAgent.py
110 lines (93 loc) · 4.03 KB
/
XMLAgent.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
from typing import List, Optional
from langchain.agents import create_xml_agent
from langchain_core.prompts import ChatPromptTemplate
from langflow.base.agents.agent import LCAgentComponent
from langflow.field_typing import LanguageModel, Text, Tool
from langflow.schema import Data
class XMLAgentComponent(LCAgentComponent):
display_name = "XMLAgent"
description = "Construct an XML agent from an LLM and tools."
def build_config(self):
return {
"llm": {"display_name": "LLM"},
"tools": {"display_name": "Tools"},
"user_prompt": {
"display_name": "Prompt",
"multiline": True,
"info": "This prompt must contain 'tools' and 'agent_scratchpad' keys.",
"value": """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}""",
},
"system_message": {
"display_name": "System Message",
"info": "System message to be passed to the LLM.",
"advanced": True,
},
"tool_template": {
"display_name": "Tool Template",
"info": "Template for rendering tools in the prompt. Tools have 'name' and 'description' keys.",
"advanced": True,
},
"handle_parsing_errors": {
"display_name": "Handle Parsing Errors",
"info": "If True, the agent will handle parsing errors. If False, the agent will raise an error.",
"advanced": True,
},
"message_history": {
"display_name": "Message History",
"info": "Message history to pass to the agent.",
},
"input_value": {
"display_name": "Inputs",
"info": "Input text to pass to the agent.",
},
}
async def build(
self,
input_value: str,
llm: LanguageModel,
tools: List[Tool],
user_prompt: str = "{input}",
system_message: str = "You are a helpful assistant",
message_history: Optional[List[Data]] = None,
tool_template: str = "{name}: {description}",
handle_parsing_errors: bool = True,
) -> Text:
if "input" not in user_prompt:
raise ValueError("Prompt must contain 'input' key.")
def render_tool_description(tools):
return "\n".join(
[tool_template.format(name=tool.name, description=tool.description, args=tool.args) for tool in tools]
)
messages = [
("system", system_message),
(
"placeholder",
"{chat_history}",
),
("human", user_prompt),
("placeholder", "{agent_scratchpad}"),
]
prompt = ChatPromptTemplate.from_messages(messages)
agent = create_xml_agent(llm, tools, prompt, tools_renderer=render_tool_description)
result = await self.run_agent(
agent=agent,
inputs=input_value,
tools=tools,
message_history=message_history,
handle_parsing_errors=handle_parsing_errors,
)
self.status = result
return result