教科書
前提知識ゼロから、原理と実装を体系的に学ぶ。実習環境は ~/dev/dev-harness。読了目安 60〜90分。
この教科書は、AI に開発作業を任せながら、その成果が本当に合格かどうかを機械が判定する仕組み——「検証駆動の開発ハーネス」——を、原理から実装まで一歩ずつ学ぶための本です。読み手はこのプロジェクトを自分の手で動かす人、たった1名を想定しています。速く要点だけ知る本ではありません。読み終えたときに「なぜこの設計なのか」を自分の言葉で説明できることを目指します。
~/dev/dev-harness がどんな大きさで、なぜその大きさなのかこの教科書で学ぶのは、AI に開発作業を任せたとき、その成果が本当に合格しているのかを人間の代わりに確かめる仕組みです。仕組みそのものの考え方(原理)と、実際に動くコード(実装)の両方を扱います。読むだけでなく、章ごとに実際のファイルを開いたりコマンドを実行したりして、手を動かしながら理解を進めます。
実習に使うのは ~/dev/dev-harness という小さなリポジトリです。学習対象の実装一式(docs/ の資料類を除く)は27ファイルで、半日あれば全部読み切れる量に、意図的に抑えてあります。理由は後の章で何度も出てきますが、ひとことで言えば「一気に作ると全体が把握できなくなり、直せなくなる」という失敗を避けるためです。小さいからこそ、1ファイルずつ「これは何のためにあるのか」を追いかけられます。
章の並びには意味があります。第1章から第5章までが土台で、これはいま実際に動いている部分の話です。1回きりの流れ——依頼して、AI が作り、別の AI が採点し、機械が合否を出す——を、部品ひとつずつ理解します。第6章と第7章は次の段の予習です。まだ作っていないけれど、土台の部品をそのまま使って組み上げる予定の「自動でやり直すループ」と「本物の環境での受け入れ」を先取りします。第8章は事業の話です。この仕組みを開発会社にどう売るか、何が価値として残るのかを扱います。
各章はできるだけ独立して読めるように書いてあります。前の章で導入した用語は、必要なときに軽く再掲します。専門用語は避けません。むしろ、平易な言葉で説明したうえで用語を導入し、それ以降はその用語で話を進めます。初めて出てくる用語は太字にしてあります。
目次へ戻るAI に開発作業を頼むと、AI はたいてい最後に「できました」と報告してきます。ところが、この報告はしばしば当てになりません。原稿の見本にはこう書かれています。
「頼んだことが抜けていても、本人は気づいていないからです。」
なぜ当てにならないのか。AI には、放っておくと出てしまう3つのクセがあります。①自己申告は証拠にならない——頼んだ項目のうち1つが抜けていても、本人はそれを見落としたまま「できました」と言います。抜けに気づいていないのだから、正直に報告しているつもりなのです。②期待に合わせて答えを歪める——「これでいいよね?」と聞かれると「いいです」と返しやすく、ヒントを与えられると、そのヒントに合うように後から理屈を組み立てます。③会話が長くなるほど判断が鈍る——入力が長くなると正答率が落ち、本題と関係のない情報も注意力を奪います。
この3つがあるので、これまでは人間が毎回レビューして、間違いを見つけ、直しを指示していました。ここが厄介です。AI がコードを書く速度が上がるほど、その分だけ人間の確認作業が増えます。書くのは一瞬なのに、検品が追いつかない。これを人間の確認の渋滞と呼びます。
この渋滞をほどくために導入するのがハーネスです。ハーネスとは、もともと馬を安全に走らせるための馬具一式のことです。手綱や胴当てで、暴れる馬の力を目的の方向に向けます。ここでは、AI という「速いけれど当てにならないことがある働き手」を、安全に・目的どおりに走らせるための装具一式を指します。具体的には、AI の成果物を別の AI が採点し、その点数で合格かどうかを機械が判定し、判定の記録をすべてファイルに残す、という仕組みです。
大事なのは、AI(モデルと呼びます。文章やコードを生成する頭脳の部分です)と、ハーネスとで、責任をきっぱり分けることです。
| モデル(AIの頭脳)がやること | ハーネス(装具)がやること |
|---|---|
| 計画の提案 | 実行と権限の管理 |
| コード変更の提案 | 成功条件の判定 |
| 原因の推定 | 状態の保存・証跡の記録 |
| 修復案の提示 | コスト管理・人間承認の要求 |
左の列はどれも「〜の提案」「〜の推定」です。モデルは賢い提案者ですが、自分の提案が正しいかどうかの判定は自分ではしません。右の列——実行してよいか、成功したか、記録は残ったか——はすべてハーネスが握ります。合否をモデルに委ねないこと、これがこの本を貫く一番大事な考え方です。
最後に、この仕組みの価値を何で測るか。生成したコードの量ではありません。派手に大量のコードを吐いても、間違っていれば価値はマイナスです。測るべきは受け入れ済みの変更——検証を通過し、人が安心して受け取れた変更——の数と、その1件あたりにかかった総コストです。次の図が、渋滞する従来のやり方と、ハーネスのやり方の違いです。
いまは README.md を読み込む必要はありません。代わりに、仕組みの自己テストを走らせて、7項目すべてが緑(ok)になるのを見てください。中身が何を確かめているかは、第3章から第5章で全部わかります。
cd ~/dev/dev-harness
bash scripts/smoke.sh
末尾に smoke ok (7 checks) と出れば、この仕組みは健全な状態です。「壊れた採点表を弾けるか」まで機械で確かめている、という予告だけ受け取っておいてください。
確認問題 1-1. AI の「できました」を証拠にしてはいけないのはなぜですか。3つのクセのうち少なくとも1つを使って説明してください。
自己申告は証拠にならないからです(クセ①)。頼んだ項目が抜けていても、本人はその抜けに気づいていないので、嘘をつくつもりがなくても「できました」と報告します。報告が正直かどうかと、成果物が正しいかどうかは別の問題であり、正直な報告でも成果物は不完全でありえます。だから報告ではなく成果物そのものを、本人以外が確かめる必要があります。
確認問題 1-2. 「合否の判定」をモデル(AIの頭脳)ではなくハーネス側に置くのは、なぜですか。
モデルは「提案する部品」だからです。計画・変更・原因・修復案を出すのはモデルの仕事ですが、その提案が成功条件を満たしたかどうかを同じモデルに判定させると、クセ②(期待に合わせて歪める)が働き、自分の成果を甘く見ます。判定・記録・統制を装具の側に固定しておけば、モデルが賢くなっても・別のモデルに入れ替えても、合否の基準がぶれません。
確認問題 1-3. この仕組みの価値を「生成したコードの量」で測ってはいけないのはなぜですか。
量は目的ではないからです。狙いは「人が安心して受け取れる変更を、少ない手間で出す」ことです。間違ったコードを大量に生成すれば、確認と手直しのコストがむしろ増え、価値はマイナスにもなります。だから測るべきは受け入れ済みの変更の数と、その1件あたりの総コストです。この指標は第8章で商品の効果指標として再登場します。
このハーネスの設計は、まさお氏という、数百本の部品を作り込んできた実践者の考え方を土台にしています。まず土台の第一が「スキル」という部品の作法です。スキルとは、AI への指示や知識に名前を付けて、繰り返し使えるようにした仕組みです。単なるプロンプト(AIへの指示文)の保存場所ではなく、「これは何を引き受けるのか」という責務を持った部品として設計します。
なぜ部品に分けるのか。すべてを1つの巨大な指示書に書くと壊れるからです。項目を1つ足すたびに、関係ないはずの別の挙動が変わってしまう。毎回すべてを読ませるので、目の前のタスクと無関係な情報が注意力を奪う(第1章のクセ③)。そして、大きくなりすぎて誰も直せなくなる。だから責務ごとに分けます。
最初の分かれ目は副作用の有無です。副作用とは、ファイルを書き換えたりコマンドを実行したりして、外の世界を変えてしまうことです。読ませるだけで何も変えないスキルを辞書型(接頭辞 ref-)、ファイルやコマンドに実際に作用するスキルをワークフロー型と呼び、この2つを1本のスキルに混ぜません。混ざると「いつ呼ばれるべきか」も「何を返すべきか」も曖昧になるからです。
スキルの名前の接頭辞(先頭に付ける短い印。prefix)で、そのスキルの責務を宣言します。全部で5種類です。名前を見ただけで、呼ぶ側は中身を読まずに「これは副作用がないな」「これは自分が直接叩くものだな」と前提を置けます。これを名前は契約と呼びます。
| 接頭辞 | 責務 | 副作用 | 誰が呼ぶか |
|---|---|---|---|
ref- | 参照知識(辞書型) | 無し | 誰でも(読むだけでも可) |
run- | 独立したワークフロー | 契約に明示 | ユーザーが直接叩く |
wrap- | 既存スキルの派生(base: 必須) | 派生元に準ずる | ユーザー |
assign-*-{evaluator/generator/contributor} | 内部の役割部品 | 役割に閉じる | 親スキルのみ |
delegate- | 外部のAIへの委譲 | 出力は未信頼扱い | ユーザー |
まさお氏の配布コード ~/Downloads/skills には、この命名で作られた19本のスキルが並んでいます。たとえば assign-slide-evaluator という名前を見れば、中を読まなくても「これは assign- だから内部部品で、-evaluator だから採点役で、親スキル(run-slide)からしか呼ばれない」と分かります。実際そのとおりで、frontmatter(ファイル先頭のメタ情報欄)には user-invocable: false(ユーザーは直接呼べない)と pair: assign-slide-generator(相方は生成役)が書かれています。名前が守るべき約束を宣言し、中身がそれを裏づけている、という関係です。
約束は破れます。assign- なのにユーザーが直接叩ける設定にする、といった違反です。だからこの約束は機械が検出します。dev-harness では scripts/harness_lint.sh が、接頭辞・frontmatter の name: とフォルダ名の一致・wrap- の派生元 base: の実在などを照合し、契約違反があれば LINT NG と出して止めます。
名前の次は、スキル本文の書き方です。ここにも理由のある作法があります。
第一に、description は発動条件だけを書きます。description とは「このスキルをいつ呼ぶか」を書く短い欄です。ここに動作の手順や出力形式まで書いてはいけません。理由は実測にあります——手順を description に書くと、本文が読まれず、短い description の要約だけで動いてしまうのです。ref-harness-rules にはこう書かれています。
## 3. description は発動条件
人間向け紹介文ではなく「いつ呼ぶか」を書く。発動ワードは2個まで。
動作の手順・段数・出力形式を書かない
(理由: 手順を書くと本文が読まれず、description の短縮版だけで動いてしまう)。
第二に、大事なことは冒頭に・短く置きます。最重要のルールは本文の冒頭30行以内、全体は500行未満に収め、細かい参照や例は補助ファイルに降ろします。理由は、長い文書ほど中程が読み飛ばされること、そして会話が長くなって内部で圧縮されると、各スキルの先頭しか残らない前提で設計する必要があるからです。だから一番効かせたいルールを先頭に置きます。
第三に、AI が知っていることは書かない。一般的なプログラミング知識をスキルに書き込むほど、この現場だけに必要な固有の指示が薄まって埋もれます。そして命令には理由を添える。「絶対にこうしろ」と強調するより「なぜそうするか」を書くほうが、想定外の新しい状況でも同じ判断軸を当てはめてくれます。前掲の抜粋がまさにその実例です。
第四に、踏んだ落とし穴の扱いです。実際に踏んだ罠はGotchas(落とし穴メモ)として1行と理由1行で記録します。ただし、同じ罠を繰り返し踏むなら、注意書きを増やすのではなく昇格の階段を上らせます。「Gotcha(注意書き)→ 機械の検査 → 毎回自動で実行 → 提出時の必須検査」という順で、人の注意力に頼る段階から機械が確実に止める段階へと引き上げるのです。理由は明快で、注意力で確率的に防ぐより、機械で100%防ぐほうが常に安いからです。
最後に、スキルはメタ層だという考え方です。決まった手順で機械的にできることはスクリプトに逃がし、スキル本文には「どの道具を、いつ、どう使うか」だけを書きます。判定や照合のような決定論的な処理をスキルの文章でやらせると不安定になるので、そこは scripts/*.sh に任せる、という役割分担です。
まず、この章の内容がそのまま規約になっているファイルを開きます。
less ~/dev/dev-harness/.claude/skills/ref-harness-rules/SKILL.md
次に、まさお氏の19スキルの名前を並べて、それぞれの接頭辞から責務を当ててみてください。
ls -1 ~/Downloads/skills
run-slide(ユーザーが叩く)・assign-slide-evaluator(内部の採点役)・wrap-thumbnails(run-thumbnail の派生)・delegate-codex(外部AIへ委譲)が、名前だけで見分けられるか試してください。
確認問題 2-1. description に動作の手順を書いてはいけないのはなぜですか。
手順を description に書くと、本文が読まれずに description の短縮版だけで動いてしまう、という実測があるからです。description は「いつ呼ぶか(発動条件)」を伝える短い欄で、その短さゆえに常に読まれます。そこに手順まで詰めると、AI はそれで足りたと判断し、肝心の本文(正確な手順・安全機構)に到達しません。役割を「発動条件だけ」に限定することで、本文が確実に読まれる設計を保ちます。
確認問題 2-2. 「名前は契約」という考え方は、呼ぶ側にどんな得をもたらしますか。
中身を読まずに前提を置けることです。接頭辞が責務・副作用・呼び出し元を宣言しているので、ref- なら「読んでも何も壊れない」、assign- なら「自分ではなく親スキルが呼ぶ内部部品だ」と、名前だけで安全に扱えます。毎回中身を精読しなくてよいので、部品を組み合わせるコストが下がります。約束が守られている保証は、機械(harness_lint.sh)が名前と実体を照合して担保します。
確認問題 2-3. 同じ落とし穴を繰り返し踏むとき、注意書きを増やすのではなく「昇格の階段」を上らせるのはなぜですか。
人の注意力で確率的に防ぐより、機械で100%防ぐほうが常に安いからです。注意書き(Gotchas)は読み飛ばされたり忘れられたりする確率がゼロになりません。繰り返し踏む罠は、それだけ実害の期待値が高いので、機械の検査・毎回の自動実行・提出時の必須検査へと引き上げて、そもそも通り抜けられなくします。注意力というあてにならない資源から、決定論的な機械へ、防御の責任を移すわけです。
ここからがこの仕組みの心臓部です。第1章で見たとおり、自分の答案を自分で採点すると甘くなります(クセ②)。だから、作る係と採点する係を、別の AI・別の会話に完全に分けます。作る側をgenerator(生成係)、採点する側をevaluator(採点係)と呼びます。この2つが同じ会話の中にいると、採点係が作業の経緯や言い訳を知ってしまい、判断が引きずられます。だから採点係は、経緯を何も知らないまっさらな状態で起動します。
dev-harness では、生成係が run-task、採点係が assign-task-evaluator です。採点係のスキルには、先頭に4つの契約が置かれています。
**4つの契約(先に読む)**
1. 実物だけを見る。実装係の報告・言い訳は読まない。成果物ファイルを自分で開き、
checks を自分で再実行する。
2. 採点基準(criteria)・本スキル・verdict-schema.json を書き換えない。読み取り専用
(理由: 基準を緩めて合格させる裏口を塞ぐ)。
3. 絶対評価。前回の点・改善の経緯・期待に引きずられず、毎回ゼロから採点する。
4. 数えられるものは実測する(テストは実行、件数は wc、変更範囲は git status / git diff)。
目視で数えない。
この4つを噛み砕くと、こうなります。①採点係は成果物ファイルを自分で開き、テストを自分で実行し直します。作った本人の報告を鵜呑みにしません。②採点基準や自分のスキルを書き換えません。基準を緩めて合格させる裏口を塞ぐためです。③前回が何点だったか、どう改善してきたかを一切考えず、毎回ゼロから「契約と基準にどれだけ合うか」だけで採点します。④「たぶん通っている」で数えず、テストは実行して、変更範囲は git diff で実測します。
採点係の出力は、文章の感想ではありません。決まった形の構造化データ——verdict.json(採点表)——です。実際に、median 関数を追加するサンプルタスクを1周流したときの verdict がこれです。
{
"score": 100,
"quality": {
"overall": 100,
"breakdown": {
"受入条件充足": 100, "スコープ遵守": 100,
"テスト品質": 100, "コード整合": 100
}
},
"passed": true,
"evaluator_skill": "assign-task-evaluator",
"feedback": "acceptance 6項目すべてを実物で照合し充足を確認。… test/median.test.js を
追加、cd sample-app && node --test を採点係が再実行し 8 tests / 8 pass / 0 fail。…"
}
score、軸別の内訳 breakdown、次の直しに使える feedback、合否 passed。各フィールドの意味を押さえましょう。score は総合点です。quality.breakdown はbreakdown(内訳)で、軸ごとの点数を並べたものです。feedback は次の修正にそのまま使える具体的な指摘で、ここでは「どのファイルの何行目をどう確認したか」まで書かれています。passed は合否です。感想文でなくこの形にする理由は、機械が読めて、次のやり直しにそのまま渡せるからです。
ここが決定的です。合否を最終的に決めるのは、採点係(AI)ではありません。scripts/verdict_check.sh という小さなプログラムが、点数と合格ラインを数値で比較して決めます。終了コードは3種類です。
| 終了コード | 意味 |
|---|---|
| exit 0 | 合格(点数が合格ライン以上) |
| exit 1 | 採点表は有効だが不合格(点数が合格ライン未満) |
| exit 2 | INVALID(採点表そのものが契約違反で無効) |
注目すべきは、採点係が verdict に書いた passed: true をそのまま信じない点です。プログラムは点数(score)と合格ライン(threshold)を自分で比べ直し、その結果と採点係の passed が食い違っていたら、点数に関係なく無効(exit 2)にします。つまり採点係にすら、最終的な合否の宣言権を与えていません。「できました」を信用しないという原則を、AI の一段外側でもう一度徹底しているわけです。全体の1周は次のように流れます。
対比として、採点者のいないループの失敗例を挙げます。同じ指示をただ無限に繰り返すだけの仕組み——通称 RALPH ループ——は、「何が悪かったか」の指摘が返ってこないので、毎回同じ失敗を繰り返します。品質が上がるループは「採点 → 直し方の指摘 → 作り直し」が毎周まわるループです。採点と feedback が輪の中に組み込まれているかどうかが、回るループと空回りするループの分かれ目です(このループ化は第6章の主題です)。
もう一点。状態は会話でなくファイルに残すのが原則です。verdict.json は runs/ に証跡として残ります。会話が途切れても、まっさらな AI が runs/ を見れば、どこまで進んだか・何点だったかを引き継げます。判断の材料を人の記憶や会話の流れに置かず、ファイルに固定する。これも「できました」を信用しない思想の一部です。
まず、実際の採点表を開いて score / breakdown / feedback を読みます。
cat ~/dev/dev-harness/runs/sample-task/verdict.json
次に、その採点表を機械にかけて合否を出させ、PASS が出るのを見てください。
cd ~/dev/dev-harness
bash scripts/verdict_check.sh runs/sample-task/verdict.json client/criteria/sample-task.md
PASS score=100 threshold=90 と出れば、点数(100)が合格ライン(90)以上だと機械が数値で判定した証拠です。
確認問題 3-1. 採点係を「まっさらな状態」で、実装係の報告を読ませずに起動するのはなぜですか。
作業の経緯や言い訳を知ると、採点が引きずられるからです(第1章のクセ②)。「頑張ったから」「ここは事情があって」という文脈が入ると、成果物そのものより努力や事情に甘くなります。採点係が見るべきは成果物の実物だけであり、経緯を遮断することで、毎回ゼロからの絶対評価が保てます。だから採点係は成果物ファイルを自分で開き、テストも自分で実行し直します。
確認問題 3-2. 採点係にも「最終的な合否の宣言」をさせず、機械(verdict_check.sh)が数値比較で合否を決めるのはなぜですか。
採点係もまた AI であり、自己申告はどの層でも合否の根拠にしない、という原則を貫くためです。採点係が passed: true と書いても、機械は点数と合格ラインを自分で比べ直し、食い違えば無効にします。合否という一番重い判断を、気分や忖度の入りうる AI ではなく、決定論的な数値比較に固定することで、「たぶん大丈夫」が入り込む余地をなくします。
確認問題 3-3. 採点結果を感想文でなく verdict.json という構造化データにするのは、何のためですか。
機械が読めて、次のやり直しにそのまま使えるようにするためです。総合点 score は機械が合格ラインと比較でき、内訳 breakdown はどの軸が弱いかを示し、feedback は次の修正の入力になります。感想文だと機械判定にも次周の改善にも使えません。構造化しておくことで、合否判定の自動化(第3章)と、指摘を入力にした自動やり直し(第6章)の両方が成立します。
採点係をどれだけ厳しく作っても、採点する基準そのものが曖昧なら意味がありません。実は、ループの品質は採点設計でほぼ決まります。そしてその出発点は、完了の定義を変えることです。「良い感じにできたら完了」ではなく、完了は「採点できること」で定義する。採点できない仕事は、そもそも任せられません。
採点基準は二階建てで考えます。下の階は、機械が○×を付けられる条件です。テストが通るか、字数が足りているか、触ってよい場所だけを触っているか。ここは機械の床(土台)です。上の階は、機械では○×を付けにくい質です。読みやすさや設計の妥当性がこれにあたります。ここは観点を言葉にして採点係(AI)に渡します。見分けるコツは「アルバイトの人がチェックリストで○×を付けられるか?」という問いです。付けられれば下の階(機械の床)に、付けられなければ上の階(観点採点)に置きます。
翻訳の手順は3ステップです。①曖昧な形容詞を書き出す——「良い」「ちゃんとした」「読みやすい」など。②数えられる事実に翻訳する——「読みやすい」を「1関数40行以内」のように。③各観点に採点アンカーを書く。採点アンカーとは「100点はどういう状態か、70点は、40点は」という点数の目盛りです。これがあると、採点係が同じ成果物に何度採点しても点がぶれません。
「median 関数をいい感じに実装して。ちゃんとテストも書いてね。読みやすくして。」
受入条件を機械○×で6個。scope で sample-app/** に限定。criteria に4軸+各軸のアンカー。
観点は、使うモデルに合わせて狭く具体的に書きます。このプロジェクトは Opus という最上位モデルで回る前提ですが、それでも「察してくれるはず」に頼らず、観点を細かく具体的に書きます。賢いモデルの気を利かせる力に基準の明確さを肩代わりさせると、モデルを入れ替えたときに崩れるからです。
ここで一番大事な原則が出てきます。依頼書を書くこと=採点表を書くことです。何を作るかを決める行為と、何をもって合格とするかを決める行為は、本来同じものです。書く前に4つの問いに答えます——誰が使う? どれくらいの量? 何を入れて何を入れない? どうなったら「できた」? この4問に答えられれば、それがそのまま採点表になります。dev-harness の採点基準の実物を見てみましょう。
# criteria: sample-task
axes: 受入条件充足, スコープ遵守, テスト品質, コード整合
threshold: 90
## スコープ遵守
- 100: 変更が sample-app/** に閉じている(git status / git diff で実測)
- 0: scope 外のファイルに1つでも変更がある
(この軸が 0 のとき、総合 score は 60 を超えないこと)
axes:(採点軸)と threshold:(合格ライン)は機械が読む行。各軸の下にアンカー(100点/0点の定義)を書く。この基準には、注目すべき上限則が仕込まれています。「スコープ遵守が0点のとき、総合 score は60を超えないこと」という一行です。触ってはいけない場所に手を出したら、他の軸がどれだけ満点でも総合は合格ライン(90)に届きません。単純平均だと、致命的な違反を他の高得点で埋め合わせて合格できてしまう。それを防ぐ仕掛けです。致命的な軸が低いときは総合も低くする、という設計がここに表れています。
運用していると「点数は出るのに、成果物が一向に良くならない」ことがあります。これは採点軸に抜け穴がある兆候です。たとえば「800字以上」という軸だけだと、中身の薄い水増しでも点が取れてしまいます。対策は軸を締めることで、「5論点を各100字以上」のように、水増しでは満たせない形に直します。ここで大事なのは、合格ラインをいじる前に採点軸を疑うことです。点が出るのに良くならないとき、合格ラインを上げても、抜け穴が残っていれば水増しの上限が上がるだけです。直すべきは軸の側です。
依頼書と採点基準を並べて読み、両者の対応を確かめます。
cat ~/dev/dev-harness/tasks/sample-task.md # 合格条件6個(機械○×)
cat ~/dev/dev-harness/client/criteria/sample-task.md # 4観点+アンカー+axes:/threshold:
criteria の「スコープ遵守」の項を読み、「この軸が0点なら総合は60点を超えない」という上限則を自分の目で見つけてください。なぜこの一行が要るのかを、上の本文と照らし合わせて考えてみましょう。
確認問題 4-1. 上司から「このレポートを読みやすくして」とだけ言われました。これを採点できる形に翻訳してください(翻訳の手順に沿って)。
①曖昧な形容詞「読みやすい」を書き出す。②数えられる事実に翻訳する——たとえば「1段落5文以内」「専門用語は初出で1行の説明を添える」「見出しが3階層を超えない」など、○×が付く条件に落とす。③各観点にアンカーを付ける——「100点=全段落5文以内かつ全専門用語に説明あり/70点=どちらか1つに軽微な違反/40点以下=両方が崩れている」。こうすれば、アルバイトがチェックリストで○×を付けられ、機械の床か観点採点のどちらに置くかも決まります。理由は、数えられる形にして初めて採点係の点がぶれず、完了が定義できるからです。
確認問題 4-2. 「スコープ遵守が0点なら総合は60を超えない」という上限則は、なぜ必要ですか。
致命的な違反を、他の軸の高得点で埋め合わせて合格するのを防ぐためです。総合を単純平均で出すと、触ってはいけない場所に手を出しても、テストやコード整合が満点なら平均が合格ラインを超えてしまいます。スコープ違反は品質以前の禁止事項なので、それが起きた時点で総合を合格ライン未満に抑え込みます。致命軸が低いときは総合も低くする、という設計原則の具体例です。
確認問題 4-3. 「点は出るのに良くならない」とき、合格ラインを上げる前に採点軸を疑うべきなのはなぜですか。
症状の原因が軸の抜け穴にあるからです。たとえば「800字以上」だけの軸なら、水増しで点が取れます。この状態で合格ラインを上げても、AI はより多くの水増しで応じるだけで、質は上がりません。直すべきは軸で、「5論点を各100字以上」のように水増しでは満たせない形にする。合格ラインの調整は、抜け穴を塞いだ後にすべき最後の手段です。
採点係を分け、機械で合否を出す。ここまでで心臓部はできました。しかし、もう一つ強敵がいます。グッドハートの法則です。これは「ある指標を目標にした瞬間、その指標は指標として壊れる」という経験則です。テストの点を上げる方法は2つあります——勉強して実力を上げるか、問題のほうを易しく書き換えるか。後者を選べば、点は上がっても実力は上がりません。指標(点)を目標にすると、指標を満たす最短経路が探され、その経路には必ずズルが混じります。
AI は点を上げる最短経路を探すので、放っておくと後者に流れます。実際に起きるズルは具体的です——採点基準を緩める・合格ラインを下げる・採点項目を減らす・通らないテストのほうを消す。どれも「実力で合格ラインに届く」より速く点が上がるので、規律がないと必ずそちらに流れます。
dev-harness は、これらのズルを AI の良心に頼らず、すべて機械検査で塞ぎます。対策は5つです。
| # | ズル | 構造的な対策(機械検査) |
|---|---|---|
| ① | 採点軸を勝手に増減・改名する | verdict の breakdown キーを criteria の axes: 行と完全一致させる。ずれたら無効 |
| ② | 採点基準を書き換えて緩める | 採点係は criteria を読み取り専用で扱う(書き換え禁止) |
| ③ | 点数不足なのに「合格」と自己申告 | passed と「score≧threshold」の食い違いを機械が検出し無効 |
| ④ | 総合点と内訳をこっそり食い違わせる | score と quality.overall が不一致なら無効 |
| ⑤ | 上の検査自体が壊れていないか | 自己テスト(smoke)が毎回、番人の正常/異常系を確認 |
①をもう少し見ましょう。採点係が「テスト品質」の軸だけ消して残り3軸で高得点を出せば、平均は上がります。それを防ぐため、verdict の内訳キーは基準の axes: 行と一字一句一致していなければなりません。verdict_check.sh の中で、この照合はこう行われます。
# criteria の axes 行と breakdown キーの完全一致(軸の増減 = 採点のすり替えを禁止)
axes_line="$(grep -m1 '^axes:' "$criteria" | sed 's/^axes:[[:space:]]*//')"
expected="$(printf '%s\n' "$axes_line" | tr ',' '\n' | ... | sort)"
actual="$(jq -r '.quality.breakdown | keys_unsorted[]' "$verdict" | sort)"
if [ "$expected" != "$actual" ]; then
invalid "breakdown keys do not match criteria axes. ..."
fi
invalid(exit 2)。軸を1つ消すだけで即無効になる。この分かれ道を図にすると、実力で90点を取った採点表はすべての検査を通り抜けますが、基準を緩めて90点にした採点表は、緩めた瞬間にどれかの検査で止まります。
ここで疑問が湧きます——検査を任されている verdict_check.sh が、実はバグで不正な採点表を見逃していたら? そのために、フィクスチャがあります。フィクスチャとは、テスト用にわざと用意した見本のことです。scripts/fixtures/ には5つの見本が置いてあります。契約違反で無効(exit 2)にされるべき不正な見本が3つ(壊れた JSON・軸が欠けた採点表・点数不足なのに「合格」と自己申告した採点表)、有効だが不合格(exit 1)と判定されるべき見本が1つ、有効で合格(exit 0)となるべき見本が1つです。smoke が毎回、これらを番人に渡し、それぞれ正しい終了コードで裁かれることを確かめます。
{
"score": 80,
"quality": { "overall": 80, "breakdown": { "正確性": 85, "完成度": 75 } },
"feedback": "smoke fixture: 閾値未満なのに passed=true と自己申告するケース",
"passed": true
}
passed: true と嘘をついた採点表。番人はこれを INVALID(exit 2)にできなければならない。smoke は「壊れた採点表を渡して、番人が弾くことを確かめる」ためのテストです。番人が正しく弾けなくなったら、その瞬間に smoke が赤くなります。これで、番人自身の健全性まで機械で守られます。第1章の実習で走らせた7項目の緑の内訳は、lint が1つ、この5フィクスチャの判定確認が5つ、実アプリのテストが1つだったわけです。
嘘の採点表(80点なのに合格と自己申告)を番人に渡し、無効になるのを見ます。
cd ~/dev/dev-harness
bash scripts/verdict_check.sh scripts/fixtures/verdict-lying.json scripts/fixtures/criteria-fixture.md
echo "exit code = $?"
INVALID: ... と表示され、exit code = 2 になります。次に、フィクスチャを自分でコピーして書き換え、たとえば軸を1つ消したり score と overall を食い違わせたりして、別の弾かれ方も試してみてください。どのチェックで止まるかを観察すると、5つの対策が体感できます。
確認問題 5-1. 「テストを通せ」という指示に対して、AI がやりがちなズルは何ですか。それを機械でどう防ぎますか。
やりがちなズルは、通らないテストのほうを消す・無効化することです。テスト勉強せずに問題を消すのと同じで、そのほうが速く「全部通った」状態を作れます。防ぎ方は、テストの削除・無効化を禁止し(policies)、変更範囲を git diff で実測して既存テストが減っていないかを採点で確認すること、そしてスコープを機械で縛って検証の土台に触らせないことです。人の良心ではなく、範囲の機械検査でズルの経路自体を塞ぎます。
確認問題 5-2. 採点係が「基準ファイルを書き換えられない(読み取り専用)」のは、グッドハートの法則にどう効きますか。
基準を緩めて合格させる、という最短経路を物理的に塞ぐからです。指標(点)を目標にすると、AI は指標を満たす近道を探し、基準そのものを易しく書き換えるのが最速の近道になります。採点係に criteria の書き換え権を与えなければ、その近道は使えません。基準への不満は feedback に書いて人間に届ける経路だけを残すことで、緩和は人間の判断を経由しないと起きなくなります。
確認問題 5-3. 異常系フィクスチャと smoke は、なぜ必要ですか。正常系のテストだけでは足りないのはなぜですか。
番人自身が壊れていないかを確かめるためです。正しい採点表を通せることだけを確認しても、不正な採点表を「見逃さない」保証にはなりません。番人の仕事の本質は不正を弾くことなので、わざと壊した見本(壊れたJSON・軸欠け・自己申告矛盾など)を毎回渡し、ちゃんと INVALID にできることを確かめる必要があります。もし番人がバグで見逃すようになれば、その瞬間に smoke が赤くなって気づけます。
ここまでは1回きりの流れでした。不合格なら、人間が feedback を見てもう一度依頼し直します。次の段(このプロジェクトで言う「段1」)では、これを自動にします。不合格なら、AI が自分で指摘を読んでやり直す。合格するまで、あるいは打ち切り条件に達するまで、輪が回り続けます。この「作業→検証→修正→再検証」の輪をループと呼びます。
効くループと回らないループの差は、回数ではありません。止め方です。止め方を間違えると、良くならないのに延々回り続けたり、まだ伸びるのに諦めたりします。だから停止条件は3重にします。
| 停止条件 | これ1つだけだと起きる事故 |
|---|---|
| ①品質:点数が合格ライン以上 | 頭打ちなのに合格ラインに届かず、無限に周回する |
| ②回数:最大◯周 | まだ改善の余地があるのに、途中で諦めて終わる |
| ③時間:最大◯分 | 良否を見ないまま、時間切れだけで終了する |
この3つの判断を、会話の流れの中で AI にやらせてはいけません。判断がぶれるからです。代わりに、状態をstate.json(状態ファイル)に置きます。いま何周目か、最新の点は何点か、合格ラインはいくつか、最大何周か、これまでの最高点は何点か——を、すべてファイルに書きます。そして「もう1周するか」を、会話の外にある小さなプログラム——Stop hook——が整数比較で決めます。Stop hook とは、AI の応答が終わるたびに自動で走る仕掛けのことです。
まさお氏のループ実装 eval-loop では、この心臓部が数十行の bash に収まっています。応答終了時に走る hook-stop.sh は32行しかなく、状態ファイルの場所を組み立てて、判断ロジック本体である loop-control.sh を読み込む(source する)だけです。実際の整数比較は、その loop-control.sh の中にあります。
# スコアが閾値以上 → 完了
if [ "$SCORE" != "null" ] && [ "$SCORE" -ge "$THRESHOLD" ] 2>/dev/null; then
jq '.active = false | .ended_reason = "threshold_met"' ... # ①品質で停止
fi
NEXT_ITERATION=$((ITERATION + 1))
# max 到達 → 終了
if [ "$NEXT_ITERATION" -ge "$MAX" ]; then
jq ... '.ended_reason = "max_iterations"' ... # ②回数で停止
fi
SCORE -ge THRESHOLD(①品質)と NEXT_ITERATION -ge MAX(②回数)の整数比較。③時間は同ファイルの wall-clock 予算(wall_clock_exceeded)が受け持つ。合否は AI でなくこの数行が決める。大事な性質があります。点は毎周上がるとは限りません。90→92→88 のように、途中で下がることもあります。だから、毎周の成果物を退避しておき、最後は最高点だった版——最良版——を採用します。eval-loop では毎周 best_score を更新し、作業ツリーを snapshot として冷凍保存しておき、最後にベスト版へ復元できるようにしています。「最後の周が一番良い」という思い込みで最終版を採ると、途中のより良い版を捨ててしまうからです。
もう一つの落とし穴が目標ドリフトです。ループを何周も回すうちに、当初の目的から少しずつズレていきます。周ごとの計画は、元の依頼を圧縮した派生物なので、ズレを受け継いでしまう。対策は単純で、毎周依頼書の原文を作業係に渡し直します。eval-loop のオーケストレーターも「task 原文を必ず同梱すること(目標再注入)。plan は task を圧縮した派生物にすぎず、ドリフトを継承する」と明記しています。
ループには入れ子の構造があります。内側ループは「1つの仕事を合格まで詰める」輪です。第3章の1周が、そのまま内側ループの1周になります。外側ループは「複数の仕事を順に、あるいは定時に流す」輪です。内側の部品(依頼書・採点・機械判定)はそのまま使い、外側だけを足す設計になっています。
合格 or 打ち切りまで内側が回る
仕事A → 仕事B → 仕事C … を外側が並べる
応答終了時に走る Stop hook の本体を開きます。32行しかありません。
cat "$HOME/dev/eval-loop-main/plugins/eval-loop/scripts/hook-stop.sh"
これは状態を組み立てて loop-control.sh を source するだけです。判断本体を開いて、SCORE -ge THRESHOLD(品質で停止)と NEXT_ITERATION -ge MAX(回数で停止)の整数比較を探してください。
grep -n -e '-ge "\$THRESHOLD"' -e '-ge "\$MAX"' -e wall_clock \
"$HOME/dev/eval-loop-main/plugins/eval-loop/scripts/loop-control.sh"
確認問題 6-1. 停止条件を「点数のみ」にすると、何が起きますか。
頭打ちになったのに合格ラインに届かないと、無限に周回します。点数が伸びなくなっても、合格ラインだけを見ていると「まだ合格していない=続ける」となり、いつまでも止まりません。だから回数の上限(②)と時間の上限(③)を併せ持ち、「伸びなくなったら/暴走したら止まる」経路を用意します。3重にして初めて、事故なく止まれます。
確認問題 6-2. 点が毎周上がるとは限らない(90→92→88もある)とき、なぜ最後の版でなく最良版を採るのですか。
最後の周が一番良いとは限らないからです。改善は単調に上がるわけではなく、途中で下がることがあります。最終版を機械的に採用すると、途中のより高得点だった版を捨ててしまいます。だから毎周の成果物を退避(snapshot)して best_score を追跡し、最後は最高点の版へ復元します。ループの目的は「最良の成果物を得る」ことであって「最後まで回すこと」ではありません。
確認問題 6-3. 毎周「依頼書の原文」を渡し直すのは、なぜですか。
目標ドリフトを防ぐためです。周ごとの計画は元の依頼を圧縮した派生物で、少しずつ当初の目的からズレます。そのズレは次周の計画に受け継がれ、回すほど元の目的から離れていきます。毎周、圧縮していない原文を注入し直すことで、判断の基準を当初の目的に引き戻します。合否の基準(criteria)を毎回まっさらな採点係に渡すのと同じ発想です。
成果物のテストが全部通った。では完成か——まだです。動きの検証は別問題だからです。模擬環境(作業係の中だけで完結する検証)では、原理的に見えない挙動があります。たとえば、自動で回り続けられるか、あるスキルが別のスキルを入れ子で呼べるか、人への確認待ちを越えて進めるか、本番と同じ設定で動くか。これらは成果物ファイルをいくら眺めても分かりません。実際に動かして初めて分かります。
そこで登場するのが live-trial(実走試験)です。本物の Claude セッションをもう1本、別プロセスで立ち上げます。tmux(1つの画面に複数の作業を同居させる画面多重化ツール)の中で被験セッションを動かし、外から入力を送り、画面を覗き、出てきた成果物で受け入れを判定します。まさお氏の live-trial スキルは、この方式が「作業係の中だけの検証」では届かない領域を埋める、と表で示しています。
| 検証したい挙動 | 作業係の中だけ | live-trial(本物のセッション) |
|---|---|---|
| 自動で回り続ける(Stop hook 自走) | ✗ | ✓ |
| 入れ子でスキルを呼ぶ | ✗ | ✓ |
| 対話の確認待ちを越える | ✗(止まる=合格と誤認) | ✓ |
| 本番の設定・hook で動く | △ | ✓ 同一 |
ここで肝になるのが完了判定です。live-trial は「成果物が出た」ことと「動作が止まった」ことの両方を必須にします。時間だけで判断すると事故ります。長い無音の処理中を「終わった」と誤認するからです。スキルのルールにもこう書かれています。
どちらの層でも完了は「成果物の出現 + busy 不在」
(busy 不在だけだと未着手/tool 境界/質問返し停止を完走と誤判定する)
もう一つの工夫が運転役と被験役の分離です。試験を回す側(運転役)と、試験される側(被験役)を分けます。状態管理や例外処理といった難しい仕事は強いモデルが運転し、検証対象そのものは安いモデルでもかまいません。この分離のうまみは、安く・再現性高く回せることです。さらに、被験セッションが実際にどのモデルで走ったかは、記録(transcript)から機械的に取り出して照合します。運転役の思い込みで「Opus で走った」と報告させず、証拠で確かめるためです。
受け入れ判定:まっさらな採点役が「スキルの目的を成果物が満たすか」を独立に判定
試験を繰り返すと、同じ弱点が毎回出ることがあります。そのとき直すべきは、個々の成果物ではなくスキル本体——指示書・採点基準・スクリプト——です。これをiter-improve(反復改善)と呼びます。1つの入力だけで起きる弱点なら成果物を直せば済みますが、複数の入力で同じ弱点が再現するなら、それは部品の設計に穴があるということです。1箇所のスキル修正が全入力に波及して、初めて頭打ちを破れます。
ただし、この改善ループには強い規律が要ります。iter-improve は8つの不変条件を掲げ、その筆頭がこう始まります。
この 8 つの不変条件を破る改善ループは、score がいくら上がっても失敗である。
1. PASS 詐欺禁止: score を上げる手段に「evaluator を緩める / 採点 mode を
易しい方に倒す / rubric の閾値を下げる / 採点対象を goal から外す」が
含まれていたら、それは改善ではなく詐欺。
要点は3つに集約できます。1回の改善は1〜2か所まで——3つ以上入れると消化不良で、かえって後退します(一括投入で平均88→72という実測が残っています)。効果は、改善履歴を知らないまっさらな AI が判定する——運転役の「前より良くなった気がする」という体感は証拠にしません。採点を緩める「改善」は、点が上がっても失敗と定義する——これはまさに第5章のグッドハート対策の応用です。点を上げる方法は2つあり(作る側を良くするか、採点を緩めるか)、規律がないと速いほう(緩める)に流れるので、それを構造で禁じます。
最後に、成果物受け入れの死角にも触れておきます。「結果は正しいが、踏むべき手順を外した」という失敗は、成果物だけを見ても分かりません。正しい答えにたまたま別ルートで着いた場合です。これを埋めるには、実行ログと照合する検査を重ねます(このプロジェクトで言う段2の課題です)。成果物の正しさと、手順の正しさは、別々に確かめる必要があります。
live-trial の絶対ルールと、iter-improve の8つの不変条件を、現物で読みます。
less "$HOME/Downloads/anti-goodhart-main 3/.claude/skills/run-skill-live-trial/SKILL.md"
less "$HOME/Downloads/anti-goodhart-main 3/.claude/skills/run-skill-iter-improve/SKILL.md"
live-trial では「完了=成果物の出現+busy 不在」の記述を、iter-improve では「1 iter 1-2 件」と「PASS 詐欺禁止」を探し、それぞれ第5章・第6章のどの原則の応用かを対応づけてください。
確認問題 7-1. 完了判定に「成果物が出たこと」を必須にするのは、なぜですか。停止(動きが止まったこと)だけでは足りないのはなぜですか。
停止には「まだ着手していない」「道具の実行の境目で一瞬止まった」「質問を返して止まっている」など、完走以外の理由が混じるからです。動きが止まっているだけを完了とみなすと、これらを完走と誤判定します。成果物という証拠の出現を必須にすることで、「本当に仕事を終えて止まった」ことと「別の理由で止まっている」ことを区別できます。だから完了は成果物+停止の両方で確定させます。
確認問題 7-2. 同じ弱点が繰り返し出るとき、個々の成果物でなくスキル本体を直すのは、なぜですか。
複数の入力で同じ弱点が再現するのは、部品の設計に穴がある兆候だからです。成果物を1つずつ手で直すのは対症療法で、次の入力でまた同じ弱点が出ます。指示書・基準・スクリプトというスキル本体に手当てを入れれば、その1箇所の修正が全入力に波及し、頭打ちを構造的に破れます。個別対応の敗北を認め、原因の層まで登って直す、という判断です。
確認問題 7-3. iter-improve で「採点を緩めて点が上がった」場合、それを改善でなく失敗と定義するのはなぜですか。
グッドハートの法則そのものだからです。点を上げる方法は「作る側を本当に良くする」か「採点を緩めて点を通す」かの2つで、後者のほうが速いので規律がないと必ずそちらに流れます。採点を緩めて得た高得点は、実力の向上を伴わない見せかけで、目的(goal)には一歩も近づいていません。だから点が上がっても失敗と定義し、改善履歴を知らないまっさらな AI に goal 達成そのものを判定させて、見せかけを弾きます。
最後は事業の話です。前提として、モデルはこれからも賢くなり続けます。だから「AI をうまく動かすコツ」だけを売る商品は、すぐ陳腐化します。ハーネスを3種類に分けると、どこに事業を置くべきかが見えます。能力補完(モデルの苦手を外付けで補う)は、モデルが賢くなれば消えます。企業適合(その会社のリポジトリ・ルール・工程へつなぐ)は残ります。品質保証・統制(基準・権限・証跡・停止)は、AI の自律性が上がるほど重要になります。事業は後ろの2つに置きます。
顧客が買うのは何か。コードを書く支援ではありません。「受け入れ可能な変更を、少ない人手で、予測可能に、安全に本番へ出す能力」です。そしてその効果は、第1章で予告した指標——受け入れ済み変更1件あたりの総コストと、一発で合格する率——で示します。
どこまで AI に任せるかは、一気に全部ではなく段階で刻みます。これを自律レベルと呼び、L1 から L4 まで4段あります。
| レベル | 任せる範囲 | 人間の関与 |
|---|---|---|
| L1 | AI が変更案と PR を作る | 人間が全部レビュー |
| L2 | 自己検証まで AI がやる | 承認は人間 |
| L3 | 低リスク変更(ドキュメント・テスト追加等)のみ自動で合流 | 低リスク以外は人間 |
| L4 | 条件を満たした変更のみ自動配備+異常時は自動で巻き戻し | 認証・決済・削除・インフラは人間承認を残す |
線引きの基準がここで一番大事です。どこまで任せるかは、モデルの賢さでなく損失の大きさで決めます。どれだけモデルが賢くても、認証・決済・削除・インフラのように、失敗したときの損失が大きい領域は人間承認を残します。賢さは「うまくやれる確率」を上げますが、稀に起きる失敗の損失を消しはしません。だから判断軸は賢さではなく、失敗したときにどれだけ痛いか、です。
商品設計の中核がengine / client の2層分離です。engine(採点の仕組み・番人・検査)は提供側が保守する、薄く退屈な共通部品です。client(合格基準・ルール・失敗メモ)は、お客さんが自分のフォルダで自分の言葉で育てる層です。dev-harness の実物でも、この2層はきれいに分かれています。
| 層 | 中身(dev-harness の実物) | 触る人 |
|---|---|---|
| engine(エンジン) | .claude/skills/(スキル3本)・scripts/(判定・lint・smoke) | 提供側 |
| client(顧客層) | client/criteria/(採点基準)・client/policies.md(禁止領域)・client/gotchas.md(失敗メモ) | 顧客 |
harness_lint.sh が検出する。なぜ2層に分けるのか。理由は技術ではなく人間の心理です。人は他人が作ったものに愛着を持てない。既製のスキルを渡されても、自分のものとは感じられず、使い続ける動機が湧きません。逆に、自分で育てた基準は自分の資産になります。だから、個性と価値の宿る部分(何を合格とするか)は顧客が自分の言葉で育て、退屈で共通な部分(採点の仕組み)は提供側が保守する。顧客が基準をいじって壊しても、規約から外れた書き方は harness_lint.sh が自動で見つけます。提供の最終形は、リポジトリ1つを単位にした「自律化パッケージ」——タスク契約の型・検証ルール・承認ポリシー・評価データ・計測——として納品します。
dev-harness 自体も段階で進めます。各段の目的と順序には理由があります。段0(完成済み)は1回きりの流れで心臓部(生成と評価の分離+機械判定)を検証しました。実装一式(docs/ の資料類を除き27ファイル)を半日で読める量に抑え、「一気に作って把握不能」の再発を防ぐためです。段1は自動やり直し(第6章)。段2は本物の環境での受け入れ+手順照合(第7章)。段3は、お客さんが自分で基準や部品を増やせる補助——これが愛着問題の本丸です。段4は配布形態と効果測定。そして昇段の条件は毎回同じで、「自己テスト全緑+実際の仕事1本が合格」です。小さく確かめてから次に進む、という規律を全段で守ります。
お客さんが触ってよい層(client/)に何があるかを開いて確かめます。
ls -1 ~/dev/dev-harness/client
cat ~/dev/dev-harness/client/README.md
criteria/(採点基準)・policies.md(禁止領域)・gotchas.md(失敗メモ)だけが顧客の層で、.claude/skills/ と scripts/ は含まれないことを確認してください。この境界がそのまま「顧客の資産はどこに宿るか」を表しています。
確認問題 8-1. 3種のハーネス(能力補完/企業適合/品質保証・統制)のうち、モデルが進化しても残る価値はどれですか。それはなぜですか。
企業適合と、品質保証・統制です。能力補完はモデルの苦手を外付けで補うものなので、モデルが賢くなればその苦手ごと消えます。一方、企業適合(その会社固有のリポジトリ・ルール・工程への接続)はモデルが変わっても必要で、品質保証・統制(基準・権限・証跡・停止)は AI の自律性が上がるほど重要になります。事業価値をモデル依存の部分に置くと陳腐化するので、残る2つに置きます。
確認問題 8-2. 「どこまで AI に任せるか」を、モデルの賢さでなく損失の大きさで決めるのはなぜですか。
賢さは失敗の確率を下げますが、失敗したときの損失を消さないからです。認証・決済・削除・インフラのような領域は、稀な失敗でも損失が甚大です。賢いモデルなら大丈夫、という基準だと、その稀な事故が起きたときに取り返しがつきません。だから任せる範囲は「うまくやれそうか」ではなく「外したらどれだけ痛いか」で決め、損失の大きい領域には人間承認を残します。
確認問題 8-3. engine と client を2層に分け、価値を client 層に宿らせるのはなぜですか。
人は他人が作ったものに愛着を持てないからです。既製の仕組みをそのまま渡しても、顧客は自分のものと感じられず、使い続けません。何を合格とするかという基準・ルール・失敗メモを顧客が自分の言葉で育てられるようにすると、それは顧客自身の資産になり、使い続ける動機が生まれます。採点の仕組み(engine)は退屈で共通なので提供側が保守し、個性と価値の宿る基準(client)は顧客が育てる。壊す変更は lint が検出するので、安心して育てられます。
本文で教えた用語だけを、最初に出た章とともに並べます。
axes: 行と完全一致でなければ無効になる。threshold: 行に書く。axes:(軸)と threshold:(合格ライン)の行+各軸のアンカーからなる。score・内訳 breakdown・具体的な feedback・合否 passed を持つ構造化データ。smoke ok。ref-)と、ファイルやコマンドに作用するスキル(ワークフロー型)。1本に混ぜない。bash scripts/smoke.sh を実行し、7項目の緑を見る。ref-harness-rules/SKILL.md を開き、ls ~/Downloads/skills の実在スキル名から接頭辞の責務を当てる。runs/sample-task/verdict.json を読み、verdict_check.sh で PASS を出す。tasks/sample-task.md と client/criteria/sample-task.md を並べ、スコープ遵守の上限則を見つける。fixtures/verdict-lying.json を番人に渡して INVALID(exit 2)を見る。書き換えて別の弾かれ方も試す。hook-stop.sh(32行)と loop-control.sh を開き、品質と回数の整数比較を探す。run-skill-live-trial と run-skill-iter-improve の SKILL.md を読み、第5・6章の原則との対応を取る。client/ を開き、顧客が触ってよい層の中身を確認する。axes:・threshold:・各軸のアンカー)を一枚書いてみる。この教科書の内容は、次の実物に基づいています。事実の創作はしていません。
~/dev/dev-harness(docs/HANDOVER.md・docs/handover.source.md・DESIGN.md・README.md・.claude/skills/*/SKILL.md・scripts/*.sh・client/・tasks/・runs/sample-task/verdict.json・scripts/fixtures/*)~/Downloads/skills(接頭辞命名の19スキル)/~/Downloads/eval-loop-main 2/plugins/eval-loop(ループ実装。参考コピー ~/dev/eval-loop-main)/~/Downloads/anti-goodhart-main 3/.claude/skills(live-trial・iter-improve)dev-harness 教科書 — AIに任せて、機械が合否を決める開発