Claude Media
Claudeの長時間タスクをtests.jsonとprogress.txtで管理する

Claudeの長時間タスクをtests.jsonとprogress.txtで管理する

複数のコンテキストウィンドウをまたぐClaudeの長時間タスクを、tests.jsonとprogress.txtで状態管理する具体的な手順とプロンプト例をまとめます。

1つのコンテキストウィンドウでは終わらないタスクをどう引き継ぐか

Claudeに大きめの実装タスクを任せると、1回のセッションでは終わらないことがあります。コンテキストウィンドウが切れて会話が要約されたり、新しいセッションを開いたりするたびに、Claudeは「どこまで進んだか」を再確認しなければなりません。ここで再確認の手がかりが無いと、既に直したバグを再調査したり、実装済みの機能をもう一度作り始めたりする無駄が発生します。

Claude公式のプロンプトエンジニアリングガイドは、この問題への対処を「複数のコンテキストウィンドウをまたぐワークフロー」として整理しています。中心になるのが、テスト結果をtests.jsonのような構造化ファイルで管理し、進捗メモをprogress.txtのような自由記述ファイルで残すという2ファイル構成です。本記事では、このパターンをどう作り、どう読み直させるかを手順に分けて示します。

この記事が扱うのはプロンプトとファイル運用でClaudeに状態を持たせる方法です。Claude API・Agent SDK・Claude Codeのいずれでも使える汎用的なパターンです。Claude Codeで使う場合は組み込み機能との役割分担が別に必要になるため、後半で扱います。

tests.jsonとprogress.txtの基本形

公式ガイドが例として示している2ファイルの構成は次のとおりです。テスト結果は数値と状態を持つJSON、進捗メモは自然言語のテキストという役割分担になっています。

