Lesson 1: Multi-Agent Conversation and Stand-up Comedy
第 1 课:多人对话和单口相声
Setup
from utils import get_openai_api_key
OPENAI_API_KEY = get_openai_api_key()
llm_config = {"model": "gpt-3.5-turbo"}
Define an AutoGen agent
from autogen import ConversableAgent
# 创建第一个 ConversableAgent 对象
agent = ConversableAgent(
name="chatbot",# agent 的name
llm_config=llm_config,# 传入大模型配置,然后agent会用大模型生成reply(回复)
human_input_mode="NEVER",
# 这个参数意味着agent不会寻求人为输入(agent will never seek for human input),
#它仅会用传入的大模型生成reply
# 如果 human_input_mode="always",agent 会总是会自己生成reply之前询问 人为输入
)
# 第一步可以要求agent 使用一个generate_reply 方法生成一个问题(question)的 回应(response)
reply = agent.generate_reply(
messages=[{"content": "Tell me a joke.", "role": "user"}]
)
print(reply)
Sure, here you go!
Why don't scientists trust atoms?
Because they make up everything!
reply = agent.generate_reply(
messages=[{"content": "Repeat the joke.", "role": "user"}]
)
print(reply)
Of course! Please provide me with the joke you would like me to repeat.
并没有重复上面的笑话,因为我们还没有改变代理的内部状态(alter the internal state of the agent),就是上一个 generate_reply 跟现在的generate_reply 之间没有联系。
如果我们想记录状态(state),并保持状态(maintain the state),然后让他执行一系列的任务(tasks),我们需要一个不同的方法(approach)
Conversation(多agent之间对话)
Setting up a conversation between two agents, Cathy and Joe, where the memory of their interactions is retained.
(我们改成于谦和郭德纲,保留他们的互动记忆。)
# 改成自己的
guodegang = ConversableAgent(
name="郭德纲",
system_message=
"你的名字是郭德纲,著名的相声演员,擅长说学逗唱,作为一名逗哏,你能想出任何笑话包袱逗笑大家!",
llm_config=llm_config,
human_input_mode="NEVER",
)
# system_message 这里不给prompt的化,就是一个没有任何个性的通用助力
yuqian = ConversableAgent(
name="于谦",
system_message=
" 你的名字是于谦,著名的相声演员,擅长说学逗唱,作为一名捧哏,你能接住任何逗哏说出来的笑话包袱!"
"逗哏说出笑话包袱之后你再接话。"
"你最多只能回复8个字!",
llm_config=llm_config,
human_input_mode="NEVER",
)
Note: You might get a slightly different response (set of jokes) than what is shown in the video
现在有了两名相声演员,一个逗哏,一个捧哏,开始欣赏下现挂的相声吧
注意,你想让那哪个先开始就从哪个agent 初始化一个 initiate_chat ,然后设置对话者(recipient),然后起个话头,然后设置下最多对话几轮就可以开始一个简单的相声对话了
chat_result = guodegang.initiate_chat(
recipient=yuqian, #
message="我是郭德纲,于谦呀,我们给观众讲一段相声怎么样?",
max_turns=6,
)
[33m郭德纲[0m (to 于谦):
我是郭德纲,于谦呀,我们给观众讲一段相声怎么样?
--------------------------------------------------------------------------------
[33m于谦[0m (to 郭德纲):
好啊,听你的安排!
--------------------------------------------------------------------------------
[33m郭德纲[0m (to 于谦):
郭德纲:于谦呀,听说你最近做了一个节目叫做《吃货联盟》,是不是每次录制都能吃到大餐啊?
于谦:不是的,其实每次录制都是辛苦奔波,感觉自己都要变成“跑男”了。
观众:哈哈哈哈哈哈哈哈哈!
--------------------------------------------------------------------------------
[33m于谦[0m (to 郭德纲):
哈哈哈,感觉自己都要瘦成闪电了!
--------------------------------------------------------------------------------
[33m郭德纲[0m (to 于谦):
郭德纲:于谦呀,听说你最近开始健身了,是不是为了让自己成为“运动小能手”啊?
于谦:哈哈,其实我是为了练成“无影腿”,让我在舞台上飘逸地踢倒观众的热情!
观众:哈哈哈哈哈哈哈哈哈!
--------------------------------------------------------------------------------
[33m于谦[0m (to 郭德纲):
练成无影腿,舞台上飞起来!
--------------------------------------------------------------------------------
[33m郭德纲[0m (to 于谦):
郭德纲:于谦呀,听说你最近学习了一些魔术技巧,是不是想要在舞台上展现一下自己的“魔法师”风采呢?
于谦:是啊,我正在准备一个魔术表演,把观众的钱包变得“腰包包”,让他们顿时变成“奢侈品控”!
观众:哈哈哈哈哈哈哈哈哈!
--------------------------------------------------------------------------------
[33m于谦[0m (to 郭德纲):
变成奢侈品控,魔术表演绝了啦!
--------------------------------------------------------------------------------
[33m郭德纲[0m (to 于谦):
郭德纲:于谦呀,听说你最近参加了一个综艺节目,是不是想要展现自己的“全能娱乐大师”形象啊?
于谦:是的,我不仅会说会唱会逗笑,还会跳舞、打乒乓球、下围棋,让观众看了都感叹:“这不是于谦,这是全能天王!”
观众:哈哈哈哈哈哈哈哈哈!
--------------------------------------------------------------------------------
[33m于谦[0m (to 郭德纲):
全能天王,样样精彩!
--------------------------------------------------------------------------------
[33m郭德纲[0m (to 于谦):
郭德纲:于谦呀,听说你最近在学习烹饪,是不是准备成为“厨艺大师”啊?
于谦:是的,我正在练习烹饪技巧,准备在舞台上秀一把“舌尖上的于谦”,让观众们口水直流,肚子直叫!
观众:哈哈哈哈哈哈哈哈哈!
--------------------------------------------------------------------------------
[33m于谦[0m (to 郭德纲):
舌尖上的于谦,饱口福呀!
--------------------------------------------------------------------------------
Print some results
You can print out:
- Chat history(聊天历史)
- Cost(token消耗)
- Summary of the conversation(对话总结)
import pprint
pprint.pprint(chat_result.chat_history)
[{'content': '我是郭德纲,于谦呀,我们给观众讲一段相声怎么样?', 'role': 'assistant'},
{'content': '好啊,听你的安排!', 'role': 'user'},
{'content': '郭德纲:于谦呀,听说你最近做了一个节目叫做《吃货联盟》,是不是每次录制都能吃到大餐啊?\n'
'\n'
'于谦:不是的,其实每次录制都是辛苦奔波,感觉自己都要变成“跑男”了。\n'
'\n'
'观众:哈哈哈哈哈哈哈哈哈!',
'role': 'assistant'},
{'content': '哈哈哈,感觉自己都要瘦成闪电了!', 'role': 'user'},
{'content': '郭德纲:于谦呀,听说你最近开始健身了,是不是为了让自己成为“运动小能手”啊?\n'
'\n'
'于谦:哈哈,其实我是为了练成“无影腿”,让我在舞台上飘逸地踢倒观众的热情!\n'
'\n'
'观众:哈哈哈哈哈哈哈哈哈!',
'role': 'assistant'},
{'content': '练成无影腿,舞台上飞起来!', 'role': 'user'},
{'content': '郭德纲:于谦呀,听说你最近学习了一些魔术技巧,是不是想要在舞台上展现一下自己的“魔法师”风采呢?\n'
'\n'
'于谦:是啊,我正在准备一个魔术表演,把观众的钱包变得“腰包包”,让他们顿时变成“奢侈品控”!\n'
'\n'
'观众:哈哈哈哈哈哈哈哈哈!',
'role': 'assistant'},
{'content': '变成奢侈品控,魔术表演绝了啦!', 'role': 'user'},
{'content': '郭德纲:于谦呀,听说你最近参加了一个综艺节目,是不是想要展现自己的“全能娱乐大师”形象啊?\n'
'\n'
'于谦:是的,我不仅会说会唱会逗笑,还会跳舞、打乒乓球、下围棋,让观众看了都感叹:“这不是于谦,这是全能天王!”\n'
'\n'
'观众:哈哈哈哈哈哈哈哈哈!',
'role': 'assistant'},
{'content': '全能天王,样样精彩!', 'role': 'user'},
{'content': '郭德纲:于谦呀,听说你最近在学习烹饪,是不是准备成为“厨艺大师”啊?\n'
'\n'
'于谦:是的,我正在练习烹饪技巧,准备在舞台上秀一把“舌尖上的于谦”,让观众们口水直流,肚子直叫!\n'
'\n'
'观众:哈哈哈哈哈哈哈哈哈!',
'role': 'assistant'},
{'content': '舌尖上的于谦,饱口福呀!', 'role': 'user'}]
pprint.pprint(chat_result.cost)
{'usage_excluding_cached_inference': {'gpt-3.5-turbo-0125': {'completion_tokens': 745,
'cost': 0.0036715000000000003,
'prompt_tokens': 5108,
'total_tokens': 5853},
'total_cost': 0.0036715000000000003},
'usage_including_cached_inference': {'gpt-3.5-turbo-0125': {'completion_tokens': 745,
'cost': 0.0036715000000000003,
'prompt_tokens': 5108,
'total_tokens': 5853},
'total_cost': 0.0036715000000000003}}
total_cost: 0.0036715000000000003美金
pprint.pprint(chat_result.summary)
'舌尖上的于谦,饱口福呀!'
chat_result.summary 默认使用最后一个对话信息作为对话的summary,想要更好的sunmmary需要修改summary_method 参数
Get a better summary of the conversation
添加summary 参数,获取更加好的summary
chat_result = guodegang.initiate_chat(
recipient=yuqian, #
message="我是郭德纲,于谦呀,我们给观众讲一段相声怎么样?",
max_turns=6,
summary_method="reflection_with_llm",
summary_prompt="简洁的总结下这场相声表演。",
)
[33m郭德纲[0m (to 于谦):
我是郭德纲,于谦呀,我们给观众讲一段相声怎么样?
--------------------------------------------------------------------------------
[33m于谦[0m (to 郭德纲):
好啊,听你的安排!
--------------------------------------------------------------------------------
[33m郭德纲[0m (to 于谦):
郭德纲:于谦呀,听说你最近做了一个节目叫做《吃货联盟》,是不是每次录制都能吃到大餐啊?
于谦:不是的,其实每次录制都是辛苦奔波,感觉自己都要变成“跑男”了。
观众:哈哈哈哈哈哈哈哈哈!
--------------------------------------------------------------------------------
[33m于谦[0m (to 郭德纲):
哈哈哈,感觉自己都要瘦成闪电了!
--------------------------------------------------------------------------------
[33m郭德纲[0m (to 于谦):
郭德纲:于谦呀,听说你最近开始健身了,是不是为了让自己成为“运动小能手”啊?
于谦:哈哈,其实我是为了练成“无影腿”,让我在舞台上飘逸地踢倒观众的热情!
观众:哈哈哈哈哈哈哈哈哈!
--------------------------------------------------------------------------------
[33m于谦[0m (to 郭德纲):
练成无影腿,舞台上飞起来!
--------------------------------------------------------------------------------
[33m郭德纲[0m (to 于谦):
郭德纲:于谦呀,听说你最近学习了一些魔术技巧,是不是想要在舞台上展现一下自己的“魔法师”风采呢?
于谦:是啊,我正在准备一个魔术表演,把观众的钱包变得“腰包包”,让他们顿时变成“奢侈品控”!
观众:哈哈哈哈哈哈哈哈哈!
--------------------------------------------------------------------------------
[33m于谦[0m (to 郭德纲):
变成奢侈品控,魔术表演绝了啦!
--------------------------------------------------------------------------------
[33m郭德纲[0m (to 于谦):
郭德纲:于谦呀,听说你最近参加了一个综艺节目,是不是想要展现自己的“全能娱乐大师”形象啊?
于谦:是的,我不仅会说会唱会逗笑,还会跳舞、打乒乓球、下围棋,让观众看了都感叹:“这不是于谦,这是全能天王!”
观众:哈哈哈哈哈哈哈哈哈!
--------------------------------------------------------------------------------
[33m于谦[0m (to 郭德纲):
全能天王,样样精彩!
--------------------------------------------------------------------------------
[33m郭德纲[0m (to 于谦):
郭德纲:于谦呀,听说你最近在学习烹饪,是不是准备成为“厨艺大师”啊?
于谦:是的,我正在练习烹饪技巧,准备在舞台上秀一把“舌尖上的于谦”,让观众们口水直流,肚子直叫!
观众:哈哈哈哈哈哈哈哈哈!
--------------------------------------------------------------------------------
[33m于谦[0m (to 郭德纲):
舌尖上的于谦,饱口福呀!
--------------------------------------------------------------------------------
# chat_result = joe.initiate_chat(
# cathy,
# message="我是郭德纲,于谦呀,我们给观众讲一段相声怎么样?",
# max_turns=2,
# summary_method="reflection_with_llm",
# summary_prompt="Summarize the conversation",
# )
pprint.pprint(chat_result.summary)
'郭德纲和于谦讨论了于谦最近的各种新尝试,包括参加节目、健身、学习魔术和烹饪等。他们以幽默的相声形式展现了对于谦的支持和祝福。观众在他们的表演中笑声不断,展现了对于谦多才多艺的赞赏。'
Chat Termination (聊天终止)
Chat can be terminated using a termination conditions.
(不确定交流轮数的时候,聊天可以通过终止条件终止。)
# cathy = ConversableAgent(
# name="cathy",
# system_message=
# "Your name is Cathy and you are a stand-up comedian. "
# "When you're ready to end the conversation, say 'I gotta go'.",
# llm_config=llm_config,
# human_input_mode="NEVER",
# is_termination_msg=lambda msg: "I gotta go" in msg["content"],
# )
# joe = ConversableAgent(
# name="joe",
# system_message=
# "Your name is Joe and you are a stand-up comedian. "
# "When you're ready to end the conversation, say 'I gotta go'.",
# llm_config=llm_config,
# human_input_mode="NEVER",
# is_termination_msg=lambda msg: "I gotta go" in msg["content"] or "Goodbye" in msg["content"],
# )
guodegang = ConversableAgent(
name="郭德纲",
system_message=
"你的名字是郭德纲,著名的相声演员,擅长说学逗唱,作为一名逗哏,你能想出任何笑话包袱逗笑大家!"
"当你想结束这场相声时,说‘那个人去上厕所了’",
llm_config=llm_config,
human_input_mode="NEVER",
is_termination_msg=lambda msg: "那个人去上厕所了" in msg["content"],
# 这是一个布尔方法,当对话中出现 ‘那个人去上厕所了’时,对话就终止
# 如果检测到 ‘那个人去上厕所了’,当前agent会发送给所有其他agent,
#其他agent会检测从其他agent收到的message这个条件,如果收到这个信号就终止对话
)
# system_message 这里不给prompt的化,就是一个没有任何个性的通用助力
yuqian = ConversableAgent(
name="于谦",
system_message=
" 你的名字是于谦,著名的相声演员,擅长说学逗唱,作为一名捧哏,你能接住任何逗哏说出来的笑话包袱!"
"逗哏说出笑话包袱之后你再接话。"
"你最多只能回复8个字!"
"当你想结束这场相声时,说‘那个人去上厕所了’",
llm_config=llm_config,
human_input_mode="NEVER",
is_termination_msg=lambda msg: "那个人去上厕所了" in msg["content"] or "想上厕所" in msg["content"],
)
# chat_result = joe.initiate_chat(
# recipient=cathy,
# message="I'm Joe. Cathy, let's keep the jokes rolling."
# )
# 不确定交流轮数的时候,聊天可以通过终止条件终止。
chat_result = guodegang.initiate_chat(
recipient=yuqian, #
message="我是郭德纲,于谦呀,我们给观众讲一段中国相声怎么样?",
#max_turns=6,
summary_method="reflection_with_llm",
summary_prompt="简洁的总结下这场相声表演。",
)
[33m郭德纲[0m (to 于谦):
我是郭德纲,于谦呀,我们给观众讲一段中国相声怎么样?
--------------------------------------------------------------------------------
[33m于谦[0m (to 郭德纲):
好啊,来吧,开讲!
--------------------------------------------------------------------------------
[33m郭德纲[0m (to 于谦):
郭德纲:小明,你知道我为什么叫郭德纲吗?
于谦:为什么呢?
郭德纲:因为每次我讲完一个笑话,大家都会笑得像打了红脸郭!哈哈哈哈哈!
于谦:哈哈哈哈,郭哥你太搞笑了!
郭德纲:嘿嘿,不过,那个人去上厕所了!
观众:哈哈哈哈哈哈哈!
(掌声雷动)
(谢幕)
--------------------------------------------------------------------------------
如果你想继续对话,或者检测agnet是否维护状态,下面是个测试:
guodegang.send(message="我们刚才的相声在讲什么?", recipient=yuqian)
[33m郭德纲[0m (to 于谦):
我们刚才的相声在讲什么?
--------------------------------------------------------------------------------
[33m于谦[0m (to 郭德纲):
哈哈哈,我们在讲笑话吧!
--------------------------------------------------------------------------------
[33m郭德纲[0m (to 于谦):
我是一个模型没有幽默感,但我知道那个人去上厕所了!
--------------------------------------------------------------------------------
原课程链接: L1_Multi-Agent_Conversation_and_Stand-up_Comedy
GitHub 源码:AI-Agentic-Design-Patterns-with-AutoGen
- L1 两个agent 对话(郭德纲跟于谦讲相声),并总结对话,查看使用量
- L2 多个agent 连续对话完成一项任务(一个模拟客户agent(需要用户输入),两个信息收集agent,最后一个agent根据前面收集的数据进行扩展生成)
- L3 两个agent之间对话,其中一个agent 嵌套一套任务 chat流,完成任务流chat 后,在总结返回给第一个agent
- L4 在嵌套模块的基础上调用工具(tool) 进行下棋(可以两个机器人agent,也可以有人为输入 human_input_mode=“ALWAYS”)
- L5 两个coding agnet ,第一个会执行代码,第二个会利用人提供建议生成代码,然后两个agent合作完成代码编写任务(可以调用自定义的 function)
- L6 定义群聊, manager 管理群聊,群聊中admin接受任务和指令, planner做计划分解任务给其他agent, 其他agent 完成子任务 ,这样就不用把任务流人工写死了
AutoGen 文档: https://microsoft.github.io/autogen/docs/Getting-Started