多智能体编排框架学习--Swarm

随着大模型技术越来越成熟,更多的人将目光放在了智能体研发上,智能体依赖于基座大模型的能力,但也更注重协作执行能力,这篇文章我们就来分享一个OpenAI公司开源的多智能体框架--Swarm。

Swarm是一个轻量级、高可控性并且易于测试的agent框架,该框架提出了两个概念:AgentsHandoffs,一个Agent包含了instruction和tools,并且该Agent可在任何时间选择将对话权Handoffs(接力)给另外一个Agent。

一、安装&使用

# 安装需要 Python3.10+

pip install git+ssh://git@github.com/openai/swarm.git

pip install git+https://github.com/openai/swarm.git

# 如果是离线安装,可在github上下载swarm-main.zip,然后运行以下命令

pip install swarm-main.zip

【注意】 安装后需要注意一个地方,Swarm框架会将pip安装的openai依赖包改为1.33.0版本,需要自己再更改为需要的版本。

安装好之后,我们来简单看一下Swarm框架给的官方使用示例。

from swarm import Swarm, Agent

client = Swarm()

def transfer_to_agent_b():
    return agent_b


agent_a = Agent(
    name="Agent A",
    instructions="You are a helpful agent.",
    functions=[transfer_to_agent_b],
)

agent_b = Agent(
    name="Agent B",
    instructions="Only speak in Haikus.",
)

response = client.run(
    agent=agent_a,
    messages=[{"role": "user", "content": "I want to talk to agent B."}],
)

print(response.messages[-1]["content"])


# Result
"""
Hope glimmers brightly,
New paths converge gracefully,
What can I assist?
"""

在这个使用示例里,我们可以看到作者定义了两个Agent:agent_aagent_b。之后,优先将对话权交给了agent_a,并且发送消息"I want to talk to agent B."。agent_a拿到对话权后,会选择调用transfer_to_agent_b函数,并将对话权交给agent_b。agent_b接力后,它的指令是"only speak in Haikus.",因此大模型将以Haikus(三行俳句)的形式输出结果.

上述的例子是基于chatgpt线上服务进行调用的,但我们国内大多数人并不会直接调用chatgpt,我们更多的是使用开源模型本地部署运行。下面我们就来看一下本地运行需要对官方示例修改哪些地方.

"""
Swarm框架给出的版本
"""

from swarm import Swarm, Agent

client = Swarm()


"""
因为Swarm框架中默认调用了chatgpt
如果想改为自己部署的模型需要添加本地模型api
本地模型应为标准openai输入输出,建议使用vllm启动
"""

from swarm import Swarm, Agent

client = Swarm(
    client=OpenAI(
        api_key="123",
        base_url="http://127.0.0.1:9876/v1/"
    )
)
"""
Swarm给出的agent定义
"""
agent_a = Agent(
    name="Agent A",
    instructions="You are a helpful agent.",
    functions=[transfer_to_agent_b],
)

"""
使用本地部署模型时需要写清楚调用的模型名称,该名称与vllm启动名称保持一致
"""
agent_a = Agent(
    name="Agent A",
    model="qwen2.5-14b",
    instructions="You are a helpful agent.",
    functions=[transfer_to_agent_b],
    tool_choice="auto"
)

这样,我们就对Swarm有了一个基本的认识。

二、函数描述

第二部分,我们来看一下swarm框架的代码。

swarm框架的核心代码就是swarm/types.pyswarm/cores.py,这两个代码文件分别实现了对智能体的创建(Agent类)和智能体的交互(Swarm类)。

2.1 client.run()

Swarm的run()函数类似于 Chat Completions API 中chat.completions.create()函数接收并返回messages不记录任何调用之间的状态。同时,run()函数也处理Agent的执行、handoffs(接力)、上下文变量引用,并且可以在返回给用户之前进行多轮对话。

作为Swarm框架的核心,client.run()主要实现了以下内容:

  1. 从当前Agent中获取一个回复。

  2. 执行工具调用并添加结果。

  3. 如果必要可切换调用Agent。

  4. 如有必要可更新上下文变量。

  5. 如果没有新的函数调用则返回结果。

