はじめに:禁止リストを増やすほどAIが迷った
当社(合同会社ジョインクラス)は、出版・マーケ・営業などの定常業務をClaude Codeとシェルスクリプトで回しています。その中心にあるのが CLAUDE.md です。
過去に僕は、事故が起きるたびに CLAUDE.md へ「〜するな」を足していました。AIが git push --force を実行してブランチが消えたときは「絶対禁止リスト」を作りました。営業メールを確認なしで送って敬語のおかしいメールが取引先に届いたときも、禁止事項を追加しました。
その結果、CLAUDE.md は1,000行を超え、ルール同士が矛盾し、指示と逆の動作をするようになった。これが当社の実体験です。そこから「200行以内に収め、詳細は .claude/agents/ に分離」「禁止ではなく手順で書く」という方針に切り替えました。
この記事では、その書き分けを実ファイル・実スクリプトで解説します。今日から自分の CLAUDE.md を書き換えられる粒度で書きます。
なぜ「禁止」は効きにくいのか
禁止文には3つの弱点があります。
- 代わりに何をすべきかが書かれていない:「直接送信するな」と書いても、では何をするのかが空白です。モデルは空白を推測で埋めます。
- 否定はトリガーが曖昧:「危険な操作をするな」の「危険」の範囲をモデルが毎回解釈し直します。
- 禁止は積み上がって衝突する:「中間確認するな」と「対外アクションは承認を取れ」が並ぶと、どちらが優先か分かりません。当社で実際に起きた矛盾がこれでした。
一方、手順文は 「条件 → 行動 → 出力先」 が揃っているので、モデルは判断ではなく実行をすれば済みます。
Before / After:実際の書き換え
例1:対外アクション
Before(禁止形):
- メールを勝手に送らないこと
- SNSに勝手に投稿しないこと
- 請求書を勝手に発行しないこと
After(手順形・当社の CLAUDE.md から抜粋):
## 権限制御ルール
全てのアクションは `.company/steering/permissions.md` の閾値に従う。
- **read-only:** 分析・レポート系は承認不要で自動実行
- **draft:** 対外アクション(メール送信、請求書発行、SNS投稿、デプロイ等)は必ずdraftモードで生成し、approval-queue.md に追加
- **execute:** 閾値内の内部アクション(バグ修正、テスト実行等)は自動実行
**重要:** 対外に影響のあるアクションを直接実行してはならない。必ずdraft → 承認 → 実行のパイプラインを通す。
ポイントは、禁止文を1行だけ残し、その直後に「代わりに通る道」を書いていることです。禁止を消す必要はありません。禁止の後ろに必ず手順を置く、というのがルールです。
例2:判断が必要なゲート
「よく調べずに新施策を始めるな」は典型的な効かない禁止文です。当社ではこれを、トリガーを列挙した表と除外条件に書き換えました。
### 仮説検証の必須トリガー(`/validate-hypothesis`)
以下に該当する施策が提案された場合、実行前に必ず `/validate-hypothesis` の実行をCEOに提案する。
| トリガー | 例 |
|---------|---|
| 新しい広告チャネルへの出稿 | X広告、Meta広告など未検証のプラットフォーム |
| 新商品・新サービスの開発 | 新書籍、新SaaS、新講座 |
| 月額¥5,000以上の継続的な投資 | 広告予算、新ツール導入、外注契約 |
**除外(仮説検証不要):**
- 既存事業の運用改善
- 既に検証済みの施策の拡大
- コスト削減・効率化の施策
**違反時の対応:**
- 検証なしに実行した場合 → 「仮説検証をスキップしました。リスクがあります」と明示的に警告する
ここには3つの部品があります。
- トリガー(いつ):具体例つきの表。「新しい」の解釈を例で固定する
- 除外(いつやらないか):これがないとモデルは何にでもゲートをかけて作業が止まる
- 違反時の対応(失敗したら何を出すか):完璧に守れなかったときの挙動まで手順化する
特に「違反時の対応」は禁止形では絶対に書けない部分で、効果が大きいと感じています。
自動実行プロンプトでも同じ書き分けを使う
CLAUDE.md だけでなく、cron / launchd から claude -p を叩くプロンプトも同じ原則で書いています。以下は当社で毎日動いている記事補充スクリプト auto-replenish-articles.sh の一部です(claude_run は claude CLIのラッパー関数)。
claude_run replenish --effort low --allowedTools "Write,Read,Edit" -p "
以下のテーマでZenn記事を1本書いて、ファイルに保存してください。
テーマ: $theme
【最重要】この記事の読者は「導入を決める立場の人」です。機能解説ではありません。
- 判断の裏づけとして、**設定例またはコマンドのブロックを1つ以上**必ず含めること
- コードは架空のものではなく、自社で実際に動いている実装をベースにすること
参照: /Users/kyoagun/workspace/one-ceo/.company/scripts/ 配下の実スクリプト
- 読んだ開発者がその日に手を動かせる粒度で書くこと(手順・落とし穴・検証方法)
ルール:
- topics は技術タグを最低3つ含める
- 経営視点は「なぜこれを作ったか」の導入と結びに留め、本体は実装で構成すること
- published: false で作成
保存先: /Users/kyoagun/workspace/zenn-content-company/articles/${slug}.md" > /dev/null 2>&1
「架空のコードを書くな」ではなく「このディレクトリの実スクリプトを参照せよ」と書いています。参照先パスを渡すと、モデルは「書かない」を守る代わりに「読みに行く」という具体的な行動を取ります。
手順は「検証」までセットで書く
手順形にしても、守られたかどうかを確かめなければ意味がありません。当社では生成直後に機械的なチェックを入れています。同じスクリプトの続きです。
# バリデーション: コードブロックが2つ以上あるか
GENERATED_ZENN="/Users/kyoagun/workspace/zenn-content-company/articles/${slug}.md"
if [ -f "$GENERATED_ZENN" ]; then
FENCE_COUNT=$(grep -c '^```' "$GENERATED_ZENN" || true)
if [ "$FENCE_COUNT" -lt 4 ]; then
echo "$(date): WARNING: コードブロックが不足(${slug}: $((FENCE_COUNT / 2))個)" >> "$LOG_FILE"
fi
fi
プロンプトの手順(「2つ以上含める」)と、検証(フェンス4本以上)が1対1で対応しています。数えられる形で手順を書けば、検証も書ける。これが禁止文との一番大きな違いです。「質の低い記事を書くな」は検証できませんが、「コードブロックを2つ以上」は grep -c で検証できます。
自分のCLAUDE.mdを点検するワンライナー
同じ考え方で、既存の CLAUDE.md から「後ろに手順がない禁止文」を洗い出せます。以下は僕が書き換え作業で使っている簡易チェックです。
# 禁止表現を含む行と、その次の行を表示する
grep -n -A1 -E '(しない|するな|禁止|してはならない|NEVER|DO NOT|Don.t)' CLAUDE.md
出力を見て、各禁止行に次のどれかが付いているか確認します。
- 代わりの行動(「代わりに〜する」「必ず〜を通す」)
- 参照先パス(「〜は
path/to/fileに従う」) - 違反時の出力(「〜した場合は〜と報告する」)
どれもなければ書き換え対象です。
書き換えの手順(今日やること)
- 上のgrepで禁止行を一覧化する
- 各行を「条件 → 行動 → 出力先」の3点に書き換える。禁止文自体は1行残してよい
- 判断を伴うものは「トリガー表+除外+違反時の対応」の3部品にする
- 詳細手順が5行を超えるものは
.claude/agents/や.claude/skills/に切り出し、CLAUDE.mdにはパスだけ残す(当社は200行以内が目安) - 自動実行するプロンプトは、手順に対応する機械検証(
grep -cなど)を1つ追加する
落とし穴
- 除外条件を書き忘れる:手順形にした直後、何でもゲートにかかって作業が止まりがちです。最初から「やらなくていいケース」を書きます。
- 手順同士の優先順位:「完全自律で中間確認しない」と「対外アクションは承認を取る」は両立します。ただし、「内部作業は自律、対外はdraft」と境界を明文化しないと衝突します。
- 数値で書けるものは数値で書く:「少し」「適切に」はモデルの解釈に任せることになります。「1日1件まで」「200行以内」のように書きます。
検証方法
書き換え前後で同じタスクを claude -p で数回ずつ流し、ログを比べるのが手軽です。
for i in 1 2 3; do
claude -p "新しい広告チャネルとしてTikTok広告を始めたい。進めて" \
--allowedTools "Read" > "out-$i.txt"
done
grep -l "validate-hypothesis" out-*.txt | wc -l
当社の例だと、ゲートが効いていれば全回で /validate-hypothesis の提案が出ます。出ない回があれば、トリガー表の例が足りないサインです。
おわりに
僕が CLAUDE.md を1,000行まで膨らませて学んだのは、「AIに何をさせないか」より「AIが何をすればいいか」を書くほうが、結果的に事故が減るということでした。禁止は事故の記録で、手順は運用の設計です。経営でも、部下に「ミスするな」と言うより手順書を渡すほうが成果が出るのと同じ話だと感じています。
CLAUDE.md の分割設計・優先順位の付け方・コストを抑える書き方は、書籍『CLAUDE.md設計パターン』で体系的にまとめています。この記事の「トリガー表+除外+違反時の対応」の型も、他のパターンと合わせて収録しています。
書籍一覧はこちら: https://zenn.dev/joinclass?tab=books