swarms 框架 OneToOne 指南:双智能体一对一对话模式详解
【免费下载链接】swarmsThe Enterprise-Grade Multi-Agent Orchestration Framework. Website: https://swarms.ai项目地址: https://gitcode.com/GitHub_Trending/swar/swarms
本文围绕 swarms 多智能体编排框架中的OneToOne模式展开,讲解如何在共享会话(conversation)上让两个智能体交替发言、反复交换观点直至完成任务。读完本文,你将掌握类式(可复用)与函数式(单次调用)两种用法、max_loops轮次控制、output_type输出格式体系,以及底层“角色化消息投递”的实现原理,可直接照抄示例跑通自己的写手-编辑、分析师-质疑者等双角色协作场景。
一、OneToOne 是什么:共享会话上的两人对话
OneToOne是 swarms 中最小粒度的多智能体协作模式。它把两个Agent放进同一条Conversation(共享会话),按固定顺序交替发言:
- 发送方(sender)先回答问题;
- 接收方(receiver)回应发送方;
- 整个交换按
max_loops参数重复指定轮数。
关键设计在于每个智能体都能把共享会话读取为“带角色的聊天轮次”:自己的历史消息被标成assistant轮次,对方的消息被标成带对方名字的user轮次(如Editor: needs a stronger opening)。这样模型既能分辨“哪些话是自己说的”,也能看到对话的完整来龙去脉,而不是把所有内容都混成一条无差别的user消息。
源码位置:swarms/structs/one_to_one.py,其中
one_to_one函数与OneToOne类共同实现该模式。
二、两种用法:类式OneToOne与函数式one_to_one
仓库在 examples/multi_agent/one_to_one_examples/README.md 中给出了两种入口:
| 形式 | 入口 | 适用场景 | 示例模型 |
|---|---|---|---|
| 类式 | OneToOne(可复用对象) | 同一对智能体要反复执行多个任务 | OpenAIgpt-5.4 |
| 函数式 | one_to_one()(单次调用) | 只需要执行一轮独立交换 | Anthropicclaude-sonnet-4-6 |
最小示例:
from swarms import Agent, OneToOne, one_to_one pair = OneToOne(sender=writer, receiver=editor, output_type="dict") history = pair.run("Write a tagline.", max_loops=2) # 或者,只交换一次 history = one_to_one(writer, editor, "Write a tagline.")两种形式最终都返回会话历史(历史格式由output_type决定)。类式本质上是函数式的“可复用外壳”:OneToOne在构造时保存sender、receiver、output_type等配置,run()内部直接委托给one_to_one()(见 swarms/structs/one_to_one.py),因此同一个pair可以对不同任务反复调用而无需重建。
三、类式示例:写手与编辑的反复打磨
完整代码见 one_to_one_class_example.py:
from swarms import Agent, OneToOne writer = Agent( agent_name="Writer", system_prompt="You write short product taglines. Reply with one tagline.", model_name="gpt-5.4", max_loops=1, print_on=False, ) editor = Agent( agent_name="Editor", system_prompt="You are a strict editor. Rewrite the tagline to be shorter and punchier.", model_name="gpt-5.4", max_loops=1, print_on=False, ) pair = OneToOne( sender=writer, receiver=editor, name="Tagline-Pair", description="A writer drafts, an editor tightens.", output_type="dict", ) history = pair.run( "Write a tagline for a password manager.", max_loops=2 ) for message in history: print(f"[{message['role']}] {message['content']}\n")要点拆解:
- 两个 Agent 的
agent_name不同(Writer/Editor)。这个名称就是共享会话里的“角色标识”,OneToOne依赖它来区分消息归属,务必保持唯一。 - 每个 Agent 的
max_loops=1:这里的max_loops控制单个 Agent 内部自循环的次数;而OneToOne.run()的max_loops=2控制的是“发送方+接收方”这一完整交换对重复的次数,两者含义不同,不要混淆。 print_on=False:关闭 Agent 运行时的控制台打印,便于自己接管输出。若希望实时看到每轮输出,可改为print_on=True。name与description:为这个通信模式命名并说明用途,方便在更复杂的编排中标识。
由于output_type="dict",history是字典列表,每个元素形如{"role": "Writer", "content": "..."},所以示例用message['role']和message['content']遍历打印。
四、函数式示例:分析师与质疑者的单轮交锋
完整代码见 one_to_one_function_example.py:
from swarms import Agent, one_to_one analyst = Agent( agent_name="Analyst", system_prompt="You summarise a company's position in two sentences.", model_name="claude-sonnet-4-6", max_loops=1, print_on=False, ) skeptic = Agent( agent_name="Skeptic", system_prompt="You point out the single biggest risk in the analyst's summary.", model_name="claude-sonnet-4-6", max_loops=1, print_on=False, ) result = one_to_one( sender=analyst, receiver=skeptic, task="Assess a mid-size airline expanding into long-haul routes.", max_loops=1, output_type="str", ) print(result)函数式的参数更扁平:task直接作为首个任务传入,max_loops=1表示只做“分析师作答 → 质疑者反驳”这一轮;output_type="str"让返回结果直接是可打印的字符串。同样地,发送方先基于task作答,接收方回应的是发送方的回答,而非原始任务本身。
五、参数与返回格式详解
5.1 函数式one_to_one()签名
对应源码 swarms/structs/one_to_one.py:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
sender | Agent | 必填 | 先发言的智能体 |
receiver | Agent | 必填 | 回应发送方的智能体 |
task | str | 必填 | 要处理的任务文本 |
max_loops | int | 1 | 发送方/接收方的交换轮数 |
output_type | OutputType | "dict" | 返回历史格式 |
校验逻辑:sender、receiver、task任一为空都会抛出ValueError("Sender, receiver, and task cannot be empty.")。测试 tests/structs/test_one_to_one.py 专门验证了空任务被拒绝。
5.2 类式OneToOne构造参数
对应源码 swarms/structs/one_to_one.py:
| 参数 | 默认值 | 说明 |
|---|---|---|
sender | 必填 | 发送方 Agent |
receiver | 必填 | 接收方 Agent |
name | "OneToOne" | 通信模式名称 |
description | "A one-to-one communication pattern between two agents" | 用途描述 |
output_type | "dict" | 输出格式 |
类实例通过run(task, max_loops=1)执行任务,方法签名与函数式完全对齐。
5.3output_type支持的全部格式
OneToOne与one_to_one的返回值由history_output_formatter统一处理(见 swarms/utils/history_output_formatter.py),类型声明位于 swarms/utils/output_types.py。支持以下取值:
| 取值 | 返回内容 |
|---|---|
list | 消息字典列表 |
dict/dictionary | 整个会话转字典 |
string/str/all | 会话拼接字符串 |
final/last | 最后一条消息的内容 |
json | 会话的 JSON 字符串 |
yaml | 会话字典的 YAML 字符串 |
xml | 以conversation为根标签的 XML 字符串 |
dict-all-except-first | 除首条外全部消息转字典 |
str-all-except-first | 除首条外全部消息转字符串 |
dict-final | 最后一条消息转字典 |
list-final | 最后一条消息转列表 |
basemodel | 基础模型对象 |
传入未知类型会抛出ValueError(f"Invalid type: {type}")。
六、底层原理:共享会话如何被“角色化”投递
one_to_one()的执行主循环(swarms/structs/one_to_one.py)非常简洁:
conversation = Conversation() conversation.add(role="User", content=task) for _ in range(max_loops): run_on_conversation(sender, conversation) run_on_conversation(receiver, conversation)任务先以User角色写入会话,随后每个循环内发送方、接收方轮流执行一次。真正的消息投递逻辑在 swarms/structs/context_utils.py 的三个函数中:
messages_for(agent_name, conversation)(swarms/structs/context_utils.py):把共享会话从某个智能体的视角重写为聊天轮次——自己的消息变成assistant,对方消息变成带名字前缀的user(如Editor: ...),系统级结构消息(如团队名单)被过滤掉。这就是 README 所说“每个智能体以带角色的轮次读取会话、能区分自己的历史消息”的实现基础。split_last_turn(messages, fallback)(swarms/structs/context_utils.py):把最新一轮消息拆出来作为本次task,其余作为prior历史传给agent.run(task=..., messages=prior)。这保证了“接收方回应的是发送方的最新消息,而不是原始任务”。agent_answer(agent, fallback)(swarms/structs/context_utils.py):由于Agent.run()默认按output_type返回整个会话而非本轮回答,agent_answer负责从中提取出本轮真正的答案文本,再写回共享会话(conversation.add(agent.agent_name, answer)),供下一轮读取。
这套“角色化”设计还有两个额外收益:模型能稳定区分自己与对方的发言;请求保持稳定的前缀结构,有利于 prompt 缓存(源码注释中明确提到 “keeps a stable prefix for caching”)。
七、行为验证:测试如何锁定语义
仓库用 tests/structs/test_one_to_one.py 通过一个记录调用历史的EchoAgent锁定了该模式的核心语义:
- 消息顺序(test_one_to_one_records_user_sender_receiver):一次交换后历史角色序列必须为
["User", "Sender", "Receiver"],且接收方收到的任务里包含发送方的回答。 - 轮次交替(test_one_to_one_loops_alternate):
max_loops=2时角色序列为["User", "Sender", "Receiver", "Sender", "Receiver"],且第二轮发送方在回应接收方的回复。 - 空任务校验(test_one_to_one_rejects_empty_task):空任务抛
ValueError。 - 类与函数等价(test_one_to_one_class_matches_function):类式结果与函数式一致。
- 可复用性(test_one_to_one_class_reusable_across_tasks):同一个
pair跑第二个任务时,会话以新任务开头、长度不累积(每个run()内部新建Conversation,不会把上一任务的历史带进下一任务)。
另外,tests/structs/test_swarm_architectures.py 也在架构测试中调用了one_to_one,验证其可嵌入更大规模的编排。
八、模型配置与运行环境
示例中模型均以普通 LiteLLM 字符串指定(如gpt-5.4、claude-sonnet-4-6),这意味着:
- 你可以把
model_name换成任何你持有 API Key 的提供商模型; - 使用 OpenRouter 模型时需要设置环境变量
OPENROUTER_API_KEY; - 运行前请确认对应提供商的 API Key 已通过环境变量正确配置(swarms 启动时会读取环境配置,参见 swarms/env.py)。
需要git clone仓库后自行运行示例时,克隆地址为https://gitcode.com/GitHub_Trending/swar/swarms;随后参照 pyproject.toml 与 requirements.txt 安装依赖,即可直接执行one_to_one_class_example.py与one_to_one_function_example.py复现文中的写手-编辑、分析师-质疑者两类双智能体协作流程。
【免费下载链接】swarmsThe Enterprise-Grade Multi-Agent Orchestration Framework. Website: https://swarms.ai项目地址: https://gitcode.com/GitHub_Trending/swar/swarms
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考