長時間稼働エージェントのハーネス設計 — Anthropic engineeringが示す失敗モードと対処パターン
Anthropic engineering blogが公開した長時間エージェント運用の知見をまとめます。コンテキスト窓を超えて作業させる際の失敗モードと、Feature List / 段階的commit / init.shなどのハーネス対処を整理します。
Anthropicのengineeringブログが2025年11月26日に公開した「Effective Harnesses for Long-Running Agents」は、Claude Opus 4.5を複数のコンテキスト窓にまたがる長時間タスクで安定して動かすために、ハーネス(エージェント実行基盤)側で何を用意すべきかを整理した記事です。著者はJustin Young氏、claude.aiのクローンを200以上の機能でゼロから構築させた実装経験から得られたパターンが報告されています。
本記事では、このブログで指摘された失敗モードと対処パターンを、Claude Agent SDKやClaude Codeで自前のエージェントを設計している開発者向けに、実装観点で読み替えていきます。
背景 — なぜ「長時間エージェント」専用のハーネスが必要なのか
LLMエージェントの単発タスク(1コンテキスト窓で完結するもの)は、すでに実用域に入っています。Claude Codeでファイル編集、Cursorでリファクタ、Bedrock / Vertex経由のAPIエージェントで定型業務、いずれもツール利用のループ + 短い反復で多くの仕事をこなせます。
問題は、1つのコンテキスト窓を超える規模の作業に拡張したときに起きます。Anthropicのブログは冒頭で「each new session starts with no memory of the previous session(各新セッションは前セッションの記憶を持たずに始まる)」と問題を定義し、Claude Opus 4.5を例に2つの典型的な失敗を挙げています。
- 詰め込みすぎ: アプリ全体を1セッションで実装しようとして、途中でコンテキスト窓が枯渇する
- 早期完了宣言: 進捗を見て、未完成でも「完了した」とマークしてしまう
つまりモデルの能力ではなく、エージェントを動かす環境(harness)側の設計が長時間タスクの可否を決めます。記事はこのハーネスを「環境管理」「失敗モードへの対処」「セッション開始時の立ち上げ」の3軸で整理しています。
検証環境 — claude.aiクローンを200機能で作らせる
Anthropicが本記事の検証台として使ったのは、claude.ai自身のクローンをゼロから作るというタスクです。いきなりClaude本体のクローン構築という重さが攻めていますが、ここで重要なのは規模です。
- 200を超える機能(例: 「New Chatボタンが新規会話を作成する」)を1記事の中で扱う
- 機能リストはJSON形式で管理、各機能に
passes: falseフラグを付ける - 1セッションでは終わらない前提で、複数セッションにまたがる進捗管理が必要になる
JSON形式を選んだのは「モデルがJSONファイルをMarkdownより適切に扱う傾向を確認したため」と明記されています。このあたりは経験則ですが、ハーネスが管理する「機械が読み書きする状態ファイル」はJSONを基本にするという指針は他のエージェント設計でも参考になります。
ハーネスを構成する4つの仕組み
ブログ本文から抽出すると、ハーネス側で用意すべきメカニズムは大きく4つに整理できます。各仕組みが、どの失敗モードを抑え込むために存在しているかを併記します。
| ハーネスの仕組み | 抑える失敗モード | 役割 |
|---|---|---|
| Feature List(JSON) | プロジェクト全体の早期完了宣言 / 機能の未成熟マーク | 完了基準を外部ファイルに固定する |
| Incremental Progress(段階commit + progress file) | 環境のバグや未文書化の進捗 | セッション間で状態を引き継ぐ |
| Testing(Puppeteer MCPなど) | 機能を未テストのまま「passing」にする | 完了判定を実証ベースに変える |
| init.shスクリプト | アプリ実行方法の習得に時間を浪費する | セッション開始時の立ち上げを定型化 |
以下、それぞれを掘り下げます。
Feature List — 「完了の定義」をモデルから取り上げる
Feature Listは初期化エージェントが200以上の機能を列挙したJSONファイルで、各エントリは「機能の自然言語記述」と「passes: false」のフラグを持ちます。実装エージェントは、このリストの中から1つだけ選んで取り組み、テストが通ってからpasses: trueに書き換える運用です。
ブログには "It is unacceptable to remove or edit tests because this could lead to missing or buggy functionality"(テストを削除・編集してはならない、機能の欠落やバグを招くため)と明記されており、モデルが「テストを直す代わりに消す」近道を取らせないことが意図されています。
実装観点でのポイントは2つです。
- 完了の定義を「モデルの自己申告」ではなく「外部の機械可読ファイル」に置く
- ファイルの編集規則(削除禁止、passing変更には実テスト必須)をシステムプロンプトで縛る
これはClaude Codeのワークフローで言うところのUltraplan(計画ファイル)に近い発想ですが、Ultraplanが「タスク分割の計画」なのに対し、Feature Listは「完了基準の固定」に役割が振られている点が違います。
Incremental Progress — gitとprogress fileの二段構え
セッションが切れても進捗がロストしないようにするための仕組みが、git commitとclaude-progress.txtの併用です。
- git commit: 1機能ごとに「説明的なメッセージで」コミットする。バグが入ったらrevertできる
- claude-progress.txt: 自然言語で「いま何を作業中か」「直前のセッションで何が分かったか」を残す
- セッション開始時はgit logとprogress fileの両方を読んでから作業に入る
git commitは「機械が解釈しやすい状態の記録」、progress fileは「次のセッションのモデルに引き継ぐメモ」と、目的が分離されている点が読みどころです。Claude Codeの git revert 文化とCheckpointingの考え方は、このパターンの延長線上にあると見るとつながりやすいでしょう。
Testing — Puppeteer MCPによる視覚的な完了判定
テストはPuppeteer MCP(Model Context Protocol)サーバーを介したブラウザ自動化で行われています。エージェントが実際にブラウザを操作してスクリーンショットを撮り、機能がエンドツーエンドで動くことを確認してからpasses: trueにする流れです。
ブログでは「視覚的検証が不足する領域も存在(例: ブラウザネイティブのalertダイアログ)」と限界も明記されています。MCPで完全自動化できる部分は完全自動化し、できない部分はFeature List側で除外するか手動確認に回す、という現実的な切り分けが取られています。
init.sh — セッション開始の儀式を1コマンドにする
Anthropicが特に強調しているのがinit.shです。これは開発サーバー起動とテスト初期化を1スクリプトに固めたもので、セッション開始時のエージェントが必ずこれを実行します。
ブログに記載されている典型的なセッションの流れを整理すると、こうなります。
pwdで作業ディレクトリを確認- git logと
claude-progress.txtを読む - Feature Listから最優先で未実装の機能を1つ選ぶ
init.shで開発サーバーとMCPを立ち上げる- 既存機能の基本e2eテストで「壊していないこと」を確認
- 新機能の実装に入る
この順序の意味は、「環境を信頼してから作業に入る」という原則です。エージェントが環境を信頼できないまま実装を始めると、自分の出した変更でバグったのか元から壊れていたのか判別できず、デバッグにコンテキスト窓を浪費します。init.shはその判別コストを削るための仕組みです。
4つの失敗モードと対応マップ
Anthropicが本記事で抽出した失敗モードは4つで、それぞれに「初期化エージェント側の対応」と「コーディングエージェント側の対応」の2層で対処する設計になっています。
| 失敗モード | 初期化エージェント側 | コーディングエージェント側 |
|---|---|---|
| プロジェクト全体の早期完了宣言 | Feature Listファイルを作る | 1機能ずつ選んで段階的に実装 |
| 環境のバグや未文書化の進捗 | gitリポジトリ + progress noteファイルを用意 | セッション開始時にテスト、終了時にcommit |
| 機能を未成熟のまま完了マーク | Feature Listの厳密な完了定義 | 完全テスト後のみ passes: true に変更 |
| アプリ実行方法の学習に時間 | init.shを用意 | セッション開始時に必ず読み込み |
注目すべきは、同じ失敗モードに対して「環境を整える側」と「環境で動く側」の両方から手を打っている点です。たとえば「未成熟マーク」問題に対して、ハーネス側はFeature Listで定義を縛り、エージェント側はテスト合格を絶対条件にする。片側だけだと抜け穴ができますが、両側で挟むと回避ルートが消えます。
ハーネスは何を意味するか — 単発エージェントとの設計差
ここからは独自解釈です。本記事から読み取れる最大の示唆は、「長時間エージェントの設計は、単発エージェントの延長線ではなく、別の設計問題である」という点です。
単発エージェントの設計は、おおむね以下の最適化問題でした。
- 良いシステムプロンプトを書く
- 必要なツールを過不足なく定義する
- ツール戻り値を簡潔にしてコンテキスト消費を抑える
長時間エージェントになると、これに加えて以下の問題が発生します。
- 状態の永続化: コンテキスト窓を超えて引き継ぐべき情報の選別と置き場所
- 完了の客観化: モデルが「終わった」と言うのを信じない仕組み
- 環境の冪等性: セッションを何度立ち上げても同じ状態に戻せること
- 失敗の局所化: 1セッションが破綻しても全体が壊れない構造(git revertが効く粒度)
Feature List / progress file / init.sh / git commitはそれぞれ、これらの問題に1対1で対応する具体策です。Claude Agent SDKやClaude Codeのバージョン2.1系で進んでいるworktree分離やCheckpointingも、本質的には同じ問題群を別アングルから解こうとしている動きと読めます。
単一エージェントvsマルチエージェント — Anthropicが残した宿題
ブログ末尾の「Future work」では、現状の単一エージェント構成に対し、役割分担した複数エージェント(テスト担当、QA担当、コード整理担当など)の構成が検討課題として挙げられています。
現時点の本記事の構成は、1つのコーディングエージェントがすべてを担う設計です。役割分担すれば各エージェントのコンテキストは軽くなりますが、エージェント間の状態同期コスト(誰がFeature Listを更新するか、誰がprogress fileを書くか)が新たに発生します。
この方向は、Claude CodeのSub-agent機能やAgent SDKのマルチエージェント例と地続きです。Anthropic側もまだ「単一が良いか分業が良いか結論は出ていない」段階を明示しているため、しばらくは両方のパターンが並行して試される時期が続きそうです。
自前エージェントへの実装読み替え
最後に、本ブログの知見を自前のエージェント実装に持ち込むときのチェック項目を以下に挙げます。読者が自分のプロジェクトに当てはめて確認できる粒度にしてあります。
- 完了の定義は外部ファイルか: Feature ListのようにJSONで明示し、モデルの自己申告に依存させない
- 状態ファイルはJSON or Markdownどちらか: 機械が更新するならJSON、人が読むだけならMarkdown
- セッション開始の立ち上げが1コマンドか:
init.sh相当のスクリプトを最初に走らせる - commit粒度が1機能か: 機能単位でgit commitし、revertで巻き戻せるようにする
- テストがエージェントの手で実行されるか: Puppeteer MCPなど、モデル自身がテストを走らせて結果を見る経路を確保する
- 「やってはいけないこと」をシステムプロンプトで縛っているか: テスト削除禁止のような近道を明示的に塞ぐ
これらが揃ってはじめて、「コンテキスト窓を超える規模のタスクをエージェントに任せる」が選択肢に入ってきます。
まとめ
本記事の核は、長時間エージェントの安定運用はモデル能力ではなくハーネス設計に依存するという主張です。Feature List(完了の固定) / Incremental Progress(状態の引き継ぎ) / Testing(完了判定の客観化) / init.sh(立ち上げの定型化)という4本柱を組むことで、Claude Opus 4.5のようなモデルでも200機能規模のアプリ構築を複数セッションで通せる、という実証が示されました。
Agent SDKやClaude Codeでマルチセッションのエージェントを設計する開発者にとって、本記事のパターンは「自分のハーネスに何が足りないか」を点検する素材として使えます。Anthropic側もマルチエージェント分業はまだ宿題と認めており、ここから先のベストプラクティスが詰まる領域として注目しておく価値がありそうです。
関連する記事
Anthropic をもっと見る →Managed Agentsの設計思想 — セッション/ハーネス/サンドボックスを分離した長時間エージェントのつくり方
長時間動くエージェントのハーネス設計 — Anthropicが社内で組んだPlanner / Generator / Evaluatorの三段構成
Advanced Tool Use — Claudeが大量ツールを「探して・書いて・呼ぶ」3つの新ベータ機能を読み解く
AIエージェントのEval設計 — Anthropicが示す採点者3類型と非決定性のpass@k / pass^k
AnthropicのContext Engineering論 — 長時間エージェントを動かす4つの実装戦略
エージェント向けツール設計の原則 — Anthropicが説く5つの設計指針と評価駆動の作り方
Claude Opus 4.6がBrowseCompを「テストだ」と見抜いた事例 — eval awarenessと評価汚染の最前線
MCPでコード実行する設計 — Anthropicが示す「ツール呼び出し」から「コードAPI」への移行