Read OSS

仕様駆動ワークフロー:テンプレートがAIエージェントに指示する仕組み

中級

前提知識

  • 第1回:アーキテクチャとプロジェクトナビゲーション
  • 第3回:インテグレーションシステム(テンプレートの処理方法を理解するために)
  • YAMLフロントマターの基本的な知識
  • AIコーディングアシスタントの使用経験

仕様駆動ワークフロー:テンプレートがAIエージェントに指示する仕組み

Spec Kitの真の革新は Python CLI にあるのではなく、CLI が生成するマークダウンファイルにあります。9つのコマンドテンプレートは、AIエージェントへの構造化された指示書です。YAMLフロントマターを通じて完全な開発ワークフローを有向非循環グラフ(DAG)として表現し、AIだけでは実行できないファイルシステム操作のためのシェルスクリプト呼び出しを埋め込み、拡張機能が追加の動作を注入するフックのチェックポイントも備えています。AIエージェントはこれらのドキュメントの読み手であり、同時に実行者でもあります。この記事では、その中身を詳しく見ていきます。

9つのスラッシュコマンドとワークフローDAG

templates/commands/ ディレクトリには9つのマークダウンファイルが格納されており、それぞれがスラッシュコマンドに対応しています。

コマンド 目的 引き継ぎ先
specify 説明からフィーチャー仕様を作成する planclarify
plan 技術的な実装計画を生成する taskschecklist
tasks 計画を順序付きタスクリストに分解する analyzeimplement
implement タスクリストのタスクを実行する
clarify 不明確な要件を構造的に整理する
analyze 成果物間の整合性を横断的に分析する
constitution プロジェクトの指針となる原則を作成・更新する
checklist 品質検証チェックリストを生成する
taskstoissues tasks.md をGitHub Issueに変換する

YAMLフロントマターの handoffs フィールドがDAGを構成しています。

flowchart TD
    specify["speckit.specify"] -->|"Build Technical Plan"| plan["speckit.plan"]
    specify -->|"Clarify Requirements"| clarify["speckit.clarify"]
    plan -->|"Create Tasks"| tasks["speckit.tasks"]
    plan -->|"Create Checklist"| checklist["speckit.checklist"]
    tasks -->|"Analyze Consistency"| analyze["speckit.analyze"]
    tasks -->|"Implement"| implement["speckit.implement"]

    constitution["speckit.constitution"]
    taskstoissues["speckit.taskstoissues"]

handoffs はただのドキュメントではありません。AIアシスタントによっては、これをアクション可能なボタンや提案として描画するためのメタデータとして機能します。たとえば、templates/commands/specify.mdspecify.md フロントマターはこのようになっています。

handoffs:
  - label: Build Technical Plan
    agent: speckit.plan
    prompt: Create a plan for the spec. I am building with...
  - label: Clarify Spec Requirements
    agent: speckit.clarify
    prompt: Clarify specification requirements
    send: true

send: true フィールドは、ユーザーの確認を待たずに引き継ぎを自動的にトリガーすることを示します。これにより、仕様の作成が完了すると自然に計画フェーズへと続く流れが生まれます。

コマンドテンプレートの構造

すべてのコマンドテンプレートは同じ構造に従っています。templates/commands/plan.mdplan.md テンプレートを例に解説しましょう。

flowchart TD
    subgraph "YAML Frontmatter"
        A["description: one-line summary"]
        B["handoffs: next-step commands"]
        C["scripts:<br/>  sh: scripts/bash/setup-plan.sh --json<br/>  ps: scripts/powershell/setup-plan.ps1 -Json"]
        D["agent_scripts:<br/>  sh: scripts/bash/update-agent-context.sh __AGENT__"]
    end
    subgraph "Body"
        E["## User Input<br/>{ARGS} placeholder"]
        F["## Pre-Execution Checks<br/>Hook system checkpoint"]
        G["## Outline<br/>Step-by-step instructions for the AI"]
        H["## Guidelines<br/>Quality constraints"]
    end
    A --> E
    C --> E

