Fable 5.2 에이전트 작업 중 모델을 바꾸고 진행 상태를 보존하는 방법

검증된 체크포인트와 도구 결과 기록으로 다른 모델에서 작업을 이어갑니다. 실제 Ofox 인계 테스트, 합성 재고 데이터와 검증기를 제공합니다.

온전한 주황색 바통이 두 운반체 사이에 놓여 검증된 작업을 모델 간에 전달하는 모습을 표현합니다.

에이전트가 Fable 5.2에서 다른 모델로 전환할 때는 검증된 작업 상태를 대화 이력과 분리해 보존하세요. 새 모델에는 입력, 완료된 도구 결과, 남은 작업, 검수 조건이 필요합니다. 이전 모델이 무엇을 “생각했는지” 읽기 쉽게 요약한 것만으로는 신뢰할 만한 대체물이 되지 않습니다.

2026년 11월 10일 Ofox를 통해 이 방식을 테스트했습니다. Fable 5.2가 읽기 전용 재고 조회를 요청하고 합성 데이터 세 행을 받아 네이티브 도구 왕복을 완료했습니다. 이어서 애플리케이션이 만든 체크포인트로 새 Opus 5.5 대화를 시작했습니다. 최종 JSON은 모든 SKU와 수량에 대한 독립 검증을 통과했습니다. 작은 상태 전달 워크플로 하나를 확인한 것이며, 수 시간짜리 에이전트 벤치마크나 숨겨진 추론 보존을 입증한 것은 아닙니다.

성공한 fallback에서도 유용한 상태를 잃을 수 있는 이유

공식 preserved-thinking 문서는 모델 호환성과 애플리케이션 진행 상태를 구분합니다. 문서에 나온 Claude API 및 Google 관리 경로에서 이전 모델은 Fable 5.2의 thinking 블록을 읽지 못하며, 요청이 성공해도 지원되지 않는 블록이 버려질 수 있습니다. 다른 계정이 후속 요청을 처리하면 계정 바인딩이라는 경계도 생깁니다.

이 규칙이 모든 모델 전환을 오류로 만드는 것은 아닙니다. HTTP 성공만으로 추론의 연속성을 입증할 수 없다는 뜻입니다. Ofox 카탈로그는 라우팅 기능을 나열하지만 모든 공급자·계정 간 서명 이력 전달의 동작까지 증명하지 않습니다. 계정 간 재생은 테스트하지 않았고, 이번 인계는 의도적으로 거기에 의존하지 않습니다.

전략은 두 가지입니다. 이력 보존이 적절하다면 호환성이 검증된 경로에서 바뀌지 않은 대화를 계속합니다. 또는 모델, 도구, 작업 설정을 의도적으로 바꿀 때 애플리케이션이 관리하는 상태로 새 대화를 시작합니다. 이 튜토리얼은 두 번째 전략을 구현하며 서명을 수정하거나 비공개 추론을 재구성하지 않습니다.

작은 재현 예제 다운로드하기

checkpoint_demo.py를 다운로드하세요. Python 3.9 이상과 표준 라이브러리만 사용합니다. 기본 검사는 API를 호출하지 않습니다. 생성 파일이 기존 작업을 덮어쓰지 않도록 빈 폴더에 넣으세요.

Fable 도구 요청 → 도구 결과를 포함한 후속 요청 → 새 Opus 세션까지 실행하려면 같은 폴더에 run_handoff.py도 받으세요. python3 run_handoff.py는 로컬 검사만 수행합니다. OFOX_API_KEY를 설정한 뒤 python3 run_handoff.py --live를 실행하면 최대 세 번의 유료 요청을 명시적으로 보내고 새 handoff-run 폴더에 요청·응답 파일을 저장한 뒤 최종 결과를 검증합니다. 자동 재시도는 없으며 기존 출력 폴더 재사용을 거부합니다. 실패하거나 결과가 불확실한 시도는 새 실행 전에 확인하세요.

각 요청은 출력 4,096토큰과 작은 합성 본문으로 제한됩니다. 이는 데모 범위를 제한할 뿐 보편적인 달러 상한이나 타임아웃 요청의 무료 처리를 보장하지 않습니다. 공개 실행기는 테스트한 요청 순서를 따르며, 로컬 검사와 요청 직렬화는 별도로 검증했습니다.

python3 checkpoint_demo.py self-test
python3 checkpoint_demo.py prepare

첫 명령은 정상·오류 사례 검사를 실행합니다. 두 번째는 checkpoint.json과 handoff.txt를 만들고 기존 파일 교체는 거부합니다. 데이터는 합성 재고 예제이며 고객 재고나 사업상 권고가 아닙니다.

SKU현재 재고목표 재고예상 부족 수량
DEMO-0017103
DEMO-00215120
DEMO-003044

작업은 모든 행에 대해 max(target − available, 0)를 보고하는 것입니다. 주문은 명시적으로 금지합니다. 부족 수량이 0인 행도 작업의 일부이므로, 재고가 필요한 상품만 나열한 응답은 여기서는 불완전합니다.

다른 모델에게 넘기기 전에 증거 저장하기

