---
title: 다른 대화에 바인딩된 사고 블록 수정하기
url: https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/fix-bound-to-a-different-conversation
description: 사고 블록이 다른 대화에 바인딩되어 있다는 400 오류 이후 대화를 다시 진행하고, 코드가 변경한 내용을 찾고, 변경이 사라졌는지 테스트합니다.
featureMetadata:
  status: stable
  supportedModels:
    - claude-fable-5-2
    - claude-mythos-5-2
    - claude-fable-5-1
    - claude-mythos-5-1
    - claude-opus-5-5
    - claude-sonnet-5-5
    - claude-haiku-5-5
  supportedPlatforms:
    Claude API: stable
    Amazon Bedrock: stable
    Amazon Bedrock (bedrock-runtime): stable
    Claude Platform on AWS: stable
    Claude Models on Google Cloud (Anthropic managed): stable
    Claude Models on Google Cloud (Google managed): stable
    Microsoft Foundry: stable
---

같은 요청을 다시 보내는 것으로는 해결될 수 없습니다. 기록에 코드가 변경한 내용이 여전히 남아 있기 때문입니다. [지금 바로 오류 중단하기](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/fix-bound-to-a-different-conversation#prefix-mismatch-error)를 하려면 `"drop_block"`을 보내세요. 장기적인 해결책은 코드를 [“append-only”(추가 전용)](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/prefix-checks#prefix-check)로 만드는 것입니다.

## 오류: The block is bound to a different conversation

“Thinking block”(사고 블록)이 [“prefix check”(접두사 검사)](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/prefix-checks#prefix-check)에 실패했습니다. Claude가 블록을 생성한 후 그 앞의 무언가가 변경되었거나([변경으로 간주되는 것](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/prefix-checks#what-counts-as-an-edit) 참조), 다른 블록들 사이에 있던 사고 블록이 누락되거나 이동되었습니다. 오류는 다음과 같으며, 이어서 [무엇이 변경되었는지 명시할 수 있습니다](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/fix-bound-to-a-different-conversation#prefix-mismatch-error-details):

```text wrap
messages.1.content.0: Invalid `signature` in `thinking` block. The block is bound to a different conversation. Remove the block, or set `thinking.block_binding.prefix_mismatch_behavior` to "drop_block".
```

“A different conversation”은 블록 앞의 내용이 다르다는 뜻입니다. [접두사 검사](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/prefix-checks#prefix-check)는 세션이나 사용자를 비교하지 않습니다. 오류 메시지는 블록을 제거하라고 하지만, [해당 블록만 제거하는 것으로는 충분하지 않습니다](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/fix-bound-to-a-different-conversation#remove-by-hand). [다른 오류](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/fix-bound-to-a-different-conversation#similar-errors)도 비슷하게 보일 수 있습니다.

앱이 직접 만든 것이 아니라면 새 대화를 시작하고 해당 앱의 유지 관리자에게 알리세요. [비밀 정보, 개인 데이터 또는 주입된 텍스트를 제거했거나](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/change-tools-or-instructions#remove-sensitive-content), 요청에서 [사고를 끄는](https://platform.claude.com/docs/ko/build-with-claude/thinking#turning-thinking-off) 경우에는 1단계 대신 [사고를 수동으로 제거하세요](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/fix-bound-to-a-different-conversation#remove-by-hand).

<Steps>
  <Step title="지금 바로 오류 중단하기">
    `thinking.block_binding.prefix_mismatch_behavior`를 `"drop_block"`으로 설정하고, [베타 헤더](https://platform.claude.com/docs/ko/api/beta-headers#beta-features-on-other-platforms) `anthropic-beta: thinking-binding-controls-2026-08-01`을 보내세요. API는 요청 간에 이 설정을 저장하지 않으므로, 대화의 이후 모든 요청에서 이렇게 하세요. 저장된 대화에는 코드를 수정한 후에도 변경 내용이 그대로 남아 있으므로, 설정을 대화와 함께 저장하세요. 다음과 같이 `type`을 `"adaptive"`로 설정하세요:

    ```json
    {
      "thinking": {
        "type": "adaptive",
        "block_binding": {
          "prefix_mismatch_behavior": "drop_block"
        }
      }
    }
    ```

    SDK에서는 [테스트 프로그램](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/fix-bound-to-a-different-conversation#how-to-tell-whether-your-integration-is-impacted-details)처럼 베타 Messages 메서드를 호출하고 헤더 값을 전달하세요. 오류가 [여전히 헤더를 요구한다면](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/fix-bound-to-a-different-conversation#setting-not-received), 헤더가 도달하지 않은 것입니다.

    이렇게 하면 유효하지 않은 사고를 제외하여 오류를 멈추지만, [비용이 더 들 수 있고](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/fix-bound-to-a-different-conversation#drop-block-cost) 출력 품질과 “latency”(지연 시간)에 영향을 줄 수 있습니다. 다음 요청은 성공하며, 그 응답의 `input_transformations` 배열에는 API가 제외한 각 블록이 나열됩니다.

    요청에서 `thinking` 매개변수를 설정하지 않는다면, 이를 추가해도 다른 것은 바뀌지 않습니다. [“preserved thinking”(보존된 사고)을 지원하는 모델](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/prefix-checks#outcomes)은 기본적으로 적응형으로 사고하기 때문입니다.
  </Step>

  <Step title="장기적인 해결책">
    통합을 추가 전용으로 만드세요:

    1. 변경 내용을 찾으세요. 오류가 이를 명시할 수 있습니다. 코드의 어느 부분에서 변경이 일어나는지 찾으려면 `claude update`를 실행한 다음, 코드 리포지토리에서 Claude Code로 `/claude-api preserved-thinking-migration`을 실행하세요. 또는 [직접 찾아보세요](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/fix-bound-to-a-different-conversation#find-the-change-details).
    2. 변경을 중단하세요. 그렇지 않으면 새 대화에서도 오류가 발생할 수 있습니다. [대신 끝에 업데이트를 보내세요](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/change-tools-or-instructions).
    3. 진행 중인 각 대화에는 [마지막으로 성공한 요청](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/change-tools-or-instructions#saved-sessions)의 `system`과 `tools`를 계속 보내세요.
  </Step>
</Steps>

변경이 최근에 이루어졌다면 대신 되돌릴 수 있습니다. 코드가 변경한 내용을 원래대로 복원하세요. 변경 이전의 사고는 다시 유효해집니다. 그 이후에 생성된 사고는 접두사 검사에 실패하므로, 제거하거나 `"drop_block"`을 계속 보내세요.

## 사고 제외의 비용

Claude는 더 이상 읽을 수 없는 추론을 다시 풀어내는 데 더 많은 출력 토큰을 사용할 수 있습니다. 또한 블록을 제외하면 처음으로 제외된 블록 이후의 프롬프트 캐시가 무효화됩니다.

매 턴마다 무언가가 변경되면 매 턴에서 이전 턴의 사고를 잃게 되므로, 증가가 반복됩니다. `"drop_block"`에 의존하기 전에 자체 워크로드로 평가(eval)를 실행하세요.

<Frame>
  ![변경 후의 요청 네 개: 첫 번째는 거부되고, 다음 세 개는 이전 "thinking"(사고)을 제외하고 각각의 새 블록은 유지합니다](https://platform.claude.com/docs/ko/images/preserved-thinking-drop-block-loss.svg)
</Frame>

`"drop_block"`은 수정 중인 변경이 남아 있는 기존 대화를 계속 이어가기 위해, 그리고 [자체 요약 이후](https://platform.claude.com/docs/ko/build-with-claude/compaction-thinking-blocks#own-summary)처럼 계획된 제외를 위해 사용하세요. 코드가 계속 만들어내는 변경을 숨기기 위해 켜 두지 마세요. 유효하지 않은 블록이 기록에서 빠지면 [보내는 것을 중단할 수 있습니다](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/fix-bound-to-a-different-conversation#drop-block-cost-details).

## 코드가 변경한 내용 찾기

변경은 API가 명시한 첫 번째 블록보다 앞에 있습니다. 400 오류는 `system`, `tools`, 누락된 사고 블록, 또는 처음으로 달라진 메시지 등 무엇이 변경되었는지 알려줄 수 있습니다. 오류가 없거나 오류가 이를 알려주지 않는다면, `prefix_binding_mismatch` 항목이나 늘어난 출력 토큰 등 [가지고 있는 정보에서 시작하세요](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/fix-bound-to-a-different-conversation#find-the-change-details).

## 접두사 검사 실패에 대비해 코드 테스트하기

테스트는 실패하는 것을 확인한 후에야 신뢰할 수 있습니다. 먼저 자체 코드를 통해 Claude가 사고하도록 하는 세션을 실행하고, 의도적으로 무언가를 변경하세요. 이 단계에서는 `"drop_block"`을 보내서, 응답이 첫 번째 블록에서 멈추지 않고 유효하지 않은 모든 블록을 나열하도록 하세요. [다섯 단계와 프로그램](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/fix-bound-to-a-different-conversation#how-to-tell-whether-your-integration-is-impacted-details)에서 보여주는 것과 같습니다.

그런 다음 그 변경을 제거하고 실제 세션을 실행하세요. 모든 요청에서 베타 헤더 `thinking-binding-controls-2026-08-01`을 보내고 [`prefix_mismatch_behavior`](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/prefix-checks#preserved-thinking-controls)를 `"error"`로 설정하여, 해당 세션에서 코드가 만드는 변경이 400 오류로 빌드를 실패시키도록 하세요.

압축하거나, 나중에 도구를 추가하거나, 지침을 변경하거나, [모델을 전환하거나](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking#switching-models), 재개하는 세션을 테스트하세요. 일반 턴으로는 해당 코드에 도달하지 않습니다.

깨끗한 실행에는 `prefix_binding_mismatch` 항목도 오류도 없습니다. 이는 실행한 세션에서 확인된 블록이 유효하다는 것만 보여줍니다. 다음의 경우에는 아무것도 증명하지 못합니다:

* 세션에 사고 블록이 없었던 경우
* 코드가 모든 사고를 제거하거나, 모델이 보존된 사고를 지원하지 않는 경우
* 베타 헤더를 보내지 않았고, [모델이 접두사 검사에 실패한 블록을 오류 없이 통과시킬 수도 있는](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/prefix-checks#outcomes) 경우

## 프로덕션을 모니터링하고, 오류 없이 손실된 추론 찾기

각 400 오류를 기록하고, 대화가 계속되도록 [코드에서 처리하세요](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/fix-bound-to-a-different-conversation#handle-the-error-in-code). 대신 `prefix_mismatch_behavior`를 요청에 포함하지 않고 두는 경우에는, 접두사 검사에 실패한 채 Claude에 도달한 사고가 있는지 [프로덕션 트래픽을 모니터링하세요](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/prefix-checks#watch-production-traffic).

추론은 `"drop_block"`, 배치 항목, 모델 전환, [다른 계정](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking#account-bound-thinking)으로의 이동, 또는 사고를 다시 보내지 않는 코드를 통해 오류 없이 손실될 수 있습니다. 베타 헤더를 사용하면 마지막 경우를 제외한 각각이 항목을 남깁니다. 마지막 경우에는 요청에 `thinking` 블록이 포함되어 있는지 확인하세요.

## 기술 세부 사항

### 오류 메시지가 추가로 알려줄 수 있는 내용

API가 판단할 수 있는 경우, 오류 메시지는 이어서 `system`, `tools`, 처음으로 달라진 메시지나 블록, 누락되거나 새로 추가된 내용, 또는 누락되거나 순서가 바뀐 이전 사고 블록 등 무엇이 변경되었는지 명시합니다. 이 문장의 문구는 변경될 수 있으므로 이를 기준으로 매칭하지 마세요. 요청에 베타 헤더가 없었다면 오류 메시지에 다음 문장이 추가됩니다:

```text wrap
That setting requires the `thinking-binding-controls-2026-08-01` value in the `anthropic-beta` header.
```

### 오류가 여전히 헤더를 요구하거나, `Extra inputs are not permitted`라고 표시되는 경우

오류가 여전히 헤더를 요구한다면 헤더가 API에 도달하지 않은 것입니다. 프록시나 라이브러리가 헤더를 제거했을 수 있습니다. `block_binding: Extra inputs are not permitted`로 끝나는 다른 오류도 같은 의미이거나, 사고가 꺼져 있다는 의미입니다.

### 유효하지 않은 사고를 수동으로 제거하기

설정을 보낼 수 없는 경우, 또는 다음 중 하나에 해당하는 경우에 이 방법을 사용하세요:

* 비밀 정보, 개인 데이터 또는 주입된 텍스트를 제거한 후. `"drop_block"`은 저장된 기록에 사고를 남겨 두기 때문입니다.
* 사고가 꺼져 있는 경우(`"disabled"` 또는 `"between_tools"`). `"drop_block"`에는 `"adaptive"`가 필요한데, 이는 사고를 켜고 출력 토큰을 늘리기 때문입니다.

1. 오류가 명시한 블록과 그 뒤의 모든 `thinking` 및 [`redacted_thinking`](https://platform.claude.com/docs/ko/build-with-claude/thinking#redacted-thinking-blocks) 블록을 제거하세요. 그렇지 않으면 같은 오류가 다음 유효하지 않은 블록을 명시합니다. 단, 기록에 `role: "system"` 메시지가 있거나 같은 역할의 메시지가 연속으로 두 개 있는 경우에는 모든 `thinking` 및 `redacted_thinking` 블록을 제거하세요. 오류는 그러한 메시지를 바로 앞 메시지의 일부로 계산하므로, 오류가 명시하는 위치가 배열의 인덱스보다 작을 수 있습니다. `input_transformations` 항목의 `path`는 모든 메시지를 개별적으로 계산합니다.
2. 다른 모든 블록은 유지하고 요청을 다시 보내세요. 제거한 블록을 다시 넣지 마세요.

### 이 오류와 비슷해 보이는 오류

다음 오류들은 블록이 다른 대화에 바인딩되어 있다고 말하지 않으며, `prefix_mismatch_behavior`를 설정해도 해결되지 않을 수 있습니다:

* “Invalid `signature` in `thinking` block”에서 끝나는 메시지, “cannot be modified”라고 하는 메시지, 또는 `budget_tokens`에 관한 메시지: [사고 문제 해결](https://platform.claude.com/docs/ko/build-with-claude/thinking-troubleshooting)
* `temperature` 또는 미리 채운 응답에 관한 메시지: [제한 사항 및 기능 호환성](https://platform.claude.com/docs/ko/build-with-claude/thinking#limits-and-feature-compatibility)

### `"drop_block"` 전송을 중단할 수 있는 시점

`"drop_block"` 전송을 중단하려면, 이 설정으로 제외되는 블록을 제거하고 그 이후에 생성된 사고는 유지하세요. 다른 변경이 없다면, 그러면 대화는 `"error"`로도 통과합니다.

### 코드에서 오류 처리하기

코드에서 오류를 처리하려면 모든 요청에서 베타 헤더와 `"error"`를 보내, 모든 모델에서 실패가 400 오류가 되도록 하세요. 오류가 발생하면 해당 대화만 이후 모든 요청에서 `"drop_block"`으로 전환하고, 그 선택을 대화와 함께 저장한 뒤, 한 번 다시 보내고, 오류를 기록하세요. 같은 오류가 다시 발생하면 설정이 API에 도달하지 않은 것입니다. [오류가 여전히 헤더를 요구하거나, `Extra inputs are not permitted`라고 표시되는 경우](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/fix-bound-to-a-different-conversation#setting-not-received)를 참조하세요.

코드는 이 오류를 `message` 필드로 인식해야 합니다. 이는 오류 텍스트로 매칭하지 말라는 일반적인 권고의 예외입니다. 모든 400 오류는 `invalid_request_error` 유형이며, 이 오류에는 `error.details.error_code`가 없습니다. 메시지의 나머지 부분은 변경될 수 있으므로 “The block is bound to a different conversation”에만 매칭하세요.

### 오류가 없거나, 오류가 무엇이 변경되었는지 알려주지 않는 경우

* **400 오류가 있지만 변경 내용을 명시하지 않는 경우:** 요청을 직접 비교하세요. 한 가지 원인은 압축 블록이 요약하는 메시지를 제거하지 않고 압축 블록을 보낸 경우입니다.

* **`prefix_binding_mismatch` 항목:** 첫 번째 항목의 `path`까지의 `system`, `tools`, `messages`를 해당 블록이 생성되었을 때의 대화와 비교하세요. 모든 블록이 나열되어 있다면 `system`과 `tools`부터 시작하세요.

  다른 점이 없다면 [내용이 변경된 이미지 또는 문서 URL](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/change-tools-or-instructions#files-by-id), “Model Context Protocol”, 즉 MCP 서버의 변경된 도구 목록([MCP 서버의 도구 목록 고정하기](https://platform.claude.com/docs/ko/agents-and-tools/mcp-connector#pin-mcp-tool-list) 참조), 또는 누락되거나 이동되거나 다시 추가된 사고 블록을 찾아보세요. 요청 로그가 없다면 `"error"`로 요청을 다시 보내고, 무엇이 다른지 알려주는 문장이 있으면 읽어 보세요.

* **중간에 직접 관리하지 않는 프록시나 라이브러리가 있는 경우:** 그것이 보내는 내용을 보낸 내용과 비교하고, 해당 유지 관리자에게 [라이브러리, 프록시, 게이트웨이](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/change-tools-or-instructions#libraries-proxies-gateways)를 안내하세요.

* **의심만 있고 Claude Code가 없는 경우:** 압축이나 도구 변경이 있는 대화의 요청 본문을 캡처하세요. 새 턴을 제외하고 각 요청 본문을 이전 것과 비교하세요.

### 실패할 수 있는 테스트를 위한 다섯 단계와 이를 실행하는 프로그램

1. 자체 코드에서, 세션의 각 요청에 베타 헤더와 `"drop_block"`을 담아 [보존된 사고를 지원하는 모델](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/prefix-checks#outcomes)로 보내세요.
2. Claude가 사고하도록 하는 프롬프트를 사용하고, 첫 번째 응답에 `thinking` 블록이 있는지 확인하세요. “Adaptive thinking”(적응형 사고)에서는 쉬운 프롬프트에 대해 Claude가 사고를 건너뛸 수 있습니다.
3. reason이 `prefix_binding_mismatch`인 `input_transformations` 항목에 대해서만 실패하도록 하세요. 빈 배열을 기대하는 테스트는 모델 전환 후에도 실패합니다. 그때는 `model_binding_mismatch` 또는 `organization_binding_mismatch` 항목이 예상되기 때문입니다.
4. 세 번째 요청에만 `system` 프롬프트를 추가하는 등 의도적으로 무언가를 변경하세요.
5. `input_transformations`에 변경 이후에 있는 사고 블록이 나열되는지 확인하세요. 아무것도 나열되지 않으면 기록에 사고 블록이 있는지 확인하세요.

이 프로그램은 1, 2, 4, 5단계를 수행합니다. 각 응답에 있는 사고 블록과 `input_transformations` 항목의 개수를 출력한 다음, 3단계에서 확인하는 각 항목을 출력합니다:

<CodeGroup exclude="shell:cURL, shell:CLI">
  <CodeGroupItem language="cURL">
    이 워크플로에는 단일 셸 명령보다 더 많은 로직이 필요합니다. 실행하려면 [Anthropic SDK](https://platform.claude.com/docs/ko/cli-sdks-libraries/overview)를 사용하세요.
  </CodeGroupItem>

  <CodeGroupItem language="CLI">
    이 워크플로에는 단일 셸 명령보다 더 많은 로직이 필요합니다. 실행하려면 [Anthropic SDK](https://platform.claude.com/docs/ko/cli-sdks-libraries/overview)를 사용하세요.
  </CodeGroupItem>

  ```python Python
  client = anthropic.Anthropic()

  user_turns = [
      "How many positive integers below 500 have exactly 6 positive divisors?",
      "How many have exactly 8?",
      "How many have exactly 10?",
  ]

  messages = []
  for turn, user_turn in enumerate(user_turns, start=1):
      messages.append({"role": "user", "content": user_turn})
      response = client.beta.messages.create(
          model="claude-opus-5-5",
          max_tokens=16000,
          thinking={
              "type": "adaptive",
              "block_binding": {"prefix_mismatch_behavior": "drop_block"},
          },
          # 마지막 요청에만 시스템 프롬프트를 추가하며, 이는 의도적으로 접두사를 변경합니다
          system="Answer briefly." if turn == len(user_turns) else anthropic.omit,
          messages=messages,
          betas=["thinking-binding-controls-2026-08-01"],
      )
      messages.append({"role": "assistant", "content": response.content})
      thinking_blocks = sum(block.type == "thinking" for block in response.content)
      entries = response.input_transformations or []
      print(f"thinking blocks: {thinking_blocks}, entries: {len(entries)}")
      for entry in entries:
          if entry.type == "thinking_dropped":
              print(entry.type, entry.path, entry.reason)
  ```

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

  const userTurns = [
    "How many positive integers below 500 have exactly 6 positive divisors?",
    "How many have exactly 8?",
    "How many have exactly 10?"
  ];

  const messages: Anthropic.Beta.BetaMessageParam[] = [];
  for (const [turnIndex, userTurn] of userTurns.entries()) {
    messages.push({ role: "user", content: userTurn });
    const response = await client.beta.messages.create({
      model: "claude-opus-5-5",
      max_tokens: 16000,
      thinking: {
        type: "adaptive",
        block_binding: { prefix_mismatch_behavior: "drop_block" }
      },
      // 마지막 요청에서만 시스템 프롬프트를 추가하며, 이는 의도적으로 접두사를 변경합니다
      system: turnIndex === userTurns.length - 1 ? "Answer briefly." : undefined,
      messages,
      betas: ["thinking-binding-controls-2026-08-01"]
    });
    messages.push({ role: "assistant", content: response.content });
    const thinkingBlocks = response.content.filter((block) => block.type === "thinking");
    const entries = response.input_transformations ?? [];
    console.log(`thinking blocks: ${thinkingBlocks.length}, entries: ${entries.length}`);
    for (const entry of entries) {
      if (entry.type === "thinking_dropped") {
        console.log(entry.type, entry.path, entry.reason);
      }
    }
  }
  ```

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

  AnthropicClient client = new();

  string[] userTurns =
  [
      "How many positive integers below 500 have exactly 6 positive divisors?",
      "How many have exactly 8?",
      "How many have exactly 10?",
  ];

  List<BetaMessageParam> messages = [];
  foreach (var (turnIndex, userTurn) in userTurns.Index())
  {
      messages.Add(new BetaUserMessageParam { Content = userTurn });
      var response = await client.Beta.Messages.Create(
          new()
          {
              Model = Model.ClaudeOpus5_5,
              MaxTokens = 16000,
              Thinking = new BetaThinkingConfigAdaptive
              {
                  BlockBinding = new()
                  {
                      PrefixMismatchBehavior = BetaThinkingPrefixMismatchBehavior.DropBlock,
                  },
              },
              // 마지막 요청에만 시스템 프롬프트를 추가하며, 이는 의도적으로 접두사를 변경합니다
              System = turnIndex == userTurns.Length - 1 ? new("Answer briefly.") : null,
              Messages = messages,
              Betas = [AnthropicBeta.ThinkingBindingControls2026_08_01],
          }
      );
      messages.Add(new BetaAssistantMessageParam
      {
          Content = response.Content.Select(block => new BetaContentBlockParam(block.Json)).ToList(),
      });
      var thinkingBlocks = response.Content.Count(block => block.TryPickThinking(out _));
      var entries = response.InputTransformations ?? [];
      Console.WriteLine($"thinking blocks: {thinkingBlocks}, entries: {entries.Count}");
      foreach (var entry in entries)
      {
          if (entry.TryPickThinkingDropped(out var dropped))
          {
              Console.WriteLine($"{dropped.Type} {dropped.Path} {dropped.Reason.Raw()}");
          }
      }
  }
  ```

  ```go Go
  client := anthropic.NewClient()

  userTurns := []string{
  	"How many positive integers below 500 have exactly 6 positive divisors?",
  	"How many have exactly 8?",
  	"How many have exactly 10?",
  }

  messages := []anthropic.BetaMessageParam{}
  for turnIndex, userTurn := range userTurns {
  	messages = append(messages, anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock(userTurn)))
  	// 마지막 요청만 시스템 프롬프트를 추가하며, 이는 의도적으로 접두사를 변경합니다
  	var system []anthropic.BetaTextBlockParam
  	if turnIndex == len(userTurns)-1 {
  		system = []anthropic.BetaTextBlockParam{{Text: "Answer briefly."}}
  	}
  	response, err := client.Beta.Messages.New(context.TODO(), anthropic.BetaMessageNewParams{
  		Model:     anthropic.ModelClaudeOpus5_5,
  		MaxTokens: 16000,
  		Thinking: anthropic.BetaThinkingConfigParamUnion{
  			OfAdaptive: &anthropic.BetaThinkingConfigAdaptiveParam{
  				BlockBinding: anthropic.BetaThinkingBlockBindingParam{
  					PrefixMismatchBehavior: anthropic.BetaThinkingPrefixMismatchBehaviorDropBlock,
  				},
  			},
  		},
  		System:   system,
  		Messages: messages,
  		Betas:    []anthropic.AnthropicBeta{anthropic.AnthropicBetaThinkingBindingControls2026_08_01},
  	})
  	if err != nil {
  		log.Fatal(err)
  	}
  	messages = append(messages, response.ToParam())
  	thinkingBlocks := 0
  	for _, block := range response.Content {
  		if block.Type == "thinking" {
  			thinkingBlocks++
  		}
  	}
  	fmt.Printf("thinking blocks: %d, entries: %d\n", thinkingBlocks, len(response.InputTransformations))
  	for _, entry := range response.InputTransformations {
  		if entry.Type == "thinking_dropped" {
  			fmt.Println(entry.Type, entry.Path, entry.Reason)
  		}
  	}
  }
  ```

  ```java Java
  import com.anthropic.models.beta.AnthropicBeta;
  import com.anthropic.models.beta.messages.BetaContentBlock;
  import com.anthropic.models.beta.messages.BetaInputTransformation;
  import com.anthropic.models.beta.messages.BetaMessage;
  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;
  import com.anthropic.models.messages.Model;

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

      List<String> userTurns = List.of(
          "How many positive integers below 500 have exactly 6 positive divisors?",
          "How many have exactly 8?",
          "How many have exactly 10?");

      MessageCreateParams.Builder conversation = MessageCreateParams.builder()
          .model(Model.CLAUDE_OPUS_5_5)
          .maxTokens(16000L)
          .thinking(BetaThinkingConfigAdaptive.builder()
              .blockBinding(BetaThinkingBlockBinding.builder()
                  .prefixMismatchBehavior(BetaThinkingPrefixMismatchBehavior.DROP_BLOCK)
                  .build())
              .build())
          .addBeta(AnthropicBeta.THINKING_BINDING_CONTROLS_2026_08_01);

      for (int turnIndex = 0; turnIndex < userTurns.size(); turnIndex++) {
          if (turnIndex == userTurns.size() - 1) {
              // 마지막 요청만 시스템 프롬프트를 추가하며, 이는 의도적으로 접두사를 변경합니다
              conversation.system("Answer briefly.");
          }
          conversation.addUserMessage(userTurns.get(turnIndex));
          BetaMessage response = client.beta().messages().create(conversation.build());
          conversation.addMessage(response);
          long thinkingBlocks = response.content().stream()
              .filter(BetaContentBlock::isThinking)
              .count();
          List<BetaInputTransformation> entries = response.inputTransformations().orElse(List.of());
          IO.println("thinking blocks: " + thinkingBlocks + ", entries: " + entries.size());
          for (BetaInputTransformation entry : entries) {
              entry.thinkingDropped().ifPresent(dropped ->
                  IO.println(entry.type() + " " + dropped.path() + " " + dropped.reason()));
          }
      }
  }
  ```

  ```php PHP
  use Anthropic\Beta\AnthropicBeta;
  use Anthropic\Beta\Messages\BetaThinkingBlock;
  use Anthropic\Beta\Messages\BetaThinkingBlockBinding;
  use Anthropic\Beta\Messages\BetaThinkingConfigAdaptive;
  use Anthropic\Beta\Messages\BetaThinkingDroppedInputTransformation;
  use Anthropic\Beta\Messages\BetaThinkingPrefixMismatchBehavior;
  use Anthropic\Client;
  use Anthropic\Messages\Model;

  $client = new Client();

  $userTurns = [
      'How many positive integers below 500 have exactly 6 positive divisors?',
      'How many have exactly 8?',
      'How many have exactly 10?',
  ];

  $messages = [];
  foreach ($userTurns as $turnIndex => $userTurn) {
      $messages[] = ['role' => 'user', 'content' => $userTurn];
      $response = $client->beta->messages->create(
          model: Model::CLAUDE_OPUS_5_5,
          maxTokens: 16000,
          thinking: BetaThinkingConfigAdaptive::with(
              blockBinding: BetaThinkingBlockBinding::with(
                  prefixMismatchBehavior: BetaThinkingPrefixMismatchBehavior::DROP_BLOCK,
              ),
          ),
          // 마지막 요청만 시스템 프롬프트를 추가하며, 이는 의도적으로 접두사를 변경합니다
          system: $turnIndex === array_key_last($userTurns) ? 'Answer briefly.' : null,
          messages: $messages,
          betas: [AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01],
      );
      $messages[] = ['role' => 'assistant', 'content' => $response->content];
      $thinkingBlocks = array_filter(
          $response->content,
          fn ($block) => $block instanceof BetaThinkingBlock,
      );
      $entries = $response->inputTransformations ?? [];
      echo 'thinking blocks: ', count($thinkingBlocks), ', entries: ', count($entries), PHP_EOL;
      foreach ($entries as $entry) {
          if ($entry instanceof BetaThinkingDroppedInputTransformation) {
              echo $entry->type, ' ', $entry->path, ' ', $entry->reason, PHP_EOL;
          }
      }
  }
  ```

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

  user_turns = [
    "How many positive integers below 500 have exactly 6 positive divisors?",
    "How many have exactly 8?",
    "How many have exactly 10?"
  ]

  messages = []
  user_turns.each_with_index do |user_turn, turn_index|
    messages << { role: "user", content: user_turn }
    # 마지막 요청에만 시스템 프롬프트를 추가하여 의도적으로 접두사를 변경합니다
    system_param = (turn_index == user_turns.length - 1) ? { system_: "Answer briefly." } : {}
    response = client.beta.messages.create(
      model: Anthropic::Model::CLAUDE_OPUS_5_5,
      max_tokens: 16_000,
      thinking: {
        type: "adaptive",
        block_binding: { prefix_mismatch_behavior: "drop_block" }
      },
      messages: messages,
      betas: [Anthropic::AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01],
      **system_param
    )
    messages << { role: "assistant", content: response.content }
    thinking_blocks = response.content.count { |block| block.is_a?(Anthropic::Beta::BetaThinkingBlock) }
    entries = response.input_transformations || []
    puts "thinking blocks: #{thinking_blocks}, entries: #{entries.length}"
    entries.each do |entry|
      if entry.is_a?(Anthropic::Beta::BetaThinkingDroppedInputTransformation)
        puts "#{entry.type} #{entry.path} #{entry.reason}"
      end
    end
  end
  ```
</CodeGroup>

```text Output wrap
thinking blocks: 1, entries: 0
thinking blocks: 1, entries: 0
thinking blocks: 1, entries: 2
thinking_dropped messages.1.content.0 prefix_binding_mismatch
thinking_dropped messages.3.content.0 prefix_binding_mismatch
```

`"drop_block"` 대신 `"error"`를 사용하면 세 번째 요청에서 [400 오류](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/fix-bound-to-a-different-conversation#prefix-mismatch-error)가 발생합니다.

### 각 `input_transformations` 항목의 의미와 직접 수정해야 하는 항목

베타 헤더를 사용하면, 사고를 지원하는 모델의 응답에는 `usage` 옆에 `input_transformations` 배열이 있습니다. 제외된 것이 없고 유효하지 않은 것이 통과되지 않았다면 이 배열은 비어 있습니다. 스트리밍할 때는 `message_start` 이벤트의 `message`에 있으며, 스트림 중간 폴백 이후에는 최종 `message_delta` 이벤트가 실제로 적용되는 배열을 담고 있습니다. 오류의 위치와 달리, `path`는 항상 보낸 그대로의 블록 위치입니다:

```json
{
  "input_transformations": [
    {
      "type": "thinking_dropped",
      "path": "messages.1.content.0",
      "reason": "prefix_binding_mismatch"
    }
  ]
}
```

각 항목의 `type`과 `reason`, 그리고 그 의미:

* **`thinking_dropped`, `prefix_binding_mismatch`:** 이 블록 앞에 온 내용이 블록이 기록한 내용과 다릅니다. 직접 수정해야 합니다: [코드가 변경한 내용 찾기](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/fix-bound-to-a-different-conversation#find-the-change).
* **`thinking_mismatch_allowed`, `prefix_binding_mismatch`:** 위와 같지만, Claude가 블록을 변경 없이 읽었으며 요금이 청구됩니다. 이 항목은 [일부 모델](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/prefix-checks#outcomes)에서 설정이 요청에 포함되지 않은 경우에만 나타납니다. 직접 수정해야 합니다.
* **`thinking_dropped`, `model_binding_mismatch`:** 이 모델은 블록을 생성한 모델의 블록을 읽을 수 없습니다. 직접 수정할 필요가 없습니다: [전체 대화를 계속 보내세요](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking#switching-models).
* **`thinking_dropped`, `organization_binding_mismatch`:** 다른 계정이 블록을 생성했으므로 [API가 이를 제외했습니다](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking#account-bound-thinking). 직접 수정할 필요가 없습니다.

인식하지 못하는 `type` 또는 `reason`이 있는 항목은 무시하세요.

### 배치 및 토큰 계산

* **[메시지 배치](https://platform.claude.com/docs/ko/build-with-claude/batch-processing):** `prefix_mismatch_behavior`를 요청에 포함하지 않은 항목은 400 오류를 절대 받지 않습니다. API는 유효하지 않은 블록을 제외하거나, [일부 모델](https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/prefix-checks#outcomes)에서는 이를 통과시킬 수도 있습니다. `"error"`를 설정한 항목은 블록이 접두사 검사에 실패하면 `errored`로 처리됩니다. `block_binding`은 항목의 `params.thinking`에 넣습니다.
* **[토큰 카운팅](https://platform.claude.com/docs/ko/build-with-claude/token-counting):** Claude API에서 토큰 계산은 동일한 400 오류를 반환할 수 있으며, 같은 헤더와 함께 `prefix_mismatch_behavior`를 받습니다. 제외된 블록은 계산에서 빠지며, `input_transformations`는 반환하지 않습니다.

## 다음 단계

<CardGroup cols={2}>
  <Card title="접두사 검사에 실패하지 않고 도구 또는 지침 변경하기" icon="edit" href="https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking/change-tools-or-instructions">
    코드가 대화에 만드는 각 변경 대신 보내야 할 내용.
  </Card>

  <Card title="보존된 사고" icon="book" href="https://platform.claude.com/docs/ko/build-with-claude/preserved-thinking">
    보존된 사고란 무엇인지, 사고 블록이 무엇에 연결되는지, 그리고 모델 또는 계정 전환.
  </Card>

  <Card title="사고 문제 해결" icon="wrench" href="https://platform.claude.com/docs/ko/build-with-claude/thinking-troubleshooting">
    검증되지 않는 서명 등 다른 사고 오류에 대한 해결 방법.
  </Card>
</CardGroup>