3種類のプレースホルダーはそれぞれ異なる役割を持っています。

  • {SCRIPT}scripts.<type> に定義されたシェルコマンドに置き換えられます。ファイルシステムのセットアップをAIが実行できるよう、実行すべきコマンドを渡します。
  • {ARGS} — エージェント固有の引数プレースホルダー(多くは $ARGUMENTS、Gemini の場合は {{args}})に置き換えられます。
  • __AGENT__ — エージェント名に置き換えられます。どのエージェントが動作しているかを把握する必要があるスクリプトで使用されます。

第3回で見たように、process_template() パイプラインが初期化時にこれら3つをすべて解決し、最終出力がクリーンになるよう scripts:agent_scripts: ブロックをフロントマターから取り除きます。

シェルスクリプト:操作レイヤーとしての役割

AIエージェントはファイルを読んだりコードを書いたりすることはできますが、「既存の spec ディレクトリをスキャンして次の連番を決定する」といった構造化されたファイルシステム操作を確実に行うことは苦手です。そこでシェルスクリプトの出番となります。

scripts/bash/create-new-feature.sh は最も重要なスクリプトで、before_specify フック(git 拡張機能経由)から呼び出され、連番付きのフィーチャーブランチを作成します。機械で解析しやすい出力のために --json フラグを受け付けます。

JSON_MODE=false
# ... argument parsing ...
if [ "$JSON_MODE" = true ]; then
    echo "{\"BRANCH_NAME\":\"$BRANCH_NAME\",\"FEATURE_NUM\":\"$FEATURE_NUM\"}"
fi

--json フラグはすべてのスクリプトで共通のパターンです。コマンドテンプレートはAIに対してスクリプトを実行し、JSON出力を解析し、その値を後続ステップで使用するよう指示します。たとえば check-prerequisites.sh はこのような出力を返します。

{"FEATURE_DIR": "specs/003-user-auth", "AVAILABLE_DOCS": ["spec.md", "plan.md"]}
sequenceDiagram
    participant AI as AI Agent
    participant CMD as Command Template
    participant SH as Shell Script

    AI->>CMD: Read /speckit.tasks
    CMD->>AI: "Run: .specify/scripts/bash/check-prerequisites.sh --json"
    AI->>SH: Execute script
    SH->>AI: {"FEATURE_DIR": "...", "AVAILABLE_DOCS": [...]}
    AI->>AI: Parse JSON, locate spec artifacts
    AI->>AI: Generate tasks.md

すべてのスクリプトは bash/powershell/ の両方のバリアントとして提供されています。specify init 時の --script フラグによって、どちらのバリアントを .specify/scripts/ にインストールするかが決まります。クロスプラットフォーム対応は徹底されており、すべての .sh スクリプトには同等の動作を持つ .ps1 の対応ファイルが存在します。

ヒント: --json 出力モードは、AIエージェントとシェルスクリプトを組み合わせる際の核心的な考え方です。人間が読みやすい出力はデバッグには便利ですが、JSON出力があればAIは正規表現を使わずに構造化データを確実に取り出せます。同様のAIエージェントツールを構築する際は、機械で解析しやすい出力モードを必ず用意しましょう。

フックシステム:すべてのコマンドに設けられた拡張ポイント

すべてのコマンドテンプレートには、実行前と実行後の2つのフックチェックポイントが含まれています。specify.md の実行前チェックを見てみましょう。

## Pre-Execution Checks

**Check for extension hooks (before specification)**:
- Check if `.specify/extensions.yml` exists in the project root.
- If it exists, read it and look for entries under the `hooks.before_specify` key
- Filter out hooks where `enabled` is explicitly `false`
- For each executable hook, output based on its `optional` flag:
  - **Optional hook**: Present to user with prompt
  - **Mandatory hook**: Execute immediately via `EXECUTE_COMMAND: {command}`

