この記事は Zenn に投稿したものの再掲です。
https://zenn.dev/reona777/articles/slash-commands-as-trap-notes
教育系の事業所で現場の運営をしています。エンジニアではありません。2026年の春から Claude Code で社内ツールを作り始めて、5か月で6本を本番稼働させました。
前の記事で、プロジェクトの中で破綻しないように CONTEXT.md と SPEC.md と ADR を書かせる話をしました。
あの3つはプロジェクトの中では効きます。ただ、プロジェクトをまたぐ作業には効きません。デプロイ、公開、決まった様式の資料作り。これらは「プロジェクト」ではなく「作業」なので、置き場所がありません。結果として、私は同じ説明を毎回ゼロから書いていました。
今は ~/.claude/commands/ に4本のコマンドが置いてあります。合計653行です。この記事はその中身の話です。
結論を先に書きます。このファイルに書く価値があるのは手順ではありません。手順はAIが自分で調べられます。書く価値があるのは、実際にやってみて壊れた場所のほうです。
同じ説明を3回したらコマンドにする
私が最初に作ったのは、GASのコードをローカルから反映させるためのコマンドでした。
やること自体は clasp push の一行です。それでも毎回説明が必要でした。アカウントが2つあってスクリプトごとに所有者が違うこと、ディレクトリを移動してから打つこと、-f を付けないと弾かれること。会話が変わるたびにこれを書いていました。
同じことを何度か書いたあとで、ファイルにしました。
コマンドは ~/.claude/commands/<名前>.md に置くだけです。Markdownで、中身は日本語の指示で構いません。置くと /名前 で呼び出せて、引数は $ARGUMENTS で受け取れます。
現在の4本はこうなっています。
-
/clasp— GASプロジェクトをアカウント別に操作する(92行) -
/obs— 直前に生成した内容をObsidianに保存する(32行) -
/public— 社内ツールを固有名を落として作品として公開する(152行) -
/mendan— 決まった様式の面談資料を組み立てる(377行)
行数がばらついているのは、扱う作業の危なさがばらついているからです。/obs は保存先のフォルダを決めるだけなので32行で足ります。/public が152行あるのは、一度でも間違えると取り返しがつかないからです。
中身の大半は「前に踏んだ罠」になった
/clasp を例にします。92行のうち、実際のコマンドの打ち方を書いているのは10行ほどです。残りは、どのアカウントで何が見えるかと、私が踏んだ場所です。罠の節だけで34行あります。
-u はサブコマンドより前に置く。 clasp login -u reona は弾かれます。-u はプログラム全体のオプションなので clasp -u reona login が正しい。これは調べれば分かることですが、調べ直す時間が毎回かかります。
create-script は appsscript.json を既定値で上書きする。 timeZone が America/New_York に戻ります。GASのトリガーが走る時刻はこの設定で決まるので、直し忘れると毎日動くはずのものが動く時間だけずれます。エラーは出ません。気づくのは誰かが「今日の通知が来ていない」と言ったときです。
{
"timeZone": "Asia/Tokyo",
"dependencies": {},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8"
}
login は対話式なので代理実行できない。 ブラウザが開いて人が承認するので、AIには実行できません。ここには「ユーザーに ! clasp -u <名前> login を打ってもらう」と書いてあります。誰がやるのかを書いておかないと、AIは実行できないコマンドを実行しようとして失敗し、そこから復帰しようとしてさらに時間を使います。
delete-script はあてにしない。 確認プロンプトで止まるので -f が要るうえ、-f を付けても has not granted the app write access で弾かれることがあります。claspのOAuthが drive.file しか持っていないためです。ここには「消すのは管理画面から手作業でやってもらう方が確実」と書いてあります。できないことを、できないと書いておくのも中身のうちです。
一覧の照合はタイトルではなくIDでやる。 スクリプト一覧はタイトルを「問題集復習管理バッ…」のように途中で切ります。フルネームで grep すると「無い」と判定されます。私はこれを実際にやって、あるものを無いと報告しました。
いちばん高くついた罠は、テストの話でした
/public に書いてある罠のうち、1本だけ性質が違うものがあります。
社内ツールを公開用に作り直すとき、コードに入っている人名を架空の名前に差し替えます。差し替えてテストを流したら落ちました。
原因は localeCompare(_, "ja") でした。名前を変えると並び順が変わります。ここまではよくある話です。
問題はそのあとです。落ちたのは優先順位を検証しているテストでした。よく見ると、そのテストの期待値は名前の五十音順と同じ並びになっていました。つまり、優先順位のロジックが壊れて名前順を返すようになっても、そのテストは通り続ける状態でした。 名前を差し替えたことで、たまたま両者がずれて、初めて表に出たわけです。
期待値を書き直せばテストは緑に戻ります。でもそれをやると、壊れても気づけないテストがそのまま残ります。ここでやるべきは、優先順位と名前順が逆になるように名前を割り当て直すことでした。
/public にはこの経緯ごと書いてあります。「期待値を直すだけで済ませない」という1行だけでは、半年後の自分が理由を思い出せないからです。
もう1つ、環境の癖も書いてあります。Git Bash の grep はマルチバイト文字クラス([一-鿿])が壊れます。 漢字の連続を探して人名の消し漏れを見つける処理を書いたのに、何も出てこない。パターンが悪いのだと思って何度も書き直しました。壊れていたのは grep のほうでした。この種の検査は必ずPythonで書く、と書いてあります。
何を書くか
4本書いてみて、骨格はだいたいこの順に落ち着きました。
# /<名前> — 一行で何をするコマンドか
## やること
`$ARGUMENTS` が空なら AskUserQuestion で選ばせる。
あるなら聞かずに、1語目を<なにか>として扱う。
## 破ってはいけない
**<取り返しがつかないこと>。** 理由。
## 手順
```bash
そのまま実行できる形で書く
```
## 罠
**<症状>。** 原因と、どう避けるか。
## 関連
[[別の記録]] … 判断の理由はそっちに置く
効く順に並べると、こうなります。
破ってはいけないことを先頭に置く。 /public は手順より先に「破ってはいけない3つ」が来ます。既存のプライベートリポジトリを公開に切り替えない、本名を出さない、元のリポジトリには手を加えない。禁止事項が手順の後ろにあると、AIは手順を実行し終えてから禁止事項を読みます。
引数が空のときの振る舞いを決める。 /clasp は引数が無ければ AskUserQuestion でアカウントと操作を選ばせ、引数があれば聞かずに実行します。ここを決めておかないと、毎回どちらかで揉めます。
手順はそのまま実行できる形で書く。 説明文ではなくコマンドで書きます。git -C ~/<private> archive HEAD | tar -x -C ~/<public-name> のように書いておけば、解釈の余地が減ります。ちなみにこの一行にも理由があって、ディレクトリごとコピーすると node_modules や .env が紛れ込むので git archive を使っています。
「これは人がやる」を明記する。 対話式の認証、ブラウザでの承認、権限の再取得。gh repo delete が既定トークンの権限不足で403になる話もここです。AIができないことの一覧は、AIに渡す文書にこそ要ります。
関連する記録にリンクする。 私は判断の理由を別のノートに書いているので、コマンドからはそこへ飛ばします。コマンド自体は手順と罠だけにして、経緯は外に置きます。
効いたこと、効かなかったこと
効いたのは3つです。
説明が消えました。/clasp reona push と打てば、アカウントの使い分けもディレクトリ移動も -f も全部済みます。
同じ事故を繰り返さなくなりました。timeZone の巻き戻しは、書く前に踏んだから書いてあります。書いてからは踏んでいません。
そして、自分が読み返す文書になりました。 これがいちばん予想外でした。半年前に何をどう決めたかは覚えていません。コマンドを開けば、手順ではなく「何がまずかったか」が書いてあります。
効かなかったこともあります。
全部をコマンドにしようとしたのは失敗でした。 1回しかやらない作業をコマンドにしても、書く時間のほうが高くつきます。3回同じ説明をしたら、が今のところちょうどいい基準です。
手順だけのコマンドは、あってもなくても変わりませんでした。 調べれば分かることを書いても、AIは調べれば分かります。差が出るのは、調べても出てこない部分——自分の環境で、実際に、何が壊れたか——だけです。
長ければ強いわけでもありません。 377行あるものは、扱う作業に分岐が多いのでそうなっただけです。長くなるほど読ませる負荷も上がるので、短く済むならそのほうがいいです。32行のものは32行のままで困っていません。
まとめ
Claude Codeのスラッシュコマンドは、手順書の置き場だと思っていました。実際に運用してみると、踏んだ罠の置き場として使ったときにいちばん効きました。
手順はAIのほうが速く正確に調べます。調べられないのは、自分の環境の癖と、自分が過去に壊した場所です。そこだけを書き残すと、653行の大半が罠になりました。
ほかに作ったものはここに置いています。
書いている人
エンジニアではありません。勤務先の業務ツールを Claude Code で作って運用していて、作ったものと、壊れたときに直した話を書いています。
Claude Code の実務運用については X(@KouritsuONI)でも書いています。スプレッドシート・GAS・LINE・Salesforce まわりの業務自動化について、ご相談は X のDMからどうぞ。
この記事のシリーズ
Claude Code の実務運用について、順に9本書いています。
- 非エンジニアがClaude Codeで社内ツールを6本 本番稼働させるまでにやったこと
- AIに作らせたツールが本番で壊れた5つの原因と、直し方
- Claude CodeにCONTEXT.mdとSPEC.mdとADRを書かせると、途中で破綻しなくなる
- Claude Codeのスラッシュコマンドには、手順ではなく踏んだ罠を書く(この記事)
- Claude Codeのメモリに53本ためて分かった、書く価値のある事実とない事実
- 実行は成功、でも誰にも届いていない。無言で失敗する自動化に気づく仕掛け
- Salesforceの項目は「ある」と「使える」が別だった。外から自動化して踏んだ6つ
- Salesforceのパスワードを変えたら、連携が8箇所いっせいに止まった
- Salesforceのログインが2027年6月に廃止される。自動化10本を調べたら、直す場所は1つではなかった