メインコンテンツまでスキップ

AIエージェントの規約と外部スキルを、リポジトリで管理する

· 約8分
Darasa.jp管理人
Darasa.jp管理人

このサイトは、教材だけでなくコードもかなりの部分を AI と書いています。

やってみて分かったのは、AIの出力の質は、リポジトリ側の準備でかなり変わるということでした。

同じモデルでも、リポジトリに何が置いてあるかで結果が違う。プロンプトを工夫するより、守ってほしいことをリポジトリに置くほうが効きます。

いま置いているものを書きます。

「絶対に守ること」に番号を振る

CLAUDE.md が414行あります。その半分近くが禁止事項です。

大事なのは中身より、番号が振ってあることです。

## 絶対に守ること

### A. 今の段階で新しく加わるもの

#### A-1. card_id を安定させる。これが唯一の取り返しのつかない失敗
#### A-2. レビューログを localStorage に入れない
#### A-3. レビューログは追記専用。編集も削除もしない
#### A-4. エクスポートは version 2。既存形式との相互互換を壊さない

### B. 前の段階から引き継ぐ禁止事項(変更なし)

番号があると、コードのコメントから参照できます。

/**
* ハラカ表示の設定を無視して、母音記号を必ず残す(CLAUDE.md A-6)。
*
* ⚠️ 逆方向の例外は作らない。
*/
forceHarakat?: boolean;

これがあると、数か月後の自分も、AIも、「なぜこうなっているか」を辿れます。規約の本文をコードに書き写す必要がなくなるのが大きい。

禁止の理由を、必ず一緒に書く

やってみて一番効いたのがこれです。

「〜するな」だけ書くと、AIは別の方法で同じことをやります。禁止した行為の目的が分かっていないからです。

だから理由をセットで書きます。

A-2. レビューログを localStorage に入れない

localStorage の実効上限は多くのブラウザで 5 MB 前後。レビューログは5万件で約 5 MB に達する。数年使った利用者から順に壊れる。 しかも同期 API なので、数 MB の読み書きのたびに UI が固まる。

ここまで書いておくと、AIは「じゃあ IndexedDB ですね」と自分で言います。理由が分かっていれば、こちらが指定していないケースでも正しい側に倒れる。

備考

これは人間の同僚に説明するときと同じでした。

「ダメ」より「壊れる理由」のほうが、圧倒的に伝わる。 AIを相手にすると、そのことがはっきり可視化されます。

規約は、できる限りテストに落とす

文章で書いただけの規約は守られません。

たとえば「トップレベルでブラウザの API を触らない」という規約があります。Docusaurus はビルド時にサーバー側で React を実行するので、windowindexedDB をモジュールのトップレベルで触ると落ちるからです。

これは「気をつける」では守れないので、テストにしました。

src/vocab/test/ssr.test.ts ← 規約 B-4 に対応

規約の番号とテストのファイル名を対応させておくと、規約が生きているかどうかが CI で分かります。

テストに落とせない規約は、規約として弱い。 落とせないなら、せめて検査コマンドを作る。それも無理なら、その規約は守られない前提で設計を考えます。

スコープ外を、はっきり書く

これも効きました。

### スコープ外(勝手に着手しない)

- オンライン同期・アカウント・Firebase(次の段階。SYNC-PLAN.md は将来の資料)
- 日本語 → アラビア語の産出方向の出題

リポジトリの中に将来の計画書があると、AIは親切心で先回りします。「ついでに同期の下準備をしておきました」みたいなことが起きる。

将来の資料は「将来の資料である」と書いておく。 これだけで先回りが止まりました。

順序を指定する

マイルストーンには順序があります。そして、その順序に理由があることがあります。

Q3(保存層とエクスポート)は Q4(復習画面)より先に完成させる。

サーバを持たない構成では、エクスポートが唯一の生命線である。画面を先に作ると、復習が習慣になった頃に履歴を失う利用者が出る。

画面から作るほうが楽しいし、AIに投げても画面のほうが早く形になります。だからこそ、順序を先に固定しておく必要がありました。

3つのエージェントで、同じスキルを共有する

いま3系統のエージェントを使い分けています。それぞれ設定を置く場所が違います。

.claude/skills/
.agents/skills/
.junie/skills/

同じスキルを3か所にコピーすると、必ずズレます。なので実体を1か所に置いて、あとはシンボリックリンクにしました。

.agents/skills/grill-me/ ← 実体
.claude/skills/grill-me -> ../../.agents/skills/grill-me
.junie/skills/grill-me -> ../../.agents/skills/grill-me

.agents/ を実体側にしているのは、特定のツールに寄せたくないからです。ツールを乗り換えても、リンクを張り替えるだけで済みます。

注記

シンボリックリンクなので git にもそのまま入ります。clone した人の環境でも同じ構造になる。

素朴なやり方ですが、いまのところこれで困っていません。

skills-lock.json ─ プロンプトも依存関係である

これがいちばん書きたかった話です。

公開されているスキル(エージェント向けの手順書)を使うことがあります。他人のリポジトリにある Markdown です。

他人のリポジトリの中身は、いつ変わるか分かりません。

コードなら誰でもそう考えるのに、プロンプトだと「まあ Markdown だし」と流してしまう。でも、それはエージェントの振る舞いを決める入力です。変われば結果が変わります。

なので、ロックファイルを置きました。

{
"version": 1,
"skills": {
"grill-me": {
"source": "mattpocock/skills",
"sourceType": "github",
"skillPath": "skills/productivity/grill-me/SKILL.md",
"computedHash": "f361db4e15e6bf..."
}
}
}

やっていることは package-lock.json と同じです。どこから来たか、どのパスか、中身のハッシュは何か。

更新するときは、ハッシュが変わったことに気づいてから、差分を読んで、意図的に上げる。黙って変わるのを防ぐのが目的です。

プロンプトは依存関係です。 だからロックする。この発想はもっと広まっていい気がしています。

やってみて分かった限界

正直なところも書いておきます。

規約が増えると、読まれなくなります。 414行はもう限界に近い。全部を毎回読ませるより、いま触っている領域の規約だけを見せる形にしたい、と思いつつできていません。

規約どうしの矛盾に、AIは気づきません。 段階が進んで古い規約が実質死んでいても、そのまま従おうとします。定期的に自分で読み返して消す必要があります。

「なぜ」を書けない規約は、たいてい間違っています。 理由が書けないルールは、自分がまだ理解していないだけのことが多かったです。これは AI 相手というより、自分の設計の甘さが可視化される仕組みとして機能しています。

まとめ

  • 禁止事項に番号を振る。 コードのコメントから参照できる
  • 禁止の理由を必ず書く。 理由が分かれば、指定していないケースでも正しい側に倒れる
  • 規約はテストに落とす。 落とせない規約は弱い
  • スコープ外と順序を明示する。 先回りが止まる
  • スキルの実体は1か所、あとはシンボリックリンク
  • 外部のスキルはハッシュで固定する。 プロンプトも依存関係

このサイトはアラビア語の学習教材です。よかったら中身も見てみてください🙇