AI

規約は、規約について嘘をつく

  • Claude Code
  • Documentation

エージェントに読ませる規約を、規約自身の基準で検査しました。出てきたのは、書いた指示がその通りに動いていなかった箇所、自動で守らせられるかだけを見て要否を考えていなかったルール、そして直したはずが直っていなかった修正です。

GitHubGitHub - LabeeHive/standards: Shared standards repository for Labee LLC projects — a Claude Code plugin marketplace of skills, agents, and workflowsShared standards repository for Labee LLC projects — a Claude Code plugin marketplace of skills, agents, and workflows - LabeeHive/standards

読めと書いた指示が、その通りには動いていなかった

スキルには参照ファイルを添えられます。長い手順や判断基準を SKILL.md 本体から切り出して置く場所です。

必ず読ませたいものには、接頭辞 _ を付けていました。命名規則です。どれを必ず読ませたいのかを見分けるための印で、読み込みそのものは SKILL.md 側に「このファイルを読むこと」と書いて指示していました。

実際に呼び出して測ったところ、Skillツールが返すのは SKILL.md だけでした。参照の中身は届いておらず、エージェントは自分でファイルを開くまで1行も引用できません。読めと書いてあるのに、読まれていませんでした。

指示の文面は正しいままです。読めと書いてあるものを、もっとはっきり読めと書き直しても何も変わりません。直す対象は文面ではなく、指示が届いているかどうかを測っていなかったことのほうでした。

ルールが守れるかと、要るかは別の問い

同じ夜に、文書のリンターの設定も見直しています。きっかけは行の長さでした(以下も訳は筆者)。

決め手は行長だった。もとのファイルから引き継がれ、その日の全パスを生き延びたのは、ルールをツールで検査できるかしか問わず、そのルールが存在すべきかを一度も問わなかったからだ。

折り返しは、文書がどう表示されるかを何も変えません。それでいてハード折り返しを強制すると、1語直すだけで以降の全行が折り返し直され、差分が変更を実際より大きく見せます。このルールを外したことで、指摘が192件消えました。

同じ問いを他のルールにも当てて、4つを外しました。表の余白の統一は、どちらかに揃えるだけで577件か1,134件の一括編集が要るだけで、得るものがない。コードブロックの言語指定は、本物のコードならハイライトで元が取れる一方、ASCIIの図に text と付けさせるのは有用なルールを儀式に変えるだけでした。

エージェントに規約を守らせようとすると、判定できるルールばかりを足しがちになります。判定できることと、判定する価値があることは別です。

直したはずが直っていなかった

その直後に、もう一度同じ文書を監査しています。前回の修正を信用せず、検査し直す形です。

2回目の監査は、前回の修正をそのまま信じるのではなく検査した。10件のうち6件は持ちこたえたが、残りは解決ではなく言い換えられていただけで、しかもそのパス自体が新しい問題を持ち込んでいた。

出てきたものが、規約が自分について書いていることの誤りとして、分かりやすいものでした。

  • 設定の説明が「ルールを有効化することはなく、オプションを取るものを固定するだけ」と書いていた。実際には16項目のうち7つが無効化されていた
  • 「知っておくべき4項目」と書いてあったが、実際は7つあった
  • 「何にも強制されていない」という見出しの節に、既定で有効な2つのルールが入っていた
  • 言語指定を「常に付ける」と書いた文書が、自分自身では言語指定なしのコードブロックを使っていた

最後のものが厄介です。片方の文書は「常に付けろ」と言い、もう片方はそのルールを切る決定を記録している。両方を渡されたレビュアーには、どちらが標準なのか判定できません。

直した回数ではなく、直っているかを測る

3つに共通しているのは、書いた本人の申告を検査していなかったことです。

参照が届いているかどうかは、読めと書いてある以上そうなっているものとして扱われ、疑われませんでした。リンターのルールは、自動で判定できるので通っていました。修正の1回目は、修正したという事実だけで完了とみなされました。

対策は、いずれも同じ形になりました。実際に呼び出して何が返るかを測る、ルールを外したら指摘が何件消えるかを数える、修正後にもう一度独立して監査する。申告ではなく結果を見るという一点です。

エージェントに読ませる文書は、この検査から漏れやすいところにあります。コードなら型検査もテストも通りますが、規約の文章が現実と食い違っても何も落ちません。読み手が素直であるほど、書いてあるとおりに間違えます。

足元が変わることは前提に入っていなかった

いちばん効いた発見は、規約が古くなる経路が2つあることでした。

1つは、こちらが変えたのに文章を直し忘れる場合です。これは撤回した決定の伝播漏れと同じ話で、対処の仕方も分かっています。

ブログその決定、出自不明につき設計判断をADRとして積む運用で、サブエージェントが「ユーザー決定」と書いて自分で起票したADRが混ざりました。本文を書き換えず撤回ADRを足して取り消し、ADRには誰が決めたかを書かせる規約を足した話です。

もう1つは、こちらが何も変えていないのに、足元の挙動が変わって書いたことが効かなくなる場合です。文面は正しいまま、レビューでも通り、それでも効かなくなります。

参照を読ませる指示が、まさにそれでした。書式も置き場所も変えていません。それでもモデルの更新後は、明示的に書いた指示そのものが、ほとんど通らなくなっています。読まれなかったことはエラーとしては現れず、読まなかった参照についてエージェントは何も言わずに作業を続けます。

規約が古くなる経路は2つある。1つ目は自分が仕様や決定を変えたのに文章を直し忘れる経路で、波及先を洗って直すという対処が既にある。2つ目は自分は何も変えていないのに、モデルやツールの更新で足元の挙動が変わり、文面は正しいまま書いたことが効かなくなる経路で、こちらには検出の仕組みがまだ無い

こちらには、今のところ検出の仕組みがありません。モデルやツールの更新のたびに、規約が前提にしている挙動を測り直す必要がありますが、どの記述がどの挙動に依存しているかの一覧がありません。参照が読まれているかどうかが挙動への依存だと気づけたのは、たまたま疑って測ったからです。

依存しているものを先に列挙しておけば、次は測り直すだけで済みます。まずはその一覧から作ります。

起点になった参照ファイルの1行は、そのあと読ませ方ごと替えました。

ブログSKILL.md に必須の参照ファイルを注入するSKILL.md に「この参照を読むこと」と書いても、読むかどうかはモデルの裁量です。毎回必要な参照は動的コンテキスト注入で本文に埋め込む形へ切り替えました。公式ドキュメントの記述、報告されている類似の症状、プラグインで配ったときの挙動を並べます。