체크포인트에는 목표, 원본 행의 해시, 완료된 읽기 작업 하나, 실제 결과와 해시, 남은 작업, 외부 쓰기 금지가 기록됩니다. 이 기록은 애플리케이션이 도구 결과로 생성합니다. 모델에게 자신의 행동을 인증하라고 요청하는 방식이 아닙니다.

{
  "schema_version": 1,
  "task_id": "synthetic-stock-20261110",
  "objective": "Report shortage=max(target-available,0) for every SKU. Do not place orders.",
  "completed": [{
    "operation_id": "read-stock-1",
    "operation": "read_stock",
    "status": "verified"
  }],
  "pending": ["Produce all three SKU shortage rows", "Pass independent validator"],
  "side_effects": []
}

가독성을 위해 이 발췌에는 원본 해시와 결과 행을 생략했지만 생성 파일에는 포함됩니다. 실행에는 전체 파일을 사용하세요. 해시는 신뢰하는 원본과의 불일치를 감지할 뿐, 원본 작성자, 재고의 최신성, 신뢰할 수 없는 체크포인트의 안전성을 입증하지 않습니다. 운영에서는 권위 있는 입력 버전과 접근 제어도 유지해야 합니다.

실제 에이전트에서는 도구 작업이 완료된 시점에 체크포인트를 지속 저장하세요. 대화 연결을 위한 도구 호출 ID와 앱의 작업 기록용 안정적인 operation ID를 별도로 기록합니다. 목적이 다르기 때문입니다. 새 모델은 같은 논리 작업에도 다른 tool-call ID를 만들 수 있으므로 공급자가 만든 ID 하나가 일반적인 중복 실행 방지책은 아닙니다.

실제로 테스트한 Fable 도구 왕복

첫 요청에는 anthropic/claude-fable-5.2, Ofox 네이티브 Messages 엔드포인트, output_config.effort: "low", max_tokens: 4096, 빈 객체 입력 스키마를 가진 read_stock 도구 하나를 사용했습니다. 도구 선택은 auto였습니다.

응답은 tool_use로 끝나며 {}로 read_stock을 요청했습니다. 실행기는 이름과 인수를 검증하고, 일치하는 tool_use_id로 예제 세 행을 반환했으며 assistant 콘텐츠 전체를 보존했습니다. 두 번째 Fable 요청은 end_turn으로 끝났고 부족 수량 3, 0, 4를 보고했습니다.

이 네이티브 후속 요청은 중요합니다. 체크포인트가 있다고 잘못된 도구 루프를 넘어가도 되는 것은 아닙니다. 같은 모델의 요청이 ID 불일치로 실패하면 도구 결과 연결부터 고치세요. 오류가 서명 이력을 가리키면 thinking 서명 진단과 5.2 업그레이드 점검을 참고하세요.

작은 산술 예제라서 의도적으로 low effort를 사용했습니다. 어려운 장기 작업에 필요한 effort를 보여주는 결과는 아닙니다. 또한 카탈로그의 aws_bedrock 표시는 특정 응답을 처리한 상위 계정을 증명하지 않습니다. 기록된 경로는 Ofox 네이티브 엔드포인트와 응답 모델 ID입니다.

명확한 인계 지시로 새 모델 시작하기

생성된 handoff.txt의 내용은 다음과 같습니다.

Resume this read-only task from verified application state.
Do not claim access to prior reasoning.
Do not call tools or place orders.
Return only a JSON object with key rows, containing every SKU
and integer shortage. No Markdown.
Checkpoint: [the complete generated checkpoint JSON]

이 파일로 받는 모델의 요청을 만드세요. 이 예제를 실행하면 API 크레딧을 사용하지만 위 로컬 준비 명령은 사용하지 않습니다.

import json
from pathlib import Path

request = {
    "model": "anthropic/claude-opus-5.5",
    "max_tokens": 4096,
    "output_config": {"effort": "low"},
    "messages": [{"role": "user", "content": Path("handoff.txt").read_text()}],
}
Path("handoff-request.json").write_text(json.dumps(request))
curl --fail-with-body --max-time 180 \
  https://api.ofox.ai/anthropic/v1/messages \
  -H "x-api-key: $OFOX_API_KEY" \
  -H 'anthropic-version: 2023-06-01' \
  -H 'content-type: application/json' \
  --data-binary @handoff-request.json > handoff-response.json

이 요청에는 이전 assistant 메시지나 서명된 thinking 블록이 없습니다. 같은 공급자 대화가 아니라 작업을 이어갑니다. 따라서 여기서 모델을 바꿀 때 옛 프리픽스를 편집할 필요가 없습니다. 더 큰 작업에는 그에 맞게 풍부한 증거 묶음이 필요합니다. 확인되지 않은 장문 설명보다 출처 위치와 미해결 질문을 전달하세요.

전달된 결과를 독립적으로 검증하기

완료된 텍스트 출력만 추출해 JSON으로 파싱하고 제공한 검증기를 실행하세요.

import json
from pathlib import Path

