사고 블록에 대한 접두사 검사
접두사 검사가 무엇을 비교하는지, 어떤 모델이 이를 실행하는지, 요청이 접두사 검사에 실패하면 어떻게 되는지, 그리고 400 오류와 오류가 없는 경우를 처리하는 방법을 설명합니다.
사고 블록을 “preserved thinking”(보존된 사고)을 지원하는 모델로 다시 보내는 각 요청은 “prefix check”(접두사 검사)를 거칩니다. Claude가 블록을 생성한 후 system, tools 또는 이전 메시지가 변경되면 접두사 검사는 실패합니다. 다른 블록들 사이에 있던 사고 블록이 생략되었거나 이동한 경우에도 실패합니다.
접두사 검사에 실패하면 모델에 따라 400 오류가 발생할 수도 있고 발생하지 않을 수도 있으므로, 두 경우 모두 처리하세요.
접두사 검사의 영향을 받는 대상
다음 중 하나에 해당하면 변경할 것이 없습니다:
- Claude Code, claude.ai 또는 Claude Managed Agents가 대화 기록을 관리합니다.
- Claude Agent SDK가 기록을 관리하며, SDK에 제공하는 “system prompt”(시스템 프롬프트)가 동일하게 유지됩니다.
- 코드가 “append-only”(추가 전용) 통합의 세 가지 습관을 따르며, 전송 도중 요청을 다시 작성하는 것이 없습니다.
- 보존된 사고를 지원하는 모델을 호출하지 않습니다.
요청이 라이브러리, 프록시 또는 게이트웨이를 거치는 경우, 그것이 보내는 내용과 사용자가 보낸 내용을 비교하세요. 이러한 것을 직접 운영하는 경우, 무엇을 그대로 전달해야 하는지는 라이브러리, 프록시, 게이트웨이를 참조하세요.
동일하게 유지되어야 하는 것과 그 이유
통합을 추가 전용으로 만드세요. 다음 세 가지 습관으로 이를 달성할 수 있습니다:
- 각 어시스턴트 턴을 API가 반환한 그대로 다시 보내세요. 텍스트가 비어 있는 사고 블록도 포함합니다.
- 각 대화마다
system과tools를 한 번만 구성하고, 매번 그 사본을 보내세요. - 모든 업데이트는 끝에 새 메시지로 추가하고, 그대로 두세요.
각 사고 블록의 추론은 정확히 그 앞에 있던 내용, 즉 system, tools, 그리고 모든 이전 메시지에 관한 것입니다. 그 내용이 블록의 접두사(prefix)이며, 접두사 검사가 비교하는 대상입니다.
접두사 검사는 “prompt caching”(프롬프트 캐싱)과 비슷하지만, 변경이 생기면 단순히 캐시를 놓치는 것이 아니라 그 이후의 사고가 무효가 된다는 점이 다릅니다.
시스템 프롬프트에 오늘 날짜를 넣는 앱을 예로 들어 보겠습니다. 자정이 되면 날짜가 바뀌고, 대화에 이미 있는 사고의 접두사도 바뀝니다. 그 사고는 무효가 되고, 다음 요청은 실패할 수 있습니다. 추가 전용 앱은 시스템 프롬프트를 그대로 유지하고, 새 날짜를 끝에 있는 메시지에 명시합니다.
변경은 이미 그 뒤에 있는 사고만 무효로 만듭니다. 변경 이전의 사고와 이후에 Claude가 생성하는 사고는 유효하게 유지됩니다.
코드가 시스템 프롬프트, 도구 또는 기록을 변경하는 경우
| 코드가 다음을 수행하는 경우… | 해야 할 일 |
|---|---|
| 날짜, 모드 또는 지침 파일로 시스템 프롬프트를 다시 구성함 | system 변경을 중단하세요. 자체 지침을 시스템 메시지로 추가하고(messages 안의 role: "system" 항목), 새 값을 최신 턴에 명시하세요. 다른 사람이 편집할 수 있는 텍스트의 경우에는 대신 다른 사람이 편집할 수 있는 텍스트를 참조하세요. |
| 도구를 추가, 제거 또는 문구를 변경하거나, MCP 서버가 연결될 때 도구가 늘어남 | tools 변경을 중단하고, 시스템 메시지에서 도구를 추가하거나 제거하세요. |
| 오래된 턴을 잘라내거나, 축약하거나, 요약하고, 최신 턴은 변경하지 않고 유지함 | API가 요약을 작성하도록 하거나, 유지된 턴의 사고를 제거하세요. |
텍스트가 비어 있는 사고 블록을 건너뛰거나 저장된 대화를 다시 구성하는 것과 같은 다른 원인에는 각각의 해결 방법이 있습니다. 접두사 검사에 실패하지 않고 도구 또는 지침 변경하기를 참조하세요. 해당하는 원인을 찾으려면 에이전트에게 코드를 검토하도록 하세요.
접두사 검사에 실패했을 때 각 모델의 동작
Claude API와 일부 클라우드 플랫폼에서, prefix_mismatch_behavior를 지정하지 않은 상태로 접두사 검사에 실패했을 때의 결과는 모델에 따라 다릅니다:
| 보존된 사고를 지원하는 모델 | 결과 |
|---|---|
| Claude Fable 5.2 | 400 오류 |
| Claude Mythos 5.2 | 400 오류 |
| Claude Mythos 5.1 | 400 오류 |
| Claude Fable 5.1 | 400 오류 발생 가능 |
| Claude Opus 5.5 | 400 오류 발생 가능 |
| Claude Sonnet 5.5 | 400 오류 발생 가능 |
| Claude Haiku 5.5 | 400 오류 발생 가능 |
표에 “400 오류 발생 가능”이라고 표시된 모델에서는 두 가지 경우가 있습니다. 접두사 검사에 실패한 요청은 400 오류를 받을 수도 있고 오류를 받지 않을 수도 있습니다. 오류가 반환되지 않으면 접두사 검사에 실패한 블록이 모델에 전달됩니다. Claude는 이를 다른 입력과 마찬가지로 읽고, 해당 블록에 대해 요금이 청구되며, Claude는 이후 변경된 내용에 관한 추론을 바탕으로 작업합니다.
이러한 모델에서는 요청이 어떤 경우에 해당하는지 확인할 수 있지만, 두 경우 모두 처리하세요.
prefix_mismatch_behavior를 지정하지 않은 Message Batches 항목은 오류를 받지 않으며, API는 접두사 검사에 실패한 블록을 제외할 수 있습니다.
두 경우 모두 처리
모든 요청에서 하나의 결과를 얻으려면 통합을 추가 전용으로 만들거나 prefix_mismatch_behavior를 설정하세요. 그렇지 않으면 코드가 두 가지 동작을 모두 처리해야 합니다.
- 추가 전용: 세 가지 습관을 따르면, 코드 때문에 요청이 접두사 검사에 실패하는 일은 없습니다.
- 설정: 모든 요청에
"error"를 사용하면 접두사 검사의 각 실패는 400 오류가 되며, 코드에서 이를 처리합니다. - 두 가지 동작 모두: 설정을 지정하지 않는 경우, 400 오류를 처리하고 Claude에 전달된, 접두사 검사에 실패한 사고를 감시하세요.
400 오류가 발생한 후 복구하려면 해당 대화의 이후 요청에 "drop_block"을 보내세요. 여기에는 비용이 따릅니다. 사고 제외의 비용을 참조하세요. 오류를 숨기기 위해 모든 대화에 이를 보내지 마세요.
기술 세부 사항
접두사 검사의 작동 방식
보존된 사고를 지원하는 모델은 각 사고 블록의 접두사에 대한 지문(fingerprint)을 해당 블록의 signature에 기록합니다. API 레퍼런스에서는 접두사 검사를 대화 검사(conversation check)라고 부르며, 400 오류는 접두사 검사에 실패한 블록이 is bound to a different conversation라고 알립니다.
접두사 검사를 실행하는 모델
접두사 검사는 Claude API와 일부 클라우드 플랫폼에서 실행됩니다. 이는 보존된 사고를 지원하는 모델이 생성한 사고 블록을, 해당 모델 중 하나에 대한 요청에서 검사합니다. Claude API에서 Claude Opus 5와 같은 다른 모델은 접두사 검사를 실행하지 않으며, 접두사 검사는 해당 모델의 블록을 다루지 않습니다.
변경으로 간주되는 것
- 각 블록은 자체 기록과 비교하여 검사됩니다. API는 이번 요청에서 블록 앞에 있는 내용을 Claude가 해당 블록을 생성했을 때 서명이 기록한 내용과 비교합니다. 직전 요청은 아무런 역할을 하지 않습니다. 접두사 검사는 세션, ID 또는 사용자가 아닌 내용만 봅니다. 새 요청이나 포크에서 동일한 내용은 접두사 검사를 통과합니다.
- 접두사 검사는 Claude가 읽은 내용이 아니라 사용자가 보낸 내용을 비교합니다. 토큰 임계값 기반 압축과 컨텍스트 편집은 Claude가 읽는 내용만 변경하므로 변경으로 간주되지 않습니다. 임계값 압축 블록 이후에는 API가 해당 블록부터의 메시지와
system및tools만 비교합니다. 요청 시 압축(on-demand compaction)에는 자체 조건이 있습니다. 유지된 사고가 유효하게 유지되기 위한 조건을 참조하세요. URL로 보낸 파일과, Claude API에서의 MCP 도구 목록의 경우, API는 대신 자신이 가져온 내용을 비교합니다. - 보내는 사고는 끊김 없는 연속이어야 합니다. 사고 블록은 내용으로 비교되지 않습니다. 하지만 보내는 각 사고 블록은 첫 번째를 제외하고, Claude가 생성했을 때와 동일한 이전 사고 블록을 가져야 합니다. 따라서 가장 오래된 것, 가장 최신의 것 또는 전부를 생략할 수는 있지만, 중간에 있는 하나를 생략할 수는 없습니다.
변경은 도구 설명의 단어 하나처럼 작을 수도 있습니다. 이전 메시지를 변경, 삽입, 이동 또는 삭제하는 것은 역할에 관계없이 변경으로 간주됩니다. 사고 블록과 같은 메시지 안에서 그 앞에 있는 텍스트를 변경하는 것도 마찬가지입니다.
변경으로 간주되지 않는 것
| 변경으로 간주되지 않는 것 | 이유 |
|---|---|
model, effort, max_tokens, tool_choice, metadata, thinking.display 및 기타 매개변수 | system, tools, 메시지만 비교됩니다 |
| JSON 서식 또는 키 순서 | API는 텍스트가 아니라 파싱된 JSON을 비교합니다 |
cache_control 마커 | 캐시할 위치를 지정할 뿐이며, Claude가 읽는 내용이 아닙니다 |
아무것도 참조하지 않은 defer_loading: true 도구 | 무언가가 참조하기 전까지는 Claude의 컨텍스트에 포함되지 않습니다 |
prefix_mismatch_behavior 설정
베타 헤더 thinking-binding-controls-2026-08-01은 thinking.block_binding.prefix_mismatch_behavior 설정과 응답의 input_transformations 배열을 추가합니다.
| 값 | 블록이 접두사 검사에 실패하는 경우 |
|---|---|
"error" | API는 첫 번째 무효 블록을 명시하는 400 오류로 요청을 거부합니다 |
"drop_block" | API는 무효 블록을 제외하고, 요청은 성공합니다. 해당 블록에 대해서는 요금이 청구되지 않지만, 블록을 제외하면 비용이 더 들 수 있습니다 |
지정하지 않음 또는 null | 모델에 따라 다름 |
접두사 검사에 실패한 블록은 변경이 유지되는 동안, 해당 블록을 보내는 이후의 모든 요청에서 무효 상태로 남습니다. 이 설정은 이를 포함한 해당 요청 하나에만 적용됩니다. 사고가 꺼져 있는 경우("disabled" 또는 "between_tools"), 이 설정을 보내면 모든 모델에서 400 오류가 발생합니다.
다음 요청은 prefix_mismatch_behavior를 "drop_block"으로 설정합니다. 첫 번째 턴에서는 다시 보낼 사고가 없으므로 input_transformations는 비어 있는 상태로 반환됩니다:
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=16000,
thinking={
"type": "adaptive",
"block_binding": {"prefix_mismatch_behavior": "drop_block"},
},
messages=[
{
"role": "user",
"content": "What is the greatest common divisor of 1071 and 462?",
}
],
betas=["thinking-binding-controls-2026-08-01"],
)
for block in response.content:
if block.type == "text":
print(block.text)
print(f"Input transformations: {len(response.input_transformations or [])}")프로덕션 트래픽 감시
prefix_mismatch_behavior를 지정하지 않은 경우, 일부 모델에서는 접두사 검사에 실패한 요청이 오류를 받지 않을 수도 있습니다. 그러면 접두사 검사에 실패한 사고 블록이 모델에 전달됩니다. 프로덕션 트래픽에서 해당 블록을 찾으려면 thinking-binding-controls-2026-08-01 베타 헤더를 보내고, 설정은 지정하지 않은 채로 두고, 각 응답의 input_transformations 배열을 기록하세요. 헤더는 해당 배열을 추가하며, 모델이 받는 내용을 변경하지 않습니다.
이러한 각 블록은 해당 배열에 자체 thinking_mismatch_allowed 항목을 갖습니다. 하나의 항목은 다음과 같습니다:
{
"input_transformations": [
{
"type": "thinking_mismatch_allowed",
"path": "messages.1.content.0",
"reason": "prefix_binding_mismatch"
}
]
}변경을 찾으려면 코드가 변경한 내용 찾기를 참조하세요.
어떤 경우에 해당하는지 확인
일부 모델에서는 접두사 검사에 실패한 요청이 400 오류를 받을 수도 있고 오류를 받지 않을 수도 있습니다. 다음 테스트는 요청이 어느 쪽에 해당하는지 보여 줍니다:
- 해당 모델 중 하나가 생성한 사고 블록이 포함된 대화를 준비하세요. 시스템 프롬프트(
system)를 변경하거나 추가하세요. 그러면 Claude가 블록을 생성한 후 시스템 프롬프트가 변경되었으므로 블록이 접두사 검사에 실패합니다. thinking-binding-controls-2026-08-01베타 헤더와 함께 동일한 모델로 보내고,prefix_mismatch_behavior는 지정하지 않은 채로 두세요.
응답은 다음 중 하나입니다:
bound to a different conversation라고 표시하는 400 오류: 요청이 400 오류를 받았습니다.input_transformations배열에thinking_mismatch_allowed항목이 있는 200 응답: 요청이 오류를 받지 않았습니다. 각 항목은 접두사 검사에 실패하여 Claude에 전달된 사고 블록을 가리킵니다.input_transformations배열이 비어 있는 200 응답: 접두사 검사에 실패한 블록이 없으므로 테스트로 알 수 있는 것이 없습니다. 대화에 해당 모델의 사고 블록이 포함되어 있는지 확인하세요.
결과는 해당 요청 하나에 대한 것이며 이후 요청에 대해서는 아무것도 보장하지 않으므로, 두 경우 모두 처리하도록 코드를 작성하세요.
다음 단계
코드가 대화에 가하는 각 변경 대신 보내야 할 내용입니다.
접두사 검사에 실패하는 대화를 복구하고, 코드가 변경하는 내용을 찾고, 해당 변경이 사라졌는지 테스트합니다.
보존된 사고란 무엇인지, 사고 블록이 무엇에 연결되어 있는지, 그리고 모델 또는 계정 전환에 대해 설명합니다.
이 페이지가 도움이 되었나요?