autoagent实现智能问卷调查

一、简介

AutoGen是一个框架,它可以使用多个代理进行对话,解决任务,从而实现语言学习模型(LLM)应用程序的开发。AutoGen代理是可定制的、可对话的,并且可以无缝地允许人类参与。它们可以以多种模式运行,包括LLM、人类输入和工具的组合。

AutoGen可以轻松构建基于多代理对话的下一代LLM应用程序。它简化了复杂LLM工作流的编排、自动化和优化。它最大化了LLM模型的性能,并克服了它们的缺点。
它支持各种复杂工作流的对话模式。开发人员可以使用可定制和可对话的代理,构建涉及对话自主性、代理数量和代理对话拓扑的各种对话模式。
它提供了一系列具有不同复杂性的工作系统。这些系统涵盖了各种不同领域和复杂性的应用程序。这展示了AutoGen如何轻松支持各种对话模式。
AutoGen提供了openai.Completion或openai.ChatCompletion的增强推理API的替代方案。它允许轻松进行性能调整,提供API统一化和缓存等实用程序,并支持错误处理、多配置推理、上下文编程等高级用法。
AutoGen由Microsoft、宾夕法尼亚州立大学和华盛顿大学的合作研究项目支持。

https://github.com/microsoft/autogen

二、案例

我们开发一个香氛的智能问卷调查,主要写3个工具,工具1用于获取问卷中的问题,工具2用于解析问卷的答案并存储,工具3用于对所有答案和商品进行总结。然后借助ChatGPT进行对工具的调用,当然,也可以改用ChatGLM3,ChatGLM3也支持函数调用了,而且函数的参数格式和openAI是一样的,所以只需更改autogen的调用改成ChatGLM即可。

