Claude의 Anti-Distillation Rule이 에이전트 메시지 히스토리를 Append-Only로 만듦
요약
Anthropic이 Claude의 대화 기록 재작성 시 발생할 수 있는 오류를 방지하기 위해 'Anti-Distillation Rule'을 도입했습니다. 이 규칙은 에이전트 메시지 히스토리를 Append-Only 방식으로 강제하여, 이전 컨텍스트가 변경되는 것을 막습니다. Anthropic은 이를 통해 모델의 무단 사용 및 증류(distillation)를 방어하고 있습니다.
핵심 포인트
- 에이전트 히스토리는 Append-Only로 유지되어 데이터 변조를 방지합니다.
- Anthropic은 '사고 과정 보존(Preserved thinking)' 등 여러 계층적 방어 메커니즘을 적용했습니다.
- API 사용 시, 대화 기록 재작성으로 인한 400 에러 발생 가능성을 인지해야 합니다.
- 이 규칙들은 모델의 무단 증류 및 오용을 막기 위한 강력한 안전장치입니다.
만약 Claude 통합 기능이 자체 대화 기록을 재작성한다면, API는 messages.1.content.0: Invalid `signature` in `thinking` block. The block is bound to a different conversation.라는 400 에러를 반환할 수 있습니다. 앞에 있는 경로가 실패한 블록에 따라 바뀌므로, 그 뒤의 내용을 검색하십시오. 이 문구는 Anthropic's preserved-thinking docs에서 가져온 것입니다.
10월 12일, Anthropic은 해당 규칙이 어디서 왔는지 설명했습니다. distillation defenses에 대한 연구 게시물에서, 이 글은 preserved thinking을
Anthropic은 이를 '초기 증거(early evidence)'라고 부르며 측정 방법에 대해서는 언급하지 않습니다. 사용자 측의 비용은 파악하기가 더 쉽습니다. 같은 게시물에서 해당 내용은 '사고 과정 보존(preserved thinking)이 일부 개발자들에게 통합 업데이트를 요구해 왔다'고 인정합니다(Anthropic). 만약 API 계정이 2026년 8월 31일 이후에 생성되었다면, 이 확인 절차는 이미 적용되고 있습니다. 그보다 오래된 경우, 사용자가 옵트인(opt in)하기 전까지는 적용되지 않으며, 아래의 감지 섹션에서 무엇이 먼저 작동을 멈추게 할 수 있는지 확인할 수 있습니다.
세 가지 계층, 그중 하나가 요청 경로에 위치함
Anthropic은 10월 12일 게시물에서 세 가지 방어 메커니즘을 나열했습니다:
- 사고 과정 보존(Preserved thinking). Claude Fable 5.1 및 Claude Opus 5.5와 함께 출시되었습니다. Claude Sonnet 5.5에서는 추론 기록이 해당 요청을 생성한 조직에게만 제공됩니다.
- 2단계 분류기(A two-stage classifier). Claude Sonnet 5.5, Opus 5 및 5.5, 그리고 Fable 5 및 5.1에서 작동하며, Anthropic은 이의 오탐률(false positive rate)을 0.1% 미만으로 설정했습니다.
- 강제 적용(Enforcement). 추론 내용을 추출하려고 계속 시도하는 계정에는 더 엄격한 제한과 이후 차단이 가해집니다. 9월 24일 이후, Anthropic은 Claude가 응답하기 전에 안전장치(safeguards)가 차단하는 요청에 대해 청구하는 것을 재개했으며, 이는 해당 안전장치가 오탐률 0.1% 미만을 보이는 증류(distillation) 영역을 포함합니다.
영국 중심 매체인 Resultsense는 이러한 상충 관계(trade-off)가 방어 가능하며, 비용을 지불하는 고객에게 마찰(friction)을 이동시킨 점을 지적했습니다. 분류기와 청구 규칙은 운이 나쁠 때 주로 중요합니다. 사고 과정 보존은 유효한 요청의 형태 자체를 바꾸기 때문에 모든 다중 턴 통합에 중요합니다.
API가 모든 사고 블록에서 확인하는 것
Thinking 블록 전송 시 유효성 검사 및 에이전트 루프 유지 방법
반환하는 각 thinking 또는 redacted_thinking 블록에 대해, [docs]는 두 가지 검사를 설명합니다. 첫째, 모델은 해당 블록을 읽을 수 있어야 하며, 그렇지 않으면 API가 오류 없이 이를 삭제합니다. 둘째: "thinking 블록 이전에 아무것도 변경되지 않았음."
여기서 "이전(Before)"은 최상위 system 프롬프트, tools 배열, 그리고 해당 블록 이전의 모든 메시지를 의미합니다. 만약 이 중 어느 하나라도 블록을 생성했을 때와 다르다면, 해당 블록과 그 이후의 모든 thinking 블록은 유효하지 않습니다 ([docs]).
적용 여부는 [same page]에 따라 계정 연령에 달려 있습니다. 2026년 8월 31일 00:00 UTC 이후 생성된 계정은 기본적으로 해당 검사를 받으며 400 오류를 받습니다. 이전 계정의 경우에도 이 검사는 계속 실행되지만, thinking.block_binding.prefix_mismatch_behavior를 설정하는 요청에 대해서만 강제되며, 그렇지 않은 경우에는 실패한 블록이 모델로 전달됩니다. 이 접두사(prefix) 검사는 Claude Fable 5.1, Opus 5.5, Sonnet 5.5 및 Haiku 5.5를 포괄합니다.
메시지 추가는 유효합니다. 또한 effort, max_tokens, tool_choice, metadata 및 cache_control 마커 변경과 서버 측 압축(server-side compaction)도 유효한데, 이는 해당 검사가 "서버가 편집한 사본이 아닌 당신이 보낸 것을 비교한다"는 [docs]에 근거합니다.

