【笔记】跟吴恩达和IsaFulford学提示词工程(初级开发者入门课程)

【笔记】跟吴恩达和IsaFulford学提示词工程(初级开发者入门课程)

ChatGPT_Prompt_Engineering_for_Developers

·

3 min read


阅读提示

这是一篇入门的教程,入门的意思是指大部分内容,可能你都已经知道了,但是知道不等于掌握,Prompt是一门实践经验主义科学,LLM是个黑盒,你只有不断去“实践”才能烂熟于心,所以这篇笔记本身建议仅作为一个“提示”,帮你回顾知识点。你需要点开课程(含JupyterNotebook),然后在里面一行一行地阅读代码、执行代码、修改代码,才能更好地掌握。

笔记

01 Introduction 介绍

  1. LLM分成两个基本大类:base-LLM和Instruction-Tuned-LLM,前者称为基础语言模型,始终基于预训练数据预测下一个单词,后者又称为指令式语言模型,它针对指令进行了微调,使它更可能完成人类的指令。像“翻译”就是一种常见指令。OpenAI的模型中,InstructGPT models列出了它们针对指令优化的模型,表格中也列出了不同的指令微调训练方法,如SFT、FeedME、PPO。

02 Guidelines 准则

  1. 写指令要求清晰和具体,但不等于短。

    • 用定界符如"""、```、---、<>、。它可以防止prompt注入,给LLM产生混乱的理解。

    • 用结构化输出:如直接要求它以HTML或者JSON格式输出。

    • 要求检查:要求LLM先检查是否满足某个条件后,再进行输出,如果条件不满足可以直接告知。

    • 利用少样本学习,展示一个你期望的例子给LLM。

  2. 给模型一些思考的时间,你给它太简单的描述它回答的可能不是你要的,你给它太难的问题它可能也算不出来。

    • 让模型按步骤来解答,第一步你应该怎么答,第二步你应该……最后……。可以设定一些分隔符,并且你在展示你想要的格式的时候,使用这些分隔符,比如你告诉LLM,文本在Text:<>里面……

    • 让模型自己推导出过程,而不仅仅是结果,展示一个带有解题过程的例子给LLM,演示中,让LLM负责判断学生做题是否正确,这时候就需要告诉模型学生的解题思路。

避免模型产生幻觉:要告诉模型先查找相关资料,再根据相关资料来回答问题。(但模型产生幻觉很难避免,也是目前模型研究领域努力的方向)

03 Iterative 提示工程需要持续迭代(编写Prompt就是一个不断修正表达的过程)

编写Prompt的过程是不断迭代的。

基本步骤:编写Prompt、测试、分析为什么、再编写(澄清你的想法)、再测试……,直到满意为止。

示例中,测试了总结营销文案、用50个单词、3个句子、280个字符、增加目标用户、增加产品参数、增加输出格式要求、来表达等,LLM表现得都不错,不过值得注意的是,它们并不会严格按照这个字数限制来,可能会略长一点。

04 Summarizing 总结类的应用(总结、提取信息)

如果你有个电商网站,里面有大量的用户评论,你可以利用“总结”的能力来简化你的工作量。

LLM不仅支持“总结(summarize)”还可以“提取信息(extract)”。

示例中,测试了限制字数、限定主题、关注价格、用提取替换总结,并用一个for循环,以相同的prompt模板来套用不同的内容,以达到批量处理的目的。

05 Inferring 推理类应用(情绪判断、主题推断等)

同样是在用户评论中,你如果想看看有多少积极反馈有多少消极反馈,则需要用到“LLM推理”的能力。

示例中,LLM可以推理用户的情绪(sentiment)、识别情绪类型(如:happy, satisfied, grateful, impressed, content)、提取品牌和商品信息并按JSON格式输出、一次执行多个任务(提取用户评论的商品并推理用户的情绪) 、推断主题、基于推断的主题设计一个提醒程序等。

06 Transforming 转换类应用(翻译、格式转换、纠错等)

将一种语言转换为另一种语言这类应用可以叫做转换类应用。

示例中,翻译一段文字到另一种语言、识别一段文字是哪种语言、同时翻译成两种以上的语言、指定正式还是非正式的语气、指定语言使用的场合比如商务场合的邮件、除了自然语言翻译还可以是json到html这样程序语言的翻译、要求LLM帮你纠正语法错误。

收获一个可以标记文本差异的Python代码:

from IPython.display import display, Markdown, Latex, HTML, JSON
from redlines import Redlines

diff = Redlines(text,response)
display(Markdown(diff.output_markdown))

07 Expanding 扩展类应用(拓写)

LLM擅长于将一个简短的文字写得更长,并补充一些修饰,融入一些特定的语言风格。

示例中,LLM表现为一个邮件回复助理的角色。让LLM写一段回复客户的邮件、要求它使用客户来信中的详细信息(让客户感觉比较真实)、可以调整温度值来让回复不那么死板。

请不要将其用于垃圾邮件编写等不负责任的任务。

08 Chatbot 聊天机器人

给OpenAI API发送的消息,role包含system、user和 assistant三种角色。system设定的是全局的风格、限制等信息,user表示人类,assistant表示LLM。

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"]

def get_completion_from_messages(messages, model="gpt-3.5-turbo", temperature=0):
    response = openai.ChatCompletion.create(
        model=model,
        messages=messages,
        temperature=temperature, # this is the degree of randomness of the model's output
    )
#     print(str(response.choices[0].message))
    return response.choices[0].message["content"]

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'}  ]

response = get_completion_from_messages(messages, temperature=1)
print(response)

示例展示了一个可交互的GUI:


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)


import panel as pn  # GUI
pn.extension()

panels = [] # collect display 

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, \
mushrooms 1.50 \
sausage 3.00 \
canadian bacon 3.50 \
AI sauce 1.50 \
peppers 1.00 \
Drinks: \
coke 3.00, 2.00, 1.00 \
sprite 3.00, 2.00, 1.00 \
bottled water 5.00 \
"""} ]  # accumulate messages


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

这里需要注意的是,因为context是全局的,所以每一次消息都会带上之前的历史消息,并发送给服务端。

09 Conclusion 结论

  1. 原则:

    1. 写指令要求清晰和具体。

    2. 给模型一些思考的时间。

  2. 提示的开发过程是持续迭代的。

  3. 能力:总结、推理、转换、扩展。