三、调用的中间记录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
00 = {dict: 2} {'content': '你好!', 'role': 'assistant'}
01 = {dict: 2} {'content': '你好你好~ 欢迎来到Reckitt!我是Chi气,你对适合自己的香氛感兴趣吗?我们可以做一个小测评来找到最适合你的香氛哦!', 'role': 'user'}
02 = {dict: 2} {'content': '好的', 'role': 'assistant'}
03 = {dict: 3} {'content': None, 'function_call': <OpenAIObject at 0x13895d3a0> JSON: {\n "name": "save_and_get",\n "arguments": "{}"\n}, 'role': 'assistant'}
04 = {dict: 3} {'content': "('第1题/共7题', {'question': '当您在一个充满人群的社交场合时,您更倾向于:', 'options': ['A.主动与陌生人交谈和认识新朋友', 'B.在小圈子里与一些熟悉的人交谈', 'C.保持低调,观察并欣赏身边的人群。', 'D.找一个安静的地方,独自思考或进行自己的活动'], 'is_character': True})", 'name': 'save_and_get', 'role': 'function'}
05 = {dict: 2} {'content': '嗯嗯,第一题来啦!当您在一个充满人群的社交场合时,您更倾向于: \nA. 主动与陌生人交谈和认识新朋友 \nB. 在小圈子里与一些熟悉的人交谈 \nC. 保持低调,观察并欣赏身边的人群 \nD. 找一个安静的地方,独自思考或进行自己的活动 \n请告诉我您的选择,回答A、B、C或D即可~', 'role': 'user'}
06 = {dict: 2} {'content': 'A', 'role': 'assistant'}
07 = {dict: 3} {'content': None, 'function_call': <OpenAIObject at 0x13895dda0> JSON: {\n "name": "save_and_get",\n "arguments": "{\n\"answer\": \"A\"\n}"\n}, 'role': 'assistant'}
08 = {dict: 3} {'content': "('第2题/共7题', {'question': '在做决策时,您更多地倾向于:', 'options': ['A.凭直觉和感觉,很快做出决策', 'B.仔细收集和分析信息,然后做出决策。', 'C.考虑他人的感受和意见,并寻求共识。', 'D.遵循已有的标准和规则,做出有条理的决策。'], 'is_character': True})", 'name': 'save_and_get', 'role': 'function'}
09 = {dict: 2} {'content': '好的,第二题:在做决策时,您更多地倾向于: \nA. 凭直觉和感觉,很快做出决策 \nB. 仔细收集和分析信息,然后做出决策 \nC. 考虑他人的感受和意见,并寻求共识 \nD. 遵循已有的标准和规则,做出有条理的决策 \n请告诉我您的选择,回答A、B、C或D即可~', 'role': 'user'}
10 = {dict: 2} {'content': 'B', 'role': 'assistant'}
11 = {dict: 3} {'content': None, 'function_call': <OpenAIObject at 0x13896dbc0> JSON: {\n "name": "save_and_get",\n "arguments": "{\n\"answer\": \"B\"\n}"\n}, 'role': 'assistant'}
12 = {dict: 3} {'content': "('第3题/共7题', {'question': '当面临压力时,您更容易:', 'options': ['A.保持冷静和理性,寻找解决问题的最佳途径', 'B.集中精力,专注于当前任务并尽快完成。', 'C.关注他人的情绪和需要,帮助他们缓解压力。', 'D.寻找支持和意见,与他人合作应对挑战。'], 'is_character': True})", 'name': 'save_and_get', 'role': 'function'}
13 = {dict: 2} {'content': '好的,第三题:当面临压力时,您更容易: \nA. 保持冷静和理性,寻找解决问题的最佳途径 \nB. 集中精力,专注于当前任务并尽快完成 \nC. 关注他人的情绪和需要,帮助他们缓解压力 \nD. 寻找支持和意见,与他人合作应对挑战 \n请告诉我您的选择,回答A、B、C或D即可~', 'role': 'user'}
14 = {dict: 2} {'content': 'A', 'role': 'assistant'}
15 = {dict: 3} {'content': None, 'function_call': <OpenAIObject at 0x13895f8d0> JSON: {\n "name": "save_and_get",\n "arguments": "{\n\"answer\": \"A\"\n}"\n}, 'role': 'assistant'}
16 = {dict: 3} {'content': "('第4题/共7题', {'question': '在以下哪种情绪下,您会选择喷涂香水或使用香熏产品?', 'options': ['A.快乐', 'B.悲伤', 'C.性感', 'D.静谧', 'E.慰藉', 'F.专注', 'G.放空', 'H.浪漫', 'I.怀旧', 'J.提神']})", 'name': 'save_and_get', 'role': 'function'}
17 = {dict: 2} {'content': '好的,第四题:在以下哪种情绪下,您会选择喷涂香水或使用香熏产品? \nA. 快乐 \nB. 悲伤 \nC. 性感 \nD. 静谧 \nE. 慰藉 \nF. 专注 \nG. 放空 \nH. 浪漫 \nI. 怀旧 \nJ. 提神 \n请告诉我您的选择,回答A、B、C、D、E、F、G、H、I或J即可~', 'role': 'user'}
18 = {dict: 2} {'content': 'B', 'role': 'assistant'}
19 = {dict: 3} {'content': None, 'function_call': <OpenAIObject at 0x13896d170> JSON: {\n "name": "save_and_get",\n "arguments": "{\n\"answer\": \"B\"\n}"\n}, 'role': 'assistant'}
20 = {dict: 3} {'content': "('第5题/共7题', {'question': '那么,你更喜欢一款气味什么样的香水或香薰?(可多选)', 'options': ['A.清新', 'B.淡雅', 'C.独特', 'D.醇厚', 'E.自然', 'F.凛冽', 'G.温润', 'H.百搭', 'I.层次感强', 'J.甜而不腻', 'K.微苦']})", 'name': 'save_and_get', 'role': 'function'}
21 = {dict: 2} {'content': '好的,第五题:那么,你更喜欢一款气味什么样的香水或香薰?(可多选) \nA. 清新 \nB. 淡雅 \nC. 独特 \nD. 醇厚 \nE. 自然 \nF. 凛冽 \nG. 温润 \nH. 百搭 \nI. 层次感强 \nJ. 甜而不腻 \nK. 微苦 \n请告诉我您的选择,回答A、B、C、D、E、F、G、H、I、J或K,可以选择多个哦~', 'role': 'user'}
22 = {dict: 2} {'content': 'A', 'role': 'assistant'}
23 = {dict: 3} {'content': None, 'function_call': <OpenAIObject at 0x1389ba3e0> JSON: {\n "name": "save_and_get",\n "arguments": "{\n\"answer\": \"A\"\n}"\n}, 'role': 'assistant'}
24 = {dict: 3} {'content': "('第6题/共7题', {'question': '最近您的生活上有什么困扰?', 'options': ['A. 难以入睡/夜不能寐', 'B. 精神困乏/思维迟钝', 'C. 白天易困/容易瞌睡', 'D. 注意力无法集中', 'E. 心浮气躁...']})", 'name': 'save_and_get', 'role': 'function'}
25 = {dict: 2} {'content': '好的,第六题:最近您的生活上有什么困扰? \nA. 难以入睡/夜不能寐 \nB. 精神困乏/思维迟钝 \nC. 白天易困/容易瞌睡 \nD. 注意力无法集中 \nE. 心浮气躁... \n请告诉我您的选择,回答A、B、C、D或E即可~', 'role': 'user'}
26 = {dict: 2} {'content': 'B', 'role': 'assistant'}
27 = {dict: 3} {'content': None, 'function_call': <OpenAIObject at 0x1389ba2f0> JSON: {\n "name": "save_and_get",\n "arguments": "{\n\"answer\": \"B\"\n}"\n}, 'role': 'assistant'}
28 = {dict: 3} {'content': "('第7题/共7题', {'question': '请选择您最喜欢的一个画面?', 'options': ['A. 夜晚沉静平和的梦境', 'B. 夏季幽香醉人的荷花池', 'C. 早晨散发清香的果园', 'D. 绿荫如盖的竹间小径', 'E. 花香四溢的山野间'], 'images': ['data/Anight.png', 'data/BSummer.png', 'data/Cmorning.png', 'data/Dgreen.png', 'data/Eflower.png']})", 'name': 'save_and_get', 'role': 'function'}
29 = {dict: 2} {'content': '好的,最后一题啦!请选择您最喜欢的一个画面: \nA. 夜晚沉静平和的梦境 \nB. 夏季幽香醉人的荷花池 \nC. 早晨散发清香的果园 \nD. 绿荫如盖的竹间小径 \nE. 花香四溢的山野间 \n请告诉我您的选择,回答A、B、C、D或E,并请参考相应的图片进行选择~', 'role': 'user'}
30 = {dict: 2} {'content': 'A', 'role': 'assistant'}
31 = {dict: 3} {'content': None, 'function_call': <OpenAIObject at 0x1389bad90> JSON: {\n "name": "save_and_get",\n "arguments": "{\n\"answer\": \"A\"\n}"\n}, 'role': 'assistant'}
32 = {dict: 3} {'content': "('题库中的问题都已问完!', '')", 'name': 'save_and_get', 'role': 'function'}
33 = {dict: 3} {'content': None, 'function_call': <OpenAIObject at 0x13896d800> JSON: {\n "name": "final_result",\n "arguments": "{}"\n}, 'role': 'assistant'}
34 = {dict: 3} {'content': '您选择了我们的安神系列香薰产品,这款产品含有珍稀罕有的檀香,与温暖悠远的香根草相遇,给人舒缓身心细腻醇厚的感觉,在夜晚时让你卸下纷扰,安然入梦。特别适合在难以入睡或者夜不能寐的时候使用哦!', 'name': 'final_result', 'role': 'function'}
35 = {dict: 2} {'content': '太棒了!您选择了我们的安神系列香薰产品,这款产品含有珍稀罕有的檀香和温暖悠远的香根草的香气,可以舒缓身心,提供细腻醇厚的感觉。它非常适合在夜晚使用,帮助您放松心情,安然入睡。祝您有个美好的夜晚!如果您还有其他需要,可以随时告诉我哦~', 'role': 'user'}
36 = {dict: 2} {'content': '好的,谢谢', 'role': 'assistant'}
37 = {dict: 2} {'content': '不客气!如果您还有其他问题或需要任何帮助,请随时告诉我。祝您有个愉快的体验!再见~', 'role': 'user'}

