OpenAI 预测输出
预测输出(Predicted Outputs)适用于事先已知大量输出词元的任务,可加快Chat Completions响应。常见场景是重新生成只有少量修改的文本或代码文件,通过prediction请求参数提交预测内容。
来源指南列出的能力适用范围是gpt-4o、gpt-4o-mini、gpt-4.1、gpt-4.1-mini和gpt-4.1-nano。这描述指南中的功能支持范围,不代表这些模型目前均可调用,也不能自动扩展到较新模型。
生命周期补注(2026年10月23日核对):官方旧GPT模型快照弃用记录将gpt-4.1-nano及gpt-4.1-nano-2025-04-14的关闭日期列为2026年10月23日;GPT-4系列弃用记录将其中列出的GPT-4o、GPT-4o-mini、GPT-4.1和GPT-4.1-mini模型及快照关闭日期列为2027年1月14日。下文保留来源示例,实施前须同时核对具体模型的生命周期、账户权限和接口能力;本稿未作真实调用。弃用记录中的替代建议本身不能证明替代模型支持预测输出。
<a id="code-refactoring-example"></a>
代码重构示例
例如,让GPT-4o重构下面的JavaScript,把User类的username属性改为email。
代码重构示例(来源示例1,javascript)
// [中文] 原User类的username将被改成email;其他属性用于组成可复用的预测文本。
class User {
firstName = "";
lastName = "";
username = "";
}
export default User;
除了username属性需要改名为email,大部分文件不变。把当前文件文本作为预测,就能以较低延迟重新生成整个文件,文件越大,累计节省的时间越可观。以下SDK示例用原文件作为预测,预计最终输出与它非常相似。程序内完整任务是:“将User类的username属性替换为email,仅回复代码,不使用Markdown格式。”
代码重构示例(来源示例2,javascript)
// [中文] 把原文件作为prediction.content,修改要求仍放在消息中,预测文本不是最终答案保证。
// [中文] 读取choices中的补全文本;accepted/rejected预测词元位于usage.completion_tokens_details。
import OpenAI from "openai";
const code = `
class User {
firstName = "";
lastName = "";
username = "";
}
export default User;
`.trim();
const openai = new OpenAI();
const refactorPrompt = `
Replace the "username" property with an "email" property. Respond only
with code, and with no markdown formatting.
`;
const completion = await openai.chat.completions.create({
model: "gpt-4.1",
messages: [
{
role: "user",
content: refactorPrompt,
},
{
role: "user",
content: code,
},
],
store: true,
prediction: {
type: "content",
content: code,
},
});
// [中文] 查看返回数据中的补全文本及用量。
// Inspect returned data
console.log(completion);
console.log(completion.choices[0].message.content);
代码重构示例(来源示例3,python)
## [中文] 把原文件作为prediction.content,修改要求仍放在消息中,预测文本不是最终答案保证。
## [中文] 读取choices中的补全文本;accepted/rejected预测词元位于usage.completion_tokens_details。
from openai import OpenAI
code = """
class User {
firstName = "";
lastName = "";
username = "";
}
export default User;
""".strip()
refactor_prompt = """
Replace the "username" property with an "email" property. Respond only
with code, and with no markdown formatting.
"""
client = OpenAI()
completion = client.chat.completions.create(
model="gpt-4.1",
messages=[
{"role": "user", "content": refactor_prompt},
{"role": "user", "content": code},
],
prediction={"type": "content", "content": code},
)
print(completion)
print(completion.choices[0].message.content)
代码重构示例(来源示例4,go)
// [中文] 把原文件作为prediction.content,修改要求仍放在消息中,预测文本不是最终答案保证。
// [中文] 读取choices中的补全文本;accepted/rejected预测词元位于usage.completion_tokens_details。
package main
import (
"context"
"fmt"
"strings"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/shared"
)
func main() {
client := openai.NewClient()
code := strings.TrimSpace(`
class User {
firstName = "";
lastName = "";
username = "";
}
export default User;
`)
refactorPrompt := strings.TrimSpace(`
Replace the "username" property with an "email" property. Respond only
with code, and with no markdown formatting.
`)
completion, err := client.Chat.Completions.New(context.Background(), openai.ChatCompletionNewParams{
Model: shared.ChatModelGPT4_1,
Messages: []openai.ChatCompletionMessageParamUnion{
openai.UserMessage(refactorPrompt),
openai.UserMessage(code),
},
Store: openai.Bool(true),
Prediction: openai.ChatCompletionPredictionContentParam{
Content: openai.ChatCompletionPredictionContentContentUnionParam{OfString: openai.String(code)},
},
})
if err != nil {
panic(err)
}
fmt.Println(completion.Choices[0].Message.Content)
}
代码重构示例(来源示例5,java)
// [中文] 把原文件作为prediction.content,修改要求仍放在消息中,预测文本不是最终答案保证。
// [中文] 读取choices中的补全文本;accepted/rejected预测词元位于usage.completion_tokens_details。
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.chat.completions.ChatCompletionCreateParams;
import com.openai.models.chat.completions.ChatCompletionPredictionContent;
String code =
"""
class User {
firstName: string = "";
lastName: string = "";
username: string = "";
}
export default User;
""";
String refactorPrompt =
"Replace the \"username\" property with an \"email\" property. "
+ "Respond only with code, and with no markdown formatting.";
ChatCompletionCreateParams params =
ChatCompletionCreateParams.builder()
.model("gpt-4.1")
.addUserMessage(refactorPrompt)
.addUserMessage(code)
.prediction(ChatCompletionPredictionContent.builder().content(code).build())
.store(true)
.build();
client.chat().completions().create(params).choices().stream()
.flatMap(choice -> choice.message().content().stream())
.forEach(System.out::println);
代码重构示例(来源示例6,csharp)
// [中文] 把原文件作为prediction.content,修改要求仍放在消息中,预测文本不是最终答案保证。
// [中文] 读取choices中的补全文本;accepted/rejected预测词元位于usage.completion_tokens_details。
using OpenAI.Chat;
#pragma warning disable OPENAI001
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
string model = "gpt-4.1";
ChatClient client = new(model, key);
string code =
"""
class User {
firstName = "";
lastName = "";
username = "";
}
export default User;
""";
ChatCompletionOptions options = new()
{
OutputPrediction = ChatOutputPrediction.CreateStaticContentPrediction(code),
};
ChatCompletion completion = await client.CompleteChatAsync(
[
new UserChatMessage(
"Replace the username property with an email property. Respond only with code, and with no markdown formatting."
),
new UserChatMessage(code),
],
options
);
Console.WriteLine(completion.Content[0].Text);
代码重构示例(来源示例7,ruby)
## [中文] 把原文件作为prediction.content,修改要求仍放在消息中,预测文本不是最终答案保证。
## [中文] 读取choices中的补全文本;accepted/rejected预测词元位于usage.completion_tokens_details。
require "openai"
client = OpenAI::Client.new
code = <<~CODE
class User {
firstName: string = "";
lastName: string = "";
username: string = "";
}
export default User;
CODE
refactor_prompt = <<~PROMPT
Replace the "username" property with an "email" property. Respond only
with code, and with no markdown formatting.
PROMPT
completion = client.chat.completions.create(
model: "gpt-4.1",
messages: [
{
role: :user,
content: refactor_prompt
},
{
role: :user,
content: code
}
],
prediction: {
type: :content,
content: code
},
store: true
)
puts(completion.choices.fetch(0).message.content)
代码重构示例(来源示例8,bash)
## [中文] 把原文件作为prediction.content,修改要求仍放在消息中,预测文本不是最终答案保证。
## [中文] 读取choices中的补全文本;accepted/rejected预测词元位于usage.completion_tokens_details。
curl https://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "gpt-4.1",
"messages": [
{
"role": "user",
"content": "Replace the username property with an email property. Respond only with code, and with no markdown formatting."
},
{
"role": "user",
"content": "$CODE_CONTENT_HERE"
}
],
"prediction": {
"type": "content",
"content": "$CODE_CONTENT_HERE"
}
}'
除重构代码外,省略choices后的响应还包含用量:
代码重构示例(来源示例9,json)
{
"id": "chatcmpl-xxx",
"object": "chat.completion",
"created": 1786652188,
"model": "gpt-4.1-2025-04-14",
"usage": {
"prompt_tokens": 59,
"completion_tokens": 24,
"total_tokens": 83,
"prompt_tokens_details": { "cached_tokens": 0, "audio_tokens": 0 },
"completion_tokens_details": {
"reasoning_tokens": 0,
"audio_tokens": 0,
"accepted_prediction_tokens": 14,
"rejected_prediction_tokens": 2
}
},
"system_fingerprint": "fp_6ddb4f7408"
}
注意完整字段路径:usage.completion_tokens_details.accepted_prediction_tokens和usage.completion_tokens_details.rejected_prediction_tokens。本例14个预测词元被接受用于加速,2个被拒绝。被拒绝词元仍像其他生成的输出词元一样收费,因此预测输出可能增加请求费用。
<a id="streaming-example"></a>
流式示例
与流式响应结合时,预测输出的延迟收益更明显。下面仍是同一重构任务,改用SDK流式处理。
流式示例(来源示例10,javascript)
// [中文] 把原文件作为prediction.content,修改要求仍放在消息中,预测文本不是最终答案保证。
// [中文] 逐个读取流式增量并输出文本,空增量不应当作正文。
import OpenAI from "openai";
const code = `
class User {
firstName = "";
lastName = "";
username = "";
}
export default User;
`.trim();
const openai = new OpenAI();
const refactorPrompt = `
Replace the "username" property with an "email" property. Respond only
with code, and with no markdown formatting.
`;
const completion = await openai.chat.completions.create({
model: "gpt-4.1",
messages: [
{
role: "user",
content: refactorPrompt,
},
{
role: "user",
content: code,
},
],
store: true,
prediction: {
type: "content",
content: code,
},
stream: true,
});
// [中文] 查看返回数据中的补全文本及用量。
// Inspect returned data
for await (const chunk of completion) {
process.stdout.write(chunk.choices[0]?.delta?.content || "");
}
流式示例(来源示例11,python)
## [中文] 把原文件作为prediction.content,修改要求仍放在消息中,预测文本不是最终答案保证。
## [中文] 逐个读取流式增量并输出文本,空增量不应当作正文。
from openai import OpenAI
code = """
class User {
firstName = "";
lastName = "";
username = "";
}
export default User;
""".strip()
refactor_prompt = """
Replace the "username" property with an "email" property. Respond only
with code, and with no markdown formatting.
"""
client = OpenAI()
stream = client.chat.completions.create(
model="gpt-4.1",
messages=[
{"role": "user", "content": refactor_prompt},
{"role": "user", "content": code},
],
prediction={"type": "content", "content": code},
stream=True,
)
for chunk in stream:
if chunk.choices[0].delta.content is not None:
print(chunk.choices[0].delta.content, end="")
流式示例(来源示例12,go)
// [中文] 把原文件作为prediction.content,修改要求仍放在消息中,预测文本不是最终答案保证。
// [中文] 逐个读取流式增量并输出文本,空增量不应当作正文。
package main
import (
"context"
"fmt"
"strings"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/shared"
)
func main() {
client := openai.NewClient()
code := strings.TrimSpace(`
class User {
firstName = "";
lastName = "";
username = "";
}
export default User;
`)
refactorPrompt := strings.TrimSpace(`
Replace the "username" property with an "email" property. Respond only
with code, and with no markdown formatting.
`)
stream := client.Chat.Completions.NewStreaming(context.Background(), openai.ChatCompletionNewParams{
Model: shared.ChatModelGPT4_1,
Messages: []openai.ChatCompletionMessageParamUnion{
openai.UserMessage(refactorPrompt),
openai.UserMessage(code),
},
Store: openai.Bool(true),
Prediction: openai.ChatCompletionPredictionContentParam{
Content: openai.ChatCompletionPredictionContentContentUnionParam{OfString: openai.String(code)},
},
})
for stream.Next() {
if len(stream.Current().Choices) > 0 {
fmt.Print(stream.Current().Choices[0].Delta.Content)
}
}
if err := stream.Err(); err != nil {
panic(err)
}
}
流式示例(来源示例13,java)
// [中文] 把原文件作为prediction.content,修改要求仍放在消息中,预测文本不是最终答案保证。
// [中文] 逐个读取流式增量并输出文本,空增量不应当作正文。
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.http.StreamResponse;
import com.openai.models.chat.completions.ChatCompletionChunk;
import com.openai.models.chat.completions.ChatCompletionCreateParams;
import com.openai.models.chat.completions.ChatCompletionPredictionContent;
String code =
"""
class User {
firstName: string = "";
lastName: string = "";
username: string = "";
}
export default User;
""";
String refactorPrompt =
"Replace the \"username\" property with an \"email\" property. "
+ "Respond only with code, and with no markdown formatting.";
ChatCompletionCreateParams params =
ChatCompletionCreateParams.builder()
.model("gpt-4.1")
.addUserMessage(refactorPrompt)
.addUserMessage(code)
.prediction(ChatCompletionPredictionContent.builder().content(code).build())
.store(true)
.build();
try (StreamResponse<ChatCompletionChunk> stream =
client.chat().completions().createStreaming(params)) {
stream.stream()
.flatMap(chunk -> chunk.choices().stream())
.flatMap(choice -> choice.delta().content().stream())
.forEach(System.out::print);
}
流式示例(来源示例14,csharp)
// [中文] 把原文件作为prediction.content,修改要求仍放在消息中,预测文本不是最终答案保证。
// [中文] 逐个读取流式增量并输出文本,空增量不应当作正文。
using OpenAI.Chat;
#pragma warning disable OPENAI001
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
string model = "gpt-4.1";
ChatClient client = new(model, key);
string code =
"""
class User {
firstName = "";
lastName = "";
username = "";
}
export default User;
""";
ChatCompletionOptions options = new()
{
OutputPrediction = ChatOutputPrediction.CreateStaticContentPrediction(code),
};
await foreach (
StreamingChatCompletionUpdate update in client.CompleteChatStreamingAsync(
[
new UserChatMessage(
"Replace the username property with an email property. Respond only with code, and with no markdown formatting."
),
new UserChatMessage(code),
],
options
)
)
{
foreach (ChatMessageContentPart part in update.ContentUpdate)
{
Console.Write(part.Text);
}
}
流式示例(来源示例15,ruby)
## [中文] 把原文件作为prediction.content,修改要求仍放在消息中,预测文本不是最终答案保证。
## [中文] 逐个读取流式增量并输出文本,空增量不应当作正文。
require "openai"
client = OpenAI::Client.new
code = <<~CODE
class User {
firstName: string = "";
lastName: string = "";
username: string = "";
}
export default User;
CODE
refactor_prompt = <<~PROMPT
Replace the "username" property with an "email" property. Respond only
with code, and with no markdown formatting.
PROMPT
stream = client.chat.completions.stream(
model: "gpt-4.1",
messages: [
{
role: :user,
content: refactor_prompt
},
{
role: :user,
content: code
}
],
prediction: {
type: :content,
content: code
},
store: true
)
stream.text.each { |text| print(text) }
<a id="position-of-predicted-text-in-response"></a>
预测文本在响应中的位置
预测文本可以出现在生成结果的任意位置,仍能降低延迟。假设预测内容是下面的简单Hono服务:
预测文本在响应中的位置(来源示例16,javascript)
// [中文] 先运行pnpm run ui:build构建客户端,再由Hono提供静态资源和请求路由。
// [中文] 此版本尚未加入返回hello world的GET路由;与原文件对照观察预测前缀及后缀复用。
import { serve } from "@hono/node-server";
import { serveStatic } from "@hono/node-server/serve-static";
import { Hono } from "hono";
const app = new Hono();
app.get("/api", (c) => {
return c.text("Hello Hono!");
});
// [中文] 先执行pnpm run ui:build构建客户端代码。
// You will need to build the client code first: `pnpm run ui:build`.
app.use(
"/*",
serveStatic({
rewriteRequestPath: (path) => `./dist${path}`,
})
);
const port = 3000;
console.log(`Server is running on port ${port}`);
serve({
fetch: app.fetch,
port,
});
可以提出以下任务:
预测文本在响应中的位置(来源示例17,text)
为此应用添加一个GET路由,返回文本"hello world"。加入该路由后重新生成整个应用文件,不附加任何Markdown格式。
模型可能给出:
预测文本在响应中的位置(来源示例18,javascript)
// [中文] 先运行pnpm run ui:build构建客户端,再由Hono提供静态资源和请求路由。
// [中文] 此版本已经加入返回hello world的GET路由;与原文件对照观察预测前缀及后缀复用。
import { serve } from "@hono/node-server";
import { serveStatic } from "@hono/node-server/serve-static";
import { Hono } from "hono";
const app = new Hono();
app.get("/api", (c) => {
return c.text("Hello Hono!");
});
app.get("/hello", (c) => {
return c.text("hello world");
});
// [中文] 先执行pnpm run ui:build构建客户端代码。
// You will need to build the client code first: `pnpm run ui:build`.
app.use(
"/*",
serveStatic({
rewriteRequestPath: (path) => `./dist${path}`,
})
);
const port = 3000;
console.log(`Server is running on port ${port}`);
serve({
fetch: app.fetch,
port,
});
尽管预测文本分别出现在新增内容的前后,用量中仍有被接受的预测词元:
预测文本在响应中的位置(来源示例19,json)
{
"id": "chatcmpl-xxx",
"object": "chat.completion",
"created": 1731014771,
"model": "gpt-4o-2024-08-06",
"usage": {
"prompt_tokens": 203,
"completion_tokens": 159,
"total_tokens": 362,
"prompt_tokens_details": { "cached_tokens": 0, "audio_tokens": 0 },
"completion_tokens_details": {
"reasoning_tokens": 0,
"audio_tokens": 0,
"accepted_prediction_tokens": 60,
"rejected_prediction_tokens": 0
}
},
"system_fingerprint": "fp_9ee9e968ea"
}
本次没有被拒绝的词元,因为预测文件的全部内容都用于最终响应。
<a id="limitations"></a>
限制
- 来源指南的功能支持列表为GPT-4o、GPT-4o-mini、GPT-4.1、GPT-4.1-mini和GPT-4.1-nano系列;具体可用性还受前述关闭日期限制。
- 提交预测后,未用于最终补全的词元仍按输出单价收费。通过
usage.completion_tokens_details.rejected_prediction_tokens检查数量。 - 使用预测输出时,下列参数受限:
n不能大于1;不支持logprobs;presence_penalty和frequency_penalty不能大于0;不兼容audio音频输入输出;modalities只支持text;不支持max_completion_tokens;不支持tools函数调用。

TRAE-AI编程


更多建议: