1. はじめに
技術制作管轄Next開発室、生成AI・バックエンドテックリードの梶村 (@kiokisun_prog) です。 CyberAgent Developers Advent Calendar 2025 の13日目を担当させていただきます。
現在私は、既存の大規模アプリケーションにおいて「Spec駆動開発基盤」によるリニューアルPJを推進しています。 これは単なるAI Agentツールの導入だけではなく既存のシステムやワークフローを根本から刷新し、コード生成から仕様書作成、プロジェクト管理、運用に至るまでをプロンプトベースで構築・運用する試みです。
現在はPoC(概念実証)フェーズとして、実際のプロセス構築・設計を行っています。
本記事では、このPoCを通じて得られた「Spec駆動開発におけるコンテキストエンジニアリング」の実践知と、その中核となる「Custom Slash Commands(カスタムスラッシュコマンド)」の設計におけるプラクティスを共有します。
2. プロダクト開発における「AI成熟度」
CyberAgentではプロダクト開発チームにおけるAI成熟度が定義されています。

このモデルは、AI Agentが扱う業務領域におけるスコープの広さと、人間との責務境界の変化を示しています。
L1: Code-level Completion (コード補完)
IDE上でのインライン補完が主となるフェーズです。構文レベルや数行のロジック生成に留まり、人間が主体でAIが「入力支援」を行う段階です。
この段階では自律的な「AI Agent」としての振る舞いは行われず、あくまでツールの機能の一部として利用されている状態です。
L2: IDE with Chat (対話的なコード生成)
Chatインターフェースを通じて対話的にコード生成を実施するフェーズです。 AI Agentにある程度のロジック生成を任せることができますが、コンテキストの提供は人間が都度行う必要があります。
メリット
- 事前準備が不要で、導入のハードルが低い。
- 思いついたその場ですぐに試行できる。
問題点
- 毎回プロンプトを考案する必要があるため、エンジニアのプロンプトエンジニアリングスキルにおける 属人性が発生し出力品質の再現性が低い。
- 人間が常に介入して指示を出し続ける必要があり、処理が直列になるため、待ち時間が発生する。
L3: Ticket to PR (タスクレベルの生成)
GitHub Issueなどのチケットをトリガーとし、Pull Requestの作成までをAI Agentに一任する段階です。チケット自体がプロンプトの役割を果たし、そこに紐づくコンテキストを人間が整備します。
メリット
- タスクをAgentに投げて待つことができるため、人間の作業と並行して実装が進み、非同期・並列実行が可能になり効率化が図れる。
問題点
- 高品質な出力を得るためには、良質なコンテキストを手動で収集・添付する必要があり、この準備コストが高く、「自分で書いた方が早い」という本末転倒な状況になりやすい。
- 必要な情報の選定が個人の判断に委ねられるため、ノイズ情報の混入や不足が発生しやすく、成果物の品質が安定しない。
L4: PRD to Production (全プロセスの自動化)
開発プロセスの全自動化を目指すフェーズです。エンジニアリング領域だけでなく、PM、PdM、Designerの領域を含む仕様策定から実装、デプロイに至るまで、一貫してAI Agentが成果物を作成します。
最大の特徴は、L3でボトルネックとなっていた「コンテキスト設計」や「プロンプトエンジニアリング」自体が事前に仕組み化(システム化)されている点です。 Custom Slash Commands等を用いて、誰が実行しても均質で高品質なコンテキストが供給される環境を構築します。
メリット
- コンテキスト構築が自動化されるため、誰が担当しても効率的に一定以上の品質を担保できる。
問題点
- Spec駆動開発基盤の構築、およびコマンド設計に 初期投資コストがかかります
AI Agentの開発プロセスレベル定義
| レベル | フェーズ定義 | 実行トリガー / Input | コンテキスト運用 (Context Ops) | 生成される成果物 (Artifacts) | 並列実行 | 人間の主な責務 |
|---|---|---|---|---|---|---|
| L1 | Code-level Completion (コード補完) | IDE入力 | [自動・局所] カーソル周辺のコードや開いているファイルのみを参照 | コード断片 (構文・単一行) | × | ・全てのコードを書く |
| L2 | IDE with Chat (対話的生成) | チャット指示 | 人間が必要なファイルを選択・コピペして渡す | 関数・クラス 単体テストコード | × | ・プロンプト作成 ・生成コードの修正 |
| L3 | Ticket to PR (タスク自動化) | Issue / チケット | チケットに関連資料や仕様を人間が書き集めて添付 | Pull Request | ⚪︎ | ・タスク定義 (Issue作成) ・コンテキストの手動収集 ・PRレビュー |
| L4 | PRD to Production (開発プロセス自動化) | 事前準備されたプロンプトの実行 | 最適化されたコンテキストをシステムが自動注入 | 全工程の成果物 (仕様書・設計書・PR・コード・テスト) | ⚪︎ | ・コマンド自体の設計・改善 ・生成された仕様と成果物の品質管理 ・開発プロセスのエンジニアリング |
L4(全プロセスの自動化)を実現するためには、従来の開発スタイルの限界を理解し、「Spec駆動開発」へとシフトする必要があります。
3. Spec駆動開発」とは
Spec駆動開発とは、仕様書(Spec)を単なる「人間が読むためのドキュメント」としてではなく、「AIがコードを生成するための構造化されたコンテキスト」として再定義する開発手法です。
従来、ドキュメントは開発の「副産物」や「後付け」になりがちでしたが、この手法ではドキュメントこそがコードを生み出す「源泉(Single Source of Truth)」となります。
Spec駆動開発がもたらす3つの「副次的効果」
この手法のメリットは、開発プロセスの自動化そのものよりも、開発プロセス自体に「健全な強制力」が働く点にあります。
1. ドキュメントの鮮度と網羅性の維持
これまでは、コード変更後にドキュメントを更新し忘れる「ドキュメントの腐敗」が常態化していました。
しかしSpec駆動開発では、「仕様書を作成・更新しないと、正しいコードが生成できない」という依存関係が生まれます。この強制力により、ドキュメントは常に実装と同期した最新の状態に保たれるとともに仕様の抜け漏れが発生しない堅牢なドキュメンテーションを実現できます。
2. キャッチアップの効率化
鮮度の高いドキュメントが常にリポジトリにあるため、新規参画者はAI AgentやRAGに対して「この機能の仕様を教えて」「このアーキテクチャの意図は?」と質問するだけで、最新の正確な回答を得られます。
仕様書が「読むもの」から「対話するもの」へと進化し、キャッチアップやオンボーディングのコストが劇的に低下します。
Spec駆動開発基盤構築の課題
しかし、このSpec駆動開発基盤の構築は容易ではありません。
AIに渡すコンテキストが曖昧であったり、構造化されていなければ、生成される成果物もまた低品質なものとなります。
L4レベルの開発体制を実現するためには、「AIにいかに効率的に、高品質なドキュメントを与えるか」 という技術的な壁を突破しなければなりません。
もし、基盤自体の品質やアーキテクチャが未熟であれば、それは新たな 「技術的負債」 となり、開発メンバーに非効率なプロセスを強いる結果を招きます。
ここで、Spec駆動開発の成否を握るのが、次章で解説する「コンテキストエンジニアリング」です。
4. コンテキストエンジニアリングの目的
「コンテキストエンジニアリング」とは、単にプロンプト(指示文)を工夫するだけでなく、LLMに与える入力情報(コンテキスト)の「質」と「量」を戦略的に設計・制御する技術です。
コンテキストエンジニアリングはあくまで「課題解決のための手段」です。 主に、プロンプトを実行したときに成果物の生成がうまくいかない場合に、その問題を特定し、適切な対策を講じて改善していくための指針となります。
まずは、コンテキストエンジニアリングによって解決するプロンプト設計で発生する問題自体を整理します。
1. Context Rot
セッションが長期化するにつれて、LLMが内部で保持している前提情報が徐々に古くなり、現在のコードベースや仕様との整合性が崩れていく現象です。
発生する問題
- プロンプトの重要な指示を無視したり、忘却したような振る舞いが発生する
原因
主に入力トークン数が増えすぎることで発生します。
LLMには、Attention Mechanism(注意機構)と呼ばれる仕組みがあり、入力されたテキスト列の中で「どの単語(トークン)」が「他のどの単語」と強く関連しているかを計算し、その重要度(重み)を動的に割り当てています。
コンテキストが肥大化してくると、この重みづけの中で、セッションの初期に与えた重要な指示や前提情報が相対的に埋もれやすくなり、結果としてスコープから外れてしまいます。
2. Context Confusion
過剰な情報量や抽象度の高すぎる指示、あるいは指示同士の矛盾によって、LLMが「どの情報を優先すべきか」を判断できなくなる状態です。
発生する問題
- 実行するたびに結果が大きくぶれる
- ハルシネーション(もっともらしいが誤った出力)が発生しやすくなる
原因
主に過剰な情報量、抽象度の高すぎる指示、または指示同士の矛盾によって発生します。
タスク解決に本当に必要な情報(Signal)と、無関係な情報・冗長なログ(Noise)の比率、つまり S/N比 が低下することで、Attentionの重みづけが適切に機能しなくなります。その結果、
- 重要な情報の優先度が下がる
- 重要ではない情報の優先度が過剰に上がる
といった誤った重みづけが起こり、出力の品質が不安定になります。
3. Context Poisoning
生成タスクの前提として与えている情報自体に誤りやノイズが混入していることで、局所的には論理的に一貫していても、全体としては誤った成果物が出力されてしまう現象です。
発生する問題
- 間違った実装やドキュメントが生成される
- 現在の仕様と矛盾した実装や説明が出力される
原因
古い仕様書、更新されていないコメント、タスクに関係のない類似コードなどがコンテキストに混入することで発生します。 モデルは与えられた情報を前提として整合的な回答を生成しようとするため、入力側が間違っていると、その誤りをきれいな形で再生産してしまうことになります。
これらを防ぐためには、単に多くの情報を詰め込むのではなく、タスクの複雑性に応じて良質なコンテキストを動的に構成する設計が求められます。
このような高度なコンテキスト制御を行い、再現性の高い開発プロセスを構築するための強力な実装手段こそが、次章で解説する Custom Slash Commands です。
4. Custom Slash Commandsとは
Custom Slash Commandsとは、AI Agentツールにおいて、頻繁に使用するプロンプトを保存し、プロジェクト単位で永続化・共有するための機能です。
Spec駆動開発において、Custom Slash Commandsは 「AIへの指示を資産化し、開発プロセスそのものを関数化する仕組み」と言えます。
Spec駆動開発への導入により、主に以下の3つのメリットをもたらします。
1. 「プロンプトエンジニアリング」の標準化と再現性
開発チーム全員が高度なプロンプトエンジニアリングのスキルを持っているとは限りません。 個々人の書き方によって成果物の品質にバラつきが生じるのはリスクです。
ベストプラクティスを詰め込んだプロンプトをコマンドとして共有することで、誰が実行しても同じフォーマット、同じ品質の成果物が出力される「再現性」が担保されます。
これにより、開発者は「AIにどう頼むか」に悩む時間をゼロにし、「何を(Spec)作るか」という本質的な業務に集中できます。
2. コンテキスト注入の自動化と最適化
Spec駆動開発では、タスクに応じて適切な仕様書(Markdown)をAIに読み込ませることが不可欠です。しかし、手動で毎回コンテキストを選択・貼付するのは手間であり、人為的なミスを誘発します。
コマンド内でファイルを指定して読み込みを指示することで必要な仕様書(Spec)が自動的かつ過不足なくAI Agentのコンテキストとして与えることができます。
3. プロンプト自体のバージョン管理(Prompt as Code)
プロンプトが個人のチャット履歴の中に埋もれるのではなく、リポジトリ内のコードとして管理されます。 これにより、プロンプト自体に対してチームでレビューを行ったり、Gitによるバージョン管理を行ったりすることが可能になります。 プロンプトを継続的に改善(リファクタリング)し、開発効率を拡張していくための基盤となります。
次章ではPoCの中で発見したプロンプト実行時に発生する課題を解決するためのCustom Slash Commandsの設計におけるプラクティスを解説します。
5. Custom Slash Commands 設計のベストプラクティス
本章では、コンテキストエンジニアリングの観点に基づいたベストプラクティス」を解説します。
1. 単一責任の原則
「1つのコマンドには、1つの責務だけを持たせる」ことが鉄則です。
開発当初、1つのコマンドで
Webでベストプラクティスの調査 → ドキュメント作成 → ガイドライン準拠チェック →ドキュメント修正
という複雑なワークフローを実行させようとしたことがありました。
しかし想定通りにはならず、Web検索で得た大量のノイズ情報に引っ張られて Context Confusion や Context Rot を引き起こし、仕様と異なるコードが生成されたり、後半の「ガイドラインチェック」の工程がスキップされたりと最終成果物の品質が低かったり工程のスキップが発生しました。またどこの指示が間違っているのかのボトルネックの調査が難しく特定も困難でした。
改善策として、以下のように責務ごとにコマンドを分割しました。
create-reference: 指定した公式ドキュメントを本文をそのまま抜き出したファイルの作成create-best-practices: ベストプラクティス集の作成create-design-doc: 設計ドキュメントの作成review-architecture: 設計レビュー結果の作成
これを上から順番に実行するように変更することで上記の問題が解消し成果物の品質が改善しました。
また、間違っていた指示などもカスタムスラッシュコマンドのスコープが狭くなったことによって評価も細かくできるようになり原因箇所を即座に発見できたりコマンドがシンプルになってメンテナンスしやすくなりました。
このように責務を細かく分割してプロンプト設計を行うことで多くのコンテキストの問題を解決することができるようになります。
2. コンテキストの最小化
「情報は多いほど良い」という直感は、LLMにおいては誤りです。 網羅性を求めて不要なドキュメント(例えば開発タスクに関係のない Agents.md や巨大なコードベース全体)を読み込ませることによってS/N比の低下によって重要な指示が埋もれ、推論精度が下がったりコストとレイテンシの増大によってトークン消費量が指数関数的に増えて品質だけでなく開発コストも悪化します。
タスクのスコープを厳密に定義し、「必要最小限の情報」のみを注入するよう、引き算の思考で設計してください。
3. 成果物とテンプレートの事前定義
Custom Slash Commandsの設計は、関数定義のようなものです。
Input (Context/Prompt) → Logic → Output (Artifact)
このパイプラインを成立させるためには、まずOutput(成果物)の構造が厳密に定義されていなければなりません。 アジャイル開発における「User Story」なのか、ウォーターフォールにおける「詳細設計書」なのか。組織の開発プロセスや承認フローにおいて、どの粒度の成果物が「正」とされるかは異なります。まずはここを言語化することがスタートラインです。
また、ここで生成されたOutputは、次の工程(コマンド)のInputとして再利用されます。そのため、人間にとっての可読性だけでなく、「次のLLMが読み込みやすいサイズか(Context Windowを圧迫しないか)」というシステム間連携の観点での設計も求められます。
テンプレートによる「型」の強制
Outputの品質と互換性を担保するために、テンプレート(Schema)の導入は不可欠です。 ドキュメントの構造、記法(Mermaid記法など)、必須項目をテンプレートとして明示することで、モデルのバージョンアップや挙動の変化に左右されない堅牢なパイプラインを構築できます。
「モデルが賢くなるほど、自由度を与えるとフォーマットがブレる」 というパラドックスがあります。 高性能なモデルは気を利かせてフォーマットを変えたり、冗長な解説を加えたりしがちです。そこで、テンプレートによって出力の「型」を強制します。これにより、モデルの知能リソースを「フォーマットの調整」ではなく「内容の質(ロジックの正しさや網羅性)」だけに集中させることが可能になります。 「この項目は箇条書きで3行以内」といった粒度までガイドライン化することで、モデルの性能の向上の良い部分だけを取り入れた成果物を生成し続けることができます。
4. テスト可能に作成する
カスタムスラッシュコマンドの品質管理は、通常のコードよりも困難です。なぜなら、Inputとなるコンテキストの質や、LLMの非決定的な挙動がOutputに直結するからです。 そのため、「コマンドの品質を定量的に評価できるテスト環境」がなければ、改善のサイクルを回すことは不可能です。
ゴールデンマスターによるテスト手法
まずは、TodoアプリやSNSクローンなど、ドメイン知識が不要な最小限のスコープ(Sandbox)を用意し、以下の手順でテストを行います。 `
- Golden Dataの作成: まず、理想とする「正解の成果物(コードやドキュメント)」を人間が手動で作成します。
- コマンドの実装: その正解を出力できるように、カスタムスラッシュコマンドを作成します。
- 実行と差分比較: コマンドを実行し、生成されたOutputと、手動で作ったGolden Dataを比較します。 この比較により、うまくいかない生成箇所を特定しその原因となるボトルネックとなる部分をInputとするコンテキストやカスタムスラッシュコマンドを改善していくことでプロンプトチューニングを行いカスタムスラッシュコマンド自体の品質管理を行います。
軽量なコマンドを目指す
また、成果物が巨大すぎたり、指示が複雑すぎると、テストの難易度は指数関数的に跳ね上がります。 複雑な「神API」を作るとデバッグが困難になるのと同様に、プロンプトも「単機能で、テストが容易(Testable)な軽量コマンド」を目指してください。そうすることで品質管理がしやすい保守性の高いカスタムスラッシュコマンドを構築できます。
5. 1コマンドにつき1成果物を生成する
「コマンドを実行したら、必ず1つの成果物(Artifact)が生成される」状態を徹底してください。
コンソール上に出力される結果はそのセッション内でないと使用することができないです。それはコンテキストの初期化( /new, /clear) を使えないと同義であり、コンテキスト過多によるContext PoisoningやContext Rotによる成果物やプロセスの品質低下の原因になります。 レビュー結果や調査結果であっても、コンソールに流して終わりにはせず、必ずMarkdownファイルとして永続化させます。逆に、1回の実行で複数のファイルを生成しようとしている場合は、そのコマンドが「責務過多」*であるシグナルです。
ファイルを「IF(インターフェース)」にする
他に成果物をファイルとして出力するメリットとして、ワークフローのパイプライン化が可能になる点が挙げられます。
あるコマンドのOutput(成果物ファイル)が、次のコマンドのInputになります。このファイルが工程間の「橋渡し役(インターフェース)」となることで、ワークフローをまたぐ際に、チャットセッションのログや、探索で得たノイズ情報(不要なコンテキスト)を完全に遮断できます。
特に効果的なのが、「読み取りタスク」 と 「書き込みタスク」 の分離です。 巨大なコードベースを読み込んでレビューを行う工程は、コンテキスト量が膨大になりがちです。この状態でそのままコード修正を行わせると、大量の無関係なコード情報に引きずられ、生成品質が低下したり、ハルシネーション(幻覚)が起きやすくなります。
- Review Command を実行しコードを読み込み、「実装改善提案書.md」を出力して終了
/clear(/new) を実行しコンテキストを初期化- Fix Commandを実行し「実装改善提案書.md」のみを読み込み、ピンポイントで修正を実行。
このように、ファイルを通じて「レビューに必要なコンテキスト(対象コード)」と「修正に必要なコンテキスト(レビュー結果やコードスタイルガイドなど)」を分断することでコンテキストの最小化を実現し LLMの集中力を最大化し、デバッグもしやすい堅牢な設計になります。 ただ細かく分けすぎるとカスタムスラッシュコマンドの実行順序のワークフロー管理が複雑化し認知コストが高まるデメリットもあるためここのトレードオフを意識して設計することが重要です。
6. 特定のモデル・ツールに依存しない
モデルの進化やツールの盛衰が激しい現在、最も重要なのが「可搬性(Portability)」です。
Claude Codeの SubAgent や独自のTool名など、ツール固有の仕様をプロンプト内に直接記述するのは避けましょう。
また、.claude や .gemini といったツール依存のディレクトリで、コアとなるロジック(コマンド)を直接管理することも推奨しません。
抽象的な指示ファイルを docs/ 配下に置き、各ツール(Claude, Codex等)の設定ファイルからはそれを参照(インポート)するだけの「薄いラッパー」として機能させます。
SubAgent等の独自機能への依存回避
さらに踏み込んだプラクティスとして、Claude Code の SubAgentは使用せず、Custom Slash Commandsのみで完結させる設計を推奨します。
PoCでの検証の結果、SubAgentへの委譲指示を制御するコストが通常コマンドよりも高く、品質も安定しないことが判明したため採用を見送りました。
ここで得られた教訓は、「SubAgentが必要だと感じるなら、それはタスクが複雑すぎる(責務過多である)サイン」だということです。
ブラックボックス化しやすいSubAgentに頼るのではなく、タスクを小さなコマンドに分割し、「成果物ファイルをバトンとして渡し、コンテキストを都度リセットする」パイプラインを構築してください。
ツール依存を極力排除した「疎結合で拡張性の高い設計」を心がけることが、長く使えるSpec駆動開発基盤を作る鍵となります。
7. Simple Instruction (指示の簡素化)
プロンプト内の指示(Logic)は、可能な限り簡潔に保つことが重要です。 過剰に詳細な指示は、トークンコストを増大させるだけでなく、LLMが持つ推論能力や自律性を阻害する要因となります。
プロンプトの「民主化」と技術的負債
Custom Slash Commandsは、作成者個人のツールではなく、チーム全体で共有される「開発資産」となります。 ここで陥りがちなのが、特定のメンバーしか理解できない長大で複雑なプロンプトになってしまうことです。
誰もメンテナンスできないコマンドは、即座に技術的負債となり、開発プロセスの改善サイクルを止めるボトルネックになります。
プロジェクトの規模拡大を支えるためには、属人性を排除し、どのメンバーでも修正・改善が可能な「可読性が高く、シンプルな構成」を維持し続ける必要があります。
責務過多のシグナル
もし、説明文が長くなったり、複雑な条件分岐(if-else)をプロンプト内に記述しなければならないと感じたら、それは「コマンドの責務が肥大化している」の明確なサインです。
無理に一つの「神プロンプト」で全てを制御しようとせず、コマンドをマイクロな単位に分割してください。
成果物(Artifact)をインターフェースとして、次のコマンドへバトンを渡すパイプライン設計に切り替えることで、個々のコマンドはシンプルに保たれ、チーム全体での継続的な改善が可能になります。
5. おわりに
ここまで「Spec駆動開発」や それを構築する 「カスタムスラッシュコマンド」について解説してきました。
ただしこの「Spec駆動開発」はステークホルダーが多く成熟してる開発組織ほど、既存ワークフローや成果物の定義は困難を極めます。
そのため、一気に全てのスコープを対象にするのではなくご自身がコントロールできる範囲(個人のタスクや小さなチーム)にスコープを限定して戦略的に導入範囲を広げていくことで小さな実績を積み重ねていき、他の組織からの信頼を獲得しながらプロダクト全体の開発効率の向上を実現していきましょう。
※本記事は CyberAgent Developers Advent Calendar 2025 の13日目の記事です。