client.run()入参

ArgumentTypeDescriptionDefault
agentAgent初始要调用的代理。(required)
messagesList一个message对象的列表,类似于 Chat Completions API中的message(required)
context_variablesdict一个上下文变量的字典,可用于函数和Agent指令{}
max_turnsint允许的最大会话轮数float("inf")
model_overridestr可选字符串,用于更新Agent使用的模型None
execute_toolsbool如果为False,中断执行并在Agent试图调用函数时立即返回tool_calls消息True
streambool如果为True,启用流式响应False
debugbool如果为True,启用调试日志False

 client.run()响应

FieldTypeDescription
messagesList对话期间生成的消息对象列表。和Chat Completions API中的message非常相似但是有一个sender表示哪个Agent的字段消息来源。
agentAgent最后一个处理消息的Agent。
context_variablesdict和输入变量一样,加上任何变化。

2.2 Agent

Agent简单来说就是指令和函数的集合(加上一些额外的设置),并且有能力将执行权交接给另一个Agent。

Agent类参数说明

FieldTypeDescriptionDefault
namestr代理名称,主要影响sender的输出Agent
modelstragent使用的模型,可参考上面的示例更换为自己部署的模型gpt-4o
instructionsstr or func() -> strAgent的指令,可以是字符串或返回字符串的函数。You are a helpful agent.
functionsListAgent可以调用的函数列表。[]
tool_choicestr如果指定Agent选择某一工具,可填写工具名,否则默认auto。None

三、示例解析

官方在example目录下给出了以下示例

--basic:关于基础概念的简单样例,例如 setup(设置)、function calling(函数调用)、handoffs(接力)和context variables上下文变量。

--triage_agent:一个设置基本分诊步骤交接给正确的Agent的简单示例。

--weather_agent:一个调用function calling的例子。

--airline:一个用于处理航空公司乘警中不同顾客服务请求的多智能体样例。

--support_bot:一个包含用户界面Agent和带有多个工具的帮助中心Agent的客户服务中心。

--personal_shopper:一个个人购物Agent,可以帮助处理销售和退单。

在本小节,我们将基于本地模型(qwen2.5-14b)对Swarm中给出的几个基础示例调用进行解析。

