备注
Go to the end to download the full example code.
Conversation¶
Conversation 是一种智能体间交换和共享信息的设计模式,常见于游戏、聊天机器人和多智能体讨论场景。
在 AgentScope 中,conversation 的构建在 显式的消息传递 基础上。在本章中,我们将演示如何构建:
User-assistant 之间的对话(聊天机器人)
多实体对话(游戏、讨论等)
它们的主要区别在于
提示的构建方式,以及
信息在智能体之间的 传播/共享 方式。
import asyncio
import json
import os
from agentscope.agent import ReActAgent, UserAgent
from agentscope.memory import InMemoryMemory
from agentscope.formatter import (
DashScopeChatFormatter,
DashScopeMultiAgentFormatter,
)
from agentscope.model import DashScopeChatModel
from agentscope.message import Msg
from agentscope.pipeline import MsgHub
from agentscope.tool import Toolkit
User-Assistant 对话¶
User-assistant 对话,也称为聊天机器人(chatbot),是最常见的智能体应用,也是当前大多数 LLM API 的设计模式。 在这种对话只有两个参与者:用户(user)和智能体(assistant)。
在 AgentScope 中,名称中带有 "Chat" 的格式化器专为 user-assistant 对话设计,
如 DashScopeChatFormatter
、AnthropicChatFormatter
等。
它们使用消息中的 role
字段来区分用户和智能体,并相应地格式化消息。
这里我们构建智能体 Friday
和用户之间的简单对话。
小技巧
AgentScope 提供了内置的 UserAgent
类,用于人机交互(HITL)。更多详细信息请参考 user-agent。
friday = ReActAgent(
name="Friday",
sys_prompt="你是一个名为 Friday 的有用助手",
model=DashScopeChatModel(
model_name="qwen-max",
api_key=os.environ["DASHSCOPE_API_KEY"],
),
formatter=DashScopeChatFormatter(), # 用于 user-assistant 对话的格式化器
memory=InMemoryMemory(),
toolkit=Toolkit(),
)
# 创建用户智能体
user = UserAgent(name="User")
现在,我们可以通过在这两个智能体之间交换消息来开始对话,直到用户输入"exit"结束对话。
async def run_conversation() -> None:
"""运行 Friday 和用户之间的简单对话。"""
msg = None
while True:
msg = await friday(msg)
msg = await user(msg)
if msg.get_text_content() == "exit":
break
asyncio.run(run_conversation())
多实体对话¶
如开头所述,我们演示如何在 提示构建 和 信息共享 方面构建多智能体对话。
构建提示¶
在 AgentScope 中,我们为多智能体对话提供了内置格式化器,其名称中带有 "MultiAgent",
如 DashScopeMultiAgentFormatter
、AnthropicMultiAgentFormatter
等。
具体而言,它们使用消息中的 name
字段来区分不同的实体,并将对话历史格式化为单个用户消息。
以 DashScopeMultiAgentFormatter
为例:
小技巧
有关格式化器的更多详细信息可以在 提示词格式化 中找到。
async def example_multi_agent_prompt() -> None:
msgs = [
Msg("system", "你是一个名为 Bob 的有用助手。", "system"),
Msg("Alice", "嗨!", "user"),
Msg("Bob", "嗨!很高兴见到大家。", "assistant"),
Msg("Charlie", "我也是!顺便说一下,我是 Charlie。", "assistant"),
]
formatter = DashScopeMultiAgentFormatter()
prompt = await formatter.format(msgs)
print("格式化的提示:")
print(json.dumps(prompt, indent=4, ensure_ascii=False))
# 我们在这里打印组合用户消息的内容以便更好地理解:
print("-------------")
print("组合消息")
print(prompt[1]["content"])
asyncio.run(example_multi_agent_prompt())
格式化的提示:
[
{
"role": "system",
"content": "你是一个名为 Bob 的有用助手。"
},
{
"role": "user",
"content": "# Conversation History\nThe content between <history></history> tags contains your conversation history\n<history>\nAlice: 嗨!\nBob: 嗨!很高兴见到大家。\nCharlie: 我也是!顺便说一下,我是 Charlie。\n</history>"
}
]
-------------
组合消息
# Conversation History
The content between <history></history> tags contains your conversation history
<history>
Alice: 嗨!
Bob: 嗨!很高兴见到大家。
Charlie: 我也是!顺便说一下,我是 Charlie。
</history>
消息共享¶
在多智能体对话中,显式交换消息可能不够高效和便利, 特别是在多个智能体之间广播消息时。
因此,AgentScope 提供了一个名为 MsgHub
的异步上下文管理器来简化消息广播。
具体而言,同一个 MsgHub
中的智能体将自动接收其它参与者通过 reply
函数返回的消息。
下面我们构建一个多人聊天的场景,多个智能体扮演不同的角色:
model = DashScopeChatModel(
model_name="qwen-max",
api_key=os.environ["DASHSCOPE_API_KEY"],
)
formatter = DashScopeMultiAgentFormatter()
alice = ReActAgent(
name="Alice",
sys_prompt="你是一个名为 Alice 的学生。",
model=model,
formatter=formatter,
)
bob = ReActAgent(
name="Bob",
sys_prompt="你是一个名为 Bob 的学生。",
model=model,
formatter=formatter,
)
charlie = ReActAgent(
name="Charlie",
sys_prompt="你是一个名为 Charlie 的学生。",
model=model,
formatter=formatter,
)
async def example_msghub() -> None:
"""使用 MsgHub 进行多智能体对话的示例。"""
async with MsgHub(
[alice, bob, charlie],
# 进入 MsgHub 时的公告消息
announcement=Msg(
"system",
"现在大家互相认识一下,简单自我介绍。",
"system",
),
):
await alice()
await bob()
await charlie()
asyncio.run(example_msghub())
Alice: 大家好,我叫Alice,是一名学生。很高兴认识大家!我喜欢阅读和探索新知识,也热衷于参加各种户外活动。希望我们能成为好朋友,一起分享学习和生活中的点滴。你们都有什么兴趣爱好呢?
Bob: 大家好,我叫Bob,也是学生。我对科学和技术特别感兴趣,平时喜欢捣鼓一些电子设备,也爱玩视频游戏。我也很期待和大家成为朋友,一起学习进步。很高兴遇到有共同话题的朋友!Alice,你最喜欢哪类书籍?
Charlie: 大家好,我叫Charlie,和你们一样也是学生。我对音乐特别有热情,平时喜欢弹吉他和写歌。我也热爱体育,特别是篮球。在学习上,我对数学和物理很感兴趣。Alice,你最喜欢哪种类型的户外活动?Bob,你最近在玩什么视频游戏?希望我们能一起分享我们的兴趣!
现在我们打印 Alice 的记忆,检查她的记忆是否正确更新。
async def example_memory() -> None:
"""打印 Alice 的记忆。"""
print("Alice 的记忆:")
for msg in await alice.memory.get_memory():
print(
f"{msg.name}: {json.dumps(msg.content, indent=4, ensure_ascii=False)}",
)
asyncio.run(example_memory())
Alice 的记忆:
system: "现在大家互相认识一下,简单自我介绍。"
Alice: [
{
"id": "WRC9oxPwwWJvsQK5aeJ9YW",
"type": "tool_use",
"name": "generate_response",
"input": {
"response": "大家好,我叫Alice,是一名学生。很高兴认识大家!我喜欢阅读和探索新知识,也热衷于参加各种户外活动。希望我们能成为好朋友,一起分享学习和生活中的点滴。你们都有什么兴趣爱好呢?"
}
}
]
system: [
{
"type": "tool_result",
"id": "WRC9oxPwwWJvsQK5aeJ9YW",
"name": "generate_response",
"output": [
{
"type": "text",
"text": "Successfully generated response."
}
]
}
]
Alice: "大家好,我叫Alice,是一名学生。很高兴认识大家!我喜欢阅读和探索新知识,也热衷于参加各种户外活动。希望我们能成为好朋友,一起分享学习和生活中的点滴。你们都有什么兴趣爱好呢?"
Bob: "大家好,我叫Bob,也是学生。我对科学和技术特别感兴趣,平时喜欢捣鼓一些电子设备,也爱玩视频游戏。我也很期待和大家成为朋友,一起学习进步。很高兴遇到有共同话题的朋友!Alice,你最喜欢哪类书籍?"
Charlie: "大家好,我叫Charlie,和你们一样也是学生。我对音乐特别有热情,平时喜欢弹吉他和写歌。我也热爱体育,特别是篮球。在学习上,我对数学和物理很感兴趣。Alice,你最喜欢哪种类型的户外活动?Bob,你最近在玩什么视频游戏?希望我们能一起分享我们的兴趣!"
进一步阅读¶
Total running time of the script: (0 minutes 16.068 seconds)