Für lang laufende Interaktionen kannst du mit Compaction (Kontextverdichtung) den Kontext
verkleinern und dabei den Zustand erhalten, der für nachfolgende Gesprächsrunden benötigt wird.
Compaction (Kontextverdichtung) hilft dir, Qualität, Kosten und Latenz bei länger werdenden Unterhaltungen in Einklang zu bringen.
Du kannst die serverseitige Compaction (Kontextverdichtung) in einer Anfrage zum Erstellen einer Response
(POST /responses oder client.responses.create) aktivieren, indem du
context_management mit compact_threshold konfigurierst.
- Wenn die Anzahl der gerenderten Token den konfigurierten Schwellenwert überschreitet,
führt der Server eine serverseitige Compaction (Kontextverdichtung) aus.
- In diesem Modus ist kein separater Aufruf von
/responses/compact erforderlich.
- Der Antwortstream enthält das verschlüsselte Element zur Compaction (Kontextverdichtung).
- Hinweis zu ZDR: Die serverseitige Compaction (Kontextverdichtung) eignet sich für ZDR, wenn du
store=false
in deinen Anfragen zum Erstellen einer Response setzt.
Das zurückgegebene Element zur Compaction (Kontextverdichtung) überträgt wesentliche Informationen zum bisherigen Zustand und zu bisherigen Überlegungen
mit weniger Token in den nächsten Durchlauf. Sein Inhalt ist nicht einsehbar und nicht dafür gedacht,
von Menschen interpretiert zu werden.
Bei der zustandslosen Verkettung über Eingabe-Arrays hängst du wie gewohnt Ausgabeelemente an. Wenn du
previous_response_id verwendest, übergib in jeder Gesprächsrunde nur die neue Nutzernachricht. In beiden
Fällen enthält das Element zur Compaction (Kontextverdichtung) den Kontext, der für das nächste Fenster benötigt wird.
Tipp zur Latenz: Nachdem du die Ausgabeelemente an die bisherigen Eingabeelemente angehängt hast, kannst du
Elemente entfernen, die vor dem neuesten Element zur Compaction (Kontextverdichtung) stehen. So bleiben Anfragen
kleiner und besonders lange Antwortzeiten werden reduziert. Das neueste Element zur Compaction (Kontextverdichtung) enthält den
Kontext, der zum Fortsetzen der Unterhaltung benötigt wird. Wenn du Anfragen über
previous_response_id verkettest, entferne keine Elemente manuell.
- Rufe
/responses wie gewohnt auf, gib aber context_management mit
compact_threshold an, um die serverseitige Compaction (Kontextverdichtung) zu aktivieren.
- Wenn die Kontextgröße während des Antwortstreamings den Schwellenwert überschreitet,
löst der Server einen Durchlauf zur Compaction (Kontextverdichtung) aus, gibt das entsprechende Ausgabeelement im selben Stream aus
und kürzt den Kontext, bevor er die Inferenz fortsetzt.
- Setze deine Schleife mit einer der beiden Varianten fort: zustandslose Verkettung über Eingabe-Arrays (hänge
die Ausgabe einschließlich der Elemente zur Compaction (Kontextverdichtung) an dein nächstes Eingabe-Array an) oder
Verkettung über
previous_response_id (übergib in jeder Gesprächsrunde nur die neue Nutzernachricht und
verwende die jeweilige ID im nächsten Aufruf weiter).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22import OpenAI from "openai";
import { toResponseInputItems } from "openai/lib/responses/ResponseInputItems";
const client = new OpenAI();
const conversation = [
{
type: "message",
role: "user",
content: "Let's begin a long coding task.",
},
];
const response = await client.responses.create({
model: "gpt-5.3-codex",
input: conversation,
store: false,
context_management: [{ type: "compaction", compact_threshold: 200_000 }],
});
conversation.push(...toResponseInputItems(response.output));
console.log(response.output_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
25conversation = [
{
"type": "message",
"role": "user",
"content": "Let's begin a long coding task.",
}
]
while keep_going:
response = client.responses.create(
model="gpt-5.3-codex",
input=conversation,
store=False,
context_management=[{"type": "compaction", "compact_threshold": 200000}],
)
conversation.extend(response.output)
conversation.append(
{
"type": "message",
"role": "user",
"content": get_next_user_input(),
}
)
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56package main
import (
"bufio"
"context"
"encoding/json"
"fmt"
"os"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/responses"
)
func main() {
client := openai.NewClient()
conversation := []responses.ResponseInputItemUnionParam{
responses.ResponseInputItemParamOfMessage("Let's begin a long coding task.", responses.EasyInputMessageRoleUser),
}
scanner := bufio.NewScanner(os.Stdin)
for {
response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
Model: "gpt-5.3-codex",
Store: openai.Bool(false),
Input: responses.ResponseNewParamsInputUnion{OfInputItemList: conversation},
ContextManagement: []responses.ResponseNewParamsContextManagement{{
Type: "compaction", CompactThreshold: openai.Int(200000),
}},
})
if err != nil {
panic(err)
}
conversation = append(conversation, outputAsInput(response.Output)...)
fmt.Println(response.OutputText())
if !scanner.Scan() {
break
}
conversation = append(conversation,
responses.ResponseInputItemParamOfMessage(scanner.Text(), responses.EasyInputMessageRoleUser),
)
}
if err := scanner.Err(); err != nil {
panic(err)
}
}
func outputAsInput(output []responses.ResponseOutputItemUnion) []responses.ResponseInputItemUnionParam {
input := make([]responses.ResponseInputItemUnionParam, 0, len(output))
for _, item := range output {
var converted responses.ResponseInputItemUnion
if err := json.Unmarshal([]byte(item.RawJSON()), &converted); err != nil {
panic(err)
}
input = append(input, converted.ToParam())
}
return input
}
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
39
40
41
42
43
44
45
46
47
48import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.JsonValue;
import com.openai.models.responses.EasyInputMessage;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseInputItem;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
var conversation = new ArrayList<ResponseInputItem>();
conversation.add(
ResponseInputItem.ofEasyInputMessage(
EasyInputMessage.builder()
.role(EasyInputMessage.Role.USER)
.content("Let's begin a long coding task.")
.build()));
ResponseCreateParams params =
ResponseCreateParams.builder()
.model("gpt-5.3-codex")
.inputOfResponse(conversation)
.store(false)
.putAdditionalBodyProperty(
"context_management",
JsonValue.from(List.of(Map.of("type", "compaction", "compact_threshold", 200000))))
.build();
var response = client.responses().create(params);
response.output().stream()
.map(item -> JsonValue.from(item).convert(ResponseInputItem.class))
.forEach(conversation::add);
conversation.add(
ResponseInputItem.ofEasyInputMessage(
EasyInputMessage.builder()
.role(EasyInputMessage.Role.USER)
.content("Now implement the next step.")
.build()));
client
.responses()
.create(params.toBuilder().inputOfResponse(conversation).build())
.output()
.stream()
.flatMap(item -> item.message().stream())
.flatMap(message -> message.content().stream())
.flatMap(content -> content.outputText().stream())
.forEach(text -> System.out.println(text.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
27
28
29
30
31
32
33
34
35
36
37
38
39
40require "openai"
client = OpenAI::Client.new
conversation = [
{
type: :message,
role: :user,
content: "Let's begin a long coding task."
}
]
response = client.responses.create(
model: "gpt-5.3-codex",
input: conversation,
store: false,
context_management: [
{
type: :compaction,
compact_threshold: 200_000
}
]
)
conversation.concat(response.output)
conversation << {
type: :message,
role: :user,
content: "Now implement the next step."
}
next_response = client.responses.create(
model: "gpt-5.3-codex",
input: conversation,
store: false,
context_management: [
{
type: :compaction,
compact_threshold: 200_000
}
]
)
puts(next_response.output_text)
Wenn du die Compaction (Kontextverdichtung) gezielt steuern möchtest, nutze den
separaten Endpunkt zur Compaction (Kontextverdichtung) für
die zustandslose Kontextverdichtung in lang laufenden Arbeitsabläufen.
Dieser Endpunkt ist vollständig zustandslos und eignet sich für ZDR.
Du sendest ein vollständiges Kontextfenster (Nachrichten, Tools und andere Elemente). Der
Endpunkt gibt ein neues, verdichtetes Kontextfenster zurück, das du bei deinem nächsten
Aufruf von /responses übergeben kannst.
Das zurückgegebene verdichtete Fenster enthält ein verschlüsseltes Element zur Compaction (Kontextverdichtung), das
wesentliche Informationen zum bisherigen Zustand und zu bisherigen Überlegungen mit weniger Token weitergibt. Sein Inhalt ist nicht einsehbar und nicht
dafür gedacht, von Menschen interpretiert zu werden.
Hinweis: Das verdichtete Fenster enthält in der Regel mehr als nur das Element zur Compaction (Kontextverdichtung).
Es kann auch beibehaltene Elemente aus dem vorherigen Fenster enthalten.
Umgang mit der Ausgabe: Kürze die Ausgabe von /responses/compact nicht. Das zurückgegebene Fenster
ist das maßgebliche nächste Kontextfenster. Übergib es daher unverändert bei deinem nächsten Aufruf von /responses
als Eingabe.
- Verwende
/responses wie gewohnt und sende Eingabeelemente, die Nutzernachrichten,
Ausgaben des Assistenten und Tool-Interaktionen enthalten.
- Wenn dein Kontextfenster groß wird, rufe
/responses/compact auf, um ein
neues, verdichtetes Kontextfenster zu erzeugen. Das Fenster, das du an /responses/compact sendest,
muss weiterhin in das Kontextfenster deines Modells passen.
- Übergib bei nachfolgenden Aufrufen von
/responses das zurückgegebene verdichtete Fenster
(einschließlich des Elements zur Compaction (Kontextverdichtung)) als Eingabe anstelle des vollständigen Gesprächsverlaufs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23import OpenAI from "openai";
const client = new OpenAI();
const conversation = [{ role: "user", content: "Plan a trip to Kyoto." }];
const compacted = await client.responses.compact({
model: "gpt-6-astra",
input: conversation,
});
const nextInput = [
...compacted.output.map((item) => item),
{ role: "user", content: "Add two more days to the itinerary." },
];
const response = await client.responses.create({
model: "gpt-6-astra",
input: nextInput,
store: false,
});
console.log(response.output_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# Full window collected from prior turns
long_input_items_array = [{"role": "user", "content": "Plan a trip to Kyoto."}]
# 1) Compact the current window
compacted = client.responses.compact(
model="gpt-6-astra",
input=long_input_items_array,
)
# 2) Start the next turn by appending a new user message
next_input = [
*compacted.output, # Use compact output as-is
{
"type": "message",
"role": "user",
"content": user_input_message(),
},
]
next_response = client.responses.create(
model="gpt-6-astra",
input=next_input,
store=False, # Keep the flow ZDR-friendly
)
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54package main
import (
"bufio"
"context"
"encoding/json"
"fmt"
"os"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/responses"
)
func main() {
client := openai.NewClient()
longInputItems := []responses.ResponseInputItemUnionParam{
responses.ResponseInputItemParamOfMessage("Plan a trip to Kyoto.", responses.EasyInputMessageRoleUser),
}
compacted, err := client.Responses.Compact(context.Background(), responses.ResponseCompactParams{
Model: "gpt-6-astra",
Input: responses.ResponseCompactParamsInputUnion{OfResponseInputItemArray: longInputItems},
})
if err != nil {
panic(err)
}
scanner := bufio.NewScanner(os.Stdin)
if !scanner.Scan() {
return
}
nextInput := append(outputAsInput(compacted.Output),
responses.ResponseInputItemParamOfMessage(scanner.Text(), responses.EasyInputMessageRoleUser),
)
nextResponse, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
Model: "gpt-6-astra",
Store: openai.Bool(false),
Input: responses.ResponseNewParamsInputUnion{OfInputItemList: nextInput},
})
if err != nil {
panic(err)
}
fmt.Println(nextResponse.OutputText())
}
func outputAsInput(output []responses.ResponseOutputItemUnion) []responses.ResponseInputItemUnionParam {
input := make([]responses.ResponseInputItemUnionParam, 0, len(output))
for _, item := range output {
var converted responses.ResponseInputItemUnion
if err := json.Unmarshal([]byte(item.RawJSON()), &converted); err != nil {
panic(err)
}
input = append(input, converted.ToParam())
}
return input
}
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.responses.EasyInputMessage;
import com.openai.models.responses.ResponseCompactParams;
import com.openai.models.responses.ResponseCompactionItemParam;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseInputItem;
import java.util.ArrayList;
var compacted =
client
.responses()
.compact(
ResponseCompactParams.builder()
.model("gpt-6-astra")
.input("Plan a trip to Kyoto.")
.build());
var input = new ArrayList<ResponseInputItem>();
for (var item : compacted.output()) {
item.message().map(ResponseInputItem::ofResponseOutputMessage).ifPresent(input::add);
item.reasoning().map(ResponseInputItem::ofReasoning).ifPresent(input::add);
item.compaction()
.map(
value ->
ResponseInputItem.ofCompaction(
ResponseCompactionItemParam.builder()
.id(value.id())
.encryptedContent(value.encryptedContent())
.build()))
.ifPresent(input::add);
}
input.add(
ResponseInputItem.ofEasyInputMessage(
EasyInputMessage.builder()
.role(EasyInputMessage.Role.USER)
.content("Add restaurant recommendations.")
.build()));
client
.responses()
.create(
ResponseCreateParams.builder()
.model("gpt-6-astra")
.inputOfResponse(input)
.store(false)
.build())
.output()
.stream()
.flatMap(item -> item.message().stream())
.flatMap(message -> message.content().stream())
.flatMap(content -> content.outputText().stream())
.forEach(text -> System.out.println(text.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.new
long_input = [
{
role: :user,
content: "Plan a trip to Kyoto."
}
]
compaction = client.responses.compact(
model: "gpt-6-astra",
input: long_input
)
next_input = [
*compaction.output,
{
type: :message,
role: :user,
content: "Add restaurant recommendations."
}
]
response = client.responses.create(
model: "gpt-6-astra",
input: next_input,
store: false
)
puts(response.output_text)