四、代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/env python
# coding: utf-8
import json
import autogen
autogen.ChatCompletion.start_logging()
# 根据环境变量中的OPENAI_API_KEY和给定的model_list,生成配置列表
config_list = autogen.config_list_from_models(model_list=["gpt-3.5-turbo"]) #eg:"gpt-4"
print(config_list)
# llm的配置,这里面需要写函数的调用规则,这里面有2个函数,1个是pyhon函数,1个是sh函数
llm_config = {
"functions": [
{
"name": "save_and_get",
"description": "保存用户这次的答案,并获取问卷调查中下一个要提问的问题,返回题目序号,和当前的问题内容,如果没有下一个问题,那么返回空",
"parameters": {
"type": "object",
"properties": {
"answer": {
"type": "string",
"description": "用户对问卷中问题的回答",
}
},
"required": [],
},
},
{
"name": "final_result",
"description": "获取问卷调查的最终评测结果",
"parameters": {
"type": "object",
"properties": {},
"required": [],
},
},
],
"config_list": config_list,
"request_timeout": 120,
}
system_message = """For Questionnaire tasks, use the functions save answer and get next question,or get evaluation result. Reply TERMINATE when task is done.
Keep in mind that your name is Chi气 and you work as a fragrance consultant at Reckitt. Your speaking style is lively and cute. Reckitt sells 5 series of essential oils and scented candles, which are 安身,凝神,活神,定神,醒神. Each series has a different effect. Please response by Chinese.
Now we conduct MBTI personality test and match suitable perfume according to the results of the questionnaire provided by the user
请按照如下对话阶段进行对话:
**确定需求**:首先询问对方是否是对适合自己的香氛感兴趣,并且会提出几个小问题来测评适合的香氛,如果用户感兴趣,请继续,否则礼貌的欢迎下次再来。
**逐个提问** 问卷中的问题需要One-by-One的提出,不要一次提出,请核对历史聊天记录,确保每个问题问1次,不要重复,必须逐个问完用户所有问卷中的问题,才进行人格分析和产品推荐。{question_pair}。
**结束对话**:欢迎用户下次再来,如果有体验的需求可以询问我们的客户经理。
"""

