sasaryo.dev  |  blog   about

Claude CodeのカスタムスキルをAtomとRecipeに分けて運用する

#terminal

毎回、進め方がブレる問題

Claude Codeにタスクを丸投げすると、進め方が毎回違う。あるときは丁寧に調査してから実装し、あるときはいきなりコードを書き始める。設計の確認なしに実装が終わっていて、方向性が違ったので全部やり直し、ということも起きる。

CLAUDE.mdに「必ず調査してから実装すること」のような手順を書いてみたのですが、手順が増えるほど守られなくなっていきました。そこでカスタムスキル(スラッシュコマンド)で開発の進め方そのものを構造化することにしました。

最初に作ったのは、調査から実装・PR作成までを1つに詰め込んだ巨大なワークフロースキルでした。これは失敗でした。タスクの種類が違うと手順の一部が合わなくなり、その都度スキル本体を書き換えるはめになります。途中でやり直したいときの分岐も表現しきれませんでした。

この反省から、いまはAtomRecipeという2層にスキルを分けて運用しています。

発想としてはUnixのパイプに近く、小さな単機能のコマンド(Atom)をつなぎ合わせて、目的に応じたパイプライン(Recipe)を組むイメージです。

スキルの全体像

AtomスキルやRecipeスキルには以下の表のようなスキルが含まれています。

カテゴリスキル
Atomatom-research, atom-goal-to-requirement, atom-spec, atom-impl-plan, atom-verify-plan, atom-execute, atom-check, atom-checkpoint, atom-message ほか
Reciperecipe-normal(一般的な機能開発), recipe-bug-fix(バグ修正), recipe-big-task(大きな機能開発), recipe-spike(技術検証)

Atomスキル:stdin / stdout を持つ最小単位

Atomスキルの設計で一番こだわったのが、すべてのAtomが共通のstdin/stdoutインターフェイスを持つことです。

たとえば設計を担当する atom-spec の定義はこうなっています(抜粋)。

## stdin
- `resolution`: micro-service | infrastructure | app-logic
- `ref_docs`: goal-to-requirement.md, research.md(あれば)等

## stdout
session-log配下に `spec.md` として出力する。

**frontmatter:**
---
skill: atom-spec
resolution: <resolution>
version: <n>
ref_docs: [入力として参照したファイル群]
---

## Prohibitions
- 実装の詳細(コードレベル)に踏み込んではならない(それはimpl-planの責務)

ポイントは3つあります。

1つめは、出力が会話ではなくファイルであること。Claude Codeとの会話はコンテキストウィンドウとともに流れていくが、ファイルは残る。後続のAtomは ref_docs として先行Atomの出力ファイルを受け取るので、「atom-researchの調査結果を踏まえてatom-specが設計する」という受け渡しが、会話の記憶ではなくファイルで成立します。これがパイプです。

2つめは、frontmatterでトレーサビリティを持たせていること。各出力ファイルには「どのスキルが」「何を参照して」「何回目の改訂で」作ったかが記録されます。後から「この設計はどの調査に基づいているんだっけ」を辿れます。

3つめは、Prohibitionsで責務の境界を明示していること。atom-specは設計までで、コードレベルの詳細はatom-impl-planの責務。これを書いておかないと、Claudeは1つのAtomの中で先のステップまで進んでしまいがちになります。

レビューをファイル上で完結させる

Atomの出力に対するフィードバックにも決まりを作りました。ユーザーはstdoutのMarkdownファイルにHTMLコメントで直接フィードバックを書き込む。Claudeはコメントの内容から「このレビュー結果をどう取り扱うか」を判定して動きます。この取り扱い区分をdispositionと呼んでいます(処分・取り扱いの決定、という意味の英単語)。区分は次の4つ。

disposition意味アクション
approvedOK。後続へ渡せる次のAtomへ進む
commented局所的修正指示部分修正して再提示
terminal-commented全体的方向性の指摘コメント範囲を書き直して再提示
done完成。チェーン離脱終了

チャット欄で「ここを直して」と言うかわりに、ファイルの該当箇所に <!-- この設計だとエラー時のフローが考慮されてない --> のように書き込みます。コードレビューでインラインコメントを書く感覚に近く、指摘の位置が曖昧になりません。修正されるとfrontmatterのversionが上がり、Change Logに改訂履歴が残ります。

