agentic-harness-patterns について
Agentic Harness Patterns は、コーディングエージェントのランタイム、独自エージェント、マルチエージェントのワークフローを構築するエンジニア向けのガイドです。メモリ、スキル、ツールの安全性、コンテキスト管理、協調、拡張性を本番環境向けのパターンとして整理しています。
主な機能
- 01階層型の永続エージェントメモリを設計
- 02再利用可能なスキルを必要時に読み込み
- 03権限と安全な既定値でツールを制御
- 04コンテキストの選択・圧縮・分離
- 05コーディネーター・fork・swarm方式を比較
- 06ライフサイクルフックと拡張性を設計
活用シーン
- 01コーディングエージェントのランタイム設計
- 02永続メモリと再利用可能なスキルの追加
- 03ツール権限と並列呼び出しの制御
- 04マルチエージェントタスクの委譲方式の選択
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ keli-wen/ agentic-harness-patterns-skill --skill agentic-harness-patternsインストール後、Claude Code で/agentic-harness-patternsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
metadata.jsonreferences/agent-orchestration-pattern.mdbootstrap-sequence-pattern.mdcontext-engineering-pattern.mdhook-lifecycle-pattern.mdmemory-persistence-pattern.mdpermission-gate-pattern.mdskill-runtime-pattern.mdtask-decomposition-pattern.mdtool-registry-pattern.mdreferences/context-engineering/compress-pattern.mdisolate-pattern.mdselect-pattern.md詳細
エージェント型ハーネスのパターン
本番環境で使われる AI コーディングエージェントは、単に LLM がループ内でツールを呼び出すだけではありません。メモリ、スキル、安全性、コンテキスト制御、委任、拡張性を担うハーネスが、デモと本番システムを分ける要素です。
対象: コーディングエージェントのランタイム、カスタムエージェント、高度なマルチエージェントワークフローを構築または拡張するエンジニア。 対象外: プロンプトエンジニアリング、モデルの選定、一般的なソフトウェアアーキテクチャ、LLM API の基礎。
すべての原則は、本番ランタイムにおける意思決定をもとに抽出されています。Claude Code は根拠となる例として使用していますが、唯一の実装方法ではありません。
課題から選ぶ
| 目的 | 読む項目 |
|---|---|
| エージェントに記憶させ、時間とともに改善する | メモリ |
| 再利用可能なワークフローと専門知識をパッケージ化する | スキル |
| エージェントに強力かつ安全にツールを使わせる | ツールと安全性 |
| 適切なコストで、エージェントに適切なコンテキストを与える | コンテキストエンジニアリング |
| 制御を失わずに複数のエージェントに作業を分担させる | マルチエージェント連携 |
| フック、バックグラウンドタスク、起動時のロジックで動作を拡張する | ライフサイクルと拡張性 |
構築を始める前に: 落とし穴を読んでください。特に気づきにくく、最も大きな時間のロスにつながる失敗パターンをまとめています。
1. メモリ
ユーザーの課題:「エージェントがセッションをまたぐと、修正内容やプロジェクトのルールを忘れてしまいます。」
基本原則: エージェントが「知っていること」(指示メモリ)、「学習すること」(自動メモリ)、「抽出すること」(セッションメモリ)を分けます。それぞれのレイヤーで、永続性、信頼性、レビューの要件が異なります。
使用する場面: 複数のセッションにわたって動作するエージェントや、時間の経過とともにプロジェクト固有の知識を蓄積する必要があるエージェント。
仕組み:
- 指示メモリは、優先順位に沿ってシステムコンテキストに注入される、階層化されたキュレーション済みの設定です(組織全体 → ユーザー → プロジェクト → ローカル。ローカルが優先されます)。プロジェクトの規約、コーディング標準、動作ルールを記述します。人間が作成し、安定して維持されます。
- 自動メモリは、分類体系(ユーザー/フィードバック/プロジェクト/リファレンス)と上限付きインデックスを備えた、エージェントが書き込む永続的な知識です。保存は、トピックファイルを書き込み、その後インデックスを更新するという2段階で行います。上限によって際限のない増加を防ぎます。整理しないと、新しい項目の追加時に古い項目が気づかれないまま消えてしまいます。
- セッション抽出は、セッション終了時にバックグラウンドエージェントとして実行されます。自動メモリに直接書き込み、同じ2段階の保存不変条件(トピックファイル、その後インデックス)に従います。メインエージェントがそのターン中にすでにメモリを書き込んでいる場合は、相互排他ガードによって抽出処理全体をスキップします。これが自律学習ループです。
- レビューと昇格では、すべてのメモリレイヤーを監査し、レイヤーをまたぐ移動(自動メモリ → プロジェクト規約、個人用の指示、またはチームメモリ)を提案します。変更が自動で適用されることはありません。提案にはユーザーの明示的な承認が必要です。
まずはここから: メモリのレイヤー(指示、自動、抽出)を定義します。2段階の保存不変条件(トピックファイル、その後インデックス)を実装します。中核となる書き込み経路が安定してから、バックグラウンドでの抽出を追加します。
Claude Code の場合:
/rememberを使うと、自動メモリの項目をレイヤーをまたいで監査し、昇格できます。
トレードオフ:
- メモリレイヤーを増やすと、より豊富に情報を想起できますが、メンテナンスの負担も増します。定期的に整理しないと、インデックスの上限によってデータが気づかれないまま失われます。
- セッション抽出を行うとセッション終了時の処理時間が増えますが、セッションをまたぐ学習が大幅に改善します。
さらに詳しく: references/memory-persistence-pattern.md
2. スキル
ユーザーの課題:「エージェントにワークフローやドメイン知識を再利用させたいのですが、そのたびに説明し直したくありません。」
**基本原則:**スキルは遅延読み込みされる指示セットであり、あらかじめプロンプトに注入するものではありません。検出にはコストがかからないようにします(メタデータのみ)。本文全体は有効化されたときにのみ読み込みます。
**使用するタイミング:**ユーザーの意図に合致したときに有効化される、再利用可能で組み合わせ可能なワークフローを必要とするあらゆるエージェント。
仕組み:
- 検出には予算の制約があります。エージェントには、利用可能なすべてのスキルを簡潔に一覧表示します(各項目では名前、説明、使用するタイミングのヒントを連結)。各項目には固定の文字数上限を設け、全体ではコンテキストウィンドウのおよそ1%を上限とします。トリガーとなる表現は先頭に置いてください。末尾は切り捨てられます。
- 読み込みは遅延方式です。常時有効なコンテキストに入るのはメタデータのみです。スキル本文全体はスキルが有効化されたときにのみ読み込まれるため、未使用時のトークンコストはほぼゼロに抑えられます。
- 実行はインライン(コンテキストを共有)にも、分離(独自のトークン予算を持つフォークされたサブエージェント)にもできます。分離することで、負荷の高いスキルが親のコンテキストを使い果たすのを防げます。
- ソースには、同梱されたもの、ユーザーがインストールしたもの、プラグインから動的に読み込まれるものがあります。正規パスで重複排除することで、複数のソースディレクトリが重複する場合でも、同じスキルが二度表示されるのを防ぎます。
**まずはここから:**メタデータ形式を選択します(フロントマターを推奨)。二段階の検出を実装します。起動時には簡易な一覧を表示し、呼び出し時には本文を遅延読み込みします。カタログが大きくなる前に、項目ごとの文字数上限を設定してください。
トレードオフ:
- 遅延読み込みはトークンを節約しますが、初回の有効化時にラウンドトリップ分の遅延が加わります。
- フォークされた実行では分離できますが、親に蓄積されたコンテキストにはアクセスできなくなります。
詳しくはこちら: references/skill-runtime-pattern.md
3. ツールと安全性
ユーザーの課題:「エージェントにツールを強力に使わせたいのですが、危険な使い方はさせたくありません。」
**基本原則:**デフォルトではフェイルクローズにします。明示的に並行実行が安全とマークされ、権限パイプラインで承認されない限り、ツールは直列に実行し、実行にゲートを設けます。
**使用するタイミング:**ツールの登録、並行実行の制御、または権限によるゲートが必要なあらゆるエージェントランタイム。
仕組み:
- 登録ではフェイルクローズをデフォルトにします。開発者が明示的に選択しない限り、ツールは並行実行不可、かつ読み取り専用ではありません。これにより、状態を変更する操作が意図せず並列実行されるのを防ぎます。
- 並行実行の分類はツール単位ではなく呼び出し単位です。同じツールでも、入力によって安全な場合と危険な場合があります。ランタイムはツール呼び出しのバッチを連続するグループに分け、安全な呼び出しは並列実行し、安全でない呼び出しがあると直列実行の区間が始まります。
- 権限パイプラインは、設定ファイル(ユーザー、プロジェクト、ローカル、フラグ、ポリシー)、CLI 引数、コマンド単位のルール、セッション許可といった複数のソースからルールを厳密な優先順位で評価します。評価器は状態を持ち、拒否を追跡し、モードを変換し、副作用として状態を更新します。
- ハンドラーのディスパッチは実行環境によって異なります。対話型(人間へのプロンプト)、自動化(コーディネーター)、非同期(スウォームエージェント)のいずれかです。同じ権限ルールが、それぞれ異なる承認画面に反映されます。
**まずはここから:**すべてのツール呼び出しを一つの権限ゲートに通します。デフォルトではフェイルクローズ(拒否または確認)にします。自動承認モードをリリースする前に、保護対象パスに対するバイパス不可能なルールを追加してください。
Claude Code の場合:
/update-configを使って権限ルールとフックを設定します。
トレードオフ:
- フェイルクローズのデフォルトにより、新しいツールは最初から安全ですが、並行実行を有効にするには開発者が明示的に選択する必要があります。読み取り専用ツールを並行実行安全として設定し忘れると、スループットが気付かないうちに低下します。
- 複数ソースにまたがる権限の階層化は強力ですが、異なるソースのルールが競合するとデバッグが困難になります。
詳しくはこちら: references/tool-registry-pattern.md | references/permission-gate-pattern.md
4. コンテキストエンジニアリング
ユーザーの課題:「エージェントが、コンテキストを見すぎたり、少ししか見なかったり、見当違いのものを見たりします。」
**基本原則:**コンテキストは、ただ詰め込むものではなく、予算として扱います。ウィンドウ内の各トークンは、「選択」「書き込み」「圧縮」「分離」の4つの操作のいずれかによって、存在する価値を示す必要があります。
**使用する場面:**長時間のセッションで性能が低下するエージェント、委任した作業によって親のコンテキストが汚染されるエージェント、またはコンテキストを先読みして読み込むために起動が遅いエージェント。
仕組み:
- 選択 — コンテキストを一度にすべて読み込むのではなく、必要なタイミングで読み込みます。3段階のプログレッシブディスクロージャーを使用します。メタデータ(常に存在し、低コスト)、指示(有効化時に読み込み)、リソース(必要に応じて読み込み)です。コストの高いコンテキストビルダーはメモ化し、既知の変更時点でのみ無効化します。反応的に無効化してはいけません。
- 書き込み — コンテキストは読み取り専用ではありません。エージェントは、オートメモリーのエントリ、バックグラウンドでの抽出結果、タスクの状態、権限ルールなどを永続ストレージに書き戻します。この書き戻しのループによって、ステートレスなエージェントが学習するシステムになります。
- 圧縮 — 長時間のセッションではウィンドウを使い切ります。反応的なコンパクションでセッション中に古いターンを要約し、最近のコンテキストを保持しながら予算を回収します。スナップショットデータにはスナップショットであることを示し、現在の状態を確認するには再取得が必要だとモデルに伝えます。
- 分離 — 委任した作業によって親のコンテキストが汚染されないようにします。コーディネーターワーカーはコンテキストを一切継承せず(明示的なプロンプトのみを受け取り)、フォークされた子はコンテキスト全体を継承しますが、階層は1段階に限られます(再帰的なフォークは行いません)。ファイルシステムレベルで分離する(worktree)と、エージェント専用の作業コピーを用意できます。
**ここから始めましょう:**現在のコンテキストコストをターンごとに監査します。可変長のブロックすべてにハード上限を設けます。圧縮を有効にする前に、切り詰めからの復旧ポインターを追加します(完全な出力を得るにはどのツールを呼び出せばよいかをモデルに伝えます)。
トレードオフ:
- 積極的なキャッシュはレイテンシを減らしますが、古いデータを使うリスクが生じます。すべての変更時点で明示的にキャッシュをクリアしないと、セッションの残りの間、モデルは古いデータに基づいて動作します。
- プログレッシブディスクロージャーはトークンを節約しますが、スキルを有効化するまでは、モデルがその機能をすべて把握して推論できません。
詳しく見る: references/context-engineering-pattern.md(インデックス) | select | compress | isolate
5. マルチエージェントの連携
ユーザーの課題:「混乱を招かずに、並列処理、専門性、連携を実現したい。」
基本原則: コーディネーターは理解を委任するのではなく、統合する必要があります。「調査結果に基づいて修正してください」はアンチパターンです。コーディネーターは、実装を割り振る前にワーカーの結果を整理し、明確な仕様にまとめる必要があります。
利用する場面: 単一のエージェントでは大きすぎるタスク、並行して調査する必要がある場合、または専門性を持つチームメイトと継続的に協働したい場合です。
仕組み:
タスクの形に応じて、次の3つの委任パターンを使い分けます。
| パターン | コンテキストの共有 | 最適な用途 |
|---|---|---|
| コーディネーター | なし — ワーカーは新規に開始 | 複雑な複数フェーズのタスク(調査 → 統合 → 実装 → 検証) |
| フォーク | 完全 — 子エージェントが親の履歴を引き継ぐ | 読み込まれたコンテキストを共有する、素早い並列分割 |
| スウォーム | 共有タスクリストを介したピアツーピア | 長時間にわたる独立したワークストリーム |
主な制約:
- フォークは1段階のみです。再帰的なフォークを行うと、コンテキストのコストが指数関数的に増大します。
- スウォームのチームメイトは他のチームメイトを起動できません。制御不能な拡大を防ぐため、メンバー構成はフラットになっています。
- 結果は非同期で届きます。結果を待たずに登録する方式では、IDがすぐに返されるため、親エージェントは作業を続行できます。
ここから始めましょう: まず委任パターンを1つ選び、パターンを組み合わせる前に完全に実装してください。各サブエージェントのプロンプトは、単独で完結するドキュメントとして記述してください。調査ワーカーと実装ワーカーの間に統合ステップを設けてください。ここでオーケストレーターが価値を発揮します。
コーディネーターパターンの実装チェックリスト:
- フェーズごとのワークフローを定義します:調査 → 統合 → 実装 → 検証
- 各ワーカー向けに単独で完結するプロンプトを記述します(「調査結果に基づいて」のような指示は避けます)
- 各ワーカーのツールセットを、必要なものだけに絞ります
- 継続するか新たに起動するかの方針を決めます:コンテキストが重複する場合は継続し、検証には新規に起動します
トレードオフ:
- コーディネーターモードは最も安全ですが、各フェーズが前のフェーズを待つため、最も時間がかかります。
- フォークは最も速い一方で、1段階に限られ、親のコンテキスト全体を引き継ぐコストがかかります。
- スウォームは最も柔軟ですが、連携が最も難しく、ピア間の通信手段は共有タスクリストのみです。
詳しくはこちら: references/agent-orchestration-pattern.md
6. ライフサイクルと拡張性
ユーザーの課題:「フック、バックグラウンドタスク、そして明確な起動シーケンスが必要です。」
**基本原則:**拡張性は継承階層ではなく、処理を注入するポイントです。フックはライフサイクルの各時点に副作用を追加し、タスクは厳格な状態遷移で非同期処理を追跡し、ブートストラップは初期化をメモ化された段階に分けて順番に進めます。
**使用する場面:**コアコードを変更せずにエージェントの動作を拡張したい場合、長時間実行されるバックグラウンド処理を追跡したい場合、または複数のエントリーモードにわたる初期化を構成したい場合に使用します。
仕組み:
- フックは、定義されたライフサイクルの各時点(ツール実行前後、プロンプト送信時、エージェントの開始・終了時)に副作用を追加して動作を拡張します。信頼性の判定は全か無かです。ワークスペースが信頼されていない場合、疑わしいフックだけでなく、すべてのフックがスキップされます。セッションスコープのフックは一時的なもので、セッション終了時にクリーンアップされます。
- 長時間実行される処理は、型付きの状態マシンを使って追跡します。各処理単位には、型付きのプレフィックス付き ID、厳格なライフサイクル(実行中 → 完了/失敗/強制終了)、ディスクに保存される出力が割り当てられます。削除は2段階で行われます。終端状態になった時点でディスク上の出力を即座にクリーンアップし、親に通知した後でメモリ内のレコードを遅延クリーンアップします。
- ブートストラップでは、初期化を依存関係の順に並べた、メモ化される段階として構成します。信頼境界、つまりユーザーが同意を与える時点が重要な転換点です。テレメトリーやシークレットを含む環境変数など、セキュリティに関わるサブシステムは、信頼が確立される前に有効化してはなりません。複数のエントリーモード(CLI、サーバー、SDK)は、異なるエントリーポイントから同じブートストラップ経路を共有します。
**まず始めること:**すべてのフックを単一のディスパッチポイントに集約します。外部フックの種類を追加する前に、信頼ゲートを実装します。クリーンアップハンドラーは使用箇所ではなく、初期化時に登録します。
Claude Code では:
/update-configを使ってフック(ツール実行前後、プロンプト送信時)を設定します。
トレードオフ:
- フックの信頼性を全か無かで判定する方式は単純ですが、大まかな制御になります。信頼されていないフックが1つあるだけで、拡張システム全体が無効になります。
- タスクの出力をディスクに保存すると、メモリ使用量を一定に保てますが、並行して処理する単位数に応じた I/O レイテンシーが発生します。
詳しく見る: references/hook-lifecycle-pattern.md | references/task-decomposition-pattern.md | references/bootstrap-sequence-pattern.md
注意点
違反するとバグの原因となる、分かりにくい原則:
-
並行処理の分類はツール単位ではなく、呼び出し単位です。 入力によっては安全に使えるツールもありますが、そうでない場合もあります。ツールの並行処理の挙動が固定されていると思い込まないでください。実行時に呼び出しごとに判断されます。
-
権限の評価には副作用があります。 権限チェッカーは拒否を追跡し、モードを変換し、状態を更新します。純粋な検索関数として扱わないでください。
-
非同期処理の大半は「保留」状態を経由しません。 実際には、作業単位は「実行中」として直接登録されます。すべての作業単位が保留状態から始まることを前提とした UI を構築しないでください。
-
フォークされた子プロセスはフォークできません。 再帰ガードにより、1 階層のみという不変条件が保たれます。フォークツールは子プロセスのツールプールに残りますが(プロンプトキャッシュを共有するため)、呼び出し時にブロックされます。
-
コンテキストビルダーはメモ化されますが、無効化は手動です。 コンテキストソースを追加しても、対応する無効化ポイントを追加しなければ、セッション全体を通してモデルには古いデータが表示されます。
-
メモリインデックスには上限があります。 上限を超えたエントリーは黙って切り詰められます。定期的にクリーンアップしないと、最近のエントリーが表示されなくなります。
-
スキル一覧の予算は限られています。 説明は連結され、エントリーごとに上限が適用されます。最も特徴的なトリガーとなる表現を先頭に配置してください。末尾は切り捨てられます。
-
フックの信頼性はシステム全体に適用されます。 ワークスペースが信頼されていない場合、個々の疑わしいフックだけでなく、フックシステム全体が無効になります。
-
ツールのデフォルトの権限は「許可」です。 独自の権限ロジックを実装していないツールは、ルールベースのシステムに全面的に委ねられます。ツール固有の制限(パス ACL、クォータなど)が必要な場合にのみ、オーバーライドしてください。
-
エビクションには通知が必要です。 終了状態の作業単位が GC の対象になるのは、親が完了通知を受け取った後だけです。通知前にエビクションすると競合が発生し、親が結果を読み取れなくなる可能性があります。
このスキルを使用しない場合
このスキルの対象は、エージェントを取り巻くハーネスであり、以下は対象外です。
- プロンプトエンジニアリングやシステムプロンプトの設計
- モデルの選択やファインチューニング
- 汎用的なソフトウェアアーキテクチャ(MVC、マイクロサービス)
- チャット UI や会話型インターフェース
- LLM API 連携の基本
システムの周辺ではなくモデル自体についての質問には、このスキルは適用されません。