중간의 메시지 하나를 변경하면, 그 이후의 모든 thinking 블록은 카운트가 중단됩니다.
이제 에이전트 루프를 깨뜨리는 습관들
대부분의 에이전트 하네스(agent harnesses)는 어딘가에서 히스토리(history)에 접근합니다. [preserved-thinking docs]에는 실패하는 패턴과 대신 취해야 할 조치들이 나열되어 있습니다:
- 시스템 프롬프트 재렌더링(Re-rendering): 오늘 날짜를 주입하거나, 업데이트된
CLAUDE.md또는AGENTS.md파일을system메시지에 다시 로드하면 접두사(prefix)가 변경됩니다. 지침 파일은 한 번에 로드하고 나중에 버전의 내용을 추가하는 시스템 메시지로 첨부하거나, 파일 내용 신뢰도가 낮다면 다음user턴에서 처리하세요. - 세션 중
tools편집: 전체 도구 세트를 시작 시점에 선언하고, 후반에 추가되는 도구에는defer_loading: true를 표시하며,tool_addition및tool_removal블록을 사용해 제공하거나 철회할 수 있습니다. - 도구 사용 중지(Switch tool use off)를 위한 도구 제거: 대신
tool_choice: {"type": "none"}을 전송하세요. - 중간 턴 잘라내기(Cutting turns out of the middle): 이는 잘린 이후의 모든 사고 과정(thinking block)을 무효화합니다. 오래된 도구 결과를 정리하려면 서버 측 컨텍스트 편집 기능을 사용하세요.
- 사용자 정의 keep-tail 요약 작성: 보존되는 턴에는 대체한 히스토리에 기반하여 생성된 사고 과정이 포함됩니다. API가 온디맨드 압축(on-demand compaction)으로 요약을 작성하게 하거나, 보존되는 턴에서 사고 과정을 제거할 수 있습니다.
- '빈' 블록을 건너뛰는 직렬화기(Serializers): 문서는
새 계정을 만들 필요는 없습니다. docs FAQ에 따르면, 기존 계정으로 thinking-binding-controls-2026-08-01 베타 헤더를 전송하고 prefix_mismatch_behavior는 설정하지 않은 상태로도 됩니다. 실패한 블록은 여전히 모델에 도달하며, 응답에서 input_transformations 필드에 thinking_mismatch_allowed로 나열됩니다. Python에서는 기존의 system_prompt, tools, 그리고 history를 사용하여 다음과 같이 구현할 수 있습니다:
import logging
import anthropic
...
각 항목은 messages.1.content.0과 같은 path를 가집니다. 첫 번째 항목은 사용자가 가장 초기에 무효화했던 블록(docs)을 가리킵니다. 제가 직접 라이브 계정으로 테스트해 본 것은 아닙니다. 이는 문서화된 요청 형태를 따릅니다.
만약 편집 사항을 아직 수정할 수 없다면, 임시 방편은 drop_block입니다:
thinking={
"type": "adaptive",
"block_binding": {
...
이렇게 요청하면 성공하며, API는 각 실패한 블록과 그 이후의 모든 블록을 제거하고, 이들을 reason: "prefix_binding_mismatch"와 함께 나열합니다. 문서는 이것이 "생성되는 출력 토큰을 상당히 증가시킬 수 있다"고 경고하며, Anthropic이 다중 턴 코딩 벤치마크에서 테스트했을 때 그 증가는 노력과 블록이 제거되는 빈도에 따라 2.5%에서 67.1%까지 다양했습니다(docs). 또한 모델은 이전 추론 없이 답변하므로, 이를 유발하는 편집 사항을 제거할 계획을 세우세요.
이번 주에 변경해야 할 것들
이 모든 것은 docs에서 가져온 것입니다:
- 전송하고 수신한 내용을 정확하게 보존하세요: 렌더링된 시스템 프롬프트와 도구 정의, 그리고 반환되는 각 어시스턴트 턴을 포함합니다. 재개 시에는 변경되었을 수 있는 입력으로부터 다시 렌더링하는 대신 이를 재생(Replay)에 사용하십시오.
- 프록시 또는 게이트웨이를 사용하는 경우,
anthropic-beta값과thinking.block_binding을 전달하고, 호출자에게input_transformations를 반환하며, thinking이 누락되어 400 에러가 발생해도 조용히 제거하고 재시도하지 마십시오. - 여러 계정을 사용하는 경우, Sonnet 5.5와 Haiku 5.5의 thinking 블록은 다른 연결되지 않은 계정에서 재사용할 수 없다는 점에 유의하십시오.
제 생각으로는: Anthropic이 그 증류 방어(distillation defense)를 위해 일부 비용을 여러분의 엔지니어링 시간으로 지불하고 있는 것 같습니다. 장점은, append-only 방식의 재생 가능한 기록(transcript)이 디버깅하기 가장 쉬운 종류의 에이전트 실행이라는 것입니다.
유용했다면
위에서 언급된 대부분의 오류는 에이전트 루프에 존재하며, 이 부분은 어떤 히스토리를 유지하고 무엇을 다시 전송할지 결정하는 곳입니다. AI Agents Pocket Guide에서는 이러한 루프 및 메모리 패턴을 다루고 있습니다. 또한 저는 Claude Code, Codex 및 기타 CLI 에이전트를 각각의 터미널과 작업 트리(worktree)에서 나란히 실행하는 무료 오픈 소스 앱인 Hermes IDE를 개발했으니 이 언급을 참고하시기 바랍니다. 내부 작동 방식을 보고 싶다면 GitHub에서 확인하실 수 있습니다.

AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기