Fable 5.2 のタスク途中でモデルを切り替えるには?進捗保存と結果検証

検証済みチェックポイントとツール結果台帳で別モデルに作業を引き継ぐ方法。Ofox での実測、合成在庫データ、実行スクリプト、検証器を紹介します。

2 人の走者の間にあるオレンジ色のバトンが、検証済みの作業をモデル間で引き継ぐことを表す。

エージェントが Fable 5.2 から別のモデルに切り替わるときは、検証済みのタスク状態を会話履歴とは別に保存します。新しいモデルに必要なのは入力、完了したツールの結果、残作業、合格条件です。前のモデルが「何を考えていたか」の読みやすい要約は、信頼できる代用品にはなりません。

2026 年 11 月 10 日に Ofox 経由でこの方法を試しました。Fable 5.2 が読み取り専用の在庫検索を要求し、3 行の合成データを受け取り、ネイティブのツール往復を完了しました。その後、アプリケーションで生成したチェックポイントを使って新しい Opus 5.5 の会話を開始しました。最終 JSON はすべての SKU と数量の独立検査を通過しました。確認できたのは小さな状態引き継ぎであり、数時間のエージェント性能試験や、非公開の推論の保存ではありません。

フォールバックが成功しても状態を失う理由

公式の思考保持文書は、モデルの互換性とアプリケーションの進捗を区別しています。文書にある Claude API と Google 管理の経路では、旧モデルは Fable 5.2 の thinking ブロックを読めません。非対応ブロックが削除されてもリクエストは成功する場合があります。別アカウントが継続を処理する場合は、アカウントへの紐付けも境界になります。

だからといって、モデル切り替えがすべてエラーになるわけではありません。HTTP 成功だけでは推論の継続を証明できないということです。Ofox カタログの経路対応情報は、プロバイダーやアカウントをまたぐ署名付き履歴のすべての移行を保証しません。今回はアカウント間の再生を試しておらず、引き継ぎも意図的にそれに依存しない構成です。

方法は 2 つあります。元の履歴を保つことが適切なら、互換性を検証した経路で変更のない会話を続けます。モデル、ツール、タスク設定を意図的に変えるなら、アプリケーション側の状態で新しい会話を始めます。この記事は後者を実装します。署名を編集したり、非公開の思考を再構成したりしません。

小さな再現用サンプルをダウンロードする

checkpoint_demo.py をダウンロードしてください。Python 3.9 以降と標準ライブラリを使います。既定の検査では API を呼び出しません。生成ファイルで既存タスクを上書きしないよう、空のフォルダーに置きます。

Fable のツール要求 → ツール結果を渡す継続 → 新しい Opus セッションまで実行する場合は、run_handoff.py も同じ場所に保存します。python3 run_handoff.py はローカル検査だけです。OFOX_API_KEY を設定して python3 run_handoff.py --live を明示的に実行すると、最大 3 回の有料リクエストを送り、新しい handoff-run フォルダーに要求と応答を保存し、最終結果を検証します。自動再試行はせず、同じ出力フォルダーの再利用も拒否します。次の実行を作る前に、失敗や結果不明の試行を調べてください。

各リクエストは出力上限 4,096 トークンと小さな合成本文に制限しています。このデモを限定する設定であり、一般的なドル建て上限や、タイムアウトした要求が無料という保証ではありません。公開ランナーは実測と同じ要求順を使い、ローカル検査と要求のシリアライズを別途確認しています。

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

最初のコマンドは正常系と異常系を検査します。2 つ目は checkpoint.json と handoff.txt を生成し、既存ファイルの置き換えを拒否します。データは合成の在庫テスト用で、顧客の在庫や業務上の推奨ではありません。

SKU在庫数目標数期待する不足数
DEMO-0017103
DEMO-00215120
DEMO-003044

タスクは各行の max(target − available, 0) を報告することで、注文は禁止しています。不足ゼロの行を残すことも要件です。補充が必要な商品だけを挙げた回答は、ここでは不完全です。

別モデルに渡す前に証拠を保存する