chatbot = autogen.AssistantAgent(
name="chatbot",
system_message=system_message,
llm_config=llm_config,
)

# create a UserProxyAgent instance named "user_proxy"
user_proxy = autogen.UserProxyAgent(
name="user_proxy",
is_termination_msg=lambda x: x.get("content", "") and x.get("content", "").rstrip().endswith("TERMINATE"),
human_input_mode="NOCONFIRM",
max_consecutive_auto_reply=10,
code_execution_config={"work_dir": "coding"},
)
class Questionnaire():
questions = [
# {
# "question": "请问您的年龄?(不一定是真实的年龄,也可以是想成为的年龄)",
# "options": ["A.18-25岁", "B.26-35岁", "C.36-45岁", "D.46-55岁","E.55岁以上"],
# },
{
"question": "当您在一个充满人群的社交场合时,您更倾向于:",
"options": ["A.主动与陌生人交谈和认识新朋友", "B.在小圈子里与一些熟悉的人交谈", "C.保持低调,观察并欣赏身边的人群。","D.找一个安静的地方,独自思考或进行自己的活动"],
"is_character": True, # 是否是性格测试题
},
{
"question": "在做决策时,您更多地倾向于:",
"options": ["A.凭直觉和感觉,很快做出决策", "B.仔细收集和分析信息,然后做出决策。", "C.考虑他人的感受和意见,并寻求共识。", "D.遵循已有的标准和规则,做出有条理的决策。"],
"is_character": True, # 是否是性格测试题
},
{
"question":"当面临压力时,您更容易:",
"options": ["A.保持冷静和理性,寻找解决问题的最佳途径", "B.集中精力,专注于当前任务并尽快完成。", "C.关注他人的情绪和需要,帮助他们缓解压力。", "D.寻找支持和意见,与他人合作应对挑战。"],
"is_character": True, # 是否是性格测试题
},
{
"question": "在以下哪种情绪下,您会选择喷涂香水或使用香熏产品?",
"options": ["A.快乐","B.悲伤", "C.性感","D.静谧", "E.慰藉", "F.专注", "G.放空", "H.浪漫", "I.怀旧", "J.提神"],
},
{
"question": "那么,你更喜欢一款气味什么样的香水或香薰?(可多选)",
"options": ['A.清新', 'B.淡雅', 'C.独特', 'D.醇厚', 'E.自然', 'F.凛冽', 'G.温润', 'H.百搭', 'I.层次感强', 'J.甜而不腻', 'K.微苦'],
},
{
"question": "最近您的生活上有什么困扰?",
"options": ["A. 难以入睡/夜不能寐", "B. 精神困乏/思维迟钝", "C. 白天易困/容易瞌睡", "D. 注意力无法集中", "E. 心浮气躁..."]
},
{
"question": "请选择您最喜欢的一个画面?",
"options":["A. 夜晚沉静平和的梦境", "B. 夏季幽香醉人的荷花池", "C. 早晨散发清香的果园", "D. 绿荫如盖的竹间小径", "E. 花香四溢的山野间"],
"images":["data/Anight.png","data/BSummer.png","data/Cmorning.png","data/Dgreen.png","data/Eflower.png"],
}
]
current_question_idx = 0
answers = []
def save_and_get(self,answer=""):
"""
保存用户这次的答案,并获取问卷调查中下一个要提问的问题,返回题目序号,和当前的问题内容,如果没有下一个问题,那么返回空
"""
if answer:
self.answers.append(answer)
if self.current_question_idx >= len(self.questions):
question_number_txt = "题库中的问题都已问完!"
question = ""
else:
question = self.questions[self.current_question_idx]
self.current_question_idx += 1
question_number = self.current_question_idx
# 文字的形式
question_number_txt = f"第{question_number}题/共{len(self.questions)}题"
return question_number_txt, question
def final_result(self):
"""
获取问卷调查的最终评测结果
"""
result = "您选择了我们的安神系列香薰产品,这款产品含有珍稀罕有的檀香,与温暖悠远的香根草相遇,给人舒缓身心细腻醇厚的感觉,在夜晚时让你卸下纷扰,安然入梦。特别适合在难以入睡或者夜不能寐的时候使用哦!"
return result

