我正在运行“基本多代理协作”的示例 LangChain/LangGraph 代码。我从here(Github)获得了示例。还有一个博客文章/视频。
配置本地虚拟环境并复制粘贴笔记本后,一切正常。
在同一个虚拟环境中,我正在调整代码以避免使用 Jupyter Notebook。为此,我将代码解耦到一些类中。
原始代码(工作):
# Helper function to create a node for a given agent
def agent_node(state, agent, name):
result = agent.invoke(state)
# We convert the agent output into a format that is suitable to append to the global state
if isinstance(result, FunctionMessage):
pass
else:
result = HumanMessage(**result.dict(exclude={"type", "name"}), name=name)
return {
"messages": [result],
# Since we have a strict workflow, we can
# track the sender so we know who to pass to next.
"sender": name,
}
llm = ChatOpenAI(model="gpt-3.5-turbo", openai_api_key=open_ai_key)
# Research agent and node
research_agent = create_agent(
llm,
[search],
system_message="You should provide accurate data for the chart generator to use.",
)
research_node = functools.partial(agent_node, agent=research_agent, name="Researcher")
# Chart Generator
chart_agent = create_agent(
llm,
[python_repl],
system_message="Any charts you display will be visible by the user.",
)
chart_node = functools.partial(agent_node, agent=chart_agent, name="Chart Generator")
#...some other cells
for s in graph.stream(
{
"messages": [
HumanMessage(
content="Fetch the UK's GDP over the past 5 years,"
" then draw a line graph of it."
" Once you code it up, finish."
)
],
},
# Maximum number of steps to take in the graph
{"recursion_limit": 100},
):
print(s)
print("----")
我的改编版本(不起作用):
节点.py
class Nodes:
def __init__(self, llm, tools):
self.llm = llm
self.tools = tools
def agent_node(state, agent, name):
result = agent.invoke(state)
if isinstance(result, FunctionMessage):
pass
else:
result = HumanMessage(**result.dict(exclude={"type", "name"}), name=name)
return {
"messages": [result],
# track the sender so we know who to pass to next.
"sender": name,
}
def research_agent_node(self):
research_agent = create_agent(
self.llm,
[self.tools[0]],
system_message="You should provide accurate data for the chart generator to use.",
)
return functools.partial(self.agent_node, agent=research_agent, name="Researcher")
def chart_generator_node(self):
chart_agent = create_agent(
self.llm,
[self.tools[0]],
system_message="Any charts you display will be visible by the user.",
)
return functools.partial(self.agent_node, agent=chart_agent, name="Chart Generator")
主.py
# Get the agent and tool nodes
nodes = Nodes(llm, tools)
research_agent_node = nodes.research_agent_node()
chart_agent_node = nodes.chart_generator_node()
#...more code
for s in graph.stream(
{
"messages": [
HumanMessage(
content="Fetch the UK's GDP over the past 5 years,"
" then draw a line graph of it."
" Once you code it up, finish."
)
],
},
# Maximum number of steps to take in the graph
{"recursion_limit": 100},
):
print(s)
print("----")
错误消息是
TypeError: Nodes.agent_node() got multiple values for argument 'agent'
,它很容易理解,但很难调试。也许我误解了如何返回functools.partial
,但我不知道如何验证它。
对于那些面临类似问题的人,解决方案是将
agent_node
函数转换为静态。
节点.py
@staticmethod
def agent_node(state, agent, name):
result = agent.invoke(state)
if isinstance(result, FunctionMessage):
pass
else:
result = HumanMessage(**result.dict(exclude={"type", "name"}), name=name)
return {
"messages": [result],
# track the sender so we know who to pass to next.
"sender": name,
}
# ... same code
return functools.partial(Node.agent_node, agent=research_agent, name="Researcher")
问题的发生是因为我使用了agent_node方法作为实例方法,它自动将
self
作为第一个参数。这打乱了参数的顺序(self
被用作state
,而第二个参数,即state,
导致了重复参数的错误消息)。