Recipeスキル:Atomの実行順序テンプレート

RecipeはAtomの実行順序を定義したテンプレートで、タスクの種類ごとに用意しています。一番よく使う recipe-normal(一般的な機能開発・改善)の流れはこうです。

### 1. Phase 1: 調査・要件定義・設計
1. /atom-goal-to-requirement を提案する
2. /atom-spec を提案する
3. /atom-checkpoint を提案する(Phase境界の文脈要約)

### 2. Phase 2: 設計・実装
1. /atom-spec を提案する
2. /git-branch を提案する
3. /atom-impl-plan を提案する
4. /atom-verify-plan を提案する
5. /atom-execute を提案する
   - ng の場合: /atom-spec resolution:app-logic に戻ることを提案する
   - ok の場合: 必要に応じて /git-commit を提案する
6. /atom-checkpoint を提案する

### 3. Phase 3: 最終確認
1. /atom-check を提案する
2. /git-push, /gh-pr, /atom-message を提案する

全部の動詞が「提案する」になっているのが重要なところで、Claudeは次のAtomを提案するだけで、実行するのはユーザーが承認してからという原則にしています。Prohibitionsにも「Userの承認なしにスキルを実行してはならない」と明記しました。ユーザーはいつでもスキルの追加・スキップ・順序変更ができる。Recipeはレールであって、ベルトコンベアではない、という気持ちで運用しています。

recipe-state.md:進行状態の外部化

Recipeを開始すると、まず session-log/<task-name>/recipe-state.md というファイルが作られます。Recipeの全ステップをチェックリストとして展開したもので、Atomが完了するたびに [x] と成果物パスが記録されていきます。

これの何が嬉しいかというと、コンテキストが飛んでも続きから再開できることです。長いタスクでは会話の要約(compact)やセッションの切れ目を必ず跨ぐことになりますが、「いまどこまで進んでいて、次に何をするか」がファイルに外部化されていれば、新しいセッションでrecipe-state.mdを読むだけで現在位置を復元できます。

同じ目的のAtomが atom-checkpoint で、こちらはPhase境界で「ここまでの議論の要点」を圧縮したrunning logを出力します。状態はrecipe-state.mdに、文脈はcheckpointに、それぞれ永続化する分担です。

タスクが終わる頃、session-logにはこんなディレクトリができています。

session-log/
  <task-name>/
    recipe-state.md
    checkpoint-01.md
    goal-to-requirement.md
    spec.md
    impl-plan.md
    verify-plan.md
    execute.md

これがそのまま開発ログになります。「なぜこの設計にしたのか」が成果物として残るのは、巨大ワークフロースキル時代にはなかった副産物でした。

この記事もRecipeで書いている

実例をひとつ。この記事自体が recipe-normal で書かれています。執筆開始時点のrecipe-state.mdはこうでした。

# Recipe State: write-atom-recipe-skills-article

## Phase 1: 調査・要件定義・設計(スキップ)
- [-] /atom-goal-to-requirement — Userの指示によりスキップ

## Phase 2: 執筆
- [x] worktreeを作成 — ../blog-worktrees/write-atom-recipe-skills-article
- [x] /atom-impl-plan — session-log/.../impl-plan.md(version 2でapproved)
- [ ] /atom-execute(記事執筆)
- [ ] /git-commit

## Phase 3: 文体の調整
- [ ] /revise-article
- [ ] /git-commit
- [ ] /git-push

ブログ記事の執筆はコードを書く作業ではないですが、「計画を立てて成果物を作り、レビューを受けて改訂する」という構造は同じなので、そのままRecipeに乗ります。記事の構成案はatom-impl-planの出力としてレビューし、HTMLコメントで修正指示を受けて改訂しました。Phase 1を丸ごとスキップしているように、合わないステップは飛ばせばいい、という気軽さで使っています。

使ってみてどうか

よかったこと。

一方で課題もある。

まとめ

巨大な1本のワークフローを書くより、小さな部品と組み合わせ方の定義に分けるほうが、修正にも例外にも強い。これが運用してみての実感です。Atomの粒度もRecipeの種類もまだ試行錯誤の途中なので、使いながら育てていきたいと思います。Claude Codeのスキル設計で悩んでいる人の参考になれば嬉しいです。