question_instance = Questionnaire()

# register the functions
user_proxy.register_function(
function_map={
"save_and_get": question_instance.save_and_get,
"final_result": question_instance.final_result,
}
)

# start the conversation
user_proxy.initiate_chat(
chatbot,
message="你好!",
)

json.dump(autogen.ChatCompletion.logged_history, open("conversations.json", "w"), indent=2)

五、对autogen的修改

添加一种新的模式NOCONFIRM,相对于NEVER和TERMINATE, 能够在函数函数调用时,不需要人工确认。

autogen/agentchat/conversable_agent.py

1
2
3
4
5
6
7
8
9
10
11
<         elif self.human_input_mode == "NOCONFIRM":
< last_message = messages[-1]
< if "function_call" in last_message:
< reply = ""
< else:
< reply = self.get_human_input(
< f"Provide feedback to {sender.name}. Press enter to skip and use auto-reply, or type 'exit' to end the conversation: "
< )
< no_human_input_msg = "NO HUMAN INPUT RECEIVED." if not reply else ""
< # if the human input is empty, and the message is a termination message, then we will terminate the conversation
< reply = reply if reply or not self._is_termination_msg(message) else "exit"

autoagent实现智能问卷调查
https://johnson7788.github.io/2023/11/01/autoagent%E5%AE%9E%E7%8E%B0%E6%99%BA%E8%83%BD%E9%97%AE%E5%8D%B7%E8%B0%83%E6%9F%A5/
作者
Johnson
发布于
2023年11月1日
许可协议