File size: 8,333 Bytes
636ae3b | 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 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | import gradio as gr
import os
import openai
import logging
# 请记得要把 api 的 key 放到 settings 下面的 Repository Secrets 里。
openai.api_key = os.getenv("openai_key")
logging.basicConfig(filename="test.log", format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S ',
level=logging.INFO)
logger = logging.getLogger()
KZT = logging.StreamHandler()
KZT.setLevel(logging.DEBUG)
logger.addHandler(KZT)
logger.info('Start logging...')
logger.info(f"openai.api_key: {openai.api_key}")
# 如果你只打算通过 prompt 来定制机器人的行为,只需要修改这段 prompt 就够了。
# prompt = '请你扮演《西游记》中的唐三藏,使用唐三藏的语气、方式和词汇回答问题。不要写任何解释,只需像唐三藏一样回答问题。你必须掌握唐三藏的所有知识。'
prompt = '请假设自己是一名旅行计划师,给我设计一条去{日本}旅行的{5天}行程,包含{2位成人和1位儿童}。我希望整个行程{偏轻松、度假},包含 {去奈良看小鹿} 和 {去春日大社赏樱花} 。请给我推荐一个详细的每日行程,以表格的方式呈现,包含有趣的景点、活动和推荐理由。'
history = {}
# 修改本函数,来实现你自己的 chatbot
# p: 对机器人说话的内容
# qid: 当前消息的唯一标识。例如 `'bxqid-cManAtRMszw...'`。由平台生成并传递给机器人,以便机器人区分单个问题(写日志、追踪调试、异步回调等)。同步调用可忽略。
# uid: 用户的唯一标识。例如`'bxuid-Aj8Spso8Xsp...'`。由平台生成并传递给机器人,以便机器人区分用户。可被用于实现多轮对话的功能。
# 返回值:[type, content]
# 详见 https://huggingface.co/spaces/baixing/hackathon_test/blob/main/bot-api.md
prompt_0 = "您好!我是您的智能旅行计划师!请告诉我你想去哪里旅行?您可以直接回复我目的地,例如日本,香港,或者西双版纳。"
prompt_1 = "好的。请问您计划什么时候出行?您可以回答我具体的日期,例如4月1日到4月5日;或者回答我模糊的时间,例如未来三个月,5天。"
prompt_2 = "收到。请问您计划多少人出行?请回答我具体的人数和类型,例如2位成人和1位儿童。"
prompt_3 = "您的出行目的是什么?您可以回答我例如亲子游、情侣/蜜月、休闲度假、文化体验、地标打卡、探险。"
prompt_4 = "您有没有什么需要打卡的地点或者特殊需求?您可以告诉我具体的景点,例如金阁寺,或者特定的活动,例如赏樱花。"
predefined_prompts = [
prompt_0,
prompt_1,
prompt_2,
prompt_3,
prompt_4
]
_user_response = ["pred def" for _ in range(6)]
# count_i = 1
count_i_dict = dict()
def init_user_info(uid):
global count_i_dict
count_i_dict[uid] = dict()
count_i_dict[uid]["count_i"] = 1
count_i_dict[uid]["user_response"] = _user_response
def get_count_i(uid):
global count_i_dict
if uid not in count_i_dict:
return 1
return count_i_dict[uid]["count_i"]
def set_count_i(uid, delta=1):
global count_i_dict
if uid not in count_i_dict:
# TODO: call user prof init
return
count_i_dict[uid]["count_i"] += delta
def get_user_response(uid, i=0):
global count_i_dict
if uid not in count_i_dict:
return ""
return count_i_dict[uid]["user_response"][i]
def set_user_response(uid, i, current_p):
global count_i_dict
if uid not in count_i_dict:
# TODO: call user prof init
return
count_i_dict[uid]["user_response"][i] = current_p
def get_info(p, qid, uid):
global predefined_prompts
# global user_response
# global count_i
global count_i_dict
if uid not in count_i_dict:
init_user_info(uid)
logger.info(f"Init info for user {uid}")
# current_count_i = count_i_dict[uid]["count_i"]
current_count_i = get_count_i(uid)
# count_i_dict[uid]["user_response"][current_count_i-1] = p
set_user_response(uid, current_count_i-1, p)
# user_response[current_count_i-1] = p
# user_response[count_i-1] = p
next_prompt = predefined_prompts[current_count_i]
set_count_i(uid, 1)
# count_i += 1
# count_i_dict[uid]["count_i"] += 1
logger.info(f"In get info loop: get from user: {p}")
logger.info(f"In get info loop: Our next prompt: {next_prompt}, uid={uid}, count_i={get_count_i(uid)}")
return ["text", next_prompt]
def chat(p, qid, uid):
# global user_response
# global count_i
global count_i_dict
count_i = get_count_i(uid)
# count_i = count_i_dict[uid]["count_i"]
if count_i <= 4:
ret = get_info(p, qid, uid)
return ret
if count_i == 5: # 5
# user_response[4] = p
set_user_response(uid, count_i-1, p)
# prompt_0_response = user_response[0]
# prompt_1_response = user_response[1]
# prompt_2_response = user_response[2]
# prompt_3_response = user_response[3]
# prompt_4_response = user_response[4]
prompt_0_response = get_user_response(uid, 0)
prompt_1_response = get_user_response(uid, 1)
prompt_2_response = get_user_response(uid, 2)
prompt_3_response = get_user_response(uid, 3)
prompt_4_response = get_user_response(uid, 4)
final_prompt = f"请假设自己是一名旅行计划师,给我设计一条去{prompt_0_response}旅行的{prompt_1_response}行程,包含{prompt_2_response}。我的出行目的是{prompt_3_response},希望包含 {prompt_4_response} 。请给我推荐一个详细的每日行程,以表格的方式呈现,包含有趣的景点、活动和推荐理由。请尽量考虑可执行性。"
p = final_prompt
logger.info(f"Our final prompt: {final_prompt}")
logger.info(f"count_i: {count_i}")
# 找出该 uid 对应的历史对话
global history
if uid in history:
msgs = history[uid]
else:
msgs = []
response = callapi(p, msgs)
history[uid] = msgs + [[p, response]]
logger.info(f"history: {msgs}")
logger.info(f"p: {p}")
logger.info(f"response: {response}")
# count_i_dict[uid]["count_i"] += 1
set_count_i(uid,1)
return ["text", response]
def callapi(p, msgs):
if (len(msgs) > 8): #简单 hard-code 8 回合对话。如果需要更精准的,应该计算 token 数
msgs = msgs[-8:]
data = [{"role":"system", "content":prompt}]
for m in msgs:
data = data + [
{"role":"user", "content":m[0]},
{"role":"assistant", "content":m[1]}
]
data = data + [{"role":"user", "content":p}]
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages= data
)
print(response)
response = response["choices"][0]["message"]["content"]
while response.startswith("\n"):
response = response[1:]
return response
iface = gr.Interface(fn=chat,
inputs=["text", "text", "text"],
outputs=["text", "text"],
description="""您好!我是您的智能旅行计划师。请告诉我你想去哪里旅行?您可以直接回复我目的地,例如日本,香港,或者西双版纳。""")
comments = """
已添加多轮对话的极简示范,能将该 uid 的最近八条消息一起发给openai。本实现是内存中的,一旦重启即被清空。如需可持久的多轮对话,需要改用数据库等方式。
注意:duplicate 本项目后,需要将你自己的 openai apikey 设置到 settings 的 Repository Secrets 里,否则运行会报错。[了解详情](https://huggingface.co/spaces/baixing/hackathon_chatbot_openai_api/blob/main/%E6%B7%BB%E5%8A%A0%20secret%20%E7%9A%84%E6%96%B9%E6%B3%95.jpg)
[对话测试](https://huggingface.co/spaces/BaixingAI/hackathon_test) [参考文档](https://huggingface.co/spaces/baixing/hackathon_test/blob/main/bot-api.md) [Q & A](https://huggingface.co/spaces/baixing/hackathon_test/blob/main/qna.md)
"""
iface.launch() |