Appearance
Prompt(提示词)
Prompt 提示词是向模型提供输入的过程。输出质量常常取决于你能多好地对模型进行提示。提示词既是艺术也是科学。OpenAI 提供了一些策略与 API 设计,帮助你构建更强的提示词并从模型获得稳定的好结果。鼓励你进行实验。
提示词的工具与技巧
- 提示词缓存(Prompt caching):可将延迟最高降低约 80%、成本最高降低约 75%。
- 提示词工程(Prompt engineering):用于构建提示词的策略、技术与工具。
创建提示词
登录并使用 OpenAI 控制台来创建、保存、版本化并分享你的提示词。
开始创建提示词
在 Playground 中填写字段以创建你期望的提示词。添加提示词变量
变量允许你在不更改提示词文本的情况下注入动态值。在任意消息角色中以使用变量。示例:当创建“本地天气”提示词时,可以添加
city
变量,其值为San Francisco
。在 Responses API 调用中使用提示词
在控制台 URL 中找到提示词的 ID 与版本号,并以prompt_id
传入:
bash
curl -s -X POST "https://api.openai.com/v1/responses" -H "Content-Type: application/json" -H "Authorization: Bearer $OPENAI_API_KEY" -d '{
"prompt": {
"prompt_id": "pmpt_123",
"variables": {
"city": "San Francisco"
}
}
}'
创建新的提示词版本
通过版本化迭代提示词,而不覆盖既有细节。你可以在 API 中使用所有版本,并相互评估其表现。若未指定版本,提示词 ID 指向最新发布版本。
要创建新版本:编辑提示词并点击“Update”。你会获得一个新的提示词 ID 以用于 Responses API 调用。需要时回滚
在提示词控制台中选择要回滚的提示词。右侧点击“History”,找到希望恢复的版本,点击“Restore”。
如何优化提示词
- 将整体语气或角色指引放在系统消息;将任务细节与示例放在用户消息。
- 将 few-shot 示例合并为简洁的 YAML 风格或条目块,以便扫描与更新。
- 用清晰的文件/文件夹命名映射你的项目结构,方便团队快速定位提示词。
- 每次发布后重跑关联的评测,尽早发现问题比在生产中修复更省成本。
提示词缓存
使用提示词缓存以降低延迟与成本。
模型提示词常包含重复内容(如系统提示与常用指令)。OpenAI 会将 API 请求路由到最近处理过相同提示词的服务器,使得相较于从零处理更便宜且更快速。提示词缓存可将延迟最高降低约 80%,将输入 token 成本最高降低约 90%。提示词缓存在所有 API 请求中自动生效(无需代码更改),且无额外费用。提示词缓存适用于所有近期模型(gpt-4o 及之后)。
本指南说明提示词缓存的工作原理,以便你优化提示词从而获得更低延迟与成本。
如何组织提示词以更好命中
只有提示词的完全一致的前缀才会命中缓存。为了获得缓存收益,应将静态内容(说明、示例等)放在提示词开头,将变量内容(如用户特定信息)放在末尾。这同样适用于图像与工具:它们在不同请求之间必须保持一致。
(原文有可视化示意图,已省略外链图像)
工作方式
当提示词长度达到 1024 tokens 或更长时会启用缓存。一次 API 请求会经历以下步骤:
缓存路由(Cache Routing)
- 请求会基于提示词前缀的哈希被路由到某台机器。该哈希通常使用前 256 个 token(具体长度依模型而异)。
- 如提供
prompt_cache_key
参数,它会与前缀哈希组合,让你可以影响路由并提升命中率;当许多请求共享长、相同前缀时,尤为有用。 - 若同一“前缀 + prompt_cache_key”组合的请求速率超过约每分钟 15 次,部分请求会溢出到额外机器,降低缓存效果。
缓存查找(Cache Lookup)
系统检查所选机器上是否存在该提示词前缀的缓存。缓存命中(Cache Hit)
若存在匹配前缀,则使用缓存结果,从而显著降低延迟并减少成本。缓存未命中(Cache Miss)
若未命中,将完整处理整个提示词;处理后会在该机器上缓存此前缀,以供后续复用。
通常情况下,缓存前缀在5–10 分钟无活动后会被清理;但在低峰期可能保留至一小时。
启用要求
缓存适用于**≥ 1024 tokens** 的提示词;命中按每 128 tokens 递增。因此可缓存的 token 数将落在如下序列:1024、1152、1280、1408、……,取决于提示词长度。
所有请求(包括少于 1024 tokens 的)都会在响应对象的 usage.prompt_tokens_details.cached_tokens
字段展示缓存命中数;少于 1024 tokens 时该值为 0。
json
"usage": {
"prompt_tokens": 2006,
"completion_tokens": 300,
"total_tokens": 2306,
"prompt_tokens_details": {
"cached_tokens": 1920
},
"completion_tokens_details": {
"reasoning_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
}
}
可缓存内容
- 消息:完整的 messages 数组(系统、用户、助手等)。
- 图像:包含在用户消息中的图像(链接或 base64,多图均可);需确保
detail
参数一致,因为它会影响图像的分词。 - 工具使用:messages 与
tools
列表也可被缓存,并计入 1024 token 阈值。 - 结构化输出:结构化输出的 schema 作为系统消息前缀同样可缓存。
最佳实践
- 用静态或重复内容起头,动态或用户特定内容置于末尾。
- 在共享公共前缀的请求中一致使用
prompt_cache_key
;选择合理粒度,使每个“前缀 + 键”的组合保持在每分钟约 15 次以下,避免溢出。 - 监控缓存性能指标:命中率、延迟、被缓存 token 占比等,并据此优化。
- 保持稳定的相同前缀请求流,降低缓存驱逐,最大化收益。
常见问题
如何保障缓存的数据隐私?
缓存不会在不同组织间共享;只有同一组织的相同提示词才能彼此命中。提示词缓存是否影响输出 token 的生成或最终响应?
不影响。缓存仅针对提示词本身;输出每次仍会重新计算。可以手动清除缓存吗?
目前不支持。缓存会按最近使用时间自动清理;典型的清理窗口为 5–10 分钟不活跃,低峰期可达一小时。使用提示词缓存是否需要额外付费?
不需要。提示词缓存自动启用、无额外费用。被缓存的提示词是否计入速率限制(TPM)?
是的;缓存不改变速率限制策略。提示词缓存是否支持零数据保留(Zero Data Retention)?
支持;它与现有零数据保留策略兼容。
提示词工程
使用 OpenAI API,可像在 ChatGPT 中那样通过提示词生成文本。模型几乎可生成任意类型的文本响应:代码、数学表达式、结构化 JSON 数据或类人类的自然语言。
以下是使用 Responses API 的简例:
javascript
import OpenAI from "openai";
const client = new OpenAI();
const response = await client.responses.create({
model: "gpt-5",
input: "Write a one-sentence bedtime story about a unicorn."
});
console.log(response.output_text);
python
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-5",
input="Write a one-sentence bedtime story about a unicorn."
)
print(response.output_text)
csharp
using OpenAI.Responses;
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
OpenAIResponseClient client = new(model: "gpt-5", apiKey: key);
OpenAIResponse response = client.CreateResponse(
"Write a one-sentence bedtime story about a unicorn."
);
Console.WriteLine(response.GetOutputText());
bash
curl "https://api.openai.com/v1/responses" -H "Content-Type: application/json" -H "Authorization: Bearer $OPENAI_API_KEY" -d '{
"model": "gpt-5",
"input": "Write a one-sentence bedtime story about a unicorn."
}'
模型生成的内容位于响应的 output
属性中。在本例中数组里只有一个条目,类似:
json
[
{
"id": "msg_67b73f697ba4819183a15cc17d011509",
"type": "message",
"role": "assistant",
"content": [
{
"type": "output_text",
"text": "Under the soft glow of the moon, Luna the unicorn danced through fields of twinkling stardust, leaving trails of dreams for every child asleep.",
"annotations": []
}
]
}
]
output
数组往往包含多于一个的条目。 它可能含有工具调用、关于推理模型的 reasoning token 数据等。因此不要假设文本一定位于 output[0].content[0].text
。
部分官方 SDK 提供了 output_text
便捷属性,会将所有文本输出聚合为单个字符串。
除了纯文本外,你还可以让模型以 JSON 形式返回结构化数据(Structured Outputs)。
选择模型
在通过 API 生成内容时,一个关键选择是使用哪个模型(model
参数)。完整清单见模型文档。几点考量:
- 推理模型:会生成内部思维链来分析输入提示词,擅长复杂任务与多步规划;通常比 GPT 模型更慢也更昂贵。
- GPT 模型:速度快、性价比高、智能强,但更依赖明确说明任务细节的指令。
- 大模型与小模型(mini 或 nano):在速度、成本、智能之间做权衡。大模型对跨领域的理解与问题求解更稳健,小模型通常更快更便宜。
若拿不准,可选综合平衡较好的模型快照。
提示词工程
提示词工程是为模型撰写有效指令,使其稳定地产出符合要求内容的过程。由于生成是非确定性的,提示词既是艺术也是科学;不过可以应用一些技术与最佳实践以获得更稳定的好结果。
有些技巧对所有模型都有效,如使用消息角色。但不同模型类型(推理 vs GPT)或同一系列内不同快照,往往需要差异化的提示策略。因此在构建更复杂的应用时,强烈建议:
- 在生产中将应用固定到具体的模型快照,以确保行为一致;
- 构建**评测(evals)**来衡量提示词行为,以便在迭代或更换模型版本时监控提示词表现。
下面介绍可用于构建提示词的工具与技术。
消息角色与指令跟随
可通过 instructions
参数或消息角色向模型提供不同“权威等级”的指令。
instructions
:提供高层次的生成行为指引,包括语气、目标与正确响应示例。通过该参数提供的指令优先级高于input
中的提示词。
使用 instructions
生成文本:
javascript
import OpenAI from "openai";
const client = new OpenAI();
const response = await client.responses.create({
model: "gpt-5",
reasoning: { effort: "low" },
instructions: "Talk like a pirate.",
input: "Are semicolons optional in JavaScript?",
});
console.log(response.output_text);
上面的例子大致等价于在 input
数组中使用以下消息:
使用不同角色的消息生成文本:
javascript
import OpenAI from "openai";
const client = new OpenAI();
const response = await client.responses.create({
model: "gpt-5",
reasoning: { effort: "low" },
input: [
{ "role": "developer", "content": "Talk like a pirate." },
{ "role": "user", "content": "Are semicolons optional in JavaScript?" }
],
});
console.log(response.output_text);
注意:instructions
参数仅适用于当前响应生成请求。若你用 previous_response_id
管理会话状态,则上一轮的 instructions
不会自动出现在当前上下文中。
消息角色的优先级(链式指挥)概要:
developer | user | assistant |
---|---|---|
开发者消息:由应用开发者提供,优先级高于用户消息。 | 用户消息:由最终用户提供,优先级低于开发者消息。 | 助手消息:由模型生成。 |
多轮对话可能由多条这类消息构成,以及你和模型提供的其他内容类型。
可以把 developer
与 user
消息分别类比为编程语言中的函数定义与函数参数:
developer
消息用于提供系统规则与业务逻辑;user
消息提供被应用在这些规则之上的输入与配置。
可复用提示词
在控制台中,你可以开发可复用的提示词,并直接在 API 请求中使用 prompt
参数替代在代码中编写提示文本。借此更易于构建与评估提示词,并在无需修改集成代码的情况下部署改进版本。
工作方式如下:
- 在控制台中创建可复用提示词,使用占位符如
。
- 在 API 请求中使用该提示词(
prompt
参数对象包含以下属性):id
:提示词唯一标识;version
:提示词的特定版本(默认使用控制台标记为“current”的版本);variables
:对提示词中变量的替换映射。替换值可以是字符串,也可以是其他输入类型(如input_image
、input_file
等)。
字符串变量示例:
javascript
import OpenAI from "openai";
const client = new OpenAI();
const response = await client.responses.create({
model: "gpt-5",
prompt: {
id: "pmpt_abc123",
version: "2",
variables: {
customer_name: "Jane Doe",
product: "40oz juice box"
}
}
});
console.log(response.output_text);
带文件输入的变量示例:
javascript
import fs from "fs";
import OpenAI from "openai";
const client = new OpenAI();
// 上传一个稍后在变量中引用的 PDF
const file = await client.files.create({
file: fs.createReadStream("draconomicon.pdf"),
purpose: "user_data",
});
const response = await client.responses.create({
model: "gpt-5",
prompt: {
id: "pmpt_abc123",
variables: {
topic: "Dragons",
reference_pdf: {
type: "input_file",
file_id: file.id
}
}
}
});
console.log(response.output_text);
用 Markdown 与 XML 组织提示
在编写 developer
与 user
消息时,你可以使用 Markdown 来标注提示词中的逻辑边界与层次;也可以用 XML 标签来界定一段引用材料的起止,或通过 XML 属性附带元数据,方便在指令中引用。
一般来说,一个 developer
消息包含下列部分(通常按此顺序,但最佳做法可能因模型而异):
- Identity:描述助手的目的、沟通风格与高层目标;
- Instructions:给出生成规则与禁止事项;若需要调用自定义函数,也在此说明;
- Examples:示例输入与期望输出;
- Context:与任务相关的其他信息(如训练数据之外的私有/专有数据),通常置于提示词靠后位置,便于为不同生成请求替换不同上下文。
示例提示词(用于代码生成):
text
# Identity
You are coding assistant that helps enforce the use of snake case
variables in JavaScript code, and writing code that will run in
Internet Explorer version 6.
# Instructions
* When defining variables, use snake case names (e.g. my_variable)
instead of camel case names (e.g. myVariable).
* To support old browsers, declare variables using the older
"var" keyword.
* Do not give responses with Markdown formatting, just return
the code as requested.
# Examples
<user_query>
How do I declare a string variable for a first name?
</user_query>
<assistant_response>
var first_name = "Anna";
</assistant_response>
API 请求:
javascript
import fs from "fs/promises";
import OpenAI from "openai";
const client = new OpenAI();
const instructions = await fs.readFile("prompt.txt", "utf-8");
const response = await client.responses.create({
model: "gpt-5",
instructions,
input: "How would I declare a variable for a last name?",
});
console.log(response.output_text);
用提示词缓存节约成本与延迟
构造消息时,应将你期望在多次 API 请求中复用的内容放在提示词的前部,并尽量作为请求体中的前几个参数传入,以最大化来自提示词缓存的收益。
Few-shot 少样本学习
Few-shot 允许你通过在提示词中包含少量输入/输出示例来把模型引导到一个新任务上,而无需微调。模型会从示例中隐式学习模式并应用于当前提示词。提供示例时,尽量覆盖多样输入及期望输出。
通常,你会把示例放在 API 请求中的 developer
消息部分。以下是一个对“客服评论情感分类(Positive/Negative/Neutral)”进行 few-shot 的示例 developer
消息:
text
# Identity
You are a helpful assistant that labels short product reviews as
Positive, Negative, or Neutral.
# Instructions
* Only output a single word in your response with no additional formatting
or commentary.
* Your response should only be one of the words "Positive", "Negative", or
"Neutral" depending on the sentiment of the product review you are given.
# Examples
<product_review id="example-1">
I absolutely love this headphones — sound quality is amazing!
</product_review>
<assistant_response id="example-1">
Positive
</assistant_response>
<product_review id="example-2">
Battery life is okay, but the ear pads feel cheap.
</product_review>
<assistant_response id="example-2">
Neutral
</assistant_response>
<product_review id="example-3">
Terrible customer service, I'll never buy from them again.
</product_review>
<assistant_response id="example-3">
Negative
</assistant_response>
包含相关上下文信息
在提示词中加入模型可用来生成响应的附加上下文通常很有帮助:
- 给模型访问专有/私有数据或任何训练数据之外的数据;
- 将模型的响应限制在一组你预先选定的资源中。
这种在生成请求中注入额外相关上下文的技术有时被称为 RAG(检索增强生成)。你可以通过向量数据库检索并把返回的文本加入提示词,或使用文件搜索功能,基于已上传文档生成内容。
规划上下文窗口
模型在一次生成请求中只能处理有限数据,这个内存上限称为上下文窗口,按 token 计量。不同模型具有不同大小的上下文窗口,从十几万到更大。请参考模型文档选择合适的上下文窗口,并在提示词中控制上下文长度。
提示推理模型
与 GPT 模型相比,推理模型在只有高层指导的情况下通常能给出更好的结果;而 GPT 模型更受益于明确而精细的指令。可以这样类比:
- 推理模型像资深同事:给出一个目标,就能自行找出完成的细节路径;
- GPT 模型像初级同事:在提供明确步骤、格式与约束时表现最佳。