📚 全体地図を見る
良いエージェントは、良いモデルより先に良いハーネスを持っている
0. シリーズの現在地 — 実務セクションMの4本目
AIのしくみ地図が F(Foundation) → B(Bridge) → M(Meta・実務) に流れる話、前にしましたよね。F の6編で LLM・Transformer・embedding・gradient descent のような土台感覚をつくり、B の3編でプロンプト・エージェント・RAG の選び方をつなぎました。M シリーズに入ってからは、M1 で retrieval の4階、M2 で long-context と memory、M3 で agent と LLM の境界線を扱いました。そしていよいよ M4 です。
M3 でつかんだ感覚がひとつありました。エージェントは LLM を1回呼び出すことではなく、LLM をシステムの中に組み込んだ構造 だということ。今回はその「システム」の中身を分解してみる編です。エージェントが乗っている 運用環境そのもの を部品単位まで解きほぐします。この運用環境を実務では ハーネス (harness) と呼びます。
この記事を読み終えたら、次の3つができるようになっているはずです。
- 「同じClaudeを使っているのに、なぜAさんはエージェントをうまく回せて、Bさんは毎回無駄な手間を使うのか」という問いに、部品単位で答えられる
- AGENTS.md・CLAUDE.md・skills・hooks・permissions・sandbox といった用語が、一枚の地図の上で読める
- 新しいプロジェクトを始めるときに、ハーネスのチェックリストをひと回りできる
始めます。
1. 同じClaudeなのに結果が違う — 原因はハーネス
現場でよく見る場面がひとつあります。A さんは Claude Code でバグを15分で直す。同じ会社のBさんが、同じClaudeの同じモデルバージョンで、似た複雑度のバグを2時間つかんだまま。答えが出ないので、B が隣の A に聞きます。「どうやったらこれができるの?」
A がプロンプトを見せます。なんてことのない内容です。「このファイルでこんなエラーが出る。直してくれ。」それだけ。なのに結果が違う。B はこの答えを聞きながら内心「なんか隠してるでしょ」と思っています。
隠してなんかいません。A が使っているのはプロンプトそのものではなく、プロンプトが乗っている土台まるごと です。
A のリポジトリには、しっかり整備された CLAUDE.md があって、エージェントはファイルを開いた瞬間から「このプロジェクトはTypeScript strictで、テストはvitestで、commit前にlintが走る」といったルールを全部知った状態で始まります。.claude/skills/ には「バグ調査ルーチン」という再利用可能な手順書が入っています。保存のたびに自動で走る pre-commit hook があり、Claude が危険なコマンドを投げられないように settings.json の permissions が細かく設定されています。テストの実行は sandbox の中で回るので、ミスしても外側が壊れない。セッションが長くなってコンテキストがあふれそうになると自動で compaction が走り、作業の終わりには「これ本当に終わったの?」を確認する検証ループがセットされています。
B にはそれが全部ありません。同じモデルなのに、運用環境がまったく別物 なんです。
これを一行でまとめるとこうなります。
同じモデルでも、どんなハーネスの上で回すかによって品質がまったく違う。
この感覚は、実務ではお金と時間でそのまま証明されます。エージェントが良いハーネスの上にいれば、同じ予算で作業量が2〜3倍になり、デバッグサイクルが短くなり、ミスの累積が減る。ハーネスがない、あるいは雑だと、良いモデルも実力を出せない。モデルのスペックシートだけを見て道具を選んで、この部分を見落とすと「YouTubeではうまくいくのに自分の手では動かない」というモヤモヤがずっと残ります。
2. ハーネスは「長いプロンプト」ではない — よくある誤解の整理
この言葉を初めて聞く方は、ハーネスを 長いプロンプトのかたまり のようなものと誤解しがちです。「system prompt をうまく書けばそれがハーネスでしょ」と。私も最初はそうでした。
でも、ハーネスはもっと広い概念です。比喩で始めます。
エージェントは、街を走り回るタクシー運転手だとイメージしてください。運転手が LLM、運転技術がモデルの能力です。でもこの運転手が実際に乗客をちゃんと運ぼうとすると、運転手だけが優秀でもダメ なんです。街には信号機がなければならず、道路が舗装されていなければならず、ナビがあって、車のブレーキがまともで、事故が起きたら救急車が来る仕組みがいる。乗客に「この運転手は特定のエリアに入れません」という区域制限もかかっていないといけない。
ハーネスはその街全体 です。運転手(モデル)だけが良くても、運転手が働く環境が丸ごと整っていないと、サービスは回りません。
もう少し技術的に言うと、ハーネスはこう定義できます。
ハーネス = LLM呼び出しを包む運用環境全体。ルール文書、ツール定義、権限境界、実行隔離、記憶管理、検証ループといった部品の総和。
「長いプロンプト」とどこで分かれるかというと、こう分かれます。
- プロンプト: LLMの1回の呼び出しに入れるテキスト。揮発性。セッションが終われば消える。
- ハーネス: セッションとセッションの間、プロジェクトとプロジェクトの間に 残り続けて エージェントの行動を一貫させる運用体系。耐久性あり。
Mitchell Hashimoto のような開発者が「AGENTS.md を書く」と言うとき、彼がやっているのはプロンプト作成ではありません。繰り返し出る指示を運用アーティファクトに昇格 させているんです。毎回口で言っていたものをファイルに落とし、そのファイルが全セッションに自動で適用されるようにしている。これがハーネスです。
だからハーネスは プロンプトエンジニアリングの延長 ではなく、システム設計の一分野 として見るのが正確です。コード品質を管理するやり方、インフラを構築するやり方、チームのルールを作るやり方と重なります。個人の天才性に頼らず、ブレにくい構造 を組む技術です。
この感覚があると、「良いハーネス = 良いOSのようなもの」という比喩が自然に入ってきます。OSがちゃんと組まれているとアプリが良く見えるのと同じように、ハーネスがちゃんと組まれているとエージェントが良く見えます。
3. ハーネスの8階層 — 地図をいったん広げる
階層をひとつずつ解く前に、全体の地図を広げておきます。暗記する必要はありません。この記事を読み終わる頃には手に馴染んでいます。
| 階 | 略名 | 役割 |
|---|---|---|
| 1 | System Prompt | エージェントの基本アイデンティティと禁止事項 |
| 2 | Rule Docs (AGENTS.md・CLAUDE.md) | プロジェクト別ルールブック |
| 3 | Skills | 再利用可能な作業手順の定義 |
| 4 | Hooks | イベントトリガー、pre/post edit、session start など |
| 5 | Permissions | どのツール・パスにアクセスできるか |
| 6 | Sandbox | 実行隔離、ネットワーク・ファイルシステム |
| 7 | Compaction | 長いセッションの圧縮戦略(M2 と連動) |
| 8 | Verification Loop | 完了前チェック(M5 と連動) |
上から下にいくほど、「教えてあげる装置」から「止めてくれる装置」、そして「確認してくれる装置」へ 性格が変わっていきます。1〜3階はエージェントに教える階、4〜6階はエージェントの行動を制御して止める階、7〜8階は全体動作を監視して締める階です。
ひとつずつ入っていきます。各階で「これは何か」「実際どこに入るか」「無いとどんな失敗が起きるか」をつないでいきます。
3-1. System Prompt — 「お前が誰か」を植え込む階
一番内側の階です。あらゆる LLM 呼び出しの先頭に入る固定テキスト。Claude Code なら「You are Claude Code, Anthropic’s official CLI for Claude」のような文から始まるあのかたまりが、まさにここです。
役割は3つです。
- アイデンティティ: 「お前は Claude Code だ」「お前はカスタマーサポートのエージェントだ」のように役割を打ち込む文。
- 基本禁止事項: 「ファイルを削除する前に必ず確認しろ」「個人情報を外部に送るな」のような絶対ルール。
- 出力スタイルのデフォルト: 「短く直接的な答えを基本にする」のようなトーン設定。
この階が大事なのは、プロジェクトごとの文書(AGENTS.md、CLAUDE.md)より優先順位が高く 働くからです。言い換えると、system prompt に埋め込まれたものは 変えられない床 です。プロジェクト文書でいくら別のことを言っても、system prompt で禁止された行動をエージェントはしません。
実務者の立場で見ると、system prompt はだいたいプラットフォーム側が管理しています。Claude Code の system prompt は Anthropic が書いて埋め込んでいます。我々が直接いじることはほとんどない。だからこそ、その床がどう作られているかを知っておくこと が大事です。「これは AGENTS.md で何をしても変わらない行動だ」という判断が立つようになります。
逆に API を直接叩いて自作エージェントを組むときは、system prompt 設計があなたの仕事です。このとき多い失敗は system prompt に詰め込みすぎる こと。「これはアイデンティティだ」という感覚が薄れてつい足していくと、3,000字の system prompt ができあがります。ところが長くなるほどモデルがその指示を無視し始めます。System prompt は 短く太く。細かいルールは次の階に押し込むのが原則です。
3-2. Rule Docs — AGENTS.md・CLAUDE.md というプロジェクト別ルールブック
2階はプロジェクトのルート直下に置くルール文書です。名前はプラットフォームごとに違います。
- Claude Code:
CLAUDE.md - OpenAI Codex 系:
AGENTS.md - Gemini コーディングエージェント:
GEMINI.md - Cursor:
.cursorrules
名前は違えど、やることは似ています。「このプロジェクトではエージェントはこう振る舞え」 を文書として置くんです。GitHub で 2,500 以上のリポジトリが AGENTS.md を使っており、関連設定ファイルを置いているプロジェクトは6万超。すでに業界標準に近い慣行です。
この文書の中にはだいたいこんなものが入ります。
- ビルド・テストコマンド: 「pnpm testでテスト」「vite build でビルド」
- コードスタイル: 「ESLint airbnb-base 準拠」「コメントはJSDocスタイル」
- 禁止行動: 「master に直接 push しない」「環境変数は編集しない」
- ドメイン知識: 「このアプリは医療レコードを扱う。ログにPIIを残すな」
- 完了の定義: 「テストpass + lint通過 + 型チェック通過の後にcommit」
毎回プロンプトに「うちのプロジェクトはTypeScript strictでvitestで…」をコピペするかわりに、一度 CLAUDE.md に書いておけば、それ以降の全セッションがこれを自動で読み取ります。これが durable guidance という概念です。Mitchell Hashimoto が AI ワークフローを説明するときに一番強く推してくる軸がこの階です。
この階の強さは 繰り返し発生するミスをルール昇格で塞いでいく ところから出てきます。エージェントが同じミスを続ける。「テストを走らせずに commit している。」そこで一度小言を言って終わりにするのではなく、CLAUDE.md に「commit の前に必ず pnpm test を走らせる」と一行追加する。その瞬間から、このミスは セッション記憶 ではなく プロジェクト記憶 になります。次のセッションでも、その次のセッションでも自動で効きます。
この階が弱いと、エージェントが毎回「初めてこのプロジェクトに来た人」のように振る舞います。そのたびに説明が要り、そのたびに同じミスが起きます。チームで使うリポジトリなら、この階をひとつ整えるだけでも生産性の差が大きく出ます。
3-3. Skills — 再利用可能な「作業レシピ」
Skill は Rule Docs のひと段階上にある概念です。Rule Docs が「町のルール」だとすると、Skill は 「その町で特定の作業をするときに使うレシピ集」 です。
例を挙げます。ブログ運営チームなら「記事公開前に SEO を13項目のチェックリストで確認する」という固定手順があります。これを毎回 Claude に「こんなことやって」と言うと、毎回ちがう結果が返ってきます。そこで publish-gate という skill として文書化し、~/.claude/skills/publish-gate/SKILL.md に入れておきます。すると「publish gate 回して」のひとことで、エージェントはその手順をそのとおりに実行します。
Skill はだいたい3つで構成されます。
- SKILL.md: この skill が何をするか、いつ使うか、入出力は何か
- 補助スクリプト: Python・Bash など実際に走る実行ファイル(任意)
- 参考文書: テンプレート、例、関連ルール
このパターンを Anthropic が Agent Skills という公式フレームワークにまとめつつあります。Skill は モデル独立 です。Claude が使う skill の構造が、他のエージェント環境にもほぼそのまま移植できます。作業手順を skill にしておけば、モデルが変わっても、エージェント環境が変わっても、その資産は残ります。
ここで微妙なポイントがひとつ。Skill と Rule Docs は 階層が違う という点です。
- Rule Docs: 「常にこのルールを守れ」(宣言的・背景で常時作動)
- Skill: 「この作業を頼まれたときはこの手順を呼べ」(手続き的・呼び出し時のみ作動)
両方とも必要です。Rule Docs だけだと、エージェントは「何を守るか」は分かっても「どうやるか」は毎回新しく考えないといけない。Skill だけだと、「特定の作業の手順」は分かっても 背景ルール が抜けて、細かいミスが積もっていきます。両方そろって初めてハーネスが硬くなります。
経験者が感じる自明でないポイントをひとつ。Skill を作りすぎると 発見コスト が上がります。エージェントが「今この作業にはどのスキルを呼ぶべきか」を判断することにコンテキストを使ってしまう。だから skill は「よく使う作業10〜30個」くらいに保つのが現実的です。100個積み上げて「自動で必要なやつを呼んでくれ」とやると、かえって品質が落ちるケースも多い。
3-4. Hooks — 動作の合間に差し込む検証・ログ装置
Hook はハーネスの中で 「自動反応回路」 を担当します。エージェントが何らかのイベントを起こしたとき、そのイベントを検知して自動で動く外部コード片です。
Claude Code を基準にした代表的なイベントはこんな感じです。
- PreToolUse: エージェントが何かのツールを使う直前。ここでツール実行を止めたり、警告を出したり、値を直したりできる。
- PostToolUse: ツール使用直後。結果をログに残したり、後続検証を走らせる。
- UserPromptSubmit: ユーザーがメッセージを送った直後。メッセージに応じてコンテキストを自動追加。
- SessionStart: セッション開始時。毎回最初に走る初期化スクリプト。
- Stop: エージェントが応答を終えたとき。結果要約、外部通知など。
例を挙げます。「ファイルを編集するたびに自動で lint を走らせたい」というニーズを hook 無しで解決しようとすると、毎回プロンプトに「編集後に lint」と書く必要があります。エージェントは覚えているときもあれば忘れるときもある。hook で解決すると、settings.json に PostToolUse を仕込んで、Edit ツールが走った直後に pnpm lint が自動で走るようにできます。エージェントの意志に依存せず、ハーネスが強制 します。
ここが決定的なポイントです。Hook は 「自動反応回路」であってエージェントの記憶ではない。エージェントが忘れても、ミスしても、指示を無視しても hook は動きます。だから「忘れるな、毎回〜しろ」のような要求は、多くの場合 memory で解決するのではなく hook に昇格させるのが正解です。
Mitchell Hashimoto が言う「プログラムされた検証ツール」がこの階です。同じミスが2回繰り返されたら、文言で小言を言うのではなく hook を新しく書いて エージェントが構造的にそのミスをできないようにする。その瞬間から、そのミスは消えます。
Hook がないハーネスは、結局 小言ベースのハーネス になります。動きはするけれど、ミスが毎回リセットされます。Hook があるハーネスは 自己強化 します。ミスが積もるほど hook が増え、ハーネスがだんだん硬くなる。
3-5. Permissions — 「これは OK、これは NG」
Permissions は、エージェントが使える ツールとパスのホワイトリスト・ブラックリスト です。Claude Code の settings.json の中にはこんなブロックが入ります。
{
"permissions": {
"allow": ["Bash(ls *)", "Bash(git status)"],
"deny": ["Bash(rm -rf *)", "Edit(.env)"]
}
}
この短いブロックひとつで、エージェントの行動範囲がものすごく変わります。普通に rm を走らせようとして止まれば、エージェントは 別の方法を探さないといけません。.env を編集しようとして止まれば、エージェントは 承認を求めるようになる。片っ端から実行するのではなく、交渉するエージェントになります。
Permissions の効果は3つの階で出ます。
- 安全: 復旧できないコマンド(
rm -rf、git push --forceなど) がエージェントの手から動かない。 - 境界: 「このパスの外には触るな」をエージェントに教える効果。
- コスト: API 呼び出しが高い外部サービスへのアクセスを制限して、コスト暴走を防ぐ。
エージェントが危険な行動をしようとするたびに permissions に引っかかって承認を求めるようになると、人が一回ずつ介入する ことになります。それがボトルネックに見えても、実は ミス防止 の役割を果たします。よくある失敗が「permissions は面倒だから全部 allow にしておく」で、その状態で大事故が一度起きると、それまで節約した時間が全部飛びます。
実務 Tips をひとつ。Permissions は 2段階 で設計するのが良いです。
- User グローバル設定 (
~/.claude/settings.json): 「ls、git status、pwd のような読み取り専用コマンドは常に許可」 - Project ローカル設定 (
.claude/settings.local.json): 「このプロジェクトでよく使うコマンドはここで追加許可、危険コマンドは deny」
こう分けると、プロジェクトごとに違う permissions がエージェントの行動を自動でチューニングしてくれます。共有リポジトリなら deny を厳しく、個人練習用なら allow を広く。
3-6. Sandbox — 実行まるごと囲っておく階
Permissions が「どのコマンドを使えるか」の階なら、Sandbox は 「使えるコマンドがどこで走るか」 の階です。
例えばエージェントがテストを走らせるとしましょう。そのテストがあなたの実ファイルシステム上で動きます。テスト中に誤ってファイルを消すコードがあったら、本物のファイルが消えます。ネットワーク呼び出しがあれば、本物の外部サービスにリクエストが飛んでいきます。
Sandbox はこの実行を 隔離された空間 に閉じ込めます。Docker コンテナ、VM、あるいはプロセスレベルの隔離のような技術が使われます。Sandbox の中でファイルが消えても外側は元のまま、ネットワーク呼び出しが出ていっても sandbox が途中で止めるか、仮想的に応答します。
Claude Code 自体はホスト OS 上で動いていますが、最近のバージョンでは Bash tool の中に dangerouslyDisableSandbox のようなフラグがあるくらい、sandbox 意識がはっきりしてきました。デフォルトは「ネットワーク・ファイルシステムに自動制限がある状態」で、明示的に外すときだけ外れる構造です。
Sandbox が実務でますます大事になる理由は、エージェントが実行できる作業の範囲が広がっているから です。昔はエージェントはテキストを作るだけでした。今はファイルを編集し、コマンドを走らせ、ウェブを巡回し、決済までさせようという試みまであります。この範囲が広がるほど、一回のミスの影響が大きくなります。Sandbox はその影響を ひとつの空間の中に閉じ込める保険 です。
Sandbox と permissions の関係はこう覚えてください。Permissions が 「このコマンドは使うな」 の塀なら、sandbox は 「万一塀を越えても隣の町には行けないように」 のフェンスです。塀だけあってフェンスがないと、塀を迂回するバグひとつでシステムが壊れます。フェンスだけあって塀がないと、フェンスの中でエージェントが好き放題します。両方そろって初めて安全になります。
3-7. Compaction — ハーネスの「記憶管理」戦略
M2 で long-context と memory を扱ったとき、ちょっと触れましたよね。コンテキストウィンドウが100万トークンあっても 無限ではなく、あふれると品質が落ちる 話。その問題をハーネス階で解く装置が compaction です。
Compaction は、長いセッションの中の対話履歴を 要約して上書きする 動作です。エージェントが一日中ひとつのセッションで作業すると、数十万トークンが積もります。その中には重要な決定もあれば、もう終わった作業の雑多なログもある。Compaction は古い雑談を一行要約にまとめ、決定事項だけを骨格として残します。この要約が次セッションの出発点になります。
実務者がここで見落としやすいポイントがあります。Compaction は「ただの要約」ではなく、ハーネスの方針 だという点。何を残して何を捨てるかを決めるルールが必要です。良い compaction 方針はこういうものを残します。
- ユーザーが明示的に下した決定(「この方式でいこう」)
- 作り終わった artifact のパス(ファイルパス、PR番号など)
- 重要な失敗事例(「このアプローチはダメだった」)
- 現在進行中のタスクの状態
捨てるのはこういうものです。
- すでに成功した中間段階の詳細ログ
- 重複する説明
- ユーザーが撤回した提案
Claude Code には /compact のような手動コマンドがあり、「strategic-compact」のような skill が 適切なタイミングで compaction を提案 する役割を担います。これがうまく回ると、ひとつのセッションが数日にわたっても、コンテキストが綺麗に維持されます。
この階がないハーネスは、セッションが長くなるほどエージェントが だんだんバカになっていきます。昔の話にコンテキストを使ってしまって、今の問題に集中できない。この階がちゃんと回るハーネスは、長いプロジェクトを通してエージェント品質が維持される。Long-context がいくら大きくなっても、compaction がないと長期セッションで品質低下が起きます。
3-8. Verification Loop — 「終わった」をどう判定するか
最後の階。M5 で本格的に扱うテーマですが、ここで要点だけ押さえておきます。
エージェントの一番さりげない失敗パターンが 「終わったと言っているのに実際は終わっていない状態」 です。テストが通ったと言っているのに実は走らせていない、バグを直したと言っているのに別のバグを作っている、とか。人が最終確認をしないと、これがそのまま通ってしまう。
Verification Loop は、この「終わった」を ハーネスが直接検証する 階です。エージェントの主張を信じず、実際の状態を確認する外部チェックで構成されます。
- Lint 通過: 静的に確認できるコード品質
- テスト通過: 実際に期待動作が合っているか
- 型チェック通過: コンパイラ・型システムが同意するか
- スクリーンショットチェック: 画面が意図通りに出ているか
- 人の承認: 自動検証では足りず、人が見るべき作業もある
これらのチェックは hook で回ることもあれば skill で回ることもあります。形はさまざまですが、共通点は エージェントの自己申告を検証する独立装置 という点です。
Verification loop がしっかり立っていれば、エージェントが「終わった」と言っても信用できます。Loop が弱いと、毎回人が最後を確認しないといけなくてボトルネックになる。逆に loop が厳しすぎるとエージェントが一歩も進めない。このバランスを取るのが verification 設計の技術です。
M5 でまるごと扱うので、ここでは「ハーネスの最後の階」という地図上の位置だけ押さえて進みます。
4. Claude Code の実ハーネス — .company/blog/CLAUDE.md がやっていること
理論だけで説明を続けると手に馴染みません。実際に私が回しているプロジェクトをひとつ開いて見せます。
shuntailor.net というブログを運営しながら、.company/blog/ というフォルダを Claude Code の「ブログ運営空間」として使っています。そのフォルダ直下に .company/blog/CLAUDE.md がある。このファイルが実質的にブログ運営エージェントのハーネスの大部分を担っています。
このファイルの中身を階層別に分けるとこうなります。
Rule Docs 階 (2階):
– 部署ミッション(「月収益 ¥120,000」「週3〜4本発行」のような目標)
– 記事文字数基準(4,000〜6,000字)
– Rank Math SEO 81点以上という合格基準
– CTA 配置ルール(ニュースレター登録ボックスを本文50〜60%地点に必ず挿入)
– 禁止CTAリスト(PDF販売、AdSense、バナー広告)
Skills 階 (3階):
– 「Publish Gate」という13項目チェックリスト。publish_gate.py という実行スクリプトに束ねられている。
– 「SEO自動修正」スクリプト。seo_auto_fixer.py を呼び出す skill。
– 「アイキャッチ生成」ルーチン。発行前必須。
Hooks 階 (4階):
– 記事発行直後に自動で wiki/published/ フォルダにアーカイブ保存
– 発行後に audit-log、daily-log、agent-activity の3箇所へ自動記録
– 発行後に memory/project_blog_articles.md を自動更新
Permissions 階 (5階):
– WordPress REST API 呼び出しは許可、ファイル削除は deny
– Playwright 使用時は特定パターン以外は事前承認
Verification 階 (8階):
– Publish Gate の13項目が全部 PASS しないと「発行完了」報告を禁止
– Gate 通過後も GSC 手動登録の案内まで終えてから本当の完了
このハーネスが無かった頃どうだったかというと、記事を一本発行するのに毎回「これ確認して、あれ抜かさないで」と全部言わないといけませんでした。抜けも多く、13項目中3〜4項目は毎回欠落。SEOスコアが75点で頭打ちになっていました。
ハーネスを立てたあとは、「今日はこのテーマで記事1本書いて」と言うだけで、エージェントが自分で13のゲートを全部回し、アーカイブを保存し、3箇所のログに記録し、スコアが出なければ自分で再生成します。同じClaudeなのに結果が違う の典型例です。
ここでひとつの洞察。このファイルは 一度に完成したものではありません。6ヶ月間、「エージェントがミスしたらルールを1つ追加、またミスしたら hook を1つ追加」を繰り返した結果物です。Mitchell Hashimoto が言う correction → rule extraction → enforcement のループが実際に回ったわけです。だからこのハーネスは今も進化し続けています。完成はありません。
5. Skills 構造 — 再利用可能な「作業レシピ」をもう一段ほどく
Skill をもう少し分解してみます。3-3 では概念だけを扱ったので、今度は実物の構造を開いてみます。
Claude Code の skill はだいたいこんなパスに置きます。
skillの説明
実行スクリプト
補助テンプレート
SKILL.md はこんな感じで始まります。
---
name: publish-gate
description: WordPress発行前に13項目のSEO/品質ゲートを走らせる
---
この skill をいつ使うか:
- 新しい記事を WordPress に発行する直前
- 発行後に再検証が必要なとき
どう使うか:
- 入力: JP_POST_ID, KO_POST_ID
- 実行: `python3 publish_gate.py --jp-id X --ko-id Y --auto-fix`
- 出力: ALL PASS または BLOCKED(未通過項目リスト)
これがファイルとしてあるだけで、エージェントは「この作業のときはこの skill を呼べばいいな」と判断できます。Description を読み、状況を照らし、実行する。人間側は「publish gate 回して」のひとことで終わりです。
Skill の価値は3つのポイントから出ます。
- 再利用: 同じ作業を何度頼んでも、毎回説明しなくていい。
- 標準化: 誰が頼んでも同じ結果。チームで使う場合は重要。
- 進化: ミスが積もったら skill 文書を直せばOK。エージェントの行動が自動で変わる。
ここで自明ではないポイントをひとつ。Skill は 暗記するものではなく探すもの です。エージェントがすべての skill を頭に入れている必要はありません。必要なときに検索して読みます。だから skill を設計するとき、description を検索できる文にするのが重要 です。「この skill は publish-gate です」ではなく「WordPress 発行前に SEO 13項目を検査する」と書くほうが、エージェントにマッチしやすい。SEO 用語で言えば「検索される文」です。
もうひとつ。Skill は 階層を持てます。大きい skill が小さい skill を呼ぶ構造。publish-gate が内部で seo-check、eyecatch-generate、auto-translate-ko のような小さな skill を呼ぶ。こう構成すると、小さい skill は単体でも、大きい skill の部品としても使える。再利用性が2層に増えます。
Anthropic の Agent Skills フレームワークはこのパターンを公式化したものです。今後、この形式で skill をやりとりするマーケットプレイスのようなものが生まれる可能性もあるし、他のエージェントプラットフォームへ移植する経路も整うはずです。今 skill をきちんと組んでおけば、それが モデル乗り換えコストを減らす資産 になります。
6. Hooks — エージェント動作の合間に差し込む検証・ログ
Hook の実際の設定を開いてみます。Claude Code の ~/.claude/settings.json にはこんなブロックが入ります。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [
{ "type": "command", "command": "pnpm lint --fix" }
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{ "type": "command", "command": "scripts/inject-context.sh" }
]
}
]
}
}
この2行の意味をほどくとこうです。
PostToolUse / Edit: Claude が Edit ツールでファイルを編集した直後に pnpm lint --fix が自動で走ります。Lint エラーがあれば自動修正され、失敗したチェックは次のターンで Claude に報告される。Claude が忘れていても lint は走る。結果として lint の通っていないコードは決して commit されない構造 になります。
UserPromptSubmit: ユーザーがメッセージを送った瞬間、inject-context.sh というスクリプトが先に走ります。例えばこのスクリプトは「今は2026年4月で、今日のTODOはこう」という現在状態をコンテキストに自動で差し込みます。毎回ユーザーが「今日の日付を教えて」と言う必要がなくなります。
Hook の本当の力は 繰り返すミスの構造的除去 です。エージェントが同じミスを2回以上したら、そのミスを止める hook を書くのが合理的な順序です。「気をつけろ、次はこうするな」のような小言はセッションが変わればリセットされますが、hook は設定ファイルに埋まっているのでリセットされません。
実務でよく使う hook パターンをいくつかまとめます。
- Edit 直後にテスト自動実行: 変更されたファイルに影響するテストだけを選んで走らせるとフィードバックが速くなる。
- Bash 実行直前に危険コマンド検査:
rm -rf、DROP TABLEのようなパターンがあれば自動でユーザー承認を要求。 - Session Start でコンテキスト注入: 今日のTODO、現在のブランチ、最後の commit のような状態を自動注入。
- Stop で作業要約を記録: エージェントがセッションを終えたときに、やった作業を audit-log に自動記録。
この4つだけセットしておいても、エージェントの体感品質がひと段階上がります。そして hook は 積めば積むほど良い という性質があります。Rule Docs は長くなりすぎるとエージェントが無視し始めますが、hook は100個積もっても各自が自分のタイミングでしか動かないので負担になりません。
自明ではないポイントをひとつ。Hook は 実行が速くないといけません。PostToolUse で lint が10秒かかると、エージェントの毎 tool 使用ごとに10秒追加されます。ユーザーの体感は「Claude が遅くなった」として現れ、「lint のせいだ」とは見えません。だから hook の中で走るスクリプトは短く、長時間かかるものは非同期・バックグラウンドに分離するのが原則です。
7. Permissions と Sandbox — 安全の2階を一緒に見る
戻って、permissions と sandbox を一緒に見ます。両者の関係が最初はあいまいな方が多いので、実例でほどきます。
場面1: 読み取り専用コマンド
エージェントが ls src/ を走らせたい。Permissions に "allow": ["Bash(ls *)"] がある。通過。コマンドが実行される。Sandbox の中で回ろうが外で回ろうが、大きな差はありません。読むだけだから。
場面2: ファイル編集
エージェントが src/app.ts を修正しようとする。Permissions でこのパス編集は許可されている。ところがエージェントが誤って同じ tool 呼び出しの中で rm src/other.ts のような副作用を引き起こしたと想像してみます。Sandbox はこれを 実ファイルシステムではなく作業用コピー 上で回します。ミスが外のファイルに反映されない。最終変更だけが commit や PR として外に流れます。人が確認したあとに。
場面3: ネットワーク呼び出し
エージェントが外部 API を呼ぶ。Permissions には「特定ドメインのみ許可」が入っている。それ以外は deny。Sandbox はこれをネットワークレベルでも強制します。エージェントがどんな裏技を使っても、sandbox の外にパケットが出ない。2階の防御 が重なっている状態。
場面4: 危険コマンド
エージェントが rm -rf / を走らせようとする。Permissions の deny に引っかかって即ブロック。ここで終わりではありません。もし何らかのバグや jailbreak でこの deny を回避したとしても、sandbox の中なら本物の / は飛ばない。Sandbox 内の偽物の / だけが飛ぶ。再起動すれば回復します。
この4場面を見ると、permissions と sandbox は機能が重ならない という感覚がつかめるはずです。Permissions は 意図をフィルターし、sandbox は 影響を隔離する。両者が揃って初めて本当に安全になります。
実務ガイドをひとつ。Permissions の許可パターンを組むときは、「よく使うが安全なコマンド」を先に allow に入れ、残りはデフォルトの deny に置くのがいい。そうすると初めて使うコマンドごとに一度ずつ承認リクエストが上がり、使用パターンが時間とともに自然に把握できます。「とりあえず全部許可」は最初は楽ですが、後で必ず事故が起きます。
8. Compaction — ハーネスの「記憶管理」戦略
M2 でちょっと触れましたが、ハーネス階でもう一度整理します。
エージェントのセッションが長くなるほど、コンテキストに積まれる情報は 時間逆転構造 になります。つまり 古いものが前、新しいものが後ろ に来る。ところがモデルは普通 新しいものを強く見る 性質があります。だからセッションが長くなるとこんな問題が起きます。
- 序盤に下した重要な決定が埋もれる。「絶対にXをしないと合意した」のような合意が3,000ターン前にあると、エージェントはそれを忘れてXを再提案してくる。
- 余計なディテールが混ざり続ける。もう終わった中間段階のログがコンテキスト空間を食う。
- コストが線形に増える。ターンごとに全累積履歴が再びプロンプトに入る。
Compaction はこの3問題を一度に解きます。方式は「古い区間を要約で上書きする」です。要約は短いが 重要な決定は抜けないように 保たれる。空いた空間は最近の作業に割り当てられる。
Compaction ポリシーの設計でやっかいなポイントがあります。何を残し、何を捨てるかの基準 です。単純に「古いものは要約」にしてしまうと、重要な初期決定が飛んでしまう。良いハーネスはこんなポリシーを明示します。
- ユーザーが明示的に言った要件は原文維持
- エージェントが作った artifact のパス・バージョン情報は原文維持
- 過去の失敗事例は要約して維持(「このアプローチはXが理由でダメだった」)
- 途中の細々したログは削除可
Claude Code には /compact コマンドがあり、strategic-compact のような skill がこのタイミングとポリシーを提案してくれます。Hook と組み合わせれば、セッションが特定トークン数を超えると自動で compact 提案が出る構造を作れます。
ここで M2 と M4 がつながります。M2 で「long-context が大きくなっても memory adaptation が必要な理由」を話しましたよね。その memory adaptation がハーネス階で具体化される装置のひとつが compaction です。コンテキストウィンドウが100万トークンあっても、compaction なしでは実際の長期プロジェクトでエージェントの品質が維持できません。
9. Verification Loop — ハーネスが「終わった」をどう判定するか
M5 で本格的に扱いますが、ハーネス地図上の位置を先に押さえます。
エージェント作業でもっともさりげない失敗モード3つ。
- 虚偽の完了報告: 「全部やりました」と言ったけど実際は走らせていない状態。
- 部分完了: 主な作業はしたけど、付随作業(テスト更新、ドキュメント更新)をやっていない状態。
- デグレを起こす: 新機能を入れたけど旧機能を壊した状態。
この3つとも 人が最後に確認しないとそのまま通過します。エージェントが自分の口で「問題ない」と言うのをそのまま信じた瞬間、これらの失敗が積もります。
Verification Loop はハーネス階でこの失敗を止める装置です。構成はだいたいこうです。
- 静的チェック: lint、型チェック、フォーマッター。速くて客観的。
- 単体テスト: 小さく、自動で、CI でも走る水準。
- 結合テスト: 実際の workflow が回るか確認。遅いが重要。
- スクリーンショット検証: UI 作業は視覚比較。Mitchell が言う「プログラムされた検証ツール」の代表例。
- 人ゲート: 自動検証では足りず、人の承認が必要な作業もある。
良い verification loop は 複数の階が重なっています。ひとつが見落としても、別のひとつが拾う。悪い loop は 一階にだけ依存 します。テストは走るが lint がない、だと品質が微妙に削れる。スクリーンショットだけ見ると、ロジックのバグが通ってしまう。
Verification 設計の核心の問いがひとつ。「この作業が終わった」をどう定義するか です。これがはっきりしないと、エージェントがいくらがんばっても評価自体がブレます。Rule Docs の「完了定義」とつながります。CLAUDE.md に「完了 = テスト pass + lint 通過 + 型通過 + スクリーンショットが期待値と一致」と打ち込まれていて、それを実際にチェックする verification loop が hook と skill で作られていれば、エージェントはその条件を満たすまで「終わった」と言えなくなります。
詳細は M5 で。ここではハーネスの 最後の階 という地図上の位置と、前の7階を全部貫く役割 を持つということだけ覚えて進みます。
10. なぜ良いハーネスが良いモデルより重要な場面が多いのか
この記事の核の主張に戻ります。同じモデルでもハーネスによって品質がまるで違う。なぜそうなるかをメカニズムでもう一度整理します。
1. モデル能力は毎回変動する。同じモデルでもプロンプトが変われば結果が変わる。同じプロンプトでも温度で変わる。ハーネスが弱いと、この変動性がそのまま作業品質の変動性として現れる。ハーネスが強いと変動性がハーネスの中で吸収される。テストが毎回走るから、モデルがぶれても最終出力は一定品質以上になる。
2. ミスは累積する。ハーネスがないと同じミスが毎回繰り返される。ハーネスがあるとミスがルール昇格を通して構造的に消えていく。時間がたつほど差が開く。1ヶ月たてば、同じモデルでハーネスがあるチームは2〜3倍の生産性になるのが珍しくない。
3. モデル乗り換えが楽になる。ハーネスがモデル独立なら、より良いモデルが出たときにすぐ乗り換えられます。プロンプトエンジニアリングに頼ってきたチームはモデルが変わるとプロンプトを全部書き直さないといけない。ハーネスベースのチームは同じ AGENTS.md・skills・hooks をそのまま使ってモデルだけ変える。
4. 人の役割が変わる。ハーネスのないチームでは、人が毎作業を監督する必要がある。ハーネスのあるチームでは、人が ハーネスを改善する役割 を持つ。はるかにレバレッジが大きい仕事です。1つの hook 改善が数百回のエージェント実行に影響する。
5. 品質の下限が上がる。良いモデルの最大能力より大事なのは 最悪のケースでも一定以上を保証すること です。ハーネスはその下限を上げる装置。「たまに天才、たまに散々」から「毎回80点以上」に変えてくれる。
この5点が合わさると、ハーネスがモデル選択より大きなレバレッジを持つという感覚が自然になってきます。経営者の立場で「うちのチームに Claude を入れるか GPT を入れるか」より先に問うべきなのが 「うちのチームのハーネスの状態はどうなっているか」 だ、ということです。
ただしひとつ重要な但し書き。ハーネスはモデル能力の差を 完全には置き換えません。同じハーネスに Claude Opus と GPT-3.5 を乗せても結果はやはり違う。モデルがある水準以上でないとハーネスは意味を持ちません。土台モデルがどれほど低くてもハーネスで何とかなる、というわけではない。ハーネスは モデルの代わり ではなく、モデルの持つ能力が実作業で無駄にならないようにする構造 です。
毎週月曜日、AIトレンドニュースレター配信中
会員登録すると、毎週月曜日に「今週のAI・バイブコーディング最新情報」をお届けします。
バナー広告なし・本当に役立つ情報だけを厳選するクリーンなAI専門メディアです。
11. ハーネス設計のよくある失敗7つ
実務で私がもっともよく見る失敗をまとめます。このリストは「ハーネスチェックリスト」としても使えます。
1. System prompt に全部入れようとする失敗。System prompt が5,000字を超えると、モデルは内部指示を無視し始めます。Prompt lost in the middle 現象が system prompt の中でも起きる。必須のアイデンティティと禁止事項だけを残し、細かいルールは Rule Docs 階に押し込まないといけない。
2. Rule Docs が長すぎる失敗。CLAUDE.md が2万字に膨らむと、エージェントが読むコストが大きくなりすぎる。テーマごとに分けるのが正解です。ルートに簡潔な CLAUDE.md があって、下位フォルダごとに詳細 CLAUDE.md がある構造。エージェントは自分が作業するフォルダの文書だけを読みます。
3. Skill を作りすぎる失敗。30を超えるとエージェントが「今どの skill を使うべきか」の判断にコンテキストを食ってしまう。よく使う10〜20に保ち、残りは on-demand で構成するほうがいい。
4. Hook なしで小言で止めようとする失敗。同じミスが2回繰り返されたら、無条件で hook に昇格するべきです。「次は気をつけろ」はセッションが変わればリセットされる。Hook はリセットされない。この切り替えがハーネスエンジニアリングの核心です。
5. Permissions を全部 allow にする失敗。楽したくて "allow": ["*"] にすると最初は速いけど、一度事故が起きると復旧に数日かかる。デフォルトは deny、よく使う安全コマンドだけ allow、が合理的なスタート地点。
6. Sandbox なしでホストで直接回す失敗。簡単なスクリプトなら問題ないけれど、ネットワーク呼び出しやファイルシステム操作が入る作業は sandbox の中で回すのが基本です。Docker Dev Container や別ユーザーアカウントのような安価な隔離手段も多い。使わないのは、保険料をケチって事故を起こすのと同じです。
7. Verification loop が抜けている失敗。Hook・skill・rule が揃っていても、「終わった」を検証する装置がないと、エージェントの自己申告をそのまま信じないといけない。これが積もるとじわじわ品質が落ちる。Lint + テストくらいを走らせるだけでも検証構造ができる。Before は人が毎回確認、after は自動検証が先に回って人は最後だけ見る構造。この切り替えが長期品質維持の核心です。
この7つを順に点検すれば、現在のハーネスの弱い部分が見えてきます。一度に全部直そうとしないで、一番痛いところから少しずつ直していくのが現実的です。Hook ひとつ、rule 一行で数日後の体感品質が変わる体験をすると、ハーネスエンジニアリングがなぜデザインシステムのような分野なのか、感覚でつかめます。
12. Meta-Harness 予告 — ハーネス自体を最適化対象に
最後にひと歩先の話。ハーネス自体をエージェントに改善させるパターン が最近浮上しています。これを meta-harness と呼びます。
基本ハーネスは人が手で組みます。Rule Docs を書き、skill を作り、hook を設定する。時間がたって、ミスが積もってきたら人がルールを追加する。この過程そのものが手作業です。
Meta-harness はこれをもう一段階引き上げる。エージェントが自分のセッションを振り返って「同じミスが3回繰り返された、これを止めるルールを追加しよう」を 自分で提案します。人は提案を承認するだけ。これがうまく回ると、ハーネスが 自己進化 します。
Mathbullet チャンネルがこのテーマをまとめた動画を最近出しました。タイトルがそのまま Meta-Harness。Correction を記録し、パターンを抽出し、ルールに昇格し、次のセッションに自動適用するループの作り方です。Continuous learning 系の skill がこの方向を指しています。
ただし注意点を一つ。Meta-harness は 基本ハーネスが硬いときにだけ意味を持ちます。基本が雑な状態で自動化すると、雑さが自動で拡散します。だから順序が大事です。
- まず手で硬い基本ハーネスを立てる(Rule Docs + Skills + Hooks + Permissions + Verification)
- そのハーネスが3〜6ヶ月、実戦の中で安定するまで動かす
- その上に meta-harness を載せて追加改善をエージェントに任せる
この順序を飛ばすと、meta-harness が誤作動を自動強化する災害になります。「良い道具を遅く使うほうがいい」という原則が meta-harness には特によく当てはまります。
この主題は後続の編で本格的に扱います。AIのしくみ地図シリーズの終盤で改めて地図に位置を描きます。
締めの一文
ハーネスは長いプロンプトではなく、エージェントが乗る OS 級の作業環境であり、System Prompt・Rule Docs・Skills・Hooks・Permissions・Sandbox・Compaction・Verification の8階で動く。同じモデルでも、この8階が硬いハーネスの上ではずっとブレが少なくなる。良いエージェントは、良いモデルより先に良いハーネスを持っている。
FAQ
Q1. ハーネスとプロンプトエンジニアリングは違うものですか?
違います。プロンプトエンジニアリングは 1回のLLM呼び出し に入れるテキストを設計する技術です。ハーネスは その呼び出しを包む運用環境全体 を設計する技術です。プロンプトエンジニアリングは揮発性でセッションが終われば消えますが、ハーネスは耐久性があって、セッション・プロジェクト・モデルが変わっても残ります。良いプロンプトエンジニアリングが悪いハーネスをカバーしてくれることはありますが、良いハーネスは平凡なプロンプトを継続的にそこそこの結果に変えてくれます。実務的なレバレッジはハーネス側のほうがはるかに大きい。
Q2. ハーネスの8階を全部揃えないとエージェントを始められませんか?
そんなことはありません。最初から8階全部を立てようとするとハードルが高すぎて始められない。実務の順序はだいたいこうです。まず Rule Docs を1枚(CLAUDE.md)書くところから始める。次に一番よく使う作業を1〜2個 skill に まとめる。ミスが積もり始めたら、その中で繰り返すものだけを hook に 昇格させる。危険な作業が見え始めたら permissions を細かくする。そのあとに sandbox・compaction・verification の順で足していく。1ヶ月に1階ずつ足すイメージで大丈夫。完成したハーネスを目標にしないで、進化し続けるハーネス を目標にすればいい。
Q3. 1人で使う小さなプロジェクトにもハーネスは要りますか?
要ります。ただし規模に合わせて。1人プロジェクトなら CLAUDE.md 30行 + skill 3〜4個 + permissions 1枚 + テストhook 1〜2個で十分です。これだけで「毎回小言を言う状態」から「ひとこと言えば事が回る状態」に移れます。1人でもこの切り替えの体感差は大きい。エージェントを使う人が 自分自身に対して繰り返し説明しなくてよくなる ことが、生産性の最初のジャンプです。大組織の複雑なハーネスを真似する必要はないけれど、もっとも小さな形のハーネスは1人プロジェクトでも明確に意味があります。
- ◀ 前の編: M3. AgentがLLMと分かれる瞬間
- 今の編: M4. ハーネス理解 — エージェントの作業環境 (14/20)
- ▶ 次の編: M5. Evaluation、『終わった』をどう判定するか
ニュースレターのご案内
こうしてひとつの概念を最後まで解きほぐしていく記事を、毎週月曜日の朝にメールでお届けしています。受け取ってみたい方は ニュースレター登録(無料・30秒) からどうぞ。
ソース
- Anthropic. “Claude Code documentation” — 公式 harness/skills/hooks 資料 (docs.claude.com)
- “Agent Skills” announcement, Anthropic blog
- Mitchell Hashimoto, “My AI coding workflow” — AGENTS.md・durable guidance の文脈
- OpenAI, “AGENTS.md” spec (openai.com)
- Claude Code
settings.jsonpermissions / hooks reference
著者: バイブコーディング テイラー(Lovable公式アンバサダー)
運営: テイラーの隠れ家(shuntailor.net)
Harness = 作業環境の位置にある編です。前後編のリンクは記事下部のマップ上の現在地ボックスで確認してください。
同じClaudeを使っても品質がバラバラな本当の原因。ハーネスをsystem prompt·rule docs·hooks·sandbox·compactionの8層に解剖。
ソースリスト
- テイラー知識百科事典 — AIのしくみ地図カテゴリ(本シリーズ20編全編)
- AIのしくみ地図 エントリーマップ — 全体構造 + 3つの読み方
- “Attention Is All You Need” (Vaswani et al., 2017)
- Anthropic · OpenAI · Google 公式ドキュメント
- mathbullet (YouTube) / Jay Alammar “Illustrated Transformer” / 3Blue1Brown — 易しい解説のリファレンス
著者: バイブコーディング テイラー (VibeCoding Tailor) — Lovable公式アンバサダー. AI·バイブコーディング専門メディアshuntailor.net運営.
本シリーズ「AIのしくみ地図」20編は、ウィキの蓄積と公式論文・公式ドキュメントを根拠に整理した体系的学習カリキュラムです。