{
  "tests": [
    { "id": 1, "name": "authentication_flow", "status": "passing" },
    { "id": 2, "name": "user_management", "status": "failing" },
    { "id": 3, "name": "api_endpoints", "status": "not_started" }
  ],
  "total": 200,
  "passing": 150,
  "failing": 25,
  "not_started": 25
}
Session 3 progress:
- Fixed authentication token validation
- Updated user model to handle edge cases
- Next: investigate user_management test failures (test #2)
- Note: Do not remove tests as this could lead to missing functionality
くらべる

2ファイルの役割分担

構造化データ

tests.json

テストごとの状態(passing / failing / not_started)と集計値を持ちます。次のセッションが機械的に読み、スキーマ通りに更新できます。

自由記述

progress.txt

直近のセッションで直したこと、次に調べる対象、守るべき注意を書きます。

公式ガイドの「状態管理のベストプラクティス」は、状態データに構造化形式(JSONなど)、進捗メモに自由記述、履歴とチェックポイントにgitを使うよう勧めています。ほかに、小さな単位で進める指示も挙げています。

手順1 — 最初のコンテキストウィンドウでテストと骨格を作る

複数セッションにわたるタスクでは、最初のセッションに渡すプロンプトを他のセッションと変えるのが起点になります。1回目はコード実装そのものではなく、後続セッションが使うテストとセットアップスクリプトを整えることに専念させます。

Claudeにテストを書かせるときは、tests.jsonのような構造化フォーマットで管理させるよう明示します。単に「テストを書いて」と頼むだけでは、ファイル形式も更新ルールもセッションごとにばらつきます。次のような指示を添えると、テストを消して通過扱いにする近道を防げます。

テストの削除や編集は許されません。機能の欠落やバグにつながるためです。

同じ最初のセッションで、開発サーバーの起動・テストスイートの実行・linterの実行を1つにまとめたinit.shのようなセットアップスクリプトも作らせます。これを用意しておくと、後続セッションが環境の立ち上げ方を再学習する時間を省けます。ハーネス全体の構成は、長時間稼働エージェントのハーネス設計で4つの仕組みに分けて解説しています。

手順2 — 新しいセッションはtests.json・progress.txt・gitログから状態を復元する

2回目以降のセッションでは、いきなり実装に入らせず、状態の確認から始めさせます。公式ガイドは新しいセッションの立ち上げ方について、次のように具体的に指示することを勧めています。

Call pwd; you can only read and write files in this directory.
Review progress.txt, tests.json, and the git logs.
Manually run through a fundamental integration test before moving on to implementing new features.
手順

新しいセッションの立ち上げ順序

  1. 1

    作業ディレクトリを固定する

    pwd を呼び、読み書きできるのはそのディレクトリだけだと伝えます。

  2. 2

    状態ファイルを読む

    progress.txt、tests.json、gitログの3つを読ませます。

  3. 3

    基本の統合テストを手で通す

    新機能の実装に入る前に、既存機能が壊れていないかを確かめさせます。

読む対象と順序をプロンプトに固定しておけば、セッションが増えても立ち上げの質はぶれません。gitのコミットログは「何をしたか」の記録であり、復元できるチェックポイントでもあります。

手順3 — コンテキストウィンドウが切れたら新規ウィンドウかcompactionかを選ぶ

コンテキストウィンドウが上限に近づいたとき、選択肢は2つあります。会話を要約して続ける(compaction)か、会話を打ち切って新しいコンテキストウィンドウをファイルシステムから立ち上げ直すかです。公式ガイドは、Claudeの最新モデルがローカルファイルシステムから状態を発見する能力に優れていることを踏まえ、状況によっては新規ウィンドウの方を選ぶ価値があるとしています。

くらべる

新規ウィンドウとcompactionの分かれ目

ファイルから復元

新規コンテキストウィンドウ

tests.json・progress.txt・gitログが整っていて、ファイルから状態を組み直せる場面に向きます。立ち上げプロンプトを毎回同じ形で与える必要があります。

会話を要約

compaction(要約継続)

ファイルへの書き出しが薄く、会話の文脈そのものが重要な場面に向きます。要約後に続けるには、返ってきた要約ブロックを次のリクエストへ積み戻す実装が要ります。

compactionを選ぶ場合の実装手順は、Compaction blocksを会話に戻す実装パターンにまとめています。要約ブロックの積み戻し、ストリーミング時の扱い、thinkingブロックの持ち越しでの400エラー回避を扱っています。本記事が扱っているtests.json・progress.txtのパターンは、どちらを選んでも土台として機能します。

context awarenessでトークン予算を使い切らせる

Claude Sonnet 5・Claude Sonnet 4.6・Claude Sonnet 4.5・Claude Haiku 4.5には、context awarenessという機能があります。これらのモデルは会話全体を通じて、残りのコンテキストウィンドウ(「トークン予算」)を自分で追跡します。有効化の操作は不要で、APIが自動的に情報を注入します。

仕組みは具体的です。リクエストのシステムプロンプトに、次のようなタグで総予算が渡されます(例は200kトークンのモデルのものです)。

<budget:token_budget>200000</budget:token_budget>

そしてツール呼び出しのたびに、残りの容量を示すタグが追加されます。

<system_warning>Token usage: 35000/200000; 165000 remaining</system_warning>

この予算はモデルが実際に持つコンテキストウィンドウと一致します。Claude Sonnet 5とClaude Sonnet 4.6は100万トークン、Claude Sonnet 4.5とClaude Haiku 4.5は20万トークンです。

一方、Claude Opus 4.7以降のOpusモデル、Claude Sonnet 5.5、Claude Fable 5.1・Mythos 5.1・Fable 5・Mythos 5は、この自動注入タグを受け取りません。これらのモデルで同様の制御をしたい場合は、ベータ提供のtask budgetsで明示的な予算を渡す形になります。

context awarenessが効くモデルでは、次のようなプロンプトを添えることで、予算切れ間際に作業を放棄させず、状態を保存させる挙動を引き出せます。

コンテキストウィンドウは上限に近づくと自動的に圧縮され、続きから作業を継続できます。そのためトークン予算を理由にタスクを早期に切り上げないでください。予算の上限に近づいたら、圧縮が起きる前に現在の進捗と状態をメモリに保存してください。

集計値のずれはjqで検出する

tests.json の集計値(total や passing)は、tests 配列から数えられる値の写しです。Claudeが1件の status だけ書き換えて集計値を直し忘れると、2つの値が食い違ったまま次のセッションに渡ります。公式の例は3件だけを載せて total を200としていますが、実際のファイルでは全件を tests に並べておくと、配列から数え直して照合できます。

次のスクリプトは、配列を数え直して保存済みの集計値と比べ、ずれていれば終了コード1を返します。

#!/bin/sh
jq -e '
  def n(s): [.tests[] | select(.status == s)] | length;
  .total == (.tests | length)
  and .passing == n("passing")
  and .failing == n("failing")
  and .not_started == n("not_started")
' tests.json > /dev/null && echo OK || { echo MISMATCH; exit 1; }

4件のテストのうち api_endpoints を passing に変えたのに、集計値は passing: 1 / not_started: 2 のまま残したファイルがあるとします。これで実行すると、次の結果になります(jq 1.7.1)。

sh check-state.sh
# MISMATCH(終了コード 1)

集計値を配列から作り直すには、同じ数え方で代入します。

jq '.tests as $t
  | .total = ($t | length)
  | .passing = ([$t[] | select(.status=="passing")] | length)
  | .failing = ([$t[] | select(.status=="failing")] | length)
  | .not_started = ([$t[] | select(.status=="not_started")] | length)' \
  tests.json > tests.fixed.json
# 再計算後は passing 2 / failing 1 / not_started 1 になり、check-state.sh は OK を返す

このスクリプトは、init.sh の末尾や立ち上げプロンプトの「tests.json を読む」直前に呼ぶ置き方があります。集計値を人間とClaudeの両方が信用できる状態で、各セッションを始められます。

検証ツールを渡して「完了」をClaudeの自己申告に任せない

自律タスクが長くなるほど、人間が毎回フィードバックすることは難しくなります。公式ガイドは、Claude自身が正しさを検証できる手段を用意することを勧めています。UIの動作確認であればcomputer useツール・browser useツール・ブラウザ操作系のMCPサーバーが候補です。

tests.jsonで「passing」に書き換える権限をClaudeに与える場合も、実際にテストを実行させてから書き換えさせるのが前提です。テストを走らせずにpassingへ変更する近道を許すと、tests.jsonは進捗の記録ではなく自己申告の記録に変わってしまい、次のセッションが誤った前提から作業を始めることになります。

よくあるつまずき

  • テストを消させてしまう: 「テストが通らないから削除する」という近道は、機能の欠落を見えなくします。テストの削除・編集を禁じる指示を、最初のセッションのプロンプトに明記しておく必要があります。
  • progress.txtを構造化データの代わりに使う: 自由記述のメモに数値の集計を混ぜると、次のセッションが正確な状態を読み取れなくなります。集計はtests.json側に置き、progress.txtは経緯と次の一手に絞ります。
  • compactionだけに頼って状態ファイルを作らない: compactionは会話を要約しますが、要約自体は毎回変わります。tests.json・progress.txt・gitログのようにファイルシステム上に固定された状態が無いと、新しいセッションが復元できる情報が要約の質に依存してしまいます。

Claude Codeでこのパターンを使うときの対応

Claude Codeでは、手順3の「新規ウィンドウ」は /clear に当たります。/clear は空のコンテキストで新しい会話を始め、プロジェクトのメモリは保ちます。要約で続ける側は /compact です。前の会話は /resume で戻せるので、状態ファイルの復元がうまくいかなかった場合も元の会話を開き直せます。

コマンドラインからは、v2.1.289の claude --help に次の2つが載っています。

-c, --continue    Continue the most recent conversation in the current directory
-r, --resume [value]    Resume a conversation by session ID, or open interactive picker with optional search term

tests.json と progress.txt はプロジェクトのディスク上に残ります。--continue で同じ会話に戻る場合も、/clear で空から始める場合も、同じファイルから状態を読み直せます。

混同しやすい別の仕組みがTodoチェックリスト(task list)です。Claudeが多段階作業を計画するために作る一覧で、ユーザーが形式を決める tests.json とは別物です。公式ドキュメントによると、task listはcompactionをまたいで保たれます。CLAUDE_CODE_TASK_LIST_ID を同じ値にすれば複数のセッションで共有でき、保存先は ~/.claude/tasks/ 内の名前付きディレクトリです。詳細はCLAUDE_CODE_TASK_LIST_IDとはにまとめています。

task listを使えるのは、タスク追跡ツールを持つセッションだけです。公式ドキュメントはClaude Codeが既定でこのツールを提供するモデルとして、Claude 3.x、Opus 4〜4.7、Sonnet 4〜4.6、Haiku 4.5を挙げています。それ以外のモデルでは、CLAUDE_CODE_ENABLE_TODO_TOOLS=1 などで有効にしない限りリストは空のままです。モデルを替えても残る進捗管理が必要なら、ファイルで持つ tests.json と progress.txt が土台になります。

まとめ

最初のセッションでテストと init.sh を整え、状態は tests.json、経緯は progress.txt、履歴はgitに分けて持たせると、新しいセッションはファイルシステムから復元できます。

状態ファイルを読ませる前に集計値の整合を機械的に確かめておけば、新規ウィンドウとcompactionのどちらを選んでも、読み込む状態が信用できます。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompt…
  2. platform.claude.com/docs/en/build-with-claude/context-windows
  3. code.claude.com/docs/en/interactive-mode
  4. code.claude.com/docs/en/commands
この記事を共有:XはてブLinkedIn