单个智能体通常可以在单个领域内使用少量工具有效地操作,但即使使用像GPT-4这样强大的模型,它在使用许多工具时也可能效果不佳。
处理复杂任务的一种方法是通过“分而治之”的方式:为每个任务或领域创建一个专门的智能体,并将任务路由到正确的“专家”。这是多智能体网络架构的一个示例。
本笔记本(灵感来自Wu等人的论文《AutoGen: 通过多智能体对话实现下一代LLM应用》)展示了如何使用LangGraph实现这一点。
生成的图将类似于以下图表:
多智能体图
在我们开始之前,快速说明一下:本笔记本和其他多智能体笔记本旨在展示如何在LangGraph中实现某些设计模式。如果该模式符合您的需求,我们建议将其与文档中描述的其他基本模式结合使用,以获得最佳性能。
首先,让我们安装所需的包并设置API密钥:
python%%capture --no-stderr
%pip install -U langchain_community langchain_anthropic langchain_experimental matplotlib langgraph
import getpass
import os
def _set_if_undefined(var: str):
if not os.environ.get(var):
os.environ[var] = getpass.getpass(f"Please provide your {var}")
_set_if_undefined("ANTHROPIC_API_KEY")
_set_if_undefined("TAVILY_API_KEY")
为LangGraph开发设置LangSmith
注册LangSmith以快速发现问题并提高LangGraph项目的性能。LangSmith允许您使用跟踪数据来调试、测试和监控使用LangGraph构建的LLM应用程序——阅读更多关于如何开始的信息。
我们还将定义一些工具,供我们的智能体将来使用:
pythonfrom typing import Annotated
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.tools import tool
from langchain_experimental.utilities import PythonREPL
tavily_tool = TavilySearchResults(max_results=5)
# 警告:此代码在本地执行,未沙盒化时可能不安全
repl = PythonREPL()
@tool
def python_repl_tool(
code: Annotated[str, "The python code to execute to generate your chart."],
):
"""使用此工具执行Python代码。如果你想查看某个值的输出,你应该使用`print(...)`打印出来。用户可以看到此输出。"""
try:
result = repl.run(code)
except BaseException as e:
return f"Failed to execute. Error: {repr(e)}"
result_str = f"Successfully executed:\n\`\`\`python\n{code}\n\`\`\`\nStdout: {result}"
return (
result_str + "\n\nIf you have completed all tasks, respond with FINAL ANSWER."
)
现在我们已经定义了工具并创建了一些辅助函数,我们将创建各个智能体,并使用LangGraph告诉它们如何相互通信。
我们现在需要定义节点。
首先,我们将创建一个实用程序来为每个智能体生成系统提示。
pythondef make_system_prompt(suffix: str) -> str:
return (
"You are a helpful AI assistant, collaborating with other assistants."
" Use the provided tools to progress towards answering the question."
" If you are unable to fully answer, that's OK, another assistant with different tools "
" will help where you left off. Execute what you can to make progress."
" If you or any of the other assistants have the final answer or deliverable,"
" prefix your response with FINAL ANSWER so the team knows to stop."
f"\n{suffix}"
)
from typing import Literal
from langchain_core.messages import BaseMessage, HumanMessage
from langchain_anthropic import ChatAnthropic
from langgraph.prebuilt import create_react_agent
from langgraph.graph import MessagesState, END
from langgraph.types import Command
llm = ChatAnthropic(model="claude-3-5-sonnet-latest")
def get_next_node(last_message: BaseMessage, goto: str):
if "FINAL ANSWER" in last_message.content:
# 任何智能体决定工作已完成
return END
return goto
# 研究智能体和节点
research_agent = create_react_agent(
llm,
tools=[tavily_tool],
prompt=make_system_prompt(
"You can only do research. You are working with a chart generator colleague."
),
)
def research_node(
state: MessagesState,
) -> Command[Literal["chart_generator", END]]:
result = research_agent.invoke(state)
goto = get_next_node(result["messages"][-1], "chart_generator")
# 包装在人类消息中,因为并非所有提供程序都允许
# 在输入消息列表的最后位置使用AI消息
result["messages"][-1] = HumanMessage(
content=result["messages"][-1].content, name="researcher"
)
return Command(
update={
# 与其他智能体共享研究智能体的内部消息历史
"messages": result["messages"],
},
goto=goto,
)
# 图表生成智能体和节点
# 注意:此操作执行任意代码执行,未沙盒化时可能不安全
chart_agent = create_react_agent(
llm,
[python_repl_tool],
prompt=make_system_prompt(
"You can only generate charts. You are working with a researcher colleague."
),
)
def chart_node(state: MessagesState) -> Command[Literal["researcher", END]]:
result = chart_agent.invoke(state)
goto = get_next_node(result["messages"][-1], "researcher")
# 包装在人类消息中,因为并非所有提供程序都允许
# 在输入消息列表的最后位置使用AI消息
result["messages"][-1] = HumanMessage(
content=result["messages"][-1].content, name="chart_generator"
)
return Command(
update={
# 与其他智能体共享图表生成智能体的内部消息历史
"messages": result["messages"],
},
goto=goto,
)
我们现在可以将所有内容放在一起并定义图!
pythonfrom langgraph.graph import StateGraph, START
workflow = StateGraph(MessagesState)
workflow.add_node("researcher", research_node)
workflow.add_node("chart_generator", chart_node)
workflow.add_edge(START, "researcher")
graph = workflow.compile()
图创建完成后,您可以调用它!让我们用它来绘制一些统计数据。
pythonevents = graph.stream(
{
"messages": [
(
"user",
"First, get the UK's GDP over the past 5 years, then make a line chart of it. "
"Once you make the chart, finish.",
)
],
},
# 图中执行的最大步骤数
{"recursion_limit": 150},
)
for s in events:
print(s)
print("----")
输出结果将显示智能体之间的交互过程,最终生成一个包含英国过去5年GDP数据的折线图。
本文作者:yowayimono
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!