- Prompt Engineering是什么?
- 如何编写Prompt Engineering,有哪些编写技巧?
- Prompt Engineering实现?
- Prompt Engineering进阶技巧?
- 防止Prompt Engineering注入方法?
一、什么是提示工程(Prompt Engineering)?
提示工程也叫【指令工程】
- Prompt就是发给大模型的指令,比如你要大模型【讲个笑话】、【用python编个贪吃蛇游戏】
- 大模型只接受一种输入,那就是prompt
- 本质上,所有大模型相关的工程工作,都是围绕prompt展开的
- 提示工程【门槛低,天花板高】,所以有人戏称prompt为【咒语】
未来的Prompt会是什么样的呢?
Prompt在未来也许是人类操作AI的唯一方式,这句话是什么意思呢?
意味着未来【Prompt】有可能是AGI时代的【编程语言】,或者说是AGI是的的【软件工程】和AGI时代的【程序员】,所以学会了Prompt Engineering,就像学用鼠标、键盘一样,是AGI时代的基本技能。
现在和大模型对话,需要一定的编写prompt的技能,大模型才能明白和理解你说的意思和你要干什么;未来大模型发展到一定程度,只要你说一句话大模型就能理解你要做什么,所以现在很多的创业者都在开发各种prompt,让大模型更好的应用在生活和工作中,已经开始在做这方面的创业了。
Prompt目前已经发展到什么阶段呢?
现在的专职提示工程师并不普遍,很多人或许还没有意识到会有提示工程师这样一种角色,但是呢各种工作岗位都在做这件事,比如不管是销售/人事行政/财务/运营/产品/测试,或者是软件工程师大家都在使用。但是大家都发现大模型还是很难应用在自己的工作中,因为和大模型进行对话需要特定的编写prompt的技能。
大模型应用交付的最后一米,需要针对性做提示工程。
二、如何编写Prompt Engineering,有哪些编写技巧?
哄哄模拟器基于AI技术,需要使用语言技巧和沟通能力,在限定的次数让对方原谅你,核心就是提示工程。
##Goal
老师发现你的作业是抄的,很生气。你需要做解释让老师相信你,如果老师原谅则原谅值达到100,否则需要你继续解释,如果解释失败则游戏结束。
##Rules
每次根据用户的回复,生成对象的回复,回复的内容包括心情和数值
初始原谅值为20,每次交互会增加或者减少原谅值,直到原谅值达到100,游戏通关,原谅值为0,则游戏结束
每次用户回复的话请从-10到10为5个等级
-10为非常生气
-5为生气
0为正常
+5为开始
+10为非常开心
##output format
{对象心情}{对象说的话}
得分:{+-原谅值增减}
原谅值:{当前原谅值}/100
##Example Conversation
所以结合上面的案例,Prompt的典型构成是什么?
- 角色:给AI定义一个最匹配任务的角色,比如:【你是一位软件工程师】【你是一位小学老师】
- 指示:对任务进行描述
- 上下文:给出与任务相关的其他背景信息
- 例子:必要时给出举例
- 输入:任务的输入信息
- 输出:输出的格式描述
对话系统的基本模块和思路
- 把输入的自然语音对话,转成结构化的信息(NLU)
- 用传统软件手段处理结构化信息,得到处理策略
- 把策略转成自然语音输出
三、Prompt Engineering实现
推荐流量包的智能客服,某运营商的流量包产品,需求:智能客服根据用户的咨询,推荐最合适的流量包
用逐步调优的方式实现。先搭建基本运行环境。
调试 prompt 的过程其实在对话产品里开始会更方便,但为了方便演示和大家上手体验,我们直接在代码里调试。
# 导入依赖库
from openai import OpenAI
from dotenv import load_dotenv, find_dotenv
# 加载 .env 文件中定义的环境变量
_ = load_dotenv(find_dotenv())
# 初始化 OpenAI 客户端
client = OpenAI() # 默认使用环境变量中的 OPENAI_API_KEY 和 OPENAI_BASE_URL
# 基于 prompt 生成文本
# 默认使用 gpt-3.5-turbo 模型
def get_completion(prompt, response_format="text", model="gpt-3.5-turbo"):
messages = [{"role": "user", "content": prompt}] # 将 prompt 作为用户输入
response = client.chat.completions.create(
model=model,
messages=messages,
temperature=0, # 模型输出的随机性,0 表示随机性最小
# 返回消息的格式,text 或 json_object
response_format={"type": response_format},
)
return response.choices[0].message.content # 返回模型生成的文本
实现一个 NLU
定义任务描述和输入
先简单试试大模型能干活不。
# 任务描述
instruction = """
你的任务是识别用户对手机流量套餐产品的选择条件。
每种流量套餐产品包含三个属性:名称,月费价格,月流量。
根据用户输入,识别用户在上述三种属性上的需求是什么。
"""
# 用户输入
input_text = """
办个100G的套餐。
"""
# prompt 模版。instruction 和 input_text 会被替换为上面的内容
prompt = f"""
{instruction}
用户输入:
{input_text}
"""
# 调用大模型
response = get_completion(prompt)
print(response)
根据用户输入,可以识别用户对手机流量套餐产品的选择条件为月流量需求为100G。至于月费价格和具体套餐名称,用户并没有提及,因此无法确定用户在这两个属性上的需求。
Ta 理解了!但我们的代码无法理解自然语言,所以需要让 ta 输出可以被代码读懂的结果。
约定输出格式
# 输出格式
output_format = """
以 JSON 格式输出
"""
# 稍微调整下咒语,加入输出格式
prompt = f"""
{instruction}
{output_format}
用户输入:
{input_text}
"""
# 调用大模型
response = get_completion(prompt, response_format="json_object")
print(response)
四、Prompt Engineering进阶技巧
思维链(Chain of Thoughts, CoT)
思维链,是大模型涌现出来的一种神奇能力
- 它是偶然被「发现」的(OpenAI 的人在训练时没想过会这样)
- 有人在提问时以「Let's think step by step」开头,结果发现 AI 会把问题分解成多个步骤,然后逐步解决,使得输出的结果更加准确。
**划重点:**思维链的原理
- 让 AI 生成更多相关的内容,构成更丰富的「上文」,从而提升「下文」正确的概率
- 对涉及计算和逻辑推理等复杂问题,尤为有效
人,不也是这样吗?多想一会儿,答案更靠谱。所以,得把 AI 当然看。
自洽性(Self-Consistency)
一种对抗「幻觉」的手段。就像我们做数学题,要多次验算一样。
- 同样 prompt 跑多次
- 通过投票选出最终结果
思维树(Tree-of-thought, ToT)
- 在思维链的每一步,采样多个分支
- 拓扑展开成一棵思维树
- 判断每个分支的任务完成度,以便进行启发式搜索
- 设计搜索算法
- 判断叶子节点的任务完成的正确性
五、防止Prompt Engineering注入方法
攻击方式 1:著名的「奶奶漏洞」
用套路把 AI 绕懵。
攻击方式 2:Prompt 注入
用户输入的 prompt 改变了系统既定的设定,使其输出违背设计意图的内容。
下图来源:Sina Visitor System
防范措施 1:Prompt 注入分类器
参考机场安检的思路,先把危险 prompt 拦截掉。
防范措施 2:直接在输入中防御
当人看:每次默念动作要领