---
title: Komprimierung und beibehaltenes Nachdenken
url: https://platform.claude.com/docs/de/build-with-claude/compaction-thinking-blocks
description: Wann Thinking-Blöcke in Turns, die nach einer On-Demand-Komprimierung beibehalten werden, bei Modellen mit bewahrtem Nachdenken gültig bleiben, und wie du das prüfst.
featureMetadata:
  status: beta
  betaHeader: compact-2026-09-04
  supportedModels:
    - claude-fable-5-1
    - claude-mythos-5-1
    - claude-fable-5
    - claude-mythos-5
    - claude-mythos-preview
    - claude-opus-5-5
    - claude-opus-5
    - claude-opus-4-8
    - claude-opus-4-7
    - claude-opus-4-6
    - claude-sonnet-5-5
    - claude-sonnet-5
    - claude-sonnet-4-6
    - claude-haiku-5-5
  supportedPlatforms:
    Claude API: beta
    Claude Platform on AWS: beta
    Google Cloud: beta
    Microsoft Foundry: beta
---

Überspringe diese Seite, es sei denn, du sendest „thinking blocks“ (Thinking-Blöcke) an ein Modell mit [„preserved thinking“ (beibehaltenem Nachdenken)](https://platform.claude.com/docs/de/build-with-claude/preserved-thinking) zurück und behältst Turns nach dem „compaction block“ (Komprimierungsblock) bei. „Kept turns“ (beibehaltene Turns) sind die Turns, die auf den Block folgen: die letzten Turns, die du aus der Komprimierungsanfrage herausgelassen hast, wie in [Komprimierung, die die letzten Turns beibehält](https://platform.claude.com/docs/de/build-with-claude/compaction-keep-recent-turns), oder Turns, die eingetroffen sind, während die Zusammenfassung geschrieben wurde, wie in [Komprimierung im Hintergrund](https://platform.claude.com/docs/de/build-with-claude/compaction-background).

Modelle mit beibehaltenem Nachdenken prüfen frühere Thinking-Blöcke gegen die Konversation, die sie erzeugt hat. Eine Zusammenfassung ersetzt einen Teil dieser Konversation, aber die Prüfung akzeptiert den Austausch, wenn die API die Zusammenfassung geschrieben hat, sodass das „thinking“ (Nachdenken) in beibehaltenen Turns gültig bleiben kann.

## Bedingungen, unter denen beibehaltenes Thinking gültig bleibt

Die Thinking-Blöcke in beibehaltenen Turns bleiben gültig, solange alle folgenden Bedingungen erfüllt sind:

* **Die Komprimierungsanfrage läuft auf einem Modell mit beibehaltenem Nachdenken.** Diese Bedingung umfasst jede Komprimierungsanfrage, seit ein Thinking-Block erzeugt wurde, nicht nur die jüngste. Eine Möglichkeit, sie zu erfüllen, besteht darin, jede Komprimierungsanfrage an das Modell zu senden, das die Konversation verwendet.
* **Die beibehaltenen Turns folgen direkt auf die zusammengefassten Nachrichten, und du sendest sie unverändert.** Sende jede beibehaltene Nachricht genau so, wie sie in deinem Verlauf steht. Überspringe keine Nachricht zwischen der letzten zusammengefassten Nachricht und der ersten beibehaltenen, und füge dort auch keine hinzu. Die erste beibehaltene Nachricht muss außerdem eine andere Rolle haben als die letzte zusammengefasste Nachricht, und sie darf keine `role: "system"`-Nachricht mitten in der Konversation sein. Andernfalls führt die API sie mit der letzten zusammengefassten Nachricht zusammen. Eine Möglichkeit, die erste beibehaltene Nachricht richtig zu setzen, besteht darin, genau die `messages` einer Anfrage zu komprimieren, die du bereits gesendet hast. Die beibehaltenen Turns beginnen dann mit Claudes Antwort darauf.
* **`system` und die `tools`, die nicht mit `defer_loading: true` markiert sind, ändern sich nicht.** Sie sind in der Komprimierungsanfrage dieselben wie in den Anfragen, die das beibehaltene Thinking erzeugt haben, und sie bleiben in den nachfolgenden Anfragen gleich. [System-Prompt oder Tools ändern](https://platform.claude.com/docs/de/build-with-claude/compaction-thinking-blocks#change-the-system-prompt-or-tools) beschreibt, wie du sie sicher änderst.

Wenn eine Bedingung nicht erfüllt ist, schlägt beim Komprimieren nichts fehl, und die API akzeptiert den Block in späteren Anfragen so oder so. Der Fehler tritt bei der ersten späteren Anfrage auf, die das beibehaltene Thinking dort sendet, wo die API die Prüfung durchsetzt: standardmäßig ein 400-Fehler oder verworfene Thinking-Blöcke, wenn die Anfrage `thinking.block_binding.prefix_mismatch_behavior` auf `"drop_block"` setzt. In der Message Batches API schlägt ein Element, das das Feld nicht setzt, nicht fehl. Wo die Prüfung standardmäßig gilt, verwirft die API stattdessen die Blöcke. [Was die API mit einem ungültigen Block macht](https://platform.claude.com/docs/de/build-with-claude/preserved-thinking#mismatch-behavior) beschreibt beide Ergebnisse, und [Wann die API die Prüfung erzwingt](https://platform.claude.com/docs/de/build-with-claude/preserved-thinking#enforcement) gibt an, welche Anfragen geprüft werden.

## Erneut komprimieren, ohne älteres Thinking ungültig zu machen

Du kannst [erneut komprimieren](https://platform.claude.com/docs/de/build-with-claude/compaction-on-demand#compact-again) und Turns beibehalten: Der neue Block umfasst die alte Zusammenfassung und jede Nachricht, die ihr in der Komprimierungsanfrage folgt, und alle Turns, die du aus dieser Anfrage herauslässt, sind beibehaltene Turns des neuen Blocks.

Die erste der [Bedingungen für beibehaltenes Thinking](https://platform.claude.com/docs/de/build-with-claude/compaction-thinking-blocks#conditions-for-kept-thinking-to-stay-valid) zählt jede Komprimierung, seit ein Thinking-Block erzeugt wurde. Bei einem Turn, den du über zwei Komprimierungen hinweg beibehältst, müssen daher beide auf einem Modell mit beibehaltenem Nachdenken gelaufen sein.

Komprimierungen, die stattfanden, bevor ein Thinking-Block erzeugt wurde, zählen nicht gegen ihn. Thinking, das erzeugt wird, nachdem ein Block vorhanden ist, ist an diesen Block gebunden und bleibt über spätere Komprimierungen hinweg gültig, die die Bedingungen erfüllen.

## System-Prompt oder Tools ändern

Eine spätere Anfrage kann ein anderes `system`, andere `tools` oder ein anderes Modell als die Komprimierungsanfrage verwenden, und die API akzeptiert den Block trotzdem. Eine solche Änderung kann das Thinking in den beibehaltenen Turns ungültig machen, hat aber keine weitere Auswirkung.

Um `system` oder `tools` zu ändern, ohne beibehaltenes Thinking ungültig zu machen, komprimiere zuerst die gesamte Konversation, sodass keine Turns beibehalten werden. Ändere sie dann in der nächsten Anfrage.

Um eine Anweisung hinzuzufügen oder die verfügbaren Tools zu ändern, ohne `system` oder `tools` anzufassen, hänge die Änderung an `messages` an, wie in [Änderungen vornehmen, ohne das Präfix zu bearbeiten](https://platform.claude.com/docs/de/build-with-claude/preserved-thinking#replace-prefix-edits) beschrieben.

System-Nachrichten mitten in der Konversation innerhalb der zusammengefassten Turns werden ebenfalls zusammengefasst, sodass ihre Textanweisungen nach dem Austausch nicht mehr gelten. Ein von ihnen gesetztes [Effort-Level pro Nachricht](https://platform.claude.com/docs/de/build-with-claude/effort#change-effort-mid-conversation-beta) wird ebenfalls nicht übernommen: Bis eine spätere Nachricht ein Level setzt, laufen Turns mit dem `output_config.effort` der obersten Ebene der Anfrage oder mit dem Standard des Modells, wenn du keines setzt. Um eine Anweisung oder ein Effort-Level in Kraft zu halten, gib sie erneut in einer `role: "system"`-Nachricht direkt nach dem ersten neuen `user`-Turn an, der auf die beibehaltenen Turns folgt. Tool-Änderungen innerhalb dieser Turns werden von selbst übernommen, wenn die Komprimierungsanfrage auch `inline-tools-2026-09-15` enthält: Der zurückgegebene Block erfasst ihre Nettowirkung in seinem Feld `tool_changes`, also sende den Block unverändert zurück. Wenn der Block kein Feld `tool_changes` hat, gib diese Tool-Änderungen auf dieselbe Weise erneut an. Eine System-Nachricht, die zwischen dem Block und den beibehaltenen Turns platziert wird, macht deren Nachdenken ungültig.

## Prüfen, ob das beibehaltene Thinking gültig geblieben ist

Die Komprimierungsantwort sagt nicht, ob das beibehaltene Thinking gültig bleibt. Das zeigt erst die erste Anfrage nach dem Austausch. So prüfst du es in deinen Tests:

1. Führe eine kurze Konversation mit aktiviertem Thinking. Verwende ein Modell, auf dem die API die Prüfung ausführt (siehe [Wann die API die Prüfung erzwingt](https://platform.claude.com/docs/de/build-with-claude/preserved-thinking#enforcement)), und verwende es für jeden Schritt, denn ein Modell, das einen Thinking-Block nicht lesen kann, verwirft ihn ohne Fehler.
2. Komprimiere die älteren Turns und behalte mindestens einen Turn bei, der einen Thinking-Block enthält.
3. Sende die nächste Anfrage mit dem Block zuerst, dann dem beibehaltenen Turn, dann einer neuen `user`-Nachricht, und mit `thinking.block_binding.prefix_mismatch_behavior` auf `"error"` gesetzt.
4. Lies das Ergebnis. Eine 200-Antwort, deren `input_transformations`-Array leer ist, bedeutet, dass jeder Thinking-Block die Prüfung bestanden hat und keiner verworfen wurde. Ein 400-Fehler, der besagt, dass der Block an eine andere Konversation gebunden ist, bedeutet, dass dies bei einem Block der Fall war. Die Meldung beginnt mit dem Pfad des ersten Blocks, der die Prüfung nicht bestanden hat, und [Was die API mit einem ungültigen Block macht](https://platform.claude.com/docs/de/build-with-claude/preserved-thinking#mismatch-behavior) zeigt sie vollständig.

Das Feld `prefix_mismatch_behavior` benötigt den Beta-Header `thinking-binding-controls-2026-08-01` zusätzlich zum [Beta-Header `compact-2026-09-04`](https://platform.claude.com/docs/de/build-with-claude/compaction-on-demand#request-a-summary). Das Setzen des Feldes aktiviert die Prüfung für die Anfrage außerdem bei Konten, bei denen die Prüfung nicht standardmäßig aktiviert ist.

Das folgende Programm führt die vier Schritte aus. Es gibt aus, wie viele Thinking-Blöcke der beibehaltene Turn enthält und wie viele Einträge `input_transformations` hat; keine Einträge bedeuten, dass das beibehaltene Thinking gültig geblieben ist:

<CodeGroup exclude="shell">
  ```python Python
  from anthropic.types.beta import BetaMessageParam, BetaThinkingConfigParam

  client = anthropic.Anthropic()

  # Claude Fable 5.1 ist das erste Modell, das zurückgesendetes Thinking mit der Konversation abgleicht.
  MODEL = "claude-fable-5-1"
  BETAS = ["compact-2026-09-04", "thinking-binding-controls-2026-08-01"]
  SYSTEM = "You help plan a recipe app's release. Keep answers short."
  # Mit "error" lässt ein Thinking-Block, der die Prüfung nicht besteht, die Anfrage mit einem 400 fehlschlagen.
  THINKING: BetaThinkingConfigParam = {
      "type": "adaptive",
      "block_binding": {"prefix_mismatch_behavior": "error"},
  }

  # 1. Führe eine kurze Konversation mit aktiviertem Thinking.
  history: list[BetaMessageParam] = [
      {"role": "user", "content": "What are the main entities in the app's data model?"}
  ]
  first = client.beta.messages.create(
      model=MODEL,
      max_tokens=8192,
      system=SYSTEM,
      betas=BETAS,
      thinking=THINKING,
      messages=history,
  )
  history += [
      {"role": "assistant", "content": first.content},
      {
          "role": "user",
          "content": "Testing starts on Tuesday, March 3, 2026, takes 10 weekdays, and pauses on March 9 and March 16. On which date does it end?",
      },
  ]
  second = client.beta.messages.create(
      model=MODEL,
      max_tokens=8192,
      system=SYSTEM,
      betas=BETAS,
      thinking=THINKING,
      messages=history,
  )
  history.append({"role": "assistant", "content": second.content})
  thinking_blocks = sum(block.type == "thinking" for block in second.content)
  print(f"Thinking blocks in the kept turn: {thinking_blocks}")

  # 2. Fasse den ersten Turn zusammen. Der zweite Turn bleibt aus der Anfrage heraus.
  summary = client.beta.messages.create(
      model=MODEL,
      max_tokens=4096,
      system=SYSTEM,
      betas=BETAS,
      thinking=THINKING,
      messages=history[:2],
      compaction={"type": "summarize"},
  )
  if summary.stop_reason != "compaction":
      raise SystemExit(f"No summary: {summary.stop_reason}")

  # 3. Setze den Block vor den beibehaltenen Turn und stelle die nächste Frage.
  history = [
      {"role": "assistant", "content": summary.content},
      *history[2:],
      {"role": "user", "content": "Which day should the release go out?"},
  ]
  third = client.beta.messages.create(
      model=MODEL,
      max_tokens=8192,
      system=SYSTEM,
      betas=BETAS,
      thinking=THINKING,
      messages=history,
  )

  # 4. Ein 200 ohne verworfene Blöcke bedeutet, dass das beibehaltene Thinking gültig war.
  print(f"Dropped thinking blocks: {len(third.input_transformations)}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  // Claude Fable 5.1 ist das erste Modell, das zurückgesendetes Thinking mit der Konversation abgleicht.
  const model: Anthropic.Model = "claude-fable-5-1";
  const betas: Anthropic.Beta.AnthropicBeta[] = [
    "compact-2026-09-04",
    "thinking-binding-controls-2026-08-01"
  ];
  const systemPrompt = "You help plan a recipe app's release. Keep answers short.";
  // Mit "error" lässt ein Thinking-Block, der die Prüfung nicht besteht, die Anfrage mit einem 400 fehlschlagen.
  const thinking: Anthropic.Beta.Messages.BetaThinkingConfigParam = {
    type: "adaptive",
    block_binding: { prefix_mismatch_behavior: "error" }
  };

  // 1. Führe eine kurze Konversation mit aktiviertem Thinking.
  let history: Anthropic.Beta.Messages.BetaMessageParam[] = [
    { role: "user", content: "What are the main entities in the app's data model?" }
  ];
  const first = await client.beta.messages.create({
    model,
    max_tokens: 8192,
    system: systemPrompt,
    betas,
    thinking,
    messages: history
  });
  history.push(
    { role: "assistant", content: first.content },
    {
      role: "user",
      content:
        "Testing starts on Tuesday, March 3, 2026, takes 10 weekdays, and pauses on March 9 and March 16. On which date does it end?"
    }
  );
  const second = await client.beta.messages.create({
    model,
    max_tokens: 8192,
    system: systemPrompt,
    betas,
    thinking,
    messages: history
  });
  history.push({ role: "assistant", content: second.content });
  const thinkingBlocks = second.content.filter((block) => block.type === "thinking").length;
  console.log(`Thinking blocks in the kept turn: ${thinkingBlocks}`);

  // 2. Fasse den ersten Turn zusammen. Der zweite Turn wird nicht in die Anfrage aufgenommen.
  const summary = await client.beta.messages.create({
    model,
    max_tokens: 4096,
    system: systemPrompt,
    betas,
    thinking,
    messages: history.slice(0, 2),
    compaction: { type: "summarize" }
  });
  if (summary.stop_reason !== "compaction") {
    throw new Error(`No summary: ${summary.stop_reason}`);
  }

  // 3. Setze den Block vor den beibehaltenen Turn und stelle die nächste Frage.
  history = [
    { role: "assistant", content: summary.content },
    ...history.slice(2),
    { role: "user", content: "Which day should the release go out?" }
  ];
  const third = await client.beta.messages.create({
    model,
    max_tokens: 8192,
    system: systemPrompt,
    betas,
    thinking,
    messages: history
  });

  // 4. Ein 200 ohne verworfene Blöcke bedeutet, dass das beibehaltene Thinking Bestand hatte.
  console.log(`Dropped thinking blocks: ${third.input_transformations?.length ?? 0}`);
  ```

  ```csharp C#
  using Anthropic.Models.Beta;
  using Anthropic.Models.Beta.Messages;
  using Model = Anthropic.Models.Messages.Model;

  AnthropicClient client = new();

  // Claude Fable 5.1 ist das erste Modell, das zurückgesendetes Thinking mit der Konversation abgleicht.
  const Model ModelId = Model.ClaudeFable5_1;
  AnthropicBeta[] betas = [AnthropicBeta.Compact2026_09_04, AnthropicBeta.ThinkingBindingControls2026_08_01];
  const string SystemPrompt = "You help plan a recipe app's release. Keep answers short.";
  // Mit "error" lässt ein Thinking-Block, der die Prüfung nicht besteht, die Anfrage mit einem 400 fehlschlagen.
  BetaThinkingConfigAdaptive thinking = new()
  {
      BlockBinding = new() { PrefixMismatchBehavior = BetaThinkingPrefixMismatchBehavior.Error },
  };

  // 1. Führe eine kurze Konversation mit aktiviertem Thinking.
  List<BetaMessageParam> history =
  [
      new() { Role = Role.User, Content = "What are the main entities in the app's data model?" },
  ];
  var first = await client.Beta.Messages.Create(new MessageCreateParams
  {
      Model = ModelId,
      MaxTokens = 8192,
      System = SystemPrompt,
      Betas = [.. betas],
      Thinking = thinking,
      Messages = history,
  });
  history.AddRange(
  [
      new()
      {
          Role = Role.Assistant,
          Content = first.Content.Select(block => new BetaContentBlockParam(block.Json)).ToList(),
      },
      new()
      {
          Role = Role.User,
          Content = "Testing starts on Tuesday, March 3, 2026, takes 10 weekdays, and pauses on March 9 and March 16. On which date does it end?",
      },
  ]);
  var second = await client.Beta.Messages.Create(new MessageCreateParams
  {
      Model = ModelId,
      MaxTokens = 8192,
      System = SystemPrompt,
      Betas = [.. betas],
      Thinking = thinking,
      Messages = history,
  });
  history.Add(new()
  {
      Role = Role.Assistant,
      Content = second.Content.Select(block => new BetaContentBlockParam(block.Json)).ToList(),
  });
  var thinkingBlocks = second.Content.Count(block => block.TryPickThinking(out _));
  Console.WriteLine($"Thinking blocks in the kept turn: {thinkingBlocks}");

  // 2. Fasse den ersten Turn zusammen. Der zweite Turn bleibt aus der Anfrage heraus.
  var summary = await client.Beta.Messages.Create(new MessageCreateParams
  {
      Model = ModelId,
      MaxTokens = 4096,
      System = SystemPrompt,
      Betas = [.. betas],
      Thinking = thinking,
      Messages = history[..2],
      Compaction = new BetaCompactionConfig(), // type defaults to "summarize"
  });
  if (summary.StopReason != BetaStopReason.Compaction)
  {
      throw new InvalidOperationException($"No summary: {summary.StopReason?.Raw()}");
  }

  // 3. Setze den Block vor den beibehaltenen Turn und stelle die nächste Frage.
  history =
  [
      new()
      {
          Role = Role.Assistant,
          Content = summary.Content.Select(block => new BetaContentBlockParam(block.Json)).ToList(),
      },
      .. history[2..],
      new() { Role = Role.User, Content = "Which day should the release go out?" },
  ];
  var third = await client.Beta.Messages.Create(new MessageCreateParams
  {
      Model = ModelId,
      MaxTokens = 8192,
      System = SystemPrompt,
      Betas = [.. betas],
      Thinking = thinking,
      Messages = history,
  });

  // 4. Ein 200 ohne verworfene Blöcke bedeutet, dass das beibehaltene Thinking gültig war.
  Console.WriteLine($"Dropped thinking blocks: {third.InputTransformations?.Count ?? 0}");
  ```

  ```go Go
  ctx := context.Background()
  client := anthropic.NewClient()

  // Claude Fable 5.1 ist das erste Modell, das zurückgesendetes Thinking mit der Konversation abgleicht.
  const model = anthropic.ModelClaudeFable5_1
  betas := []anthropic.AnthropicBeta{
  	anthropic.AnthropicBetaCompact2026_09_04,
  	anthropic.AnthropicBetaThinkingBindingControls2026_08_01,
  }
  system := []anthropic.BetaTextBlockParam{{Text: "You help plan a recipe app's release. Keep answers short."}}
  // Mit "error" lässt ein Thinking-Block, der die Prüfung nicht besteht, die Anfrage mit einem 400 fehlschlagen.
  thinking := anthropic.BetaThinkingConfigParamUnion{
  	OfAdaptive: &anthropic.BetaThinkingConfigAdaptiveParam{
  		BlockBinding: anthropic.BetaThinkingBlockBindingParam{
  			PrefixMismatchBehavior: anthropic.BetaThinkingPrefixMismatchBehaviorError,
  		},
  	},
  }

  // 1. Führe eine kurze Konversation mit aktiviertem Thinking.
  history := []anthropic.BetaMessageParam{
  	anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("What are the main entities in the app's data model?")),
  }
  first, err := client.Beta.Messages.New(ctx, anthropic.BetaMessageNewParams{
  	Model:     model,
  	MaxTokens: 8192,
  	System:    system,
  	Betas:     betas,
  	Thinking:  thinking,
  	Messages:  history,
  })
  if err != nil {
  	log.Fatal(err)
  }
  history = append(history,
  	first.ToParam(),
  	anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Testing starts on Tuesday, March 3, 2026, takes 10 weekdays, and pauses on March 9 and March 16. On which date does it end?")),
  )
  second, err := client.Beta.Messages.New(ctx, anthropic.BetaMessageNewParams{
  	Model:     model,
  	MaxTokens: 8192,
  	System:    system,
  	Betas:     betas,
  	Thinking:  thinking,
  	Messages:  history,
  })
  if err != nil {
  	log.Fatal(err)
  }
  history = append(history, second.ToParam())
  thinkingBlocks := 0
  for _, block := range second.Content {
  	if _, ok := block.AsAny().(anthropic.BetaThinkingBlock); ok {
  		thinkingBlocks++
  	}
  }
  fmt.Printf("Thinking blocks in the kept turn: %d\n", thinkingBlocks)

  // 2. Fasse den ersten Turn zusammen. Der zweite Turn wird nicht in die Anfrage aufgenommen.
  summary, err := client.Beta.Messages.New(ctx, anthropic.BetaMessageNewParams{
  	Model:     model,
  	MaxTokens: 4096,
  	System:    system,
  	Betas:     betas,
  	Thinking:  thinking,
  	Messages:  history[:2],
  	Compaction: anthropic.BetaCompactionConfigUnionParam{
  		OfSummarize: &anthropic.BetaSummarizeCompactionParam{},
  	},
  })
  if err != nil {
  	log.Fatal(err)
  }
  if summary.StopReason != anthropic.BetaStopReasonCompaction {
  	log.Fatalf("No summary: %s", summary.StopReason)
  }

  // 3. Setze den Block vor den beibehaltenen Turn und stelle die nächste Frage.
  history = slices.Concat(
  	[]anthropic.BetaMessageParam{summary.ToParam()},
  	history[2:],
  	[]anthropic.BetaMessageParam{anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Which day should the release go out?"))},
  )
  third, err := client.Beta.Messages.New(ctx, anthropic.BetaMessageNewParams{
  	Model:     model,
  	MaxTokens: 8192,
  	System:    system,
  	Betas:     betas,
  	Thinking:  thinking,
  	Messages:  history,
  })
  if err != nil {
  	log.Fatal(err)
  }

  // 4. Ein 200 ohne verworfene Blöcke bedeutet, dass das beibehaltene Thinking gültig war.
  fmt.Printf("Dropped thinking blocks: %d\n", len(third.InputTransformations))
  ```

  ```java Java
  import com.anthropic.models.beta.AnthropicBeta;
  import com.anthropic.models.beta.messages.BetaCompactionConfig;
  import com.anthropic.models.beta.messages.BetaContentBlock;
  import com.anthropic.models.beta.messages.BetaMessageParam;
  import com.anthropic.models.beta.messages.BetaStopReason;
  import com.anthropic.models.beta.messages.BetaThinkingBlockBinding;
  import com.anthropic.models.beta.messages.BetaThinkingConfigAdaptive;
  import com.anthropic.models.beta.messages.BetaThinkingPrefixMismatchBehavior;
  import com.anthropic.models.beta.messages.MessageCreateParams;

  // Claude Fable 5.1 ist das erste Modell, das zurückgesendetes Nachdenken mit der Konversation abgleicht.
  static final Model MODEL = Model.CLAUDE_FABLE_5_1;
  static final List<AnthropicBeta> BETAS = List.of(
      AnthropicBeta.COMPACT_2026_09_04,
      AnthropicBeta.THINKING_BINDING_CONTROLS_2026_08_01
  );
  static final String SYSTEM = "You help plan a recipe app's release. Keep answers short.";
  // Mit "error" schlägt die Anfrage mit 400 fehl, wenn ein Thinking-Block die Prüfung nicht besteht.
  static final BetaThinkingConfigAdaptive THINKING = BetaThinkingConfigAdaptive.builder()
      .blockBinding(BetaThinkingBlockBinding.builder()
          .prefixMismatchBehavior(BetaThinkingPrefixMismatchBehavior.ERROR)
          .build())
      .build();

  void main() {
      var client = AnthropicOkHttpClient.fromEnv();

      // 1. Führe eine kurze Konversation mit aktiviertem Nachdenken.
      var history = new ArrayList<BetaMessageParam>();
      history.add(BetaMessageParam.builder()
          .role(BetaMessageParam.Role.USER)
          .content("What are the main entities in the app's data model?")
          .build());
      var firstParams = MessageCreateParams.builder()
          .model(MODEL)
          .maxTokens(8192)
          .system(SYSTEM)
          .betas(BETAS)
          .thinking(THINKING)
          .messages(history)
          .build();
      var first = client.beta().messages().create(firstParams);
      history.add(first.toParam());
      history.add(BetaMessageParam.builder()
          .role(BetaMessageParam.Role.USER)
          .content("Testing starts on Tuesday, March 3, 2026, takes 10 weekdays, and pauses on March 9 and March 16. On which date does it end?")
          .build());
      var secondParams = MessageCreateParams.builder()
          .model(MODEL)
          .maxTokens(8192)
          .system(SYSTEM)
          .betas(BETAS)
          .thinking(THINKING)
          .messages(history)
          .build();
      var second = client.beta().messages().create(secondParams);
      history.add(second.toParam());
      long thinkingBlocks = second.content().stream().filter(BetaContentBlock::isThinking).count();
      IO.println("Thinking blocks in the kept turn: " + thinkingBlocks);

      // 2. Fasse den ersten Turn zusammen. Der zweite Turn bleibt außerhalb der Anfrage.
      var firstTurn = history.subList(0, 2);
      var summaryParams = MessageCreateParams.builder()
          .model(MODEL)
          .maxTokens(4096)
          .system(SYSTEM)
          .betas(BETAS)
          .thinking(THINKING)
          .messages(firstTurn)
          .compaction(BetaCompactionConfig.builder().build()) // type defaults to "summarize"
          .build();
      var summary = client.beta().messages().create(summaryParams);
      if (!summary.stopReason().map(BetaStopReason.COMPACTION::equals).orElse(false)) {
          throw new IllegalStateException("No summary: " + summary.stopReason().orElseThrow());
      }

      // 3. Setze den Block vor den beibehaltenen Turn und stelle die nächste Frage.
      firstTurn.clear();
      history.addFirst(summary.toParam());
      history.add(BetaMessageParam.builder()
          .role(BetaMessageParam.Role.USER)
          .content("Which day should the release go out?")
          .build());
      var thirdParams = MessageCreateParams.builder()
          .model(MODEL)
          .maxTokens(8192)
          .system(SYSTEM)
          .betas(BETAS)
          .thinking(THINKING)
          .messages(history)
          .build();
      var third = client.beta().messages().create(thirdParams);

      // 4. Ein 200 ohne verworfene Blöcke bedeutet, dass das beibehaltene Nachdenken Bestand hatte.
      IO.println("Dropped thinking blocks: " + third.inputTransformations().map(List::size).orElse(0));
  }
  ```

  ```php PHP
  use Anthropic\Beta\AnthropicBeta;
  use Anthropic\Beta\Messages\BetaCompactionConfig;
  use Anthropic\Beta\Messages\BetaMessageParam;
  use Anthropic\Beta\Messages\BetaMessageParam\Role;
  use Anthropic\Beta\Messages\BetaStopReason;
  use Anthropic\Beta\Messages\BetaThinkingBlock;
  use Anthropic\Beta\Messages\BetaThinkingBlockBinding;
  use Anthropic\Beta\Messages\BetaThinkingConfigAdaptive;
  use Anthropic\Beta\Messages\BetaThinkingPrefixMismatchBehavior;

  $client = new Client();

  // Claude Fable 5.1 ist das erste Modell, das zurückgesendetes Thinking mit der Konversation abgleicht.
  const MODEL = Model::CLAUDE_FABLE_5_1;
  const BETAS = [AnthropicBeta::COMPACT_2026_09_04, AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01];
  const SYSTEM = "You help plan a recipe app's release. Keep answers short.";
  // Mit "error" führt ein Thinking-Block, der die Prüfung nicht besteht, zum Fehlschlagen der Anfrage mit 400.
  $thinking = BetaThinkingConfigAdaptive::with(
      blockBinding: BetaThinkingBlockBinding::with(
          prefixMismatchBehavior: BetaThinkingPrefixMismatchBehavior::ERROR,
      ),
  );

  // 1. Führe eine kurze Konversation mit aktiviertem Thinking.
  $history = [
      BetaMessageParam::with(role: Role::USER, content: "What are the main entities in the app's data model?"),
  ];
  $first = $client->beta->messages->create(
      model: MODEL,
      maxTokens: 8192,
      system: SYSTEM,
      betas: BETAS,
      thinking: $thinking,
      messages: $history,
  );
  $history[] = BetaMessageParam::with(role: Role::ASSISTANT, content: $first->content);
  $history[] = BetaMessageParam::with(
      role: Role::USER,
      content: 'Testing starts on Tuesday, March 3, 2026, takes 10 weekdays, and pauses on March 9 and March 16. On which date does it end?',
  );
  $second = $client->beta->messages->create(
      model: MODEL,
      maxTokens: 8192,
      system: SYSTEM,
      betas: BETAS,
      thinking: $thinking,
      messages: $history,
  );
  $history[] = BetaMessageParam::with(role: Role::ASSISTANT, content: $second->content);
  $thinkingBlocks = count(array_filter($second->content, fn ($block) => $block instanceof BetaThinkingBlock));
  printf("Thinking blocks in the kept turn: %d\n", $thinkingBlocks);

  // 2. Fasse den ersten Turn zusammen. Der zweite Turn bleibt außerhalb der Anfrage.
  $summary = $client->beta->messages->create(
      model: MODEL,
      maxTokens: 4096,
      system: SYSTEM,
      betas: BETAS,
      thinking: $thinking,
      messages: array_slice($history, 0, 2),
      compaction: new BetaCompactionConfig(), // type defaults to 'summarize'
  );
  if ($summary->stopReason !== BetaStopReason::COMPACTION->value) {
      throw new \RuntimeException("No summary: {$summary->stopReason}");
  }

  // 3. Setze den Block vor den beibehaltenen Turn und stelle die nächste Frage.
  $history = [
      BetaMessageParam::with(role: Role::ASSISTANT, content: $summary->content),
      ...array_slice($history, 2),
      BetaMessageParam::with(role: Role::USER, content: 'Which day should the release go out?'),
  ];
  $third = $client->beta->messages->create(
      model: MODEL,
      maxTokens: 8192,
      system: SYSTEM,
      betas: BETAS,
      thinking: $thinking,
      messages: $history,
  );

  // 4. Ein 200 ohne verworfene Blöcke bedeutet, dass das beibehaltene Thinking gültig blieb.
  printf("Dropped thinking blocks: %d\n", count($third->inputTransformations));
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  # Claude Fable 5.1 ist das erste Modell, das zurückgesendetes Thinking mit der Konversation abgleicht.
  MODEL = Anthropic::Model::CLAUDE_FABLE_5_1
  BETAS = [
    Anthropic::AnthropicBeta::COMPACT_2026_09_04,
    Anthropic::AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01
  ]
  SYSTEM = "You help plan a recipe app's release. Keep answers short."
  # Mit "error" führt ein Thinking-Block, der die Prüfung nicht besteht, zum Fehlschlagen der Anfrage mit 400.
  THINKING = Anthropic::Beta::BetaThinkingConfigAdaptive.new(
    block_binding: Anthropic::Beta::BetaThinkingBlockBinding.new(
      prefix_mismatch_behavior: Anthropic::Beta::BetaThinkingPrefixMismatchBehavior::ERROR
    )
  )

  # 1. Führe eine kurze Konversation mit aktiviertem Thinking.
  history = [{ role: "user", content: "What are the main entities in the app's data model?" }]
  first = client.beta.messages.create(
    model: MODEL,
    max_tokens: 8192,
    system_: SYSTEM,
    betas: BETAS,
    thinking: THINKING,
    messages: history
  )
  history += [
    { role: "assistant", content: first.content },
    {
      role: "user",
      content: "Testing starts on Tuesday, March 3, 2026, takes 10 weekdays, and pauses on March 9 and March 16. On which date does it end?"
    }
  ]
  second = client.beta.messages.create(
    model: MODEL,
    max_tokens: 8192,
    system_: SYSTEM,
    betas: BETAS,
    thinking: THINKING,
    messages: history
  )
  history << { role: "assistant", content: second.content }
  thinking_blocks = second.content.count { it.is_a?(Anthropic::Beta::BetaThinkingBlock) }
  puts "Thinking blocks in the kept turn: #{thinking_blocks}"

  # 2. Fasse den ersten Turn zusammen. Der zweite Turn bleibt außerhalb der Anfrage.
  summary = client.beta.messages.create(
    model: MODEL,
    max_tokens: 4096,
    system_: SYSTEM,
    betas: BETAS,
    thinking: THINKING,
    messages: history.first(2),
    compaction: { type: "summarize" }
  )
  abort "No summary: #{summary.stop_reason}" unless summary.stop_reason == :compaction

  # 3. Setze den Block vor den beibehaltenen Turn und stelle die nächste Frage.
  history = [
    { role: "assistant", content: summary.content },
    *history.drop(2),
    { role: "user", content: "Which day should the release go out?" }
  ]
  third = client.beta.messages.create(
    model: MODEL,
    max_tokens: 8192,
    system_: SYSTEM,
    betas: BETAS,
    thinking: THINKING,
    messages: history
  )

  # 4. Ein 200 ohne verworfene Blöcke bedeutet, dass das beibehaltene Thinking gültig war.
  puts "Dropped thinking blocks: #{third.input_transformations.length}"
  ```
</CodeGroup>

```text Output wrap
Thinking blocks in the kept turn: 1
Dropped thinking blocks: 0
```

In der Produktion sorgt `"drop_block"` dafür, dass Anfragen weiterhin erfolgreich sind, wenn eine Bedingung nicht erfüllt ist, und meldet jeden verworfenen Block in `input_transformations` mit `reason: "prefix_binding_mismatch"`. Ein Eintrag, dessen `path` in einen beibehaltenen Turn fällt, bedeutet, dass das Nachdenken dieses Turns nicht gültig geblieben ist. [Was die API mit einem ungültigen Block macht](https://platform.claude.com/docs/de/build-with-claude/preserved-thinking#mismatch-behavior) beschreibt, was verworfen wird, und erklärt, wie du dafür Alarme einrichtest. Auf Claude Sonnet 5.5 und Claude Haiku 5.5 funktioniert `block_binding` nur mit `thinking: {"type": "adaptive"}`. Eine Anfrage, die es mit `thinking: {"type": "between_tools"}` auf Claude Sonnet 5.5 oder mit `thinking: {"type": "disabled"}` auf Claude Haiku 5.5 setzt, gibt einen 400-Fehler zurück. Stelle bei diesen Anfragen sicher, dass jede Bedingung erfüllt ist, oder entferne die Blöcke `thinking` und `redacted_thinking` aus den beibehaltenen Turns.
