はじめに
🤔「AI に毎回同じ説明をしている気がする…」
😥「前に注意したことを、また同じようにやられた…」
🫠「任せる範囲を広げたいけど、取り返しのつかない操作をされないか不安…」
AI と一緒に開発していると、こんな場面によく出会います。
AI は優秀ですが、会話が変わるたびに、前のことを覚えていません。
個人開発している口コミサービス あじぴた は、
約半年・4,300 コミットの多くを、Claude Code と一緒に書いてきました🤖
この記事では、AI に毎回ゼロから説明しなくて済むようにするために、
- 文脈をどこに・どんな形で置いているか
- 同じ失敗を2 回させないための記録の仕方
- 任せる範囲を広げても、取り返しのつかない操作だけは止める仕組み
を、実際のファイルと一緒に書きます📝
最後に、これを続けてきて気づいた「実は AI だけの話ではなかった」ことも書きます。
この記事は、個人開発サービス「あじぴた」の設計を書くシリーズの 1 本です。
単体で読めるように書いていますが、サービスの全体像はハブ記事にまとめています。
AI は、毎回「初日の新人」としてやって来る
AI と開発していて最初に感じたのは、毎回、優秀な新人が初日に来るような感覚でした。
能力は高いのに、このプロジェクトのことは何も知りません。
命名のルールも、過去に何を検討して捨てたかも、前回どこでつまずいたかも知らない状態です。
人間の新人なら、一度教えれば覚えてくれます。
AI は、次の会話ではまた初日です😇
だから、口で教えるのではなく、ファイルに置いておくことにしました。
新人が初日に読む資料を、毎回そろえておくイメージです。
それは、これまで自分の頭の中にしかなかった暗黙のルールを、すべて言葉にする作業でもありました✍️
あじぴたでは、文脈を 5 つの場所に置いています。
| 置き場所 | 中身 | 新人で言うと |
|---|---|---|
| AGENTS.md | 最初に読むもの・守るルール | 入社初日に渡す案内 |
| ADR | 過去の判断と、その理由 | 過去の会議の議事録 |
| スキル | 繰り返す作業の手順 | 業務マニュアル |
| メモリ | 一度受けた指摘と、その理由 | 先輩からの申し送り |
| 権限と hooks | やってはいけない操作 | 触ってはいけない機械の鍵 |
順に紹介します。
① AGENTS.md:全部読ませず、地図を渡す
AGENTS.md は、AI が作業を始めるときに最初に読むファイルです。
Claude Code では、CLAUDE.md から読み込ませています。
ここで気をつけたのは、全部を書かない・全部を読ませないことです。
あじぴたには、仕様書・設計書・開発規約・ADR を合わせると数十本のドキュメントがあります。
毎回すべて読ませると、肝心の作業に使える余裕が減ってしまいます。
そこで、AGENTS.md にはどこに何があるかだけを書き、読む順番を 2 段階に分けました。
# コードを書く前に
## Step 1 — 必ず読む(全タスク共通)
- `docs/development/rules.md` — 命名・配置・export・スタイリング等のコアルール
## Step 2 — 必要に応じて参照
- `docs/design/README.md` — デザイン原則(UI を含む場合)
- `docs/development/directory-structure.md` — ディレクトリ構成の詳細
- `docs/requirements/` — 機能要件・画面仕様
- `docs/decisions/` — 過去の技術判断(ADR)。「なぜそうなっているか」を確認できる
必ず読むものは 1 つだけです。残りは、必要になったときに辿れるように場所だけ示しています🗺️
新人に「まずこれを読んで、あとは困ったらここを見て」と渡すのと同じです。
② ADR:「なぜ」と「選ばなかった案」を残す
**ADR(Architecture Decision Record)**は、設計の判断を 1 本ずつ記録したドキュメントです。
あじぴたでは 36 本書いています。
形はすべてそろえています。
## 背景 何が問題で、なぜ決める必要があったか
## 検討した選択肢 案の比較表
## 決定 結論
## 理由 なぜそれを選んだか
もともとは未来の自分のために書き始めたものでした。
3 か月後の自分は、なぜそうしたかを覚えていないからです。
ところが、AI にとっても一番効く資料でした💡
コードには「なぜ」が書かれていない
コードを読めば、何をしているかは分かります。
でも、なぜそうしているか、ほかの案をなぜ選ばなかったかは、コードには残りません。
これが分からないと、AI は「もっと良い方法があります」と、過去に検討して捨てた案を提案してきます。
たとえば、あえて merge commit だけにしている理由を知らなければ、「Squash マージにすれば履歴がきれいになります」と提案したくなるはずです。
ADR に「検討した選択肢」と「選ばなかった理由」があると、この提案が目に見えて減りました。
捨てた理由まで書いておくのが、AI 相手には特に効きます✂️
前提が崩れたら、消さずに追記する
ADR は書いて終わりではありません。前提そのものが変わることがあります。
あじぴたでは、「外部 API は、Google の月 $200 の無料クレジット内で運用する」という ADR がありました。
ところが、Google がこのクレジットを廃止して、前提が成り立たなくなりました。
このとき、古い ADR は消さずに「この前提は失効した」と追記し、新しい ADR で方針を書き直しています。
消してしまうと、なぜ方針が変わったのかを、人も AI も辿れなくなるからです。
③ スキル:繰り返す作業を、手順ごと渡す
スキルは、Claude Code に繰り返しの作業手順を覚えさせる仕組みです。
/work-on-issue 123 のように呼ぶと、決めた手順どおりに作業を進めてくれます。
あじぴたでは 13 個あり、Issue を作ってから PR が通るまでの流れを、ほぼスキルでつないでいます🔗
思いつく
↓ /refine-issue new "一行のアイデア" … 雑に起票だけしておく
↓ /refine-issue 123 … 着手前に、背景・受け入れ条件まで詰める
↓ /work-on-issue 123 … ブランチを切って実装し、コミットする
↓ /create-pr … 受け入れ条件を照合して PR を作る
↓ /handle-review … レビューの指摘に対応して返信する
マージ
あえて、段階ごとに区切っている
今は、指示を 1 つ出せば、Issue を読むところから実装・PR の作成・レビュー対応まで、止まらずに進めてもらうこともできます。
それに比べると、コマンドを 1 つずつ呼ぶこのやり方は、少し遠回りに見えるかもしれません。
それでも区切っているのは、全部を任せると、途中で何が起きたのかが見えなくなるのが気持ち悪かったからです。
最後に PR だけが出てきても、どこで何を判断したのかが分かりません🫥
段階ごとに区切ると、区切りごとに成果物が残ります。
| 段階 | 残るもの | 自分が確かめること |
|---|---|---|
/refine-issue |
Issue の本文(背景・受け入れ条件) | 作ろうとしているものが合っているか |
/work-on-issue |
コミット | 実装の方向がずれていないか |
/create-pr |
PR と、受け入れ条件の照合結果 | 完了と言える根拠があるか |
/handle-review |
指摘への返信 | 直す・直さないの判断が妥当か |
おかしいと思ったら、その段階で止めて直せます。
任せる量を減らしているのではなく、途中を見える形にしている、という感覚です👀
後で書く「PR のマージだけは自分で行う」も、同じ考え方から来ています。
「雑に起票して、後で詰める」
特に効いているのが、/refine-issue です。
アイデアは、思いついた瞬間に詳しく書こうとすると、面倒になって書かなくなります。
そこで、思いついたら 1 行だけで起票しておき、着手する前に AI と一緒に詰めるようにしました。
詰めるときは、AI がコードベースを調べたうえで質問してくれるので、
背景・受け入れ条件・関連する Issue まで、ほかの Issue と同じ密度で書けます。
アイデアを取りこぼさなくなったのが、一番大きな変化でした✨
「完了」の判定を、手順に組み込む
もう 1 つ、PR を作る前の完了判定も手順に入れています。
AI に「受け入れ条件を確認して」と頼むと、全部にチェックを付けて終わることがありました。
実際には満たせていない条件も、まとめて完了扱いになってしまうのです。
そこで、受け入れ条件を 1 件ずつ、3 つに分けるようにしました。
| 分類 | 意味 | 次にやること |
|---|---|---|
| A | 満たしている | 根拠を 1 行添えてチェックする |
| B | 実装や検証が足りない | PR を作らずに対応する |
| C | この PR ではどうやっても満たせない | 未達を記録して、別の Issue に切り出す |
ポイントは、チェックを付けるのは、全部が A か C になってからという順番です。
先にチェックを付けると、「足りていないもの(B)」と「この PR の範囲外のもの(C)」の区別が消えてしまいます。
さらに、A には根拠を 1 行添えます。
根拠が書けない条件は、実は Bだった、ということがよくあるからです🔍
④ メモリ:同じ指摘を、2 回受けない
スキルが「手順」なら、メモリは「申し送り」です。
作業中に AI が間違えて、それを指摘したとき、
その内容を理由と一緒にファイルに残すようにしています。現在 31 個あります。
形はそろえていて、何をするかだけでなく、なぜかとどう使うかを必ず書きます。
---
name: feedback_pr_number_added_after_pr_creation
description: docs に「PR #N で対応」と書く一文は、PR を作った後の追加コミットで初めて足す
---
(何をするか)
**Why:** なぜそうするのか。実際に起きたこと
**How to apply:** どういう場面で、どう適用するか
理由を書かないと、応用が効かない
たとえば、こんな申し送りがあります。
ドキュメントに「PR #◯◯ で対応」と書きたいとき、PR 番号は PR を作るまで決まりません。
以前は PR #<TBD> と仮に書いておき、後から差し替えていました。
すると、レビューで毎回「実際の番号に差し替えてください」と指摘されるのです😵
5 回同じ指摘を受けて調べると、原因が分かりました。
レビューは、PR を作った時点のコミットを見ているので、どれだけ早く差し替えても、指摘は必ず来ます。
そこで、メモリにはこう残しました。
-
何をするか:
PR #<TBD>を書かない。番号の一文は、PR を作った後の追加コミットで初めて足す - なぜか: レビューの対象は、PR を作った時点のコミットで固定されるから
「TBD と書くな」だけだと、AI は似ているけれど少し違う場面で同じ間違いをします。
なぜダメなのかまで書いておくと、初めての場面でも正しく判断できるようになりました。
メモリも Git で管理する
メモリはリポジトリの中に置いて、Git で管理しています。
別の PC で作業しても、同じ申し送りが効きます。
いつ・なぜ申し送りが増えたかも、履歴から辿れます📚
⑤ 権限と hooks:取り返しのつかない操作だけ止める
最後は、AI に何をさせないかです。
AI に任せる範囲を広げるほど、作業は速くなります。
一方で、取り返しのつかない操作をされたときの被害も大きくなります。
あじぴたでは、許可は広く、止めるのは取り返しのつかない操作だけという方針にしています。
許可と禁止を、設定ファイルで決める
Claude Code の .claude/settings.json で、操作ごとに許可と禁止を決めています。
| 許可(確認なしで実行できる) | 禁止 |
|---|---|
| テスト・lint・型チェックの実行 |
.env などの秘密情報ファイルの書き換え |
git add / commit / push
|
git push --force |
| Issue の閲覧・作成・コメント、PR の閲覧・編集 |
git reset --hard などの作業の破棄 |
| ファイルの読み書き | PR のマージ |
PR のマージを禁止にしているのは、本番へ出すかどうかを決めるのは人だと考えているからです。
実装からコミット・PR 作成・レビュー対応までは任せて、最後の判断だけ自分で行っています🔑
設定だけでは止めきれないものを、hooks で止める
ただ、設定ファイルの禁止は、コマンドの先頭の一致でしか判定できません。
たとえば .env への書き込みは、> でのリダイレクトや cp / sed -i など、いろいろな書き方ができます。
先頭の一致だけでは、すべては止めきれません。
そこで、コマンドを実行する直前に、文字列全体を検査する hook を入れました。
止めるもの:
1. .env* への書き込み(リダイレクト / tee / cp / mv / sed -i など)
2. .claude/settings* への書き込み(自分で権限を広げられないように)
3. force push
4. 作業ツリーの破棄
2 つ目は、少し面白い項目です。
AI が設定ファイルを書き換えて、自分で自分の権限を広げることができないようにしています🔒
止める仕組みにも、「通るべきものが通る」テストを書く
この hook には、テストも書いています。
止めるべきコマンドが止まることだけでなく、通るべきコマンドが通ることも同じ重さで確かめています。
たとえば git push origin fix/developer-notes は、develop という文字を含みますが、保護しているブランチではありません。
これを誤って止めてしまうと、普段の作業が全部止まります。
止める仕組みは、止めすぎても役に立たないからです。
PR を作る直前に、確認事項を差し込む
もう 1 つ、PR を作るコマンドを検出したときに、確認事項を AI に差し込む hook も入れています。
- PR の向き先(どのブランチからどのブランチへ)を表示する
- 受け入れ条件の照合(③の A / B / C)を思い出させる
スキルの手順に書いてあっても、作業が長くなると抜けることがあります。
一番抜けてほしくない瞬間に、もう一度目の前に出すための仕組みです👀
1 人の開発に、レビューを足す
ここまでは、AI に作業を任せるための仕組みでした。
最後に、AI に見てもらう話です。
1 人で開発していると、レビューをしてくれる人がいません。
そこで、すべての PR に GitHub Copilot のレビューが自動で入るようにしています。
指摘への対応は、③の /handle-review で進めます。
指摘を 1 件ずつ読み、直すか、直さない理由を書くかを判断して、それぞれに返信します。
レビューの指摘がきっかけで、設計を見直したこともあります。
- 外部 API の呼び出し上限を記録する表の権限を、管理者からも外した
- 外部 API を呼ぶ条件を、テストできる関数に切り出した
- 表示速度の計測で、リダイレクトされた試行を集計から外した
どれも、1 人で書いていたら気づかなかったかもしれない点です。
AIのためのルール作りは、人のためのルール作りだった
ここまで、AI に任せるためにルールで固める話をしてきました。
ドキュメントで決め、スキルで手順を決め、lint や hooks で機械的に縛る。
そうすると、AI は迷わなくなります。
命名も、ファイルの置き場所も、PR の出し方も、判断の余地が無いからです。
判断の余地が無いと、作業の質がぶれません。
誰がやっても、同じ品質に落ち着く状態が保たれます✨
人間の新人でも、同じではないか
ただ、ここで一度立ち止まって考えました。
これは、AI にだけ役に立つことなのか?
そんなことはありません。人間でも同じです。
ルールが決まっていて、迷う余地が無ければ、
人間の新人だって初日からルールに沿って、品質の高い仕事ができます。
逆に、ルールが暗黙のままなら、ベテランでも人によって書き方がぶれます。
AI が来る前から、できたはずのこと
そう考えると、ここに書いたことは、AI が登場する前からできたはずのことです。
AGENTS.md は、言ってしまえば新しく来た人向けの手引きです。
ADR は判断の記録、スキルは作業の手順書、hooks は事故を防ぐ安全装置です。
どれも、チーム開発で昔から大事だと言われてきたものばかりでした。
AI が来る前に、ここまでルールを決めきれていた現場なら、
人間だけでも、品質の高いコードが書かれていたはずです。
AI は、それをやらざるを得なくしただけなのかもしれません。
毎回初日の新人がやって来るので、準備を後回しにできなくなったのです🤖
大事なのは、AI のための準備をすることではなく、
AI にとっても人間にとっても、立ち上がりやすい環境を整えること。
まとめ
- AI は毎回初日の新人として来る。口で教えるのではなく、ファイルに置いておく📂
- AGENTS.md は地図、ADR には捨てた案と理由、繰り返す作業はスキル、受けた指摘は理由と一緒にメモリへ
- 許可は広く、取り返しのつかない操作だけを権限と hooks で止める🔒
- 迷う余地の無い環境は、AI にも人間にも効く。整えるべきは、誰でも初日から立ち上がれる環境
任せたい作業があるときは、まず「新しく来た人がこれを初日にやるなら、何を渡すか」を考えてみてください。
その答えは、AI にも、これから一緒に働く人にも、そのまま効くはずです💡
シリーズの他の記事も、よろしければ📚
このシリーズでは、個人開発サービス「あじぴた」の設計をテーマごとに書いています。
サービスの全体像や、ほかの記事の一覧はハブ記事にまとめています👇
🔗 「低評価を公開しない」口コミサービスを個人開発した話 — 4,300コミット・6リポジトリの全体像
これまでに公開した記事です。
🔗 Google Places APIで月$1,440の請求が来る前に — 個人開発で従量課金を「呼ばない」8層の防壁
🔗 Next.js 16 で Web Vitals を測って直した実録!loading.tsx で LCP が 2 倍になった罠と関数リージョン
🔗 「全部見せるためのRLS」は書かない。Supabaseで管理画面だけRLSをバイパスした理由
🔗 ディレクトリ構成は「AIへの指示書」になる。Next.js App Routerで自分の設計論を答え合わせした話
🔗 漏洩してもエラーは出ない。非公開データをアプリではなくDBで守る、SupabaseのRLSを選んだ理由
🔗 RLSが壊れてもテストは緑のまま。漏れても気づけない非公開データを、pgTAPで「落ちるテスト」にする
🔗 CI全緑でも、マージしてはいけないPRがあった。GitHub Actionsは「どこで止めるか」で設計する
次の記事では、Supabase の定期実行のバッチが「何もしていない」ことに、どう気づくかを書きました🔔
🔗 「失敗した」より「何もしていない」が怖い。Supabaseのpg_cronとpg_netで作る、静かな失敗に気づく監視
設計の中身を通して読みたい方には、解剖ドキュメントも公開しています🔬
🔗 あじぴたの内側(ajipita-inside)
参考になれば幸いです🙏