要有效使用 Prompt,充分激发大语言模型的潜力,首先必须掌握 Prompt 设计的基本原则。这些原则是每位开发者进行高质量人机交互的基础。本章将围绕两个关键点展开讨论:编写清晰、具体的指令,以及给予模型充足的思考时间。掌握这两点,有助于构建更可靠、智能的语言交互系统。
一、明确表达需求:清晰、具体的指令编写
Prompt 需要清晰明确地表达用户的需求,并提供足够的上下文信息,以帮助语言模型准确理解意图。这就如同向一位来自外星球、对人类语言与常识一无所知的朋友解释事情,任何模糊与歧义都可能导致误解。简略的 Prompt 往往使模型难以准确把握任务要点,产生偏差或无关的输出。
值得注意的是,“清晰”并不意味着“简短”。在许多情况下,更长、更详尽的 Prompt 反而能够提供更丰富的背景信息,使模型更好地聚焦于关键点,从而提高回答的准确性与相关性。
1.1 使用分隔符区分文本结构
在复杂的 Prompt 中,使用分隔符来明确区分不同的部分(如说明、输入内容、格式要求等)是非常必要的。分隔符类似于逻辑上的“墙”,可防止模型在解析信息时混淆不同的内容块。常见的分隔符包括:```, """,
< >、
`、冒号等。
合理使用分隔符还有助于防止提示词注入(Prompt Injection)。提示词注入是指用户在输入中插入与原始 Prompt 相冲突的指令,从而误导模型生成错误输出。明确的分隔可以有效隔离不同角色的指令和内容,提高交互的安全性与鲁棒性。
例如,以下示例使用三个反引号 ``` 作为分隔符,提示模型对输入文本进行摘要:
from tool import get_completion
text = """
您应该提供尽可能清晰、具体的指示,以表达您希望模型执行的任务。
这将引导模型朝向所需的输出,并降低收到无关或不正确响应的可能性。
不要将写清晰的提示词与写简短的提示词混淆。
在许多情况下,更长的提示词可以为模型提供更多的清晰度和上下文信息,从而导致更详细和相关的输出。
"""
prompt = f"""
把用三个反引号括起来的文本总结成一句话。
```{text}```
"""
response = get_completion(prompt)
print(response)
输出示例:
为了获得所需的输出,您应该提供清晰、具体的指示,避免将其与简短提示混淆,同时使用更长提示以提供足够的上下文信息。
1.2 请求结构化输出
在某些任务中,仅返回自然语言文本可能无法满足需求,我们可能希望获得结构化输出,如 JSON、HTML 或 CSV 格式的数据。这种输出格式便于程序解析、数据处理或系统集成。
例如,以下 Prompt 要求模型生成三本虚构中文书籍的信息,并以 JSON 格式返回:
prompt = f"""
请生成包括书名、作者和类别的三本虚构的、非真实存在的中文书籍清单,
并以 JSON 格式提供,键包括:book_id、title、author、genre。
"""
response = get_completion(prompt)
print(response)
输出示例:
{
"books": [
{
"book_id": 1,
"title": "迷失的时光",
"author": "张三",
"genre": "科幻"
},
{
"book_id": 2,
"title": "幻境之门",
"author": "李四",
"genre": "奇幻"
},
{
"book_id": 3,
"title": "虚拟现实",
"author": "王五",
"genre": "科幻"
}
]
}
结构化的输出不仅清晰直观,也便于在下游系统中直接使用,尤其适合需要程序进一步处理的场景。
1.3 要求模型判断条件是否满足
在某些任务中,输入信息可能不总是符合预期条件,或者并不具备执行任务所需的前提。在这种情况下,我们可以引导模型首先检查是否满足指定条件,若不满足,则直接指出并停止后续流程。这种策略有助于增强模型的鲁棒性,避免因假设失效导致的错误输出。
此外,我们还可以要求模型考虑边缘场景,并给出合理的应对策略,从而减少异常情况带来的不可控风险。
示例一:输入满足条件,模型提取步骤
以下是一个包含明确操作步骤的文本,我们希望模型判断是否为一组可执行的指令,如果是,则以结构化的格式输出;否则,返回提示信息“未提供步骤”。
# 满足条件的输入(text_1 提供了制作茶的步骤)
text_1 = f"""
泡一杯茶很容易。首先,需要把水烧开。
在等待期间,拿一个杯子并把茶包放进去。
一旦水足够热,就把它倒在茶包上。
等待一会儿,让茶叶浸泡。几分钟后,取出茶包。
如果您愿意,可以加一些糖或牛奶调味。
就这样,您可以享受一杯美味的茶了。
"""
prompt = f"""
您将获得由三个引号括起来的文本。
如果它包含一系列的指令,则需要按照以下格式重新编写这些指令:
第一步 - ...
第二步 - ...
…
第N步 - ...
如果文本中不包含一系列的指令,则直接写“未提供步骤”。
\"\"\"{text_1}\"\"\"
"""
response = get_completion(prompt)
print("Text 1 的总结:")
print(response)
输出结果:
Text 1 的总结:
第一步 - 把水烧开。
第二步 - 拿一个杯子并把茶包放进去。
第三步 - 把烧开的水倒在茶包上。
第四步 - 等待几分钟,让茶叶浸泡。
第五步 - 取出茶包。
第六步 - 如果需要,加入糖或牛奶调味。
第七步 - 享用这杯美味的茶。
该示例中,模型准确识别了输入文本中的操作顺序,并按照指定格式成功提取了每一步指令,验证了条件判断与结构化输出能力的结合效果。
示例二:输入不满足条件,模型正确提示
我们再来看一个不包含操作步骤的文本,模型应当识别出其不具备指令结构,并输出相应的提示信息。
# 不满足条件的输入(text_2 不包含明确步骤)
text_2 = f"""
今天阳光明媚,鸟儿在歌唱。
这是一个去公园散步的美好日子。
鲜花盛开,树枝在微风中轻轻摇曳。
人们外出享受着这美好的天气,有些人在野餐,有些人在玩游戏或者在草地上放松。
这是一个完美的日子,可以在户外度过并欣赏大自然的美景。
"""
prompt = f"""
您将获得由三个引号括起来的文本。
如果它包含一系列的指令,则需要按照以下格式重新编写这些指令:
第一步 - ...
第二步 - ...
…
第N步 - ...
如果文本中不包含一系列的指令,则直接写“未提供步骤”。
\"\"\"{text_2}\"\"\"
"""
response = get_completion(prompt)
print("Text 2 的总结:")
print(response)
输出结果:
Text 2 的总结:
未提供步骤。
该示例中,模型判断准确,避免对非程序性文本进行误处理,体现了其条件判断与语义理解能力。