ClaudeCodeのコーディングのためのFeatureコマンドを実装する
初めに
本記事は「AIに任せたら30分でXXXができた」ではなくAIエージェントへの指示を人間が細かく監視し成果物を逐次確認する伴走型のコーディングスタイルについての記事となります。
前提として
現在時点ではClaudeCodeのアウトプットはいいときも悪い時もあるガチャ状態です。一定の成果物のためには生成AIへの作り直しを延々と繰り返すスタイルと、70%程度までできたら後は人間が修正するスタイルがあるかと思いますが、実際に商用での稼働を考えると人間が最終的に修正するケースの一択かと考えています。
本記事ではこの残り30%を含めAIに100%コードを書かせ尚且つ人間の意図通りのものを正確に作ることを目的としています。
はじめに下記の既知の課題について説明し、そのノウハウを持って実際のコード開発における解決策を検討していきます。
既知の課題 と解決のアプローチ
- コンテキストの量が多くなると回答精度が落ちる、同じ指示でも再現性がない
- 実行前にResetを行うメモリを解放する
- カスタムスラッシュコマンドを使う、コマンド内で/todo,/fixなどの組込みコマンドと自分が作ったコマンドを呼び出す
- 実行したい作業に合わせて@をつけて参照ファイルを明示的に読み込ませる
- 英語で指示し成果物も英語で作成後に日本語版を作成してもらう
- 長い作業の途中でIDEが落ちた場合に再開後の挙動が不安定
- 原則会話の圧縮が起こらない範囲で作業をさせる
- 作業のTodoごとにファイルを出力させる
- 作業完了ごとに細かくGitにアップする
- 作業の進捗ごとに進捗情報をファイルとして出力させる
- claude.mdファイルが肥大化してコンテキストを圧迫する
- 階層ごとに必要なルールを記述し、やりたい作業ごとにルールを記述する
- ルート階層には全体として守ってほしいこと、下層ではコーディング規約など各階層で守ってほしいルールが重複しないようにしつつ、下層ではより具体的な作業に即したルールを読み込ませる
- AIが見当違いなファイルを修正してしまい、酷い時には無限ループになる
- 修正したいファイルのあるディレクトリでIDEを開きClaude Codeを起動する
- 確定済みのファイルはsettings.jsonでwrite,denyにする
- サブモジュールかGit WorkTreeで汚染を防止する
開発のためのカスタムコマンドの実装
戦略
- メンタルモデルの言語化
- AIコーディングにおけるBDDの導入
- AIコーディングにおけるTDDの導入
メンタルモデルとはなにか?
下記の記事の内容から着想を得ています
記事の内容はAIには人間のようなメンタルモデルがないのでソフトウェアを作ることはできないとの主張です。
メンタルモデルがAIになければそれを言語化してAIに与えることができれば、よりAIに任せられる割合が増加できるんではないかというのが今回の着眼点となります。
コードやシステムがどう動くかを頭の中でシミュレーションできる能力
例:ある関数を直したら、他のモジュールやテストがどう影響を受けるかを予想できる。
抽象的な概念を組み立てる思考枠組み
例:クラス設計の責務分担、非同期処理の流れ、データベースとAPIの整合性などを理解する。
意図と仕組みをつなげる橋渡し
例:「ユーザーにこの機能を提供したい」→「UI → API → DB → インフラ」という一連の流れを頭の中で組み立てられる。
わかりやすく比喩すると:
人間エンジニアは「家を建てるときに、構造図を頭に入れて“この柱を抜くと家全体が崩れる”と予想できる」
LLMは「過去に見た家の写真を参考に“それっぽい設計図”を描ける」けれど、強度や耐震性まで理解していない
ディレクトリ構造
- features/
- .claude/
setting.json
# 基本はCWDから/features/{Feature Name}のみ編集可
# 上位階層の追加で../claude.mdを参照可能にする
# この階層では各Featureの関係性とドメイン要求の言語化を行う
- commands/
- claude.md
# 必ず下記の順で作業を行う
# (1)要求仕様の作成(2)詳細設計(3)実装順番と実装単位の分解
# (4)テスト設計(5)実装(6)セキュリティチェック、品質チェック
- docs
- bdd.md(English)
# このプロジェクトで達成したいゴール、目的を記載する
# 下位階層から参照し、上位レイヤーbdd.mdに記載のゴール、目的にそってはない実装を制限する
- scope.md
# bddの内容か作らなけれいけない機能に分割する
# 例、機能(1)フロントエンド、機能(2)バックエンド
# 各Feature間のIFを規定
# 最初にデータ設計を始めるなどの着手順を規定
- codingRules.md
# どんな時でも守るべきルールの記載(再利用性の担保、密結合の回避、単一責任の法則)
# 守るべきコーディングルールのリスト
# フロント、バックエンドなどの種別により抜粋して{Feature Name}配下に設置
-jp/
- bdd.md(Japanese)
# 文書は全て英語で記述し作成後に日本語版を作成する
- {Feature Name}
- claude.md
# 上位階層のbdd.md、scope.mdを参照する
# このディレクトリが何の作業をするべきか確認しながら作業を行う
- docs
- requirement.md
# 要求仕様を記載
- specification.md
# 詳細設計を記載
- codeList.md
# src配下のコードのリストを抜粋
# 実際のコードの記述はCWDでsrc/配下のディレクトリを開いてAIを起動する
- src
- claude.md
# 上位階層のrequirement.mdを参照
# 上位階層のspecification.md
# 上位階層のcodingRules.mdから必要なルールを抜粋してカスタムルールを作成
- codeA/
- docs/
- codingRules.md
# コーディングルールを記載
- tdd.md
# 単体テスト計画を記載
- codeC/
- codingRules.md
- tdd.md
- deploy
- codeA/
- codeC/
- tmp
- status.json
/Featureコマンドによる開発の流れ
プロジェクト概要を作成する
- Feasures配下のbdd.mdに対話形式でドキュメントを作成する
- 機能の単位はフロントの何々、データベースの何々などの単位、種別としてUI、データ、BFF、ETL
- scopeの中に各Feature間のIFを記載
開発準備
- Feasures配下のbdd.mdを参照して必要な機能を洗い出す
- 機能の単位はフロントの何々、データベースの何々などの単位、種別としてUI、データ、BFF、ETLを用意する
- コマンドを実行する際に他のFeatureコマンドとの関連性を記述する
- src単位で内部処理を洗い出し必要なコーディングルールを抜粋して作成し、実装の際は参照するようにする
- src配下で必要な機能が圧縮しないで済むコンテキスト量で済むように分割する
- 他のsrcとの関連性を記述する
- src配下での単体テストコードの計画を行う
- Feature内部での連携テストの計画を行う
実装
- src配下のディレクトリをCWDとしてIDEを開きClaudeCodeを起動する
- 上位レイヤーのScope.mdから全体の今の作業の位置、目的、関連する他のコードを確認する
- 開発ステータスを確認し、コーディング開始の指示を出す
- 単体テストまで終わったらGitにPushする
- 以下src配下のディレクトリで実装作業を全て実行
- コードの実装とデプロイは分離する
サンプル
bdd.md
# GOAL (BDD)
- Use BDD format for every feature:
Given <current context/state>
When <action/event>
Then <observable outcome and acceptance criteria>
- Always restate the goal before proposing code.
- Do not propose changes that don't move us closer to the stated goal.
codingRules.md
# CODE QUALITY CHECKLIST (All must be verified before writing code)
For every proposed change, check each item below.
If any anti-pattern is detected, STOP and propose a refactoring or alternative design.
## (1) 再利用性
- [ ] コードは特定環境/グローバル変数に依存していないか
- [ ] 関数やクラスは小さく、組み合わせて再利用できるか
- [ ] 同じ処理を重複して書いていないか(共通化可能か)
## (2) 凝集度と結合度
- [ ] 1つのクラス/モジュールは単一責任か(SRP)
- [ ] 異なる関心(UI・DB・ビジネスロジック)が混在していないか
- [ ] 外部依存(DB/HTTP/FS)はインターフェースやポート越しに扱っているか
## (3) クラス・モジュール設計
- [ ] コンストラクタは軽量か(重い処理や副作用はないか)
- [ ] if/switch の乱用ではなく、Strategy/Factory などの拡張パターンを利用しているか
- [ ] 公開メソッドは最小限か(外部に余計な実装を晒していないか)
## (4) 命名と構造
- [ ] 名前が役割や契約を明確に表しているか(曖昧な util/data ではないか)
- [ ] 1ファイル = 1主要クラス/モジュールになっているか
- [ ] ドメイン用語に沿った命名か(実装都合の略語ではないか)
## (5) エラーハンドリングと契約
- [ ] 入力検証を境界で行っているか
- [ ] エラーは握りつぶさず型/Result/例外で返しているか
- [ ] catch では必ず文脈を追加して再throwか変換しているか
## (6) 依存関係の管理
- [ ] UIやドメインから直接DB/外部サービスを叩いていないか
- [ ] 依存注入(DI)が使われているか
- [ ] 環境変数や設定値は境界層で処理され、コアに漏れていないか
## (7) 並行処理と状態管理
- [ ] 共有可変状態やグローバル状態を避けているか
- [ ] 非同期処理の順序が保証されているか、保証されないなら明示しているか
- [ ] ロックや排他は責任が明確になっているか
## (8) パターンとアンチパターン
### 推奨パターン
- Hexagonal Architecture(依存を内外に分離)
- Strategy(振る舞いの差し替え)
- Factory(生成の一元化)
- Adapter(外部API/形式の変換)
- CQRS(読み取りと更新を分離)
### アンチパターン(必ず検出し、報告+改善案を提示すること)
- [ ] God Object(なんでも詰め込んだ肥大クラス)
- [ ] Deep Inheritance(3段以上の継承)
- [ ] Long Parameter List(引数が5つ以上)
- [ ] Feature Envy(あるデータを頻繁に操作、振る舞いが別クラスにあるべき)
- [ ] Shotgun Surgery(1つの変更で多くの箇所を修正しなければならない)
- [ ] Divergent Change(1つのクラスが異なる理由で頻繁に修正される)
- [ ] Global Mutable State(グローバル変数の読み書き)
- [ ] Hidden Dependencies(隠れた依存、newやシングルトン直呼び)
- [ ] Copy-Paste Code(コピペの繰り返し)
- [ ] Primitive Obsession(ドメインを表す型を作らず、生のstring/int乱用)
- [ ] Data Clumps(常にセットで渡される引数や変数の集合)
- [ ] Inappropriate Intimacy(モジュール間で内部状態を直接触る)
- [ ] Middle Man(仲介だけして責務を持たないクラス)
- [ ] Speculative Generality(不要な抽象化や未使用の拡張点)
- [ ] Magic Numbers/Strings(定数やEnumで表現すべきものを直値で記述)
- [ ] Excessive Comments(コードで表現すべき意図をコメントで埋め合わせ)
- [ ] Circular Dependencies(相互依存)
- [ ] Law of Demeter Violation(チェーン呼び出しで他モジュールの内部を操作)
---
# AI の実行ルール
1. コード提案を行う前に、上記リストを順にスキャンし「問題なし/検出あり」を記載する。
2. アンチパターン検出時は必ず改善案を提示する。
3. 検出がゼロなら「No issues found. Proceeding to code suggestion.」と宣言してからコードを書く。
参考記事
Discussion