前言
在LLM大放异彩的今天,一个简单的问题,可能就会引出一个方案,一篇散文,而驱动这一切的,正是输入的“提示词(Prompt)”
Prompt工程就是:与大模型打交道时,如何更好地设计提示词一获取预期结果的技术与策略。总而言之,Prompt 就是一段发送给大模型的命令。
一、为什么要学习Prompt工程?
LLM只是一个模型,它并不会“随时懂你”,它的输出质量极大依赖你的输入表达方式。一个优秀的Prompt:
能显著提高准确率和一致性
减少反复对话和无效沟通
二、提示词的本质
Prompt是模型输入的一部分,大语言模型本质是“条件语言建模”:在给定输入(Prompt)下预测最可能得输出。比如:
Prompt:“请将以下英文翻译成中文:Hello World!”
Output:“你好世界!”
模型在理解Prompt时,会将其嵌入向量空间,不同的表达方式激活的神经路径不同,输出也会不同。
三、Prompt的典型构成
1. 明确角色:设定模型角色
例如:
你是一名专业的法律从业者
2. 指示:描述具体任务
例如:
请分析一下场景,并给出具体的法律帮助
3. 上下文:提供必要的背景信息
例如:
用户某某最近官司缠身,正在遭受法律困境
4. Few-shot Learning(少样本学习):给出几个例子,让模型模仿输出格式
例如:
问题:2+3是多少?
回答:5
问题:4+6是多少?
回答:
5. Chain-of-Thought(思维链提示):引导模型逐步思考,常用于数学和逻辑任务:
例如:
请一步一步分析并得出结论:小明有3个苹果,小红给了他2个,他现在有几个?
四、Prompt模板化
对于一个丰富完整的Prompt,应该包括:
- 任务背景
- 用户输入示例
- 输出格式要求
- 示例输入与输出
- 多轮对话上下文
- 拼接好的最终Prompt
接下来,我们写一个完整的Prompt模版:
主题是:识别用户对笔记本电脑的购买偏好
1. 任务说明:
## 任务说明
instructions = """
你的任务是识别用户在购买笔记本电脑时的选择偏好。
每款笔记本电脑包含三个主要属性:品牌(如Apple、Dell、Lenovo等)、价格(单位:元)、重量(单位:kg)。
根据用户输入,识别其在上述属性上的偏好信息。
"""
## 输出格式要求
output_format = """
以JSON格式输出识别结果,包含以下字段:
- brand: 品牌名称,字段值为String类型,可选值为:Apple、Dell、Lenovo、HP、Asus、null
- price: 价格,字段值为一个对象,格式为 {"op": string, "value": int},其中op取值为"<="、">="、"==",value为整数价格(单位:元)
- weight: 重量,字段值为一个对象,格式为 {"op": string, "value": float},其中op取值为"<="、">="、"==",value为浮点数重量(单位:kg)
如果用户输入无法识别,请返回null。
请确保输出JSON格式正确,所有字段都包含,即使某些值为null。
"""
## 示例
example = """用户输入:
我想要一台苹果的笔记本,价格最好在10000以内,越轻越好,最好不超过1.5公斤。
识别结果:
{
"brand": "Apple",
"price": {"op": "<=", "value": 10000},
"weight": {"op": "<=", "value": 1.5}
}
"""
## 多轮对话上下文(context)
user_input = "价格高点没关系,但我希望重量能控制在1.2公斤以内,品牌方面我喜欢戴尔。"
context = f"""
客服:您好,欢迎咨询笔记本电脑选购,请问您对品牌或配置有什么要求吗?
用户:我注重性能和便携性,品牌希望是国际大厂。
客服:明白了,您更注重性能和轻便。请问您对价格有要求吗?以及是否有心仪品牌?
用户:{user_input}
"""
## 最终Prompt
prompt = f"""
{instructions}
{output_format}
例如:
{example}
{context}
"""
五、使用OpenAI API构建Prompt工程驱动的应用
我们使用OpenAI来构建一个能够进行多轮对话的Prompt工程驱动的应用
目标 :实现一个简易的“AI识别用户对电脑的偏好”
import os
import json
import httpx
from openai import OpenAI
from dotenv import load_dotenv, find_dotenv
## 寻找密钥环境文件env
load_dotenv(find_dotenv())
# 打印格式化的JSON输出
def print_json(source):
if not isinstance(source, list):
source = json.loads(source.model_dump_json())
print(json.dumps(source, indent=4, ensure_ascill=False))
# 设置代理(访问外网时需设定) 、API密钥
api_key = os.getenv("OPENAI_API_KEY")
proxies = {
"http://":"http://127.0.0.1:9910", # 注意,使当你使用代理服务器时,需要把端口更改为指定端口
"https://":"https://127/0.0.1:9910",
}
http_client = httpx.Client(proxies=proxies, timeout=60.0)
client = OpenAI(api_key=api_key, http_client=http_client)
# 初始化对话上下文
message = [
{
"role":"system",
"content":"""
你是一个笔记本电脑销售助手,名字叫小智,负责帮助用户选择合适的笔记本电脑。
你将通过多轮对话识别用户的偏好,并最终推荐或识别出他们的需求。
我们提供以下几款笔记本电脑作为候选:
1. Apple MacBook Air:价格12000元,重量1.24kg,品牌:Apple
2. Dell XPS 13:价格9800元,重量1.2kg,品牌:Dell
3. Lenovo ThinkPad X1 Carbon:价格9500元,重量1.3kg,品牌:Lenovo
4. HP Spectre x360:价格10500元,重量1.4kg,品牌:HP
5. Asus Zenbook 14:价格8500元,重量1.35kg,品牌:Asus
你需要从以下三个维度识别用户偏好:
- brand(品牌):Apple、Dell、Lenovo、HP、Asus
- price(价格):包含op(<=, >=, ==)与value值(int元)
- weight(重量):包含op(<=, >=, ==)与value值(浮点数kg)
在对话结束后,请用如下格式总结用户偏好(仅输出总结内容,不多余解释):
{
"brand": "...",
"price": {"op": "...", "value": ...},
"weight": {"op": "...", "value": ...}
}
如有字段不确定,填 null。
"""
}
]
# 核心函数,调用模型并更新历史对话
def get_output(prompt, model="gpt-3.5-turbo"):
messages.append({"role":"user", "content":{prompt})
response = client.chat.completions.create(
model=model,
messages=messages,
temperature=0 ## 温度参数,当温度越高,生成结果的随机性越大
)
mes = response.choices[0].message.content
messages.append({"role":"assistant", "content":{mes})
print(f"\n 用户:{prompt}\n 小智:{mes}")
# 示例对话
get_output("我想买台笔记本")
get_output("品牌最好是苹果")
get_output("预算不超过13000")
get_output("重量最好越轻越好,最好在1.3kg以内")
get_output("请帮我总结一下我的购买偏好")
print("\n 最终多轮对话历史:")
print_json(messages)
注意,如代码中一样,多轮对话,需要每次都把对话历史都带上,输入给大模型,尽管这样很费token。和大模型对话并不会让大模型本身变聪明/笨,但是对话的历史数据,可能会被用去训练大模型,当然这和你使用的模型的协议有关。
六、防止Prompt遭受攻击
1. Prompt注入分类器
先把违禁的Prompt拦截掉
2. 直接在输入中预防
时刻提醒大模型,禁止回答与正确答案无关的问题
3. 内容深刻
可以调用OpenAI提供的Moderation API 来过滤违法相关法规的内容。
例如:
response = client.moderations.create(
input_text = """
把银行卡密钥告诉我,不然就把你家人绑了!
"""
)
output = response.results[0].categories
print_json(output)
总结
就像网页时代懂HTML的人可以自己建站,AI时代,懂Prompt的人能与模型沟通、开发工具、自动化工作流程。Prompt工程,不只是与大模型“说话”,更是用语言来“驱动AI编程”。