チェックポイントには目的、元データ行のハッシュ、完了した 1 回の読み取り操作、実際の結果とそのハッシュ、残作業、外部書き込みの禁止を記録します。アプリケーションがツール結果から作る記録であり、モデルに自分の行動を証明させるものではありません。

{
  "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 と、アプリケーション台帳用の安定した操作 ID を別々に記録してください。用途が異なります。新しいモデルは同じ論理操作に別の呼び出し 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 でテストデータ 3 行を返し、assistant の全内容を保存しました。2 回目の 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 の 3 行を受け入れました。SKU の過不足、ID 重複、整数型、再計算した各数量を検査します。"3" のような文字列、真偽値、欠落・余分な SKU、誤った数量は拒否します。チェックポイント検証器はさらに、ソースや結果のハッシュ変更、未検証の読み取り操作、予期しない副作用を拒否します。

このタスクでは、モデルに「本当に完全ですか」と聞くより、決定論的な検証のほうが強い証拠です。ただし範囲は意図的に狭く、任意の業務ワークフローを検証したり、現在の在庫を取得したり、本番トランザクションを管理したりするスクリプトではありません。

実行で確認できたことと、できていないこと

段階観測結果入力/出力トークン
Fable 5.2 が読み取りツールを要求HTTP 200、tool_use、許可された正しいツール467 / 27
Fable 5.2 がツール結果を受領HTTP 200、end_turn、3 件の不足数が正しい578 / 235
新しい Opus 5.5 セッションがチェックポイントを受領HTTP 200、end_turn、最終 JSON が合格457 / 67

3 件ともキャッシュ読み取り・作成トークンはゼロでした。確認済みの標準表示料金を適用すると、3 件合計 $0.022008、各 $0.004816、$0.014024、$0.003168 です。使用量からの計算であり、請求書と別途突き合わせた金額ではありません。比較記事で料金と、この小さな試験ではモデルの順位を決められない理由を説明しています。

実際のサービス障害を起こしたり、アカウント間で思考を再生したり、多数のタスクを比較したり、自動フォールバックの信頼性を証明したりはしていません。ソースデータは合成、読み取りツールはローカル実行で、注文は送っていません。モデルの応答自体は実際の API 応答です。

11 月 10 日の合成タスクで記録した API 応答と引き継ぎ検証

実際の API 応答を使い、ローカルで表示した英語のテスト記録です。Ofox の製品画面を撮影したものではありません。

書き込み付近の中断は別に扱う

読み取り専用操作は、鮮度と費用が分かっていれば再検索してよい場合があります。書き込みのタイムアウトでは、応答を失う前に外部システムが操作を完了したのか、という危険な不明点が残ります。

本番台帳では、計画済み、実行中、確認済み、失敗、不確定を区別します。タイムアウト後は再試行の前に、安定した操作キーで対象システムを照会します。対象が冪等キーに対応していれば利用し、応答を保存します。非対応なら、ローカル JSON を保存するだけで「厳密に 1 回だけ」の実行を作り出すことはできません。

モデルの要約が実行済みと言うだけで、不確定な書き込みを完了にしてはいけません。受け手のモデルに「念のため」再実行させてもいけません。確認済み結果から再開し、未解決操作は照合へ回します。フォーム送信、チケット作成、メール送信、支払いにも同じ考え方が使えますが、対象ごとの制御が必要です。

成果物に合わせてチェックポイントを設計する

調査レポートなら、ソース URL、取得した証拠、主張の確認状態、未回答の疑問を渡します。表計算なら入力バージョン、行 ID、変換ルール、出力検査、コード変更なら commit または diff、実行済みテスト、失敗、残作業を渡します。進捗率だけでなく、完了した仕事の証拠を保存してください。

最初は読み取り専用タスク 1 つ、モデル変更 1 回、独立した合格条件で試します。失敗ケースを理解してから拡大します。API ガイドは初期接続、Ofox ネイティブ Messagesとプロバイダー経路は接続仕様を説明します。次の要求が成功しても、状態の連続性はアプリケーションの責任です。