これは AIエージェントがランタイムとなる宣言的プラグインシステム です。テンプレートはAIに「このYAMLファイルを読み、フックを確認し、必須のものは実行し、オプションのものは提案せよ」と指示します。実際のフックロジックは拡張機能のマニフェスト(git拡張機能など)で定義され、拡張機能のインストール時に .specify/extensions.yml にマージされます。

flowchart TD
    A["AI reads command template"] --> B{"extensions.yml exists?"}
    B -->|No| C["Skip hooks silently"]
    B -->|Yes| D["Parse hooks.before_{stage}"]
    D --> E{"Hook optional?"}
    E -->|Yes| F["Present to user:<br/>'Run /speckit.git.commit?'"]
    E -->|No| G["Execute immediately:<br/>EXECUTE_COMMAND: speckit.git.feature"]
    F --> H["User decides"]
    G --> I["Wait for result"]
    H --> J["Continue to main logic"]
    I --> J

フックシステムの詳細は第5回で取り上げます。ここで重要なのは、すべてのコマンドテンプレートが before_after_ の両チェックポイントを持つという点です。9つのコマンド全体で合計18のフックポイントが存在し、git拡張機能は18すべてを使用しています。

LLMへの制約としてのドキュメントテンプレート

コマンドテンプレートに加えて、Spec Kit にはAIエージェントの 出力 を制約するドキュメントテンプレートも含まれています。最も重要なのは templates/spec-template.md で、フィーチャー仕様の構造を定義しています。

# Feature Specification: [FEATURE NAME]

## User Scenarios & Testing *(mandatory)*

<!--
  IMPORTANT: User stories should be PRIORITIZED as user journeys ordered by importance.
  Each user story/journey must be INDEPENDENTLY TESTABLE
-->

### User Story 1 - [Brief Title] (Priority: P1)

このテンプレートはAIに対していくつかの制約を課します。

  1. 優先順位付きユーザーストーリー — 各ストーリーにP1/P2/P3の優先度を付けることで、すべてが同等に重要に見えるフラットなリストを防ぎます。
  2. [NEEDS CLARIFICATION] マーカー — コマンドテンプレートでは最大3つに制限されており、何十もの質問を投げかける代わりに、AIが適切なデフォルトを判断することを促します。
  3. 技術に依存しない成功基準 — 「APIレスポンスタイム200ms以下」ではなく「ユーザーが3分以内にチェックアウトを完了できる」という形で記述します。
  4. 必須セクションとオプションセクション — 一部のセクションは必ず記入し、該当しないセクションは「N/A」のまま残すのではなく、完全に削除する必要があります。

templates/plan-template.md には、憲法的原則を参照する「Phase -1 ゲート」が含まれています。

## Constitution Check

Language/Version: [e.g., Python 3.11]
Primary Dependencies: [e.g., FastAPI]

そして templates/constitution-template.md は、Library-First・CLI Interface Mandate・Test-First Imperative といったコア原則を含むガバナンスの骨格を定義し、生成されるすべての実装計画を制約します。

これらのテンプレートは スケールするプロンプトエンジニアリング として機能します。やり取りのたびに完璧なプロンプトを手作りするのではなく、テンプレートに構造的な制約を埋め込むことで、基盤となるモデルに関わらずAIをより高品質な出力へと導きます。spec-driven.md の哲学ドキュメントが述べているように、テンプレートは「LLMをクリエイティブなライターから規律ある仕様エンジニアへと変容させる」のです。

次回予告

コマンドとテンプレートはAIが 何をすべきか を定義します。では、新しいコマンドを追加するにはどうすればよいでしょうか?ライフサイクルフックはどのようにワークフローに組み込まれるのでしょうか?第5回では、Spec Kit の2つの拡張メカニズムを取り上げます。拡張機能(カスタムコマンド+フック)とプリセット(テンプレートのオーバーライド)について、バンドルされているgit拡張機能とマルチカタログ探索システムの詳細なウォークスルーを交えながら解説します。