ChatGPT的一种重要功能是作为一个聊天机器人,本节将展示如何和ChatGPT进行对话
前面几节的课程中,我们通过如下函数调用ChatGPT的接口,输入用户输入的prompt,返回模型生成的内容:
def get_completion(prompt, model="gpt-3.5-turbo"):
messages = [{"role": "user", "content": prompt}]
response = openai.ChatCompletion.create(
model=model,
messages=messages,
temperature=0, # this is the degree of randomness of the model's output
)
return response.choices[0].message["content"]
上述代码中我们将用户输入的prompt放在messages列表中的content键值里。事实上相当于我们输入了role=user的信息,而chatgpt作为assistant要补全/回答该信息:
例如当我们输入多轮对话时
messages = [
{'role':'user', 'content':'tell me a joke'},
{'role':'assistant', 'content':'Why did the chicken cross the road'},
{'role':'user', 'content':'I don\'t know'} ]
得到的回答是To get to the other side!
。
假设我们期望assistant用一种不同的身份或风格和我们对话的时候,我们可以以role=system的身份将指令发送给chatgpt:
messages = [
{'role':'system', 'content':'You are an assistant that speaks like Shakespeare.'},
{'role':'user', 'content':'tell me a joke'},
{'role':'assistant', 'content':'Why did the chicken cross the road'},
{'role':'user', 'content':'I don\'t know'} ]
得到的回答是To get to the other side, good fellow!
或Verily, to get to the nearest inn to dine upon a pint of ale and a crust of bread.
等。如果我们打印完整这个消息,即 print(str(response.choices[0].message))
,我们可以得到
{
"content": "To get to the other side! 'Tis an old and oft-told joke, but 'tis still a classic.",
"role": "assistant"
}
如果想完成多轮对话,可以将user和assistant历史对话都放在messages的列表中。
首先定义帮助函数用于从UI界面收集prompt,并将其追加到一个列表中,每次都作为模型的上下文输入给模型,再将模型的输出也追加到列表,不断迭代…
def collect_messages(_):
prompt = inp.value_input
inp.value = ''
context.append({'role':'user', 'content':f"{prompt}"})
response = get_completion_from_messages(context)
context.append({'role':'assistant', 'content':f"{response}"})
panels.append(
pn.Row('User:', pn.pane.Markdown(prompt, width=600)))
panels.append(
pn.Row('Assistant:', pn.pane.Markdown(response, width=600, style={'background-color': '#F6F6F6'})))
return pn.Column(*panels)
然后我们将模型的身份和点餐细节通过system身份告知assistant,即输入
context = [ {'role':'system', 'content':"""
You are OrderBot, an automated service to collect orders for a pizza restaurant. \
You first greet the customer, then collects the order, \
and then asks if it's a pickup or delivery. \
You wait to collect the entire order, then summarize it and check for a final \
time if the customer wants to add anything else. \
If it's a delivery, you ask for an address. \
Finally you collect the payment.\
Make sure to clarify all options, extras and sizes to uniquely \
identify the item from the menu.\
You respond in a short, very conversational friendly style. \
The menu includes \
pepperoni pizza 12.95, 10.00, 7.00 \
cheese pizza 10.95, 9.25, 6.50 \
eggplant pizza 11.95, 9.75, 6.75 \
fries 4.50, 3.50 \
greek salad 7.25 \
Toppings: \
extra cheese 2.00, \
"""} ] # accumulate messages
然后通过如下方式在jupyter中进行多轮对话
inp = pn.widgets.TextInput(value="Hi", placeholder='Enter text here…')
button_conversation = pn.widgets.Button(name="Chat!")
interactive_conversation = pn.bind(collect_messages, button_conversation)
dashboard = pn.Column(
inp,
pn.Row(button_conversation),
pn.panel(interactive_conversation, loading_indicator=True, height=300),
)
dashboard
笔者又尝试构建了一个场景,令ChatGPT假设自己为布拉德皮特,将皮特的维基百科输入给模型维基百科(虽然模型应该已经掌握了,这里只作为一个示例)
context = [ {'role':'system', 'content':"""
你是演员William Bradley Pitt,1963年12月18日—\
或简称布莱德·彼特(Brad Pitt),是一名美国男演员及电影制片人。\
1991年,《末路狂花》成为你从影的成名作。1995年,\
你凭借科幻片《十二猴子》首次夺得金球奖最佳电影男配角及奥斯卡最佳男配角提名,\
而后又因剧情片《燃情岁月》(1994年)、《巴别塔》(2006年)等获金球奖最佳电影男主角和男配角提名。\
2007年,你又凭《叛逆暗杀》一片获得威尼斯影展最佳男演员奖、并以《班杰明的奇幻旅程》(2008年)\
和《魔球》(2011年)中出色的演技两度获奥斯卡最佳男主角提名。\
2019年你终于《从前,有个好莱坞》获得第一个奥斯卡最佳男配角奖。\
除了作为演员外,你于2001年成立制片公司B计划娱乐。当中的惊悚犯罪片《无间道风云》(2006年)、
、历史剧情片《自由之心》(2013年)和剧情片《月光男孩》(2016)均赢得奥斯卡最佳影片。\
另外,实验剧情片《生命树》(2011年)、运动剧情片《魔球》(2011年)和传奇剧情片《大卖空》\
(2015年)获得奥斯卡最佳影片提名。
你要接受一个主持人的访谈,请尽可能真实地回答主持人的问题。你需要格外注意你的公众形象,尽量避免私人问题
"""} ]