Reduce latency for model responses where much of the response is known ahead of time.
Predicted Outputs enable you to speed up API responses from Chat Completions when many of the output tokens are known ahead of time. This is most common when you are regenerating a text or code file with minor modifications. You can provide your prediction using the prediction request parameter in Chat Completions.
Predicted Outputs are available today using the latest gpt-4o, gpt-4o-mini, gpt-4.1, gpt-4.1-mini, and gpt-4.1-nano models. Read on to learn how to use Predicted Outputs to reduce latency in your applications.
Code refactoring example
Predicted Outputs are particularly useful for regenerating text documents and code files with small modifications. Let’s say you want the GPT-4o model to refactor a piece of JavaScript code, and convert the username property of the User class to be email instead:
Most of the file will be unchanged, except for line 4 above. If you use the current text of the code file as your prediction, you can regenerate the entire file with lower latency. These time savings add up quickly for larger files.
Below is an example of using the prediction parameter in our SDKs to predict that the final output of the model will be very similar to our original code file, which we use as the prediction text.
Refactor a JavaScript class with a Predicted Output
Note both the accepted_prediction_tokens and rejected_prediction_tokens in the usage object. In this example, 14 tokens from the prediction were used to speed up the response, while 2 were rejected.
Note that any rejected tokens are still billed like other completion tokens
generated by the API, so Predicted Outputs can introduce higher costs for your
requests.
Streaming example
The latency gains of Predicted Outputs are even greater when you use streaming for API responses. Here is an example of the same code refactoring use case, but using streaming in the OpenAI SDKs instead.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39using OpenAI.Chat;#pragma warning disable OPENAI001string 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); }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27require "openai"client = OpenAI::Client.newcode = <<~CODE class User { firstName: string = ""; lastName: string = ""; username: string = ""; } export default User;CODErefactor_prompt = <<~PROMPT Replace the "username" property with an "email" property. Respond only with code, and with no markdown formatting.PROMPTstream = 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) }
Position of predicted text in response
When providing prediction text, your prediction can appear anywhere within the generated response, and still provide latency reduction for the response. Let’s say your predicted text is the simple Hono server shown below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25import { serve } from"@hono/node-server";import { serveStatic } from"@hono/node-server/serve-static";import { Hono } from"hono";constapp=newHono();app.get("/api", (c) => {return c.text("Hello Hono!");});// You will need to build the client code first: `pnpm run ui:build`.app.use("/*",serveStatic({rewriteRequestPath: (path) =>`./dist${path}`, }));constport=3000;console.log(`Server is running on port ${port}`);serve({ fetch: app.fetch, port,});
You could prompt the model to regenerate the file with a prompt like:
Add a get route to this application that responds withthe text "hello world". Generate the entire applicationfile again with this route added, and with no othermarkdown formatting.
The response to the prompt might look something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29import { serve } from"@hono/node-server";import { serveStatic } from"@hono/node-server/serve-static";import { Hono } from"hono";constapp=newHono();app.get("/api", (c) => {return c.text("Hello Hono!");});app.get("/hello", (c) => {return c.text("hello world");});// You will need to build the client code first: `pnpm run ui:build`.app.use("/*",serveStatic({rewriteRequestPath: (path) =>`./dist${path}`, }));constport=3000;console.log(`Server is running on port ${port}`);serve({ fetch: app.fetch, port,});
An abridged model response without the choices field would still show accepted prediction tokens, even though the prediction text appeared both before and after the new content added to the response:
This time, there were no rejected prediction tokens, because the entire content of the file we predicted was used in the final response. Nice! 🔥
Limitations
When using Predicted Outputs, you should consider the following factors and limitations.
Predicted Outputs are only supported with the GPT-4o, GPT-4o-mini, GPT-4.1, GPT-4.1-mini, and GPT-4.1-nano series of models.
When providing a prediction, any tokens provided that are not part of the final completion are still charged at completion token rates. See the rejected_prediction_tokens property of the usage object to see how many tokens are not used in the final response.
The following API parameters are not supported when using Predicted Outputs:
n: values higher than 1 are not supported
logprobs: not supported
presence_penalty: values greater than 0 are not supported
frequency_penalty: values greater than 0 are not supported