/note/tech

ハーネス設計入門 〜 基礎知識の整理から実務へのステップアップ 〜

要約:

■ 1. ハーネスエンジニアリングの定義と成立

  • ハーネスエンジニアリングとは:
    • エージェントが同じ失敗を繰り返さないよう、モデルの外側(環境)を設計すること
    • AGENT = MODEL + HARNESS という関係で捉える
    • 指示ファイル、ツール、検証、ガードレール、ループなど、モデル以外のすべてがハーネス
  • 手法の変遷:
    • プロンプトエンジニアリング(2022年〜)
    • コンテキストエンジニアリング(2024年〜)
    • ハーネスエンジニアリング(2026年〜)
  • 成立の経緯:
    • 2026年2月5日、Mitchell Hashimotoが命名し、失敗したら二度と起きないよう環境を直すという考え方を示した
    • 2026年2月11日、OpenAIが3人で100万行、95%をAIが生成した実践例を公開した
    • 以降、各社・論者が追随したが、定義は論者ごとに異なった

■ 2. 5つの流派と定義の違い

  • 流派が分かれた理由:
    • 同じ「ハーネス」でも、論者が手本にした実装によって意味の範囲が違う
  • Chase派(Harrison Chase、LangChain):
    • 広義・分類論の立場
    • モデル以外のすべてがハーネスと主張する
  • Hashimoto派(Mitchell Hashimoto):
    • 運用哲学の立場
    • 失敗したら環境を再設計せよと主張する
  • Fowler派(Birgitta Böckeler、Thoughtworks):
    • 制御理論の立場
    • ハーネスをコンテキスト設計の特殊形として定義する
  • Chawla派(Avi Chawla、教育系):
    • 同心円モデルの立場
    • ハーネスをLLMのOS層として三重の入れ子で捉える
  • Codex派(Ryan Lopopolo、OpenAI Codex):
    • スケール駆動の立場
    • ハーネスをスケールで壊れる問題への答えと位置づける
  • 対立の構造:
    • Chase派とChawla派はハーネスがコンテキストを包含し、ハーネスを外層とする総合フレーム設計の視点
    • Fowler派はコンテキスト設計がハーネスを包含し、ハーネスを guides + sensors とする制御理論(feedforward / feedback)の視点
    • どちらが外側かが流派によって逆になり、2026年前半はこの違いが議論の中心だった

■ 3. 語彙の収束と標準化

  • 語彙の収束(2026年3〜7月):
    • 3月10日、LangChainが「The Anatomy of an Agent Harness」で構成要素を整理した
    • 4月19日、Addy Osmaniがハーネスはモデル同士より互いに似てきていると指摘した
    • 6月、Build 2026でAgent Harness安定版が出て、Pydantic v2.0がハーネス中心に再設計された
    • Linux FoundationがAgentic AI Foundationを設立した(MCP、AGENTS.md、Goose)
    • 5つの流派の言葉づかいは約5か月でほぼ一つにまとまった
  • Agent Plugins 1.0(2026年8月6日):
    • Skills・MCPサーバーを plugin.json+skills/+mcp.json という1つのフォルダ形式にまとめる標準
    • Vercelが発案し、Amazon・Cursor・GitHub・Microsoft・OpenAIが策定し、Googleも参加した
    • ChatGPT・Codex・Cursor・GitHub Copilot・Kiro・VS Codeが対応し、一度作れば複数のクライアントで使える
  • 互換性の限界:
    • Claude Code は独自形式のままで未対応
    • SkillsかMCPの片方だけに対応するクライアントもあり、対応表の確認が必要
    • hooks、コマンド、rules は対象外で、クライアントごとに異なる

■ 4. ハーネスで結果が変わる実証

  • モデルを変えずにハーネスだけで成績や品質が変わった例:
    • LangChainはハーネスの変更だけで Terminal Bench 2.0 の順位を30位からトップ5に上げた
    • ハーネスの設定だけでスコアが±5pt以上動く(Anthropic 2026 Agentic Coding Trends Report)
    • 2026年4月の Claude Code の品質低下は、原因3件中3件すべてがハーネス側の変更だった

