先週の現場から
先週、東京近郊の小さな物流会社の事務所で、ベテラン社員の方からこう言われた。「Excelに転記するだけで、一日の半分が消えてしまう」。今回のプロジェクトは、そのExcel転記と受信メールの仕分けを内製ツールに置き換えるという話だった。フルタイムの開発者を雇うほどの規模ではないが、放っておけば毎月数十時間が消える。Claude Codeで小さく作り、運用は社員自身が回せる形に着地させるのがゴールだった。
本記事は、その実装で実際に使ったCLAUDE.mdの組み方とサブエージェントの分け方を、後で同じ問題に当たる人のためのメモとして残す。

前提と環境
使った道具は次の通り。
Claude Code (CLI 2.x 系)
Node.js 22 / TypeScript 5
MCP: Gmail と Google Spreadsheet 用の社内ラッパー
プロジェクト構造はシンプルに分けた。
.
├── CLAUDE.md
├── .claude/
│ ├── agents/
│ │ ├── mail-triage.md
│ │ └── sheet-writer.md
│ └── commands/
│ └── weekly-run.md
├── src/
│ ├── triage.ts
│ └── sheet.ts
└── package.json
CLAUDE.md は「一枚の業務手順書」として書く
最初は技術スタックを羅列したCLAUDE.mdを書いていた。実際にやってみると、それでは効かない。Claude Codeにとって本当に効く情報は、フォルダ構成や型定義よりも「触ってはいけないところ」と「業務側の暗黙の前提」だった。
# 社内メール仕分けツール
このプロジェクトについて
受信メールを「見積依頼 / 在庫確認 / その他」に分類し、
週次でGoogleスプレッドシートに転記する。
動かすのは非エンジニアの事務担当。月曜の朝に1回。
触らない約束
スプレッドシートのA列(担当者名)は人が手で編集する
./logs/*.jsonl に個人情報を書かない (件名と分類結果のみ)
本番Gmailラベルの付け替えは dry-run を通してから
よく使うコマンド
npm run dev : ローカル実行 (Gmailはモック)
npm run triage : 分類のみ (書き込みなし)
npm run sync : 本番スプレッドシートへ反映
200行を超えた瞬間にコンテキストが太って、応答が雑になった。30行の手順書1枚に削ったほうが、結果的に意図通りに動く。長く書くほど効くわけではない。
サブエージェントは「責任分界」で切る
私の最初の切り方は機能ベースだった。「メール処理担当」「スプレッドシート担当」という具合だ。ところが運用してみると、メール本文の引用を最小限にしないと個人情報がログに漏れる。「責任分界 = どのデータを見てよいか」で切り直したら、ようやく安定した。
---
name: mail-triage
description: 受信メール本文を3カテゴリに分類する。本文の引用は最大2文まで
tools: Read, Grep
あなたは物流会社の事務担当。日本語ビジネスメールを読み、
次の3カテゴリへ分類する。
見積依頼: 価格や納期の問い合わせ
在庫確認: 商品の有無を尋ねる文面
その他
出力は JSON のみ:
{"category": "...", "reason": "理由を1文", "snippet": "本文から最大2文"}
tools を Read と Grep だけに絞ると、prompt が短くても勝手に WebFetch を呼びに行ったりしない。サブエージェントは「権限の薄い同僚」だと思って設計するとちょうどよい。
30分ハマったポイント
MCPの環境変数が、サブエージェント側のセッションでは読まれていなかった。親プロセスのenv は引き継がれるが、.mcp.json 内の参照(${YOUR_API_KEY} 形式)が、サブエージェント起動時に展開されないケースがある。.claude/settings.json のenv ブロックに改めて書くことで通った。
もうひとつ。CLAUDE.mdに「個人情報をログに書かない」と書いただけでは、ロガー側の console.log まで止められなかった。約束は文章ではなく、logger.ts のフィルタ関数で物理的に止めるのが正しい。約束は人間への宣言、コードへの強制は別物。これは小さいが、見落とすと後でつらい。
動作確認
$ npm run triage
[mail-triage] 取得: 23件
見積依頼: 8
在庫確認: 11
その他 : 4
書き込み: スキップ (dry-run)
所要: 47s
初回の23件のうち、誤分類は2件。ベテラン社員が手で直したラベルを翌週のCLAUDE.mdに「こういう件名は在庫確認に寄せる」と1行追記したら、次の週の誤分類は0件になった。手順書を育てる感覚に近い。
応用のしかた
製造業: 図面PDFからの寸法抽出と発注書の突合
小売: 在庫CSVの異常値検出と再発注候補リスト
飲食: 仕入伝票のOCR後データ整形と原価計算
建設: 現場日報からの遅延要因の要点抽出
どれも「フルタイム開発者を雇うほどではないが、毎月数十時間が消えている」たぐいの仕事だ。Claude Codeで小さく書き、CLAUDE.mdを業務手順書として育てる、という型はそのまま使える。
まとめ
正直なところ、CLAUDE.mdは長く書くほどよい、という思い込みは捨てたほうがいい。30行の業務手順書1枚と、責任分界で切ったサブエージェント数本のほうが、SMBの現場では速く、壊れにくい。参考にしたのは Zenn の「Claude Code 個人開発実録」(動くプロダクトを2つ並行運用している筆者の記録)で、業務向けツールでも同じ原則が効いた。次に試したいのは、CLAUDE.md自体をAIに育てさせる仕組みだ。
筆者は 5years+ で日本市場のAI/LLM業務応用を担当している。
Claude CodeでSMB向け業務自動化ツールを最短で作る実装メモ — CLAUDE.md とサブエージェント運用