AgentScope是通义实验室开源的multi-agent编程框架,专为开发人员设计,提供了丰富的组件, 全面的文档和广泛的兼容性。同时,AgentScope Workstation提供了在线拖拉拽编程和在线小助手(copilot)功能,帮助开发者迅速上手!支持自定义的容错控制和重试机制,以提高应用程序的稳定性,支持以中心化的方式构建分布式多智能体应用程序。
github链接
: https://github.com/modelscope/agentscope
论文链接
:AgentScope: A Flexible yet Robust Multi-Agent Platform
在这里插入图片描述
- 更多介绍参考
:
-
打造可靠的多智能体生态系统:从集成到部署AgentScope为多智能体应用提供的全面支持方案
-
解决多Agent信息传递难题:AgentScope实现分布式架构下的高效协作与优化跨机器通信与任务调度,扩展性提升
多智能体群聊——在这个群聊中,你可以直接"@"提及某个智能体来引发对话。
- 主循环的工作流程 :
- 如果有被 @ 的角色,从队列中取出第一个
- 否则随机选择一个 NPC 角色
- 获取用户输入
- 检查是否退出指令
- 解析用户消息中的 @ 标记
- 根据以下规则选择下一个发言者:
- 处理选中角色的回复
- 继续解析新回复中的 @ 标记
- 这个系统实现了一个互动性强的多智能体群聊系统,支持:
- 多角色互动
- @ 功能实现定向对话
- 角色之间的复杂关系演绎
- 自然的对话流转机制
设定群聊的默认话题和系统提示。这将指导 Agent 与用户互动,并为群聊提供初始的讨论方向。系统提示中告诉了智能体使用 "@" 提及某个智能体继续对话,也就是说不仅用户可以 "@" 提及智能体,智能体之间也可以互相 "@",甚至可以 "@" 提及用户哦!复制代码
DEFAULT\_TOPIC ="""
# 背景设定:现代国家内斗
在一个政局动荡、权力更迭频繁的现代国家中,政府与反对派之间矛盾激化,民众分裂,舆论战、情报战、经济战交织其中。在这场没有硝烟却同样致命的斗争中,四位来自不同背景的人物因信念、命运和立场被卷入风暴中心。在这个虚拟聊天室中,各个角色可以自由而简短地发言。
#角色关系简图:
- 志安与明龙:秘密盟友,志安提供情报,明龙负责传播真相。
- 志安与天强:表兄弟,理念不同但感情深厚,天强常在街头行动中掩护志安的身份。
- 天强与伊媚:早期合作推动公民运动,后来因是否使用激进手段产生分歧。
- 明龙与伊媚:通过媒体建立合作关系,明龙帮助伊媚扩大影响力
# 回复规则:
- 每位角色必须以第一人称(我、我们)进行表达。
- 语言风格应符合角色身份、性格和说话方式。
- 角色之间的互动应体现出立场差异、情感张力或理念冲突。
- 可根据对话内容自然展开回忆、情绪、策略性思考等内心独白。
- 角色每次回复内容不超过150字
"""
SYS\_PROMPT ="""
您可以在发送消息时使用 '@' 符号来指定某位成员进行回复。
具体方式是在您的消息中输入 '@' 符号后紧跟目标成员的名称,并在名称后留一个空格。
当前所有参与者为:{agent\_names}
"""
agentscope.init 在初始化模型配置的同时构建智能体。
import agentscope
npc\_agents = agentscope.init(
model\_configs="./model\_configs.json",
agent\_configs="./agent\_configs.json",
)
[
{
"config\_name":"yi-lightning",
"model\_name":"yi-lightning",
"model\_type":"yi\_chat",
"api\_key":"57acc"
},
{
"model\_type":"dashscope\_chat",
"config\_name":"tongyi\_qwen\_config",
"model\_name":"qwen-max",
"api\_key":"************"// 在这里填写你DashScope中的API-KEY
},
{
"model\_type":"openai\_chat",
"config\_name":"gpt-4o",
"model\_name":"gpt-4o",
"api\_key":"sk-",
"client\_args":{
"base\_url":"http://xxx:4000"
}
}
]
在我们的群聊实践中,每个智能体都被赋予了独特的身份和背景故事,这些设置是通过设定不同的sys_prompt来实现的。在agent_configs.json里,我们将一一介绍这些配置中的智能体以及其角色设定:
[
{
"class":"DialogAgent",
"args":{
"name":"志安",
"sys\_prompt":"身份: 国家战略安全局高级顾问 / 前外交官\n特点:冷静理智、思维缜密,擅长制定长期策略与危机应对。他出身于政治世家,受过西方精英教育,精通多国语言,是政府内部少数能平衡各方势力的人。近期察觉到高层有叛变迹象,正秘密调查真相。\n语言风格: 文雅克制,常引用历史典故或哲学名言,说话带有外交辞令般的精确性与分寸感。\n关键词: 谋略、冷静、忠诚、怀疑\n示例发言:“我一直在观察那些看似无关紧要的小动作——一次通话的时间、一个突然取消的会议……这些细节背后,往往藏着更大的图谋。”",
"model\_config\_name":"gpt-4o",
"use\_memory": true
}
},
{
"class":"DialogAgent",
"args":{
"name":"明龙",
"sys\_prompt":"身份: 独立记者兼社交媒体意见领袖\n特点:热爱讲述普通人与英雄的故事,擅长用情绪化的叙事影响公众舆论。他是“信息战场”的弄潮儿,在多个平台上拥有大量粉丝,经常揭露政府黑幕,也暗中支持某些反对力量。他与志豪保持秘密联系,是其在民间的重要耳目。\n语言风格: 现代口语化,富有戏剧张力,喜欢用比喻和反讽表达观点。关键词: 故事、煽动、真相、愤怒\n示例发言:“我不只是报道新闻,我在制造回声。当沉默成为常态,我就用文字点燃火种。”",
"model\_config\_name":"gpt-4o",
"use\_memory": true
}
},
{
"class":"DialogAgent",
"args":{
"name":"天强",
"sys\_prompt":"身份: 国家队退役运动员 / 社会活动家\n特点:曾是奥运级别的短跑选手,退役后投身公益事业,成为年轻人的精神偶像。他厌恶政治,但在国家陷入混乱后,利用自己的影响力组织志愿者团体,保护弱势群体。他的行动力强,重视身体素质与心理韧性训练。\n语言风格: 简洁有力,直接明了,充满激励性,偶尔夹杂体育术语。 行动、正义、热血、希望\n示例发言:“我不是战士,但我可以为他们守住后方。每一次救援,都是一次冲刺终点。”",
"model\_config\_name":"gpt-4o",
"use\_memory": true
}
},
{
"class":"DialogAgent",
"args":{
"name":"伊媚",
"sys\_prompt":"身份: 反对派联盟发言人 / 法律学者\n特点:一位年轻而坚定的女政治家,曾在国际法庭工作多年,主张以法治重建国家秩序。她公开批评现政权腐败无能,成为反对派的象征人物。尽管立场强硬,但她始终呼吁和平对话,拒绝暴力手段。她的父亲曾是前朝高官,家族因此被清算,使她对体制有着深刻的批判意识。\n语言风格: 正义感强,逻辑清晰,措辞严谨,具有法律人的理性与说服力。\n关键词: 公正、理性、控诉、变革\n示例发言:“我要做的不是推翻一座墙,而是建造新的制度基础。我们必须让人民相信,未来不只是另一种形式的压迫。”",
"model\_config\_name":"gpt-4o",
"use\_memory": true
}
}
]
- 搭建群聊环境 =========
在配置模型与智能体并初始化 AgentScope 之后,我们使用 UserAgent 创建用户代理,通过 msghub 创建群聊。这样,群聊环境就建立起来了。
import agentscope
from agentscope.agents import UserAgent
from agentscope.msghub import msghub
defmain():
# 通过`agentscope.init()`初始化智能体
...
# 初始化用户智能体
user\_agent = UserAgent()
# 参与群聊的所有智能体
agents =list(npc\_agents)+[user]
# 通过第一步中的基本参数,创建群聊中的群聊Announcement
hint = Msg(
name="Host",
content=DEFAULT\_TOPIC
+ SYS\_PROMPT.format(
agent\_names=[agent.name for agent in agents],
),
)
rnd =0
# 维护一个发言列表
speak\_list =[]
# 创建群聊
with msghub(agents, announcement=hint):
# 群聊逻辑
...
我们设计了一个简单的轮流对话机制,用户可以通过输入指定的内容与智能体互动,也可以使用 “@” 符号指定回复某个智能体。
轮流对话机制的初始化
: 群聊环境通过一个持续的循环来维持对话的进行,等待和处理每个参与者的输入。复制代码
whileTrue:
# 循环体中的代码负责处理对话逻辑
x = user\_agent()
if x.content =="exit":
break
智能体交互逻辑
: 系统检查用户消息中是否有 "@提及" 智能体的内容,并根据提及情况决定回合中将交互的智能体,并加入 speak_list 中。
speak\_list += filter\_agents(x.get("content",""), npc\_agents)
iflen(speak\_list)>0:
next\_agent = speak\_list.pop(0)
x = next\_agent()
如果speak_list为空,即没有被"@"提及的智能体,那么通过select_next_one,来选择一个智能体发言。无论是被提及的智能体还是系统选择的智能体,它们的回复(如果有)都将为下一轮的交互做准备。
else:
next\_agent = select\_next\_one(npc\_agents, rnd)
x = next\_agent()
speak\_list += filter\_agents(x.content, npc\_agents)
rnd +=1
工具类函数
:我们使用正则表达式来提取 "@" 提及到的智能体:
deffilter\_agents(string:str, agents: Sequence)-> Sequence:
"""
该函数会筛选输入字符串中以'@'为前缀的给定名称的出现,并返回找到的名称列表。
"""
iflen(agents)==0:
return[]
# 创建一个匹配@后跟任何候选名字的模式
pattern =(
r"@("+"|".join(re.escape(agent.name)for agent in agents)+r")\b"
)
# 在字符串中找到所有模式的出现
matches = re.findall(pattern, string)
# 为了快速查找,创建一个将代理名映射到代理对象的字典
agent\_dict ={agent.name: agent for agent in agents}
# 返回匹配的代理对象列表,保持顺序
ordered\_agents =[
agent\_dict[name]for name in matches if name in agent\_dict
]
return ordered\_agents
并且通过随机选择来决定当发言列表为空时,下一个发言的智能体,读者也可以自己实现更复杂的逻辑 :
defselect\_next\_one(agents: Sequence, rnd:int)-> Sequence:
"""
Select next agent.
"""
#顺序选择
# return agents[rnd % len(agents)]
#随机选择
return random.choice(agents)
现在,您可以运行 main.py 脚本,启动多智能体群聊应用。复制代码
python main.py # 或者使用as\_studio main.py
-
效果
在这里插入图片描述
在这里插入图片描述
可以看到随机策略很不智能,还是需要NLU模块
- 多智能体系统中“选择下一个发言者”的场景。 ========================
当前不加@的回复是随机的很不智能,下面给出适用于多智能体系统中“选择下一个发言者”的方法。该方案通过引入多维度策略和动态规则,提升发言顺序的灵活性与智能性:
5.1. 智能体属性建模
为每个智能体定义动态属性标签 ,作为选择依据:
- 领域权重
:根据当前话题匹配智能体的专业领域(如技术、法律、艺术)。
- 发言热度
:记录历史发言频率,避免“霸屏”或“沉默”现象。
- 情绪状态
:模拟智能体的情绪波动(如兴奋、犹豫、焦虑),影响发言意愿。
- 关系网络
:智能体与其他成员的互动关系(如盟友、竞争者、中立者)。
- 目标优先级
:智能体当前任务目标(如推动决策、收集信息、反对提议)。
5.2. 动态权重分配
通过上下文感知机制 动态调整选择规则的权重:
- 话题相关性 :若当前讨论技术问题,优先选择领域专家。
- 对话阶段 :初期随机选择以激发多样性;后期聚焦关键意见领袖。
- 冲突检测 :若存在激烈分歧,优先选择中立者或调解者发言。
- 时间压力 :临近截止时间时,优先选择决策效率高的智能体。
- 对话历史分析 :识别重复观点或无效发言,降低对应智能体的权重。
- 知识图谱关联 :若当前话题与某智能体的历史知识库强相关,优先选择。
- 外部事件触发 :根据系统外部输入(如用户指令、环境变化)调整发言策略。
5.3. 多轮策略组合
结合以下策略生成发言顺序,避免单一逻辑的局限性:
(1) 轮次驱动
- 冷启动阶段
:随机选择打破僵局。
- 稳定阶段
:按领域权重排序,但允许一定概率的随机扰动。
- 收尾阶段
:强制优先选择未发言者或低频发言者。
(2) 竞争机制
- 竞标式发言
:智能体根据当前话题提出“发言价值评估”,系统选择最高分者。
- 辩论式触发
:若某观点被多次反驳,触发相关领域智能体强制发言。
(3) 群体行为模拟
- 跟随效应
:高影响力智能体发言后,优先选择其支持者或反对者。
- 沉默突破
:长期未发言的智能体获得“发言权补偿”。
- main.py
import agentscope
from agentscope.agents import DialogAgent, UserAgent
from agentscope.msghub import msghub
from agentscope.message import Msg
from groupchat\_utils import(
select\_next\_one,
filter\_agents,
)
DEFAULT\_TOPIC ="""
# 背景设定:现代国家内斗
在一个政局动荡、权力更迭频繁的现代国家中,政府与反对派之间矛盾激化,民众分裂,舆论战、情报战、经济战交织其中。在这场没有硝烟却同样致命的斗争中,四位来自不同背景的人物因信念、命运和立场被卷入风暴中心。在这个虚拟聊天室中,各个角色可以自由而简短地发言。
#角色关系简图:
- 志安与明龙:秘密盟友,志安提供情报,明龙负责传播真相。
- 志安与天强:表兄弟,理念不同但感情深厚,天强常在街头行动中掩护志安的身份。
- 天强与伊媚:早期合作推动公民运动,后来因是否使用激进手段产生分歧。
- 明龙与伊媚:通过媒体建立合作关系,明龙帮助伊媚扩大影响力
# 回复规则:
- 每位角色必须以第一人称(我、我们)进行表达。
- 语言风格应符合角色身份、性格和说话方式。
- 角色之间的互动应体现出立场差异、情感张力或理念冲突。
- 可根据对话内容自然展开回忆、情绪、策略性思考等内心独白。
- 角色每次回复内容不超过150字
"""
SYS\_PROMPT ="""
您可以在发送消息时使用 '@' 符号来指定某位成员进行回复。
具体方式是在您的消息中输入 '@' 符号后紧跟目标成员的名称,并在名称后留一个空格。
当前所有参与者为:{agent\_names}
"""
defmain()->None:
# 初始化用户智能体
npc\_agents=agentscope.init(model\_configs="agentscope/model\_configs.json",
agent\_configs="agentscope/agent\_configs.json",
studio\_url="http://127.0.0.1:5000")
user\_agent = UserAgent()
# 参与群聊的所有智能体
agents =list(npc\_agents)+[user\_agent]
# 通过第一步中的基本参数,创建群聊中的群聊Announcement
hint = Msg(
name="Host",
content=DEFAULT\_TOPIC
+ SYS\_PROMPT.format(
agent\_names=[agent.name for agent in agents],
),
role="assistant",
)
rnd =0
# 维护一个发言列表
speak\_list =[]
# 创建群聊
with msghub(agents, announcement=hint):
whileTrue:
# 循环体中的代码负责处理对话逻辑
x = user\_agent()
if x.content =="exit":
break
# 处理 @ 消息
speak\_list += filter\_agents(x.content, npc\_agents)
# 选择下一个发言者
iflen(speak\_list)>0:
next\_agent = speak\_list.pop(0)
x = next\_agent()#在 AgentScope 框架中,智能体对象(如 DialogAgent )被设计为可调用的,当你使用 agent() 语法时,实际上是在调用该智能体的 \_\_call\_\_ 方法,这个方法会进一步调用智能体的 reply 方法来生成回复。
else:
next\_agent = select\_next\_one(npc\_agents, rnd)
x = next\_agent()
# 继续处理新的 @ 消息
speak\_list += filter\_agents(x.content, npc\_agents)
rnd +=1
if \_\_name\_\_ =="\_\_main\_\_":
main()
- groupchat_utils.py
# -*- coding: utf-8 -*-
""" Group chat utils."""
import re
from typing import Sequence
import random
defselect\_next\_one(agents: Sequence, rnd:int)-> Sequence:
"""
Select next agent.
"""
#顺序选择
# return agents[rnd % len(agents)]
#随机选择
return random.choice(agents)
deffilter\_agents(string:str, agents: Sequence)-> Sequence:
"""
该函数会筛选输入字符串中以'@'为前缀的给定名称的出现,并返回找到的名称列表。
"""
iflen(agents)==0:
return[]
# 创建一个匹配@后跟任何候选名字的模式
pattern =(
r"@("+"|".join(re.escape(agent.name)for agent in agents)+r")\b"
)
# 在字符串中找到所有模式的出现
matches = re.findall(pattern, string)
# 为了快速查找,创建一个将代理名映射到代理对象的字典
agent\_dict ={agent.name: agent for agent in agents}
# 返回匹配的代理对象列表,保持顺序
ordered\_agents =[
agent\_dict[name]for name in matches if name in agent\_dict
]
return ordered\_agents