■ 5. 実践編の流れとゴール

  • ゴール:
    • エージェントが自分で失敗に気づき、自分で直して完走する仕組みの設計方法を身につける
  • 3つのステップ:
    • ハーネスを作る:AGENTS.md・Skills・サブエージェントで「どう走ってほしいか」を伝える
    • ガードレールを張る:lint・型チェック・テストで逸脱を機械的に見つけ、「1コマンドの門」に束ねる
    • ループを閉じる:検証器とゴールを渡し、エージェントが自分で直して完走する
  • 概念、道具、柵、境界の順に進める

■ 6. 前提:生成AIは確率で動く

  • 確率的な動作原理:
    • 1トークンごとに次に来る語を確率で選ぶ
    • 低確率の「悪い一手」もゼロではない
    • 小さな揺らぎが数千トークン積み重なり、どの経路になるかは実行のたびに変わる
    • 同じ指示から、動くコード、別解、危険な逸脱のいずれも生じうる
  • 従来のプログラムとの違い:
    • 従来のプログラムは同じ入力から同じ出力を返す決定的な仕組み
    • 生成AIは同じ入力から分布をサンプルする確率的な仕組み
  • 指示だけに頼らず、環境と検証で受け止める必要がある

■ 7. ハーネスとガードレールの役割分担

  • 2つの仕組みへの分割:
    • モデル以外のすべてを、指示で伝える部分と機械的に判定する部分に分ける
  • ハーネス(馬具):
    • 走り出す前に「どう走ってほしいか」を伝える事前設計の層
    • ルール(カスタムインストラクション / AGENTS.md)、Skills、サブエージェントで構成する
  • ガードレール(柵):
    • 走った後に逸脱していないかを機械的に検証する事後検証の層
    • 静的解析(lint・フォーマット・型チェック)、ビルド、テスト、Hooksで構成する
  • ハーネスは確率的、ガードレールは機械的
  • 機械的な判定が強いほど、エージェントにハンドルを預けられる

■ 8. ハーネスの性質

  • 役割:
    • プロジェクトの前提・規約・手順・禁止事項を、エージェントが参照できる形で明文化する
  • 主観の層:
    • 内容は人間の判断で決める
    • 書いた分だけ効くが、書きすぎるとコンテキストを圧迫する
    • 何を書くかを選ぶことが設計
  • 効き目の限界:
    • ハーネスは自然言語で伝える「意図」であり、モデルが確率で動くため効き目は絶対ではない
    • そのため柵(機械的な判定)と組み合わせる

■ 9. ガードレールの性質

  • 役割:
    • lint・型・ビルド・テストで、道から外れていないかを Yes / No で判定する
  • 客観の層:
    • 誰が実行しても、何度実行しても結果が同じ
    • 判定が機械的であるほど、エージェントは自分で失敗に気づき、自分で直せる
    • 確率で動くモデルを、決まった判定で支える

■ 10. フィードバック・ループ

  • ループの流れ:
    • エージェントがタスクを実装する
    • check を自分で実行し、結果を読む
    • 失敗の出力をもとに修正・再実行し、これを自分で繰り返す
  • 人が用意するもの:
    • 検証器(門)として check の1コマンド
    • ゴールとして check がすべて通ること、タスク固有の条件はプロンプトで渡す
    • AGENTS.md に実行コマンドと共通の条件を書く
  • タスク固有の条件もテストにして check に入れれば、check がすべて通ることで完了を判定できる
  • 検証器とゴールを渡せば、エージェントは自分でループを閉じる

■ 11. ハーネスの道具箱

  • 適用範囲による使い分け:
    • ルール、Skills、サブエージェントの順に、適用範囲が狭く深くなる
  • ルール(AGENTS.md):
    • 主要ツールが読む事実上の共通形式で、毎回のセッションに自動で入り薄く広く効く
    • 規約、コマンド、禁止事項を担う
  • Skills:
    • 特定作業の手順書で、必要な場面でだけ読み込まれ常時のコンテキストを圧迫しない
    • 定型作業の再現性を担う
  • サブエージェント:
    • 専用のプロンプトを与えられた専門家として、調査・実装・レビューなど役割ごとに委任し独立した文脈で動く
    • 並列化と文脈の分離を担う
  • 第一歩はルール(AGENTS.md)で、常時効く土台を固めてからSkills・サブエージェントを積む