r = json.loads(Path("handoff-response.json").read_text())
if r.get("stop_reason") != "end_turn":
    raise SystemExit("Incomplete response; inspect before accepting.")
text = "\n".join(b["text"] for b in r.get("content", []) if b.get("type") == "text")
result = json.loads(text)  # Reject prose and Markdown instead of guessing.
Path("result.json").write_text(json.dumps(result, indent=2))
python3 checkpoint_demo.py validate result.json

실제 Opus 응답을 파싱한 결과는 다음과 같습니다.

{"rows":[{"sku":"DEMO-001","shortage":3},{"sku":"DEMO-002","shortage":0},{"sku":"DEMO-003","shortage":4}]}

검증기는 총 부족 수량 7인 세 행을 통과시켰습니다. 정확한 SKU 포함 범위, 중복 ID, 정수 타입, 각 수량의 재계산 결과를 확인합니다. "3" 같은 문자열, 불리언, 누락·추가 SKU, 틀린 수량은 거부합니다. 체크포인트 검증은 변경된 원본·결과 해시, 검증되지 않은 읽기 작업, 예상하지 않은 부수 효과를 별도로 거부합니다.

이 작업에서 결정론적 검사는 모델에게 “답이 빠짐없다고 확신하니?”라고 묻는 것보다 강한 증거입니다. 다만 의도적으로 좁은 검사입니다. 임의의 비즈니스 워크플로를 검증하거나 최신 재고를 조회하거나 운영용 트랜잭션 시스템을 제공하지는 않습니다.

이번 실행이 확인한 것과 확인하지 않은 것

단계관찰한 결과입력 / 출력 토큰
Fable 5.2가 읽기 도구 요청HTTP 200, tool_use, 올바른 허용 도구467 / 27
Fable 5.2가 도구 결과 수신HTTP 200, end_turn, 올바른 세 부족 수량578 / 235
새 Opus 5.5 세션이 체크포인트 수신HTTP 200, end_turn, 최종 JSON 검증 통과457 / 67

세 응답 모두 캐시 읽기·생성 토큰이 0이었습니다. 확인한 표준 공개 단가를 적용하면 세 요청은 각각 $0.004816, $0.014024, $0.003168로 합계 $0.022008입니다. 사용량 기반 계산이며 별도로 대조한 청구서는 아닙니다. 비교 글은 단가와 작은 테스트로 모델 순위를 정할 수 없는 이유를 설명합니다.

실제 서비스 장애를 일으키거나, 계정 간 thinking 재생을 시험하거나, 많은 작업을 비교하거나, 자동 fallback 신뢰성을 입증하지 않았습니다. 원본 데이터는 합성이고 읽기 도구는 로컬에서 실행했으며 주문은 제출하지 않았습니다. 모델 응답 자체는 실제 API 응답입니다.

11월 10일 합성 테스트의 실제 API 응답과 결과 검증

실제 API 응답으로 채운 로컬 테스트 기록의 영문 스크린샷입니다. Ofox 제품 인터페이스 스크린샷이 아닙니다.

쓰기 작업 중단은 다르게 처리하기

읽기 전용 작업은 최신성과 비용을 이해한다면 다시 조회해도 괜찮을 수 있습니다. 하지만 쓰기 작업의 타임아웃은 더 위험한 질문을 남깁니다. 클라이언트가 응답을 잃기 전에 외부 시스템이 동작을 완료했을까요?

운영 기록은 예정, 진행 중, 확인 완료, 실패, 불확실 상태를 구분해야 합니다. 타임아웃 뒤에는 재시도 전에 안정적인 작업 키로 대상 시스템을 조회하세요. 대상이 멱등 키를 지원한다면 사용하고 응답을 보관합니다. 지원하지 않는다면 로컬 JSON 파일 하나로 정확히 한 번의 실행을 만들어낼 수는 없습니다.

모델 요약에 실행했다고 적혀 있다는 이유로 불확실한 쓰기를 완료 처리하지 마세요. 받는 모델이 “안전을 위해” 다시 실행하도록 허용하지도 마세요. 검증된 결과에서 재개하고 미해결 작업은 별도 대조 절차로 넘깁니다. 제출한 폼, 생성한 티켓, 발송 이메일, 결제에도 같은 방식이 적용되지만 대상마다 별도의 제어가 필요합니다.

산출물에 맞는 체크포인트 만들기

조사 보고서에는 원본 URL, 수집한 증거, 주장 상태, 답하지 못한 질문을 담으세요. 스프레드시트에는 입력 버전, 행 ID, 변환 규칙, 출력 검사를 담습니다. 코드 수정에는 commit 또는 diff, 실제 실행한 테스트, 실패, 남은 작업을 담습니다. 진행률만 남기지 말고 완료 작업의 증거를 보존하세요.

읽기 전용 작업 하나, 모델 변경 한 번, 독립 검수 조건 하나로 작게 시작하세요. 실패 사례를 이해한 후 확장합니다. API 안내는 첫 연결을, Ofox 네이티브 Messages와 공급자 라우팅은 통합 방식을 다룹니다. 다음 요청이 성공하더라도 상태 연속성은 애플리케이션의 책임입니다.