3.1 示例一--Instructions(bar_minimum.py

该示例主要描述了instruction的传递功能,Agent的Instruction会直接转化为对话的system信息。只有当前活动的Agent所给出的Instruction会存在并传递(例如,如果发生了Agent接力,那么system的prompt将会改变,但是聊天历史信息不会)。

from swarm import Swarm, Agent

client = Swarm(
    client=OpenAI(
        api_key="123",
        base_url="http://127.0.0.1:9876/v1/"
    )
)

agent = Agent(
    name="Agent",
    model="qwen2.5-14b",
    instructions="You are a helpful agent.",
)

messages = [{"role": "user", "content": "Hi!"}]
response = client.run(agent=agent, messages=messages)

print(response.messages[-1]["content"])

我们看到每一个Agent都可以定义一个instructions,这样智能体之间接力时就可以很自然的进行instruction更换,做到不同的智能体实现不同的功能。

3.2 示例二--context_variables(context_variables.py

Instruction可以是一个字符串,也可以是一个函数返回的字符串。函数可以选择性的接收context_variables参数,这个参数可以通过client.run()进行传递。

from swarm import Swarm, Agent

client = Swarm(
    client=OpenAI(
        api_key="123",
        base_url="http://127.0.0.1:9876/v1/"
    )
)


def instructions(context_variables):
    name = context_variables.get("name", "User")
    return f"You are a helpful agent. Greet the user by name ({name})."


def print_account_details(context_variables: dict):
    user_id = context_variables.get("user_id", None)
    name = context_variables.get("name", None)
    print(f"Account Details: {name} {user_id}")
    return "Success"


agent = Agent(
    name="Agent",
    model="qwen2.5-14b",
    instructions=instructions,
    functions=[print_account_details],
    tool_choice="auto"
)

context_variables = {"name": "James", "user_id": 123}

response = client.run(
    messages=[{"role": "user", "content": "Hi!"}],
    agent=agent,
    context_variables=context_variables,
)
print(response.messages[-1]["content"])

response = client.run(
    messages=[{"role": "user", "content": "Print my account details!"}],
    agent=agent,
    context_variables=context_variables,
)
print(response.messages[-1]["content"])

【注意】在这个示例中,我们需要注意一个地方,在定义Agent时,应该给tool_choice传递auto值,否则会默认为None,这个在Qwen模型中会报错。function call在使用tool_choice时还可以指定一个tool,但需要以字典形式传递,这种方式Swarm目前是不支持的,因为Swarm代码内将tool_choice定义为了字符串,这块工程化其实是做的比较差的,读者有兴趣的可以自行将代码改为可接受字典的形式。

这个示例展示了context_variable如何进行透传的,我们可以看到不同的函数均可以直接接收传递的context_variables,后续基于用户指令及透传的上下文参数进行用户问题的回答。

3.3 示例三--Functions(function_calling.py

Swarm框架中的Agent可以直接调用python函数,函数通常需要返回字符串,如果一个函数返回了一个Agent,执行将会被转移给那个Agent。

from swarm import Swarm, Agent

client = Swarm(
    client=OpenAI(
        api_key="123",
        base_url="http://127.0.0.1:9876/v1/"
    )
)


def get_weather(location) -> str:
    return "{'temp':67, 'unit':'F'}"


agent = Agent(
    name="Agent",
    model="qwen2.5-14b",
    instructions="You are a helpful agent.",
    functions=[get_weather],
)

messages = [{"role": "user", "content": "What's the weather in NYC?"}]

response = client.run(agent=agent, messages=messages)
print(response.messages[-1]["content"])

与function calling一致,实现了调用函数的意图识别与实体识别,比如这个例子中,识别到了调用get_weather这个函数,并且函数的入参location是NYC。Swarm在这里面有个比较巧妙的构思,我们function calling里面对函数的description可以直接通过get_weather这个函数的注释获取,采用python的内置函数__doc__()。

3.4 示例四--handoffs(agent_handoff.py

一个Agent可以通过函数调用传给另一个Agent,Swarm中将其定义为handoffs(接力)。

from swarm import Swarm, Agent

client = Swarm(
    client=OpenAI(
        api_key="123",
        base_url="http://127.0.0.1:9876/v1/"
    )
)

english_agent = Agent(
    name="English Agent",
    model="qwen2.5-14b",
    instructions="You only speak English.",
    tool_choice="auto"
)

spanish_agent = Agent(
    name="Spanish Agent",
    model="qwen2.5-14b",
    instructions="You only speak Spanish.",
)


def transfer_to_spanish_agent():
    """Transfer spanish speaking users immediately."""
    return spanish_agent


english_agent.functions.append(transfer_to_spanish_agent)

messages = [{"role": "user", "content": "Hola. ¿Como estás?"}]
response = client.run(agent=english_agent, messages=messages)

print(response.messages[-1]["content"])

这个示例可以说是Swarm这个框架的一个核心,解释了多智能体之间是如何进行通信及协作的。首先定义两个agent,english_agent用来用英文回复问题,spanish_agent用来用西班牙语回答问题;然后在english_agent中加入函数transfer_to_spanish_agent,后于后续多智能体的接力。在程序运行时,首先将对话权交给english_agent,但是用户问题是使用西班牙语问的,因此english_agent就会调用transfer_to_spanish_agent,并将对话权交给spanish_agent,最终形成西班牙语的对话形式。

四、总结

就个人理解,Swarm框架并没有给出很多传统意义上的创新型内容,它更多的可能还是通过封装对大模型原生能力的调用,来定义了一个多智能体中的通信协议,为后续建立智能体生态奠定了比较好的基础。正如作者所说,整个项目更偏向于实验性质,因此整个工程代码中仍有不少瑕疵,但瑕不掩瑜,Swarm仍是一个比较好的学习多智能体及多智能体通信的框架。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值