■ 12. AGENTS.md の書き方

  • ルールのコスト:
    • ルールは毎回コンテキストに読み込まれるため、1行ごとに「家賃」がかかる
    • Claude Code は CLAUDE.md があればそちらを優先し、なければ AGENTS.md を読む(v2.1.277以降)
  • 書くこと:
    • 1段落のプロジェクト概要で、目的がわかると判断が揃う
    • ビルド・テスト・lint のコマンドで、エージェントが自分で検証できるようになる
    • 命名・ディレクトリ・エラー処理の流儀など、プロジェクト固有の規約・構成
    • 触ってはいけないファイル、変更禁止のAPIなど、してはいけないこと
  • 書かないこと:
    • 一般常識や言語の一般的な作法は、モデルがすでに知っているため無駄
    • コードを読めばわかることは、実装と二重管理になりすぐ食い違う
    • 長大な設計書は常時読むには重いため、Skillsや参照リンクへ回す
    • 「きれいに書く」のような検証できない精神論は、機械的に判定できる形にする
  • 育て方:
    • 最初は最小限にし、全行が実際の失敗や規約に対応していることを基準とする
    • 足りない分は、逸脱が出たら1行足して育てる

■ 13. Skills

  • 位置づけ:
    • ルールに全部書くとコンテキストが溢れるため、定型作業はSkillに切り出し必要な場面でだけ読ませる
  • SKILL.md の基本形:
    • 見出しで作業名を示し、使いどころ、手順、模範例を書く
    • 例としてエンドポイント追加では、ルート定義、処理実装、バリデーション、テスト、ドキュメント更新の手順を並べる
    • /create-skill で対話的に生成でき、この形になっていればよい
  • ルールとSkillの判断基準:
    • 毎回必要ならルール
    • 特定作業でだけ必要ならSkill
    • 迷ったらSkillに逃がす

■ 14. サブエージェント

  • 目的:
    • 親の文脈を汚さず、役割を分けて委任する
  • オンデマンド生成:
    • 親エージェントが必要になった瞬間に子を起こして仕事を振る使い捨ての委任
    • 大量の調査・比較の並列化、コンテキストを大きく消費する探索、結果の要約だけ持ち帰りたい場面に向く
    • 例として、3つのライブラリを別々のサブエージェントで並列に調査させ要点だけ報告させる
  • 事前定義して呼び出す:
    • 役割・観点・出力形式をファイルに定義しておき、名前で呼ぶ、育てて共有する委任
    • レビュー、セキュリティ監査、テストなど毎回同じ観点で行う作業や、チームで観点を共有したい場面に向く
    • 例として、差分を規約・セキュリティ・テスト網羅の3観点で指摘するレビュー専門エージェント
  • 並列のメリットと注意点:
    • 非同期で並行に走らせると待ち時間は大きく減る
    • 同時に走る数だけ時間当たりのトークン消費が増えるため、数と深さは費用対効果で決める
  • 共通原理:
    • 両者に共通するのは文脈の分離
    • 子にも子のハーネスが効き、定義ファイルはサブエージェント用の AGENTS.md にあたる

■ 15. ガードレールの階層

  • 検証対象の深まり:
    • どれも機械的に Yes / No を判定し、表記、整合性、振る舞いの順に検証が深く判定が強くなる
  • 5つの階層:
    • フォーマッタ(Prettier / gofmt など)は表記を統一し、議論の余地なく自動修正する
    • リンター(ESLint / Clippy など)はバグの芽と規約違反を静的に検出する
    • 型チェック(tsc / mypy など)はデータの流れの矛盾を実行前に検出する
    • ビルドは成果物として成り立つかの最低ラインを確認する
    • テストは仕様どおり動くかという振る舞いを保証する
  • 1コマンドの門:
    • 5つを check の1コマンドに束ね、人もAIも同じ門をくぐる
    • 共通の完了条件は check がすべて通ること
  • ガードレールが強いほどエージェントは自分の失敗に気づけ、任せられる範囲が広がる

