- はじめに ── 「指示したのに、毎回違うことをする」問題
- 前提知識 ── 3分で分かるハーネスの考え方
- 全体像 ── 「伝える」「検証する」「回す」の3層
- 留意点0 ── 作り始める前に「素の状態」を観察する
- 留意点1 ── ルールファイルは「薄く・検証可能に・育てる」
- 留意点2 ── ガードレールは「1コマンドの門」に束ねる
- 留意点3 ── ループを閉じる(自走の完成形)
- 留意点4 ── SkillsとサブエージェントはルールAfter
- 留意点5 ── 行動への柵とセキュリティ(任せるほど防具になる)
- 留意点6 ── ハーネスは育てるもの、そして捨てるもの
- よくある失敗と対処
- 最初の1時間でやること ── 導入チェックリスト
- まとめ
- 参考リソース
はじめに ── 「指示したのに、毎回違うことをする」問題
Claude CodeやCodex、Cursorのようなコーディングエージェントを使い始めると、ほぼ全員が同じ壁にぶつかります。
- 同じ依頼をしたのに、昨日と今日で書かれるコードが違う
- 「テストを書いて」と言ったのに、テストをスキップして「完了しました」と報告してくる
- 触ってほしくない設定ファイルを勝手に書き換える
- 一度注意したミスを、次のセッションでまた繰り返す
多くの人は、ここで「プロンプトをもっと丁寧に書く」方向に努力を向けます。しかし、プロンプトを長くしても根本的には解決しません。生成AIは確率で動くため、どれだけ丁寧に指示しても「たまに変な一手を打つ」ことはありうるからです。
この問題に対して、2026年に入って急速に語られるようになった考え方がハーネスエンジニアリング(Harness Engineering)です。ひとことで言えば「モデルを賢くするのではなく、モデルの外側の環境を作り込んで、失敗しても自分で気づいて自分で直せるようにする」という発想です。
この記事では、概念の解説は最小限にとどめ、「実際に作るときに何に気をつけるべきか」に絞って、手順・具体例・よくある失敗をまとめます。
想定読者
- コーディングエージェントを個人または小規模チームで使い始めて1〜3か月程度の方
AGENTS.mdやCLAUDE.mdを「とりあえず書いてみた」が、効いているのか分からない方- ハーネス・ガードレール・フックといった言葉は聞いたことがあるが、どこから手をつければよいか迷っている方
この記事で扱うこと・扱わないこと
扱うのは、ルールファイル・検証コマンド・フィードバックループ・Skills・サブエージェント・行動制限フックの「作り方と注意点」です。特定ツールの設定画面の操作方法や、エージェントフレームワークの内部実装(LangChainやPydanticのハーネス層など)には踏み込みません。
前提知識 ── 3分で分かるハーネスの考え方
モデル以外は全部ハーネス
まず用語を最低限だけ押さえます。
エージェント = モデル + ハーネスという整理が、2026年前半の定義論争を経て概ね共通理解になっています。モデル(LLM)は「考える」担当で、それ以外のすべて、つまりルールファイル・ツール・検証コマンド・フック・再試行の仕組みなどをまとめてハーネスと呼びます。
歴史的には、2022年頃の「プロンプトエンジニアリング(単発の指示を磨く)」、2024年頃の「コンテキストエンジニアリング(RAGやマルチターンで渡す情報を設計する)」に続く第三の層として位置づけられています。2026年2月にMitchell Hashimoto氏が「失敗したら、二度と起きないように環境側を工学せよ」という趣旨で命名し、直後にOpenAIが「3人のエンジニアで100万行・95%がAI生成」という実践を公表したことで一気に広まりました。
なぜ必要なのか ── 揺らぎは仕様
生成AIは1トークンずつ確率分布からサンプリングして文章を生成します。「テストを__」の次に来る語として「受ける」が最も高い確率だとしても、「スキップする」がゼロになることはありません。この小さな揺らぎが数千トークン積み重なると、実行のたびに経路が変わります。
従来のプログラムは「同じ入力 → 同じ出力」でしたが、生成AIは「同じ入力 → 分布からのサンプル」です。だからこそ、指示して祈るのではなく、逸脱を機械で検知して直させる環境が必要になります。これがハーネス設計の出発点です。
全体像 ── 「伝える」「検証する」「回す」の3層
実際に作るものを、役割で3つに分けて整理します。
| 層 | 比喩 | 役割 | タイミング | 性質 | 具体的な道具 |
|---|---|---|---|---|---|
| ハーネス | 馬具(手綱) | どう走ってほしいかを伝える | 走る前 | 人間が決める主観の層 | ルールファイル、プラン合意、Skills、サブエージェント |
| ガードレール | 柵 | 道を外れていないか検証する | 走った後 | 機械が判定する客観の層 | フォーマッター、リンター、型チェック、ビルド、テスト |
| フィードバックループ | 周回 | 失敗を次の入力にして通るまで直させる | 走った後〜再実行 | 仕組み | 完了条件の定義、フック、CI |
さらに、ガードレールには「成果物への柵(書いたものを検証する)」と「行動への柵(危険な実行を事前に止める)」の2種類があります。後者はセキュリティの話として後半で扱います。
ここで重要な原則をひとつ覚えてください。
ハーネスは主観、ガードレールは客観。機械的な判定が強いほど、エージェントに任せられる範囲が広がる。
「きれいなコードを書いてください」というルールは主観なので効きが弱く、「make check が緑になること」という完了条件は客観なので強く効きます。作るときの判断に迷ったら、常に「これは機械がYes/Noを返せるか」を自問するのがコツです。
留意点0 ── 作り始める前に「素の状態」を観察する
最初に伝えたい、そして最も守られない留意点がこれです。
ルールを書く前に、ハーネスなしで一度走らせて、逸脱を記録してください。
多くの人は、ネットで見つけた立派な AGENTS.md のテンプレートをコピーして始めます。しかしそれは、他人のプロジェクトで起きた失敗への対策です。自分のプロジェクトで起きる失敗は、走らせてみないと分かりません。
逸脱ログの取り方
観察といっても大げさなものではありません。以下のような簡単なメモを、最初の数タスク分だけ残します。
## 逸脱ログ(ハーネス導入前)
| 日付 | タスク | 起きた逸脱 | 原因の推測 | 対策の種類 |
|---|---|---|---|---|
| 08/25 | ユーザー一覧APIの追加 | テストを書かずに完了報告 | 完了条件が曖昧 | ルール+完了条件 |
| 08/25 | 同上 | snake_case と camelCase が混在 | 命名規約が伝わっていない | ルール(検証可能な表現で) |
| 08/26 | 依存ライブラリ更新 | requirements.txt を直接編集した | uv 管理だと知らない | ルール(コマンド明記) |
| 08/26 | バグ修正 | 関係ない設定ファイルも書き換えた | 触ってはいけない場所が未定義 | ルール(禁止事項)+行動への柵 |
「対策の種類」の列がポイントです。ここで「ルールで直すもの」と「機械の柵で止めるもの」を分けておくと、次のステップで書くルールが自然と「全行が実際の失敗に対応している」状態になります。
留意点1 ── ルールファイルは「薄く・検証可能に・育てる」
ハーネスの第一歩は、毎回のセッションに自動で読み込まれるルールファイルです。ツールによって名前が違うので、まず対応表を示します。
| ツール | ルールファイルの名前(代表例) |
|---|---|
| Claude Code | CLAUDE.md |
| Codex | AGENTS.md |
| Cursor | .cursor/rules/ 配下のファイル(旧 .cursorrules) |
| GitHub Copilot | .github/copilot-instructions.md |
複数ツールを併用する現場では、AGENTS.md を正本にして他をシンボリックリンクにする運用がよく見られます。名前の統一は2026年時点でも完全には解決しておらず、Agent Plugins 1.0でもルールファイルは可搬対象に含まれていません。ここは「そういうものだ」と割り切ってください。
ルールは「家賃」がかかる
ルールファイルの最大の注意点は、書いた分だけコンテキストを消費することです。1行ごとに家賃がかかると考えてください。書きすぎると、肝心の1行が長文の中に埋もれて効かなくなります。
そのため、何を書き、何を書かないかの取捨選択そのものが設計になります。
| 書くべきこと | 書いてはいけないこと |
|---|---|
| プロジェクトの目的を1段落で | 言語の一般的な作法(モデルはすでに知っている) |
| ビルド・テスト・lintのコマンド | コードを読めば分かること(二重管理になり、すぐ嘘になる) |
| プロジェクト固有の命名・ディレクトリ・エラー処理の流儀 | 長大な設計書の貼り付け(Skillsや参照リンクへ逃がす) |
| 触ってはいけないファイル・変更禁止のAPI | 「きれいに書く」のような検証不能な精神論 |
目安は最初は50行程度です。足りない分は、運用の中で「逸脱が出たら1行足す」方式で育てます。
効くルールの書き方 4原則
同じ内容でも、書き方で効き方が変わります。
- 簡潔に、構造的に書く。見出しと箇条書きで短く。物語調の長文は避けます。
- 検証可能な表現にする。「関数は読みやすく」ではなく「関数は50行以内」。機械判定に落とせる表現ほど強く効きます。
- 良い例を1つ添える。規約を文章で説明するより、
src/の模範ファイルを1つ指し示すほうが速く伝わります。 - 失敗から育てる。最初から完璧を狙わず、逸脱が起きるたびに1行追記します。
実例 ── Python(FastAPI)プロジェクトのルールファイル
先ほどの逸脱ログから起こした、最小構成の例です。元資料はTypeScript/npm構成なので、ここではあえてPython/uv構成にしています。
# AGENTS.md
## このプロジェクトについて
社内の在庫照会APIです。FastAPI + SQLAlchemy + PostgreSQL。
外部システムからは読み取り専用で呼ばれるため、既存エンドポイントの
レスポンス形式を変える変更は禁止です。
## コマンド(必ずこれを使う)
- 依存追加: `uv add <package>`(requirements.txt を直接編集しない)
- 検証: `make check`(format / lint / 型 / テストをまとめて実行)
- 開発サーバ: `make dev`
## 完了条件
- `make check` がエラーなしで通ること。通るまで修正を繰り返すこと。
- 新しいエンドポイントには必ず `tests/api/` にテストを追加すること。
## 規約
- 命名は snake_case。Pydantic モデルのクラス名のみ PascalCase。
- エラーは `app/errors.py` の例外クラスを使う。素の HTTPException は投げない。
- 模範例: `app/routers/health.py` と `tests/api/test_health.py`
## 触ってはいけないもの
- `alembic/versions/` 配下の既存マイグレーションファイル
- `.env`、`infra/` 配下(インフラ担当が管理)
- `app/schemas/legacy_*.py`(外部連携の契約。変更は人間の承認が必要)
この例が30行弱です。「コマンド」と「完了条件」の節があることで、エージェントは自分で検証して自分で直せるようになります。後述する「1コマンドの門」とセットで機能します。
下書きはAIに書かせてよい
ゼロから書くのが大変なら、「このリポジトリを分析して AGENTS.md の草案を書いて」とエージェント自身に依頼するのが最速です。ただし、AIが書いた草案はたいてい長すぎ、一般論が混ざります。人間の仕事は「削って締める」ことです。逸脱ログに対応しない行は思い切って消してください。
留意点2 ── ガードレールは「1コマンドの門」に束ねる
ルールで「どう走ってほしいか」を伝えたら、次は「道を外れていないか」を機械に判定させる柵を立てます。
柵には階層がある
検証の深さで並べると、右に行くほど判定が強くなります。
| 段階 | 道具の例 | 何を検証するか | 判定の強さ |
|---|---|---|---|
| フォーマッタ | ruff format / Prettier / gofmt | 表記の統一(議論の余地なく自動修正) | 弱 |
| リンター | ruff check / ESLint / Clippy | 作法違反とバグの芽 | ↓ |
| 型チェック | mypy / pyright / tsc | データの流れの矛盾 | ↓ |
| ビルド | 各言語のビルド | 成果物として成立するか | ↓ |
| テスト | pytest / vitest / go test | 仕様どおり動くか | 強 |
最重要の留意点 ── 「配線」を確認する
初心者が最もつまずくのがここです。エディタに出ている赤線や警告は、エージェントには見えていません。
赤線は言語サーバやエディタ拡張の仕事であり、エージェントの世界には存在しません。柵として機能するのは、エージェント自身がコマンドとして実行し、その出力を読める仕組みだけです。「lintを入れているのにエージェントが無視する」という相談の多くは、lintがコマンドとして呼べる形になっていないか、ルールファイルにそのコマンドが書かれていないことが原因です。
確認方法は簡単で、ターミナルで自分が実行して結果が出るコマンドになっているか、そしてそのコマンドがルールファイルに書いてあるか、の2点です。
1コマンドの門を作る
複数の柵をバラバラに走らせると、「lintは通したがテストは忘れた」という抜けが起きます。そこで、すべての柵を1つのコマンドに束ねます。Python構成なら Makefile が分かりやすいです。
# Makefile
# プロジェクトルートで実行する前提
.PHONY: format lint types test check dev
format:
uv run ruff format --check .
lint:
uv run ruff check .
types:
uv run mypy app/
test:
uv run pytest -q
# 人間もAIも、この1つの門をくぐる
check: format lint types test
dev:
uv run uvicorn app.main:app --reload
Node.js構成なら package.json の scripts に同じ発想で check を定義します。
{
"scripts": {
"format": "prettier --check .",
"lint": "eslint src/",
"types": "tsc --noEmit",
"test": "vitest run",
"check": "npm run format && npm run lint && npm run types && npm run test"
}
}
門を1つにすることで得られる効果は3つあります。
- 「私の環境では動く」がなくなり、判定基準が一本化されます。
- ルールファイルの完了条件に「
make checkが通ること」と書けるので、タスク完了の定義から曖昧さが消えます。 - CIにも同じ門を置けば、手元をすり抜けてもpush後に必ず捕まります(二重の柵)。
CI側の例を示します。
# .github/workflows/check.yml
name: check
on: [push, pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
- run: uv sync
- run: make check # 手元と同じ門をくぐらせる
既存プロジェクトでは段階導入する
動いているプロジェクトにいきなり全ルールを厳格に適用すると、既存コードで大量のエラーが出て、エージェントがそれを直すことにトークンを浪費し始めます。通せる柵から順に立てるのが鉄則です。
- フォーマッタ(自動修正なので導入コストがほぼゼロ)
- リンター(最初は警告扱いにし、徐々にエラーへ)
- 型チェック(最初は
app/の一部ディレクトリだけを対象にする) - テスト(既存の壊れたテストはいったん除外し、新規分から必須にする)
「まだ全部は通らない」段階でも、make check という門の存在自体を先に作っておくことが大切です。中身は後から強くできます。
留意点3 ── ループを閉じる(自走の完成形)
馬具と柵だけでは、エージェントは自走しません。柵に当たったときに「失敗の出力をそのまま次の入力にして、通るまで直させる」仕組みが必要です。これがフィードバックループです。
ループの正体は「完了条件」
仕組みとしては単純で、以下の3つを回すだけです。
- エージェントにタスクをやらせる
make checkで逸脱を機械が検知する- 失敗の出力を渡して修正・再実行させる。全部緑になるまで繰り返す
初心者が見落としがちなのは、この「繰り返す」を誰が担うのかを決めていない点です。段階的に自動化していくのが現実的です。
| 段階 | ループを回す主体 | 具体的なやり方 |
|---|---|---|
| 手動 | 人間 | make check の結果をコピーして「これを直して」と渡す |
| 半自動 | ルールファイル | 完了条件に「make check が通るまで修正を繰り返す」と明記し、エージェント自身に回させる |
| 自動 | フック/CI | ファイル保存後や編集後に自動で make check を走らせ、結果をエージェントに戻す |
まずは「半自動」で十分です。ルールファイルの完了条件に一文書くだけで、多くのエージェントは自分でループを回し始めます。
留意点 ── 無限ループと「通すためのズル」を防ぐ
ループを閉じると、新しい種類の問題が出ます。
ひとつは無限ループです。修正しても通らない状態でエージェントが延々と試行を続け、トークンを消費します。対策として、ルールファイルに「3回試して通らなければ、状況を要約して人間に報告する」といった上限を書いておくとよいです。
もうひとつは通すためのズルです。テストが落ちたときに、テスト側を書き換えて通す、# type: ignore を大量に貼る、テストをスキップする、といった行動です。これは確率的に必ず起きるもので、対策は2つあります。
- ルールに「テストコード・型無視コメント・lint無効化コメントの追加は禁止。必要なら理由を添えて人間に確認する」と書く
- サブエージェント(後述)にレビュー役を置き、「柵を弱める変更が含まれていないか」を別文脈でチェックさせる
留意点4 ── SkillsとサブエージェントはルールAfter
ルール・柵・ループが回り始めると、「毎回同じ手順を説明している」「毎回同じ観点でレビューしている」という繰り返しが見えてきます。繰り返しが見えてから、道具を増やします。
元資料が強調する順序は「ルールが先、道具は後」です。逆にすると、効かないルールと使われない道具が積み上がります。
4つの道具の使い分け
| 道具 | 効く範囲 | 読み込まれるタイミング | 向いている用途 |
|---|---|---|---|
| ルール | 常時・薄く広く | 毎セッション自動 | 規約・コマンド・禁止事項 |
| プラン | タスク単位 | 着手前 | 認識合わせと手戻り防止 |
| Skills | 必要なときだけ・深く狭く | 該当作業のとき | 定型作業の手順書 |
| サブエージェント | 役割単位・別文脈 | 委任したとき | 並列化と文脈の分離 |
判断基準はシンプルです。毎回必要ならルール、特定の作業でだけ必要ならSkill。迷ったらSkillに逃がす。 ルールに全部書くとコンテキストが溢れるので、Skillは「ルールの家賃を下げる」ための道具だと考えると分かりやすいです。
Skillの実例 ── DBマイグレーション追加
元資料の例(エンドポイント追加)とは別に、Pythonプロジェクトでよく発生する「マイグレーション追加」を例にします。
# SKILL.md ── DBマイグレーションの追加
## 使いどころ
SQLAlchemy のモデルにカラムやテーブルを追加・変更するとき
## 手順
1. `app/models/` のモデルを変更する
2. `uv run alembic revision --autogenerate -m "<変更内容を英語で>"` を実行する
3. 生成された `alembic/versions/*.py` を開き、autogenerate が拾えない
変更(データ移行、インデックス名の変更)がないか確認して追記する
4. `uv run alembic upgrade head` でローカルDBに適用する
5. `uv run alembic downgrade -1` で戻せることを確認し、再度 `upgrade head` する
6. `tests/migrations/` にモデル変更を検証するテストを追加する
7. `make check` を通す
## 禁止事項
- 既存のマイグレーションファイルを編集しない(新しいリビジョンを作る)
- `downgrade` を空にしない
## 模範例
`alembic/versions/20260810_add_stock_location.py`
Skillを書くときの留意点は、「手順」に加えて「禁止事項」と「模範例」を必ず入れることです。手順だけだと、エージェントは細部を確率で埋めます。
サブエージェントの2つの呼び出し方
サブエージェントは「親の文脈を汚さずに、役割を分けて委任する」仕組みです。呼び出し方は2系統あります。
| 系統 | 特徴 | 向く場面 | 例 |
|---|---|---|---|
| オンデマンド生成 | 親がその場で子を起こす使い捨ての委任 | 大量調査の並列化、コンテキストを大きく消費する探索、結果の要約だけ持ち帰りたいとき | 「3つのORMを別々のサブエージェントで並列に調査し、要点だけ報告して」 |
| 事前定義 | 役割・観点・出力形式をファイルに定義し、名前で呼ぶ | 毎回同じ観点で行う作業、チームで観点を共有したいとき | レビュー専門、セキュリティ監査専門、テスト設計専門 |
事前定義の実例として、先ほどの「通すためのズル」を検知するレビュー役を示します。
# agents/gate-reviewer.md
## 役割
コミット前の差分をレビューし、以下の3観点で指摘する。修正はしない。
## 観点
1. 規約: AGENTS.md の命名・エラー処理の流儀に沿っているか
2. 柵の無効化: テストの削除・skip、`# type: ignore`、
`# noqa`、lint 設定の緩和が含まれていないか
3. テスト網羅: 新規・変更されたロジックに対応するテストがあるか
## 出力形式
- 指摘は「ファイル:行番号 / 観点番号 / 内容」の1行形式
- 問題がなければ「指摘なし」とだけ出力する
留意点 ── 並列の効能と代償
サブエージェントを並列に走らせると待ち時間は短縮できますが、同時に走る数だけ時間あたりのトークン消費は増えます。「並列は速いから常に良い」ではなく、数と深さは費用対効果で決める必要があります。
もうひとつ覚えておきたいのは、子には子のハーネスが効くという点です。サブエージェントの定義ファイルは、そのサブエージェントにとってのルールファイルです。親のルールが自動で継承されるとは限らないので、子に必要な規約は子の定義に書きます。
留意点5 ── 行動への柵とセキュリティ(任せるほど防具になる)
ここまでの柵はすべて「書いたもの」を事後に検証する柵でした。もう1種類、「これからやること」を事前に止める柵があります。rm -rf、force push、本番環境への直接操作のような、起きてからでは遅い事故を止めるためのものです。
行動への柵の道具
| 道具 | 何をするか |
|---|---|
| 許可リスト/拒否リスト | 実行してよいコマンド・読んでよいパスを列挙し、それ以外を止める |
| フック | コマンド実行前などのタイミングでスクリプトを走らせ、条件に合えばブロックする |
| サンドボックス/クラウド実行 | そもそも本番や自分のPCに手が届かない環境で走らせる |
| 確認ゲート | 危険操作の前に人間の承認を必須にする |
フックの設定形式はツールごとに異なるため、ここではフックから呼び出す判定スクリプト側の例だけ示します。ツールへの配線は各公式ドキュメントで最新の形式を確認してください。
#!/usr/bin/env bash
# scripts/guard-shell.sh
# フックから「これから実行されるコマンド」を引数で受け取る想定
# 終了コードが 0 以外なら実行をブロックする
cmd="$1"
# 破壊的な操作を止める
if echo "$cmd" | grep -Eq 'rm -rf|git push .*--force|git push -f|DROP TABLE'; then
echo "BLOCKED: destructive command: $cmd" >&2
exit 2
fi
# 外部送信を止める(秘密情報の持ち出し対策)
if echo "$cmd" | grep -Eq 'curl .* -d|wget --post|scp '; then
echo "BLOCKED: outbound data transfer: $cmd" >&2
exit 2
fi
exit 0
このスクリプトは意図的に単純です。完璧な検知を目指すより、「よくある事故の8割を機械で止める」ことを優先し、残りはサンドボックスや確認ゲートで受け止める設計のほうが現実的です。
押さえておくべき4つのリスク
自律性を上げるほど、エージェントは「攻撃されうる実行主体」になります。代表的なリスクは4つです。
- 間接プロンプトインジェクション。Webページ、Issue、READMEなど、エージェントが読む外部コンテンツに悪意ある指示が紛れ込みます。モデルは「読んだ指示」と「あなたの指示」を区別できません。
- 秘密情報の漏洩。
.envや認証情報がコンテキストや外部送信に載ります。「読ませない」を規約ではなく構造(deny設定、アクセス制限)で実現します。 - 破壊的操作。許可リスト・確認ゲート・サンドボックスで物理的に実行不能にしておきます。
- サプライチェーン。エージェントが提案する依存パッケージの実在・正当性は保証されません。パッケージ導入は人間の門を通します。
「3つ同時」を許さない
覚えやすい原則として、秘密データへのアクセス × 不審コンテンツの読み取り × 外部への送信の3つを同時に許さない(通称 lethal trifecta)というものがあります。どれか1つを構造で断てば致命傷にはなりません。
初心者向けの実践としては、まず「外部への送信」を断つのが最も簡単です。ネットワークアクセスを制限したサンドボックスで走らせるか、上記のような送信系コマンドのブロックを入れるだけで、残り2つが揃っても情報は外に出ません。
留意点6 ── ハーネスは育てるもの、そして捨てるもの
逸脱が出たら1行足す
ハーネスは「設計して完成させる物」ではなく「運用で育てる物」です。エージェントが同じパターンで失敗するたびに、ルールファイルに再発防止の1行を追記し、同じ失敗を物理的に起こせなくしていきます。
実務では、以下のようなサイクルを回します。
- 逸脱が起きたら、逸脱ログに1行書く
- 「ルールで直すか、柵で止めるか」を判断する
- ルールなら1行追記、柵なら
make checkかフックに追加する - 次のタスクで再発しないことを確認する
定期的に棚卸す ── 隠れた技術的負債
一方で、2026年後半に出てきた新しい論点が「ハーネスは隠れた技術的負債」という反論です。Han Lee氏は「良いチームほど多くのハーネスを作り込んでいるが、そのほぼすべてが次世代モデルに溶けていく」と指摘しています。モデルが賢くなるたびに、誰かが誇っていた回避策の山が不要になるのです。
実際、モデル据え置きでハーネスの変更だけでベンチマーク順位が30位からトップ5に上がった事例(LangChain)がある一方で、Claude Codeの品質低下の原因がすべてハーネス層の変更だったという事後分析(2026年4月)もあります。ハーネスは効くが、同時に壊しもする、ということです。
初心者向けの実践としては、以下を推奨します。
- ルールファイルは必ずGit管理する。全削除して試す、戻す、が安全にできる
- モデルを更新したタイミングで、ルールを一度全部コメントアウトして走らせ、まだ必要な行だけ戻す
- 数か月に一度、逸脱ログと突き合わせて「最近この逸脱は起きていないか」を確認し、起きていない行は削除候補にする
「薄く・軽く保ち、定期的に棚卸す」が、2026年8月時点での現実的な落としどころです。
よくある失敗と対処
初心者がハーネスを作るときに起きやすい失敗を表にまとめます。
| 症状 | よくある原因 | 対処 |
|---|---|---|
| ルールを書いたのに無視される | ルールが長すぎて肝心の行が埋もれている/精神論で検証不能 | 50行以下に削る。検証可能な表現(数値・コマンド)に書き換える |
| lintを入れたのにエージェントが直さない | エディタの赤線しか出ておらず、コマンドとして配線されていない | make check に束ね、ルールファイルに完了条件として書く |
| テストが通るように改ざんされた | ループを閉じたが「柵を弱める行動」を禁止していない | ルールに禁止事項を追記。レビュー用サブエージェントで検知 |
| いつまでも修正が終わらない | 試行回数の上限がない | 「N回で通らなければ報告」をルールに書く |
| 既存コードでlintエラーが大量に出て作業が進まない | 全ルールを一気に厳格化した | フォーマッタ → lint(警告)→ 型 → テストの順で段階導入 |
| Skillを作ったが使われない | ルールより先に道具を作った/使いどころの記述が曖昧 | 「使いどころ」を具体的に。繰り返しが見えてから作り直す |
| 触るなと書いたファイルを編集された | ルール(主観)だけで止めようとしている | 行動への柵(deny設定、フック)で構造的に止める |
| モデル更新後に急に挙動が悪化した | 古い回避策ルールが新モデルと干渉している | ルールを全部外して走らせ、必要な行だけ戻す |
最初の1時間でやること ── 導入チェックリスト
ここまでの内容を、実際に手を動かす順番にまとめます。順序が大事です。観察より先にルールを書かない、ルールより先に道具を増やさない。
- ハーネスなしで2〜3タスク走らせ、逸脱ログを4〜5行書く
- 逸脱ログをもとに、30行程度のルールファイルを書く(AIに草案を書かせて人間が削る)
- フォーマッタとリンターだけでよいので
make check(またはnpm run check)を作る - ルールファイルの完了条件に「
make checkが通ること」「通るまで修正すること」「3回で通らなければ報告すること」を書く - 「テスト・型無視・lint無効化による回避は禁止」を1行足す
.envと本番系ディレクトリを deny 設定に入れ、rm -rfと force push をブロックするフックを1本入れる- ルールファイルとMakefileをコミットする
- 次のタスクから、逸脱が出るたびに1行足す運用を始める
型チェック・テスト・Skills・サブエージェントは、この8ステップが回り始めてからで十分間に合います。
まとめ
ハーネス設計の要点を3つに絞ると、次のようになります。
- 進路はハーネスで示す。規約・コマンド・禁止事項を薄く明文化し、逸脱が出るたびに1行育てる。書いて終わりではなく運用が本体です。
- 逸脱はガードレールで検知する。lint・型・テストを「1コマンドの門」に束ね、人もAIも同じ門をくぐる。判定は主観ではなく機械に任せます。
- ループを閉じて自走させる。失敗の出力をそのまま次の入力にし、手動 → ルール → フック と自動化を進めるほど、任せられる範囲が広がります。
そして4つ目として、この記事で強調したいのは 「作りすぎない」 ことです。ハーネスは効きますが、コンテキストの家賃を払い、モデル更新で溶け、ときには品質を下げます。逸脱ログに対応する行だけを持ち、定期的に棚卸す。この習慣があれば、定義論争がどう転んでも困ることはありません。
言葉の定義は重要ではなく、大切なのは期待した結果を得ることです。まずは逸脱ログの1行目から始めてみてください。
参考リソース
- 木下雄一朗(Kinopee)「ハーネス設計入門 〜プロンプト、コンテキストの次〜」(Speaker Deck、2026年8月29日) https://speakerdeck.com/kinopeee/hanesu-sekkei-nyuumon-kontekisuto-no-tsugi
- 同氏「ハーネスエンジニアリングとは?」(Harness Engineering Meetup Tokyo #1) https://speakerdeck.com/kinopeee/hanesuenziniaringutoha
- LangChain「The Anatomy of an Agent Harness」(2026年3月)
- Agent Plugins 1.0 仕様(2026年8月)
- 各ツールの公式ドキュメント(ルールファイル・フック・サブエージェントの設定形式は変更が速いため、必ず最新版を参照してください)