■ 16. 柵を走らせるレール

  • レールとは:
    • 柵が判定する道具であるのに対し、レールは柵を自動で走らせる仕組み
    • 3本あり、外側ほど強制力が強い
  • エージェントの Hooks(クライアント内):
    • 編集・実行の瞬間に走り、例として afterFileEdit で lint、beforeShellExecution で rm を止める
    • 最速で柵を走らせ、行動への柵も兼ねる
    • クライアントの設定で無効にできる
  • Git hooks(リポジトリ):
    • Husky・lefthook などで、pre-commit / pre-push 時に check を実行する
    • 人もAIもコミットや push の前に同じ門をくぐる
    • --no-verify で抜けられるため強制力は中程度
  • CI(リモート):
    • PR作成・更新時に同じ check をパイプラインで実行し、ブランチ保護で失敗時はマージ不可にする
    • 手元ですり抜けてもここで必ず捕まえる
    • 抜けられないため強制力は最大
  • 内側は近く速いが弱く、外側は遠く遅いが強い
  • 内側で速く気づき、外側で確実に止め、レールもハーネスの一部とみなす

■ 17. 成果物への柵と行動への柵

  • 成果物への柵:
    • 書いたものを事後に検証する柵で、lint・型チェック・ビルド・テストを npm run check に束ねる
    • 判定の対象はコードで、「正しく作れたか」を問う
    • 失敗はフィードバックループの入力になる
    • 作り込みの中心はこちら
  • 行動への柵:
    • 危険な実行を事前にブロックする柵で、Hooksや許可リストで判定する
    • /create-hook で作成し、beforeShellExecution で rm や外部送信を止める
    • 判定の対象は行為で、「実行してよいか」を問う
    • 起きる前に止めるしかない事故に使う
  • 共通の原理:
    • どちらも人の注意力に頼らず機械的に止める
    • テストが落ちたコードをマージできないのも、危険なコマンドを実行できないのも同じ仕組み

■ 18. 馬具・柵・境界の3層構造

  • 3層の役割:
    • 馬具は方向を与え、AGENTS.md・Skillsで走る前に「どう走るか」を示す
    • 柵は判定を担い、lint・型・テスト・Hooksで逸脱を機械的に検証し、結果をエージェントが読んで直す
    • 境界は可動域を決め、隔離・遮断・最小権限で触れる範囲を定める
  • 走行の構図:
    • エージェントは境界の内側で走り始め、check がすべて通ったら終わる
    • 本番、DB、機密、個人情報は壁の外にあり、到達する道がない
  • 柵は道の端で逸脱を検知し、境界は戻れない場所への道を最初から作らない

■ 19. 境界という新しい層

  • 境界が必要な理由:
    • 柵は漏れることがあり、漏れると取り返しのつかない事故も起きる
  • 境界の性質:
    • 「触れられるか」を問う
    • 構造的かつ事前の仕組みで、判定せずに到達自体を無くす
    • コンテナ / サンドボックス、通信遮断、最小権限を道具とする
    • 不可逆な事故を守備範囲とする
    • 馬具と柵は境界の内側で働く
  • 強度の階段:
    • 指示するのは確率的
    • 柵で止めるのは機械的
    • 境界で不可能にするのは構造的
  • 可逆な逸脱は柵で拾ってループに戻し、不可逆な逸脱は境界で試行そのものを無くす

■ 20. ハーネスとセキュリティ

  • 自律性を上げるほど、エージェント自体が攻撃の入口になる
  • 4つの脅威:
    • 間接プロンプトインジェクションでは、外部コンテンツに紛れた指示に従ってしまう
    • 機密・個人情報の漏洩を防ぐため、認証情報や顧客データを読ませない
    • 破壊的操作を防ぐため、rm や force push を実行できなくする
    • サプライチェーン対策として、提案された依存パッケージは人が確認する
  • lethal trifecta:
    • 機密データへのアクセス、不審コンテンツの読み取り、外部への送信の3つが揃うと危険が最大化する
    • この3つを同時に許さない(出典: Simon Willison、2025年6月16日)
  • 守りも仕組みで作る:
    • 行動への柵、隔離(サンドボックス)、信頼境界(審査済みSkill・Pluginのみ)を組み合わせる

■ 21. コストと効率

  • 自走時間は目的ではない:
    • 自走は手段であり、短く、少なく、安く終えることが目標になった
    • 長く走ったことは成果ではない
  • Uberのコスト方程式:
    • ユーザー数、セッション/ユーザー、ターン/セッション、リクエスト/ターン、トークン/リクエスト、単価/トークンの6項の掛け算
    • ユーザー数とセッション/ユーザーは利用の広がりで、増えてよい項
    • 中央の3項(ターン、リクエスト、トークン)はエージェントのオーバーヘッドで、減らすのがハーネスの仕事
    • 単価はモデル選択で決まる
  • 中央3項の減らし方:
    • ターンは、計画を速くし不要なターンやエラーを減らす
    • リクエストは、社内情報のグラフによる根拠づけで無駄な探索を減らす
    • トークンは、MCPのCLI化やキャッシュで常駐コンテキストを削る
  • Uberの結果(2026年2月→8月):
    • 利用者は7倍、リクエストは9.4倍に増えたが、総コストは4月以降ほぼ横ばいだった
    • モデル固定でピーク比のコストは1,000リクエストあたり−34%、1セッションあたり−52%に下がった
    • いちばん効いた手は、サブエージェントを安いモデルにして単価を下げることだった

■ 22. ハーネスは隠れた技術的負債

  • 作り込んだハーネスにも寿命がある
  • Han Lee(2026)の指摘:
    • 良いチームほど多くのハーネスを作るが、その多くは次世代モデルで不要になる
  • モデル更新で消えるもの:
    • 「省略せずに全部出力して」「全部読んでから直して」のような弱点を補う回避策は、モデルに吸収され消える
    • 細かく刻んだ手順や独自のリトライ処理のような作り込みも、同様に不要になる
  • モデル更新でも残るもの:
    • テスト(check)、権限と境界、プロジェクト固有の規約という中核
  • ある時点の形に固執せず、薄く軽く保ち、定期的に棚卸しする

■ 23. ハーネスエンジニアリングの手順

  • 逆順にやると、効かないルールと使われない道具が積み上がる
  • (1) 境界を引く:
    • サンドボックスかクラウドエージェントで作業し、本番の認証情報は渡さない
  • (2) ルールを書く(AGENTS.md):
    • 最小限から始め、全行を実際の失敗や規約に対応させる
    • AIに草案を書かせ、人間が削る
  • (3) 柵を立てる:
    • lint・型・テストを check の「1コマンドの門」に束ね、人もAIも同じ門をくぐる
  • (4) ループを閉じる:
    • 検証器とゴール(check がすべて通る)を渡し、エージェント自身に回させる
  • (5) 繰り返しが見えたら道具を増やす:
    • 繰り返す手順はSkillsへ、観点はサブエージェントへ移す
  • (6) 運用で育て、定期的に棚卸しする:
    • 逸脱が出たら1行追記する
    • 数か月に一度は全削除し、要るものだけ戻す棚卸しを行い、Git管理で安全に試す
  • 境界を先に引き、ルールより先に道具を増やさない

■ 24. 4原則

  • 戻れない場所に道を作らない:
    • 本番・機密・個人情報・不可逆な操作には到達できないようにする
    • 隔離環境・通信遮断・最小権限で境界を先に引く
  • 進路はハーネスで示す:
    • 規約・コマンド・禁止事項を明文化し、逸脱が出るたびに1行足す
    • 書いたあとの運用が大事
  • 逸脱はガードレールで検知する:
    • lint・型・テスト・Hooksを「1コマンドの門」に束ね、人もAIも同じ門をくぐる
    • 判定は機械的に行う
  • ループを閉じて自走させる:
    • 検証器とゴールを渡せば、エージェントが自分で直して完走する
    • その分、任せられる範囲が広がる