1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Claude Code】/goal完全ガイド:AIに「完了条件」を与えて自律的に開発させる方法

1
Posted at

Claude Code を使って開発していると、次のような経験はないでしょうか。

「TypeScript のエラーを修正して」と指示したところ、Claude は修正を完了したと報告してきた。しかし、実際に npm run build を実行すると、まだ別のエラーが残っている。

そこで再度、次のように指示します。

まだエラーが残っています。修正してください。

修正後、再びテストを実行すると別の問題が見つかり、また Claude に作業を依頼する。

このような「修正 → 検証 → 再修正」のやり取りは、AI を利用した開発において珍しくありません。

Claude Code に追加された /goal コマンドは、この問題を解決するための仕組みです。

/goal では、AI に単なる作業指示を与えるのではなく、達成すべき最終状態(Goal)を定義します。

Claude Code はそのゴールを達成するまで、自律的に作業と評価を繰り返します。

本記事では、/goal の基本的な仕組みを解説したうえで、以下の3つの実践例を紹介します。

  • Next.js:TypeScript・ESLint・ビルドエラーの自動修正
  • FastAPI:APIの実装・テスト・品質検証の自動化
  • Terraform:IaCの構文・検証エラーの自動修正

さらに、実務で重要となるゴール設計のベストプラクティスや、自律実行時の安全性についても解説します。


1. /goal コマンドとは

/goal は、Claude Code に明確な完了条件を与え、その条件が満たされるまで複数ターンにわたって自律的に作業させる機能です。

Claude Code v2.1.139 以降で利用できます。

基本構文は非常にシンプルです。

/goal <達成したい条件>

例えば、次のように指示できます。

/goal npm run build が正常終了するまでエラーを修正する

Claude Code はビルドエラーを調査し、必要なコードを修正して、再びビルドを実行します。

まだエラーが残っていれば、修正作業を継続します。

重要なのは、Claude 自身が「作業完了」と判断しても、そこで必ず終了するわけではないという点です。

/goal では、別の評価モデルが完了条件を確認し、ゴールが未達成なら次のターンを開始します。

通常の指示との違い

通常の Claude Code では、次のような流れになります。

User
  │
  ├─ ビルドエラーを修正して
  │
  ▼
Claude Code
  ├─ コード解析
  ├─ コード修正
  └─ 作業完了と判断
         │
         ▼
      Userに返答

User
  │
  └─ まだエラーがあるので修正して
         │
         ▼
      Claude Code

一方、/goal を使用すると、次のようになります。

User
  │
  └─ /goal ビルドが成功するまで修正
         │
         ▼
   Claude Code
         │
         ├─ エラーを調査
         ├─ コードを修正
         └─ ビルドを実行
                │
                ▼
         Goal Evaluator
          (評価モデル)
                │
         ┌──────┴──────┐
         │             │
       未達成         達成
         │             │
         ▼             ▼
    次のターンへ     Goal解除
         │             │
         └─ 修正継続   └─ 作業終了

このように、AIによる実装作業とゴール達成の判定が分離されていることが、/goal の大きな特徴です。


2. /goal の内部動作

/goal は、Claude Code の Stop hook を利用した仕組みです。

Stop hook は、Claude がターンを終了しようとしたタイミングで実行されるフックです。

/goal では、この Stop hook を通じて別の評価モデルがゴールの達成状況を確認します。

2.1 評価モデルによる判定

処理の流れは、概ね次のようになります。

  1. ユーザーが /goal で完了条件を設定する
  2. Claude Code が実装・修正・検証を実行する
  3. Claude がターンを終了しようとする
  4. 評価モデルがゴールと会話履歴を確認する
  5. 未達成なら理由をフィードバックして次のターンへ進む
  6. 達成済みならゴールを解除する

評価モデルには、デフォルトで Haiku 系の小型高速モデルが使用されます。

判定結果は、主に次の3種類です。

判定 意味 動作
Not yet met ゴール未達成 作業を継続
Met ゴール達成 ゴールを解除
Impossible 達成不可能と判断 失敗としてゴールを解除

例えば、次のゴールを設定したとします。

/goal npm run build が終了コード0で成功する

Claude Code がコード修正を終えても、ビルドの成功が確認できなければ評価モデルは未達成と判定できます。

その結果を受けて Claude は再び修正を開始します。

2.2 評価モデルが直接テストするわけではない

ここは重要なポイントです。

評価モデル自身は、ターミナルコマンドを実行したり、リポジトリ内のファイルを直接参照したりしません。

評価に使用するのは、Claude Code の会話履歴に記録された作業結果です。

したがって、次のような曖昧な完了条件は適切ではありません。

/goal アプリケーションを完璧にする

「完璧」という状態を客観的に確認できないためです。

代わりに、次のように指定します。

/goal 以下のすべてを満たすこと。

1. npm run build が終了コード0で成功する
2. npx tsc --noEmit が終了コード0で成功する
3. npm run lint が終了コード0で成功する

すべての実行結果を報告する。

これならば評価モデルが会話履歴から結果を判断できます。

2.3 /goal は必ず成功するまで動くわけではない

/goal は無限に処理を続けることを保証する機能ではありません。

ゴールが達成不可能と判断された場合や、認証・利用枠などの回復不能なエラーが発生した場合には、ゴールが解除されることがあります。

また、進捗のないターンが続いた場合には、ループを一時停止してユーザーに制御を返す仕組みもあります。

そのため、実務では「達成できなければ残課題を報告する」といった条件も重要です。


3. 実践例① Next.js:ビルドエラーをゼロにする

最初は、Next.js + TypeScript の開発プロジェクトです。

Next.js では、TypeScript、ESLint、React コンポーネント、Server Components、API Routes など、複数の要素が絡み合っています。

例えば、あるコンポーネントの型定義を変更すると、ほかのコンポーネントでも型エラーが発生することがあります。

このような連鎖的な修正作業は、/goal に適しています。

3.1 想定するプロジェクト

my-nextjs-app/
├── app/
│   ├── page.tsx
│   ├── layout.tsx
│   └── api/
│       └── users/
│           └── route.ts
├── components/
│   ├── Header.tsx
│   └── UserList.tsx
├── lib/
│   └── api.ts
├── package.json
└── tsconfig.json

このプロジェクトで、次のコマンドが失敗しているとします。

npm run build

例えば、以下の TypeScript エラーです。

Type error:
Property 'email' does not exist on type 'User'

通常であれば、該当コードを修正して再ビルドする作業を繰り返します。

3.2 /goal による自律修正

Claude Code を起動します。

cd my-nextjs-app
claude

続いて、次のゴールを設定します。

/goal Next.jsプロジェクトのビルドエラーをすべて修正する。

完了条件:
1. npm run build が終了コード0で成功する
2. npx tsc --noEmit が終了コード0で成功する
3. npm run lint が終了コード0で成功する

制約:
- 既存機能を削除しない
- TypeScriptのstrict設定を無効化しない
- @ts-ignoreによるエラー回避を禁止
- any型への安易な置き換えを禁止
- ESLintルールを無効化しない
- package.jsonの検証スクリプトを削除しない

各検証コマンドの結果を明示する。
最大10ターンで終了し、未達成なら残課題を報告する。

※ npm run lint は、プロジェクトの package.json に定義済みのスクリプトを想定しています。

動作イメージ

以下は説明用のシミュレーションです。

ターン 実行内容 結果
1 ビルド実行、型エラーを検出 未達成
2 User型とコンポーネントを修正 未達成
3 APIレスポンスの型を統一 未達成
4 ESLintエラーを修正 未達成
5 すべての検証コマンドが成功 達成

このように、開発者が修正を逐次指示する必要がなくなります。

3.3 なぜ制約条件が重要なのか

例えば、TypeScript エラーをなくすだけなら、型チェックを緩めてしまう方法も存在します。

// 安易な回避例
const user: any = response.data;

しかし、これでは TypeScript の型安全性が失われます。

また、tsconfig.json の strict を無効化してビルドを通すことも、問題の本質的な解決にはなりません。

そこで、ゴールに制約条件を追加します。

型チェック設定を緩和せず、
既存機能の振る舞いを維持したまま
ビルドを成功させる。

ゴールは「何を達成するか」だけでなく、「どのような方法では達成してはいけないか」まで指定することが重要です。

なお、ビルド成功はアプリケーションの全機能が正常であることを意味しません。E2Eテストや実際の画面操作による確認も、必要に応じて完了条件に追加しましょう。


4. 実践例② FastAPI:API実装とテストを自動化する

続いて FastAPI を使用したバックエンド開発の例です。

Python の API 開発では、次のような工程が頻繁に発生します。

  • Pydantic によるリクエスト検証
  • API エンドポイントの実装
  • レスポンススキーマの定義
  • pytest によるテスト
  • Ruff による静的解析

これらをまとめて /goal で管理します。

4.1 想定するプロジェクト

fastapi-project/
├── app/
│   ├── main.py
│   ├── routers/
│   │   └── users.py
│   ├── schemas/
│   │   └── user.py
│   ├── services/
│   │   └── user_service.py
│   └── dependencies.py
├── tests/
│   ├── test_users.py
│   └── test_validation.py
├── pyproject.toml
└── requirements.txt

今回は、ユーザー作成 API を実装するとします。

APIの仕様は以下のとおりです。

エンドポイント

POST /api/users
Content-Type: application/json

リクエスト

{
  "name": "Taro",
  "email": "taro@example.com"
}

正常レスポンス

{
  "id": 1,
  "name": "Taro",
  "email": "taro@example.com"
}

HTTP ステータスは 201 Created とします。

また、不正なメールアドレスや必須パラメータの不足に対して、適切なバリデーションエラーを返す必要があります。

4.2 /goal による実装

次のように設定します。

/goal FastAPIにユーザー作成APIを実装する。

API仕様:
- POST /api/users
- nameとemailを受け取る
- 正常時は201 Createdを返す
- 不正なリクエストには422を返す
- レスポンスはid、name、emailを含む

完了条件:
1. 既存のユーザー作成テストがすべて成功する
2. 新仕様を検証するpytestテストを作成する
3. pytest -q が終了コード0で成功する
4. ruff check . が終了コード0で成功する
5. 既存APIの動作を変更しない

制約:
- テストの削除・スキップを禁止
- テストを成功させるためだけの固定値を禁止
- Pydanticによる入力検証を使用する
- 既存の依存性注入設計を維持する
- DB接続情報をコードに直接記述しない

最大10ターンで終了する。
検証結果と変更ファイルを報告する。

ここで重要なのは、API仕様と完了条件を分離していることです。

「ユーザー作成 API を作って」という指示では、完成の定義が不明確です。

一方、このゴールでは次の状態を明確にしています。

  • API仕様を満たすこと
  • 正常系と異常系がテストされること
  • pytest が成功すること
  • Ruff が成功すること

そのため、単に API を作るだけでなく、検証まで含めた作業を期待できます。

4.3 pytestとの組み合わせ

例えば、次のようなテストケースが考えられます。

from fastapi.testclient import TestClient

from app.main import app

client = TestClient(app)


def test_create_user_success():
    response = client.post(
        "/api/users",
        json={
            "name": "Taro",
            "email": "taro@example.com",
        },
    )

    assert response.status_code == 201

    data = response.json()

    assert data["name"] == "Taro"
    assert data["email"] == "taro@example.com"
    assert isinstance(data["id"], int)


def test_create_user_invalid_email():
    response = client.post(
        "/api/users",
        json={
            "name": "Taro",
            "email": "invalid-email",
        },
    )

    assert response.status_code == 422

これは、テスト用に独立したデータストアを用意し、対象エンドポイントが POST /api/users で実装されていることを前提とした例です。

/goal では、こうしたテストの実行結果を完了条件として利用できます。

pytest -q
ruff check .

例えば、APIのレスポンスが 200 OK になっていた場合は、201 Created を期待するテストが失敗します。

Claude Code はその結果をもとに、ステータスコードの指定を調査・修正できます。

さらに Ruff によってコード品質上の問題が検出されれば、それも修正対象になります。

テストを生成させる場合の注意

Claude に実装とテストの両方を作成させる場合、テストが実装に都合のよい内容になってしまう可能性があります。

実務では、次の順序がより安全です。

  1. 人間が受け入れ条件を定義する
  2. テストケースをレビューする
  3. /goal で実装と修正を反復する
  4. 独立した統合テストで最終確認する

既存の信頼できるテストを完了条件に利用することで、AIによる自己評価への過度な依存を抑えられます。


5. 実践例③ Terraform:IaCの検証エラーを自律修正する

3つ目は Terraform を利用した Infrastructure as Code(IaC)の開発です。

Terraform では、モジュールの参照ミス、変数の型不一致、Provider設定の不整合などによって、terraform validate が失敗することがあります。

これらの問題を /goal で修正してみます。

5.1 想定するTerraformプロジェクト

AWS上にネットワークやアプリケーション基盤を構築する構成を想定します。

terraform/
├── environments/
│   ├── dev/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── terraform.tfvars
│   └── prod/
│       ├── main.tf
│       └── variables.tf
├── modules/
│   ├── vpc/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── outputs.tf
│   └── ecs/
│       ├── main.tf
│       ├── variables.tf
│       └── outputs.tf
└── README.md

例えば、開発環境で次のコマンドを実行すると、エラーが発生するとします。

cd terraform/environments/dev

terraform init -backend=false

terraform validate

エラーの原因としては、次のようなものがあります。

  • 未定義の変数を参照している
  • モジュールに必要な引数が不足している
  • モジュールの output 名が一致しない
  • リソース定義にサポートされない引数がある

こうした構文・設定上の問題は、/goal による反復修正と相性がよい領域です。

5.2 Terraform用 /goal

Terraform では、安全性を最優先に考え、今回はインフラストラクチャの変更を伴わない静的検証に対象を限定します。

/goal Terraform開発環境の設定エラーを修正する。

対象:
terraform/environments/dev

完了条件:
1. terraform fmt -check -recursive が成功する
2. terraform validate が成功する
3. モジュール間の変数・output参照に不整合がない
4. 実施した変更内容を報告する

作業手順:
- terraform fmt で書式を整える
- terraform init -backend=false で初期化する
- terraform validate を実行する
- エラーがあれば修正して再検証する

制約:
- terraform apply は絶対に実行しない
- terraform destroy は絶対に実行しない
- terraform plan も実行しない
- 本番環境の設定を変更しない
- terraform.tfstate を変更・削除しない
- リソースを削除してエラーを回避しない
- セキュリティ設定を緩和しない

最大10ターンで終了する。
すべての検証結果を報告する。

このゴールでは、Terraformの修正と検証のみを許可しています。

インフラの変更を伴う terraform apply は実行させません。

クラウド環境では、コード変更のミスがリソース削除やセキュリティ上の問題につながる可能性があるためです。

なお、terraform init -backend=false はバックエンドの初期化を省略できますが、Providerやモジュールのダウンロードなど、ローカル環境への変更や外部への通信は発生し得ます。

また、terraform validate が成功しても、実際のAWS環境に対する適用可能性や差分の安全性まで保証されるわけではありません。

5.3 Terraformで推奨するワークフロー

Terraformで /goal を利用する場合、次のような段階的な運用がおすすめです。

Terraformコード
       │
       ▼
/goal による修正
       │
       ├─ terraform fmt
       ├─ terraform validate
       └─ 静的解析
       │
       ▼
   Git差分の確認
       │
       ▼
 人間によるレビュー
       │
       ▼
terraform plan
       │
       ▼
 Plan結果のレビュー
       │
       ▼
 承認されたCI/CDでapply

/goal にすべての操作を任せるのではなく、コード品質の改善と実際のインフラ変更を明確に分離することが重要です。

特に本番環境では、GitのPull Requestによるレビューと、CI/CDでの承認フローを組み合わせるべきでしょう。


6. /goal を成功させるゴール設計

ここまで3つの例を紹介しましたが、/goal の成果を左右するのは、ゴールの書き方です。

実務では、次の4つの要素を意識すると設計しやすくなります。

6.1 Goal:達成すべき目的

まず、作業の目的を明確にします。

Next.jsのビルドエラーを修正する

6.2 Acceptance Criteria:完了条件

次に、客観的な検証方法を指定します。

npm run build が成功する
npx tsc --noEmit が成功する
npm run lint が成功する

6.3 Constraints:制約条件

作業の過程で守るべきルールを指定します。

既存のテストを削除しない
TypeScriptの型チェックを無効化しない
既存APIの仕様を変更しない

6.4 Limits:実行範囲

最後に、作業の上限や終了時の振る舞いを指定します。

最大10ターンで終了する
完了できない場合は残課題を報告する

これらをまとめると、次のようなテンプレートになります。

/goal [達成したい目的]

【完了条件】
1. [検証可能な条件1]
2. [検証可能な条件2]
3. [検証可能な条件3]

【制約】
- [変更してはいけないもの]
- [禁止する回避方法]
- [守るべき品質基準]

【検証方法】
- [コマンド1]
- [コマンド2]

【実行上限】
最大10ターンで終了する。
未達成なら理由と残課題を報告する。

この構成は、Next.js、FastAPI、Terraform以外の開発にも応用できます。

ただし、ターン数の上限は専用の強制停止パラメータではありません。条件文に記述した上限を評価モデルが会話履歴から判断する仕組みです。

厳格な実行時間やコストの制御が必要な場合は、外部のプロセス管理やCI/CD側のタイムアウトも併用してください。


7. /goal と /loop、Stop hook の違い

Claude Code には、/goal 以外にも作業を繰り返すための仕組みがあります。

代表的なのは、/loop と Stop hook です。

機能 動作 主な用途
/goal ゴール達成を評価しながら継続 エラー修正、機能実装
/loop 指定した時間間隔で実行 定期監視、状態確認
Stop hook ターン終了時にカスタム処理 独自の停止条件や品質ゲート

/goal の例

/goal 全pytestテストが成功するまで修正する

これは、特定の状態を達成することが目的です。

/loop の例

/loop 5m CIの実行状態を確認する

これは、一定の時間間隔で処理を実行することが目的です。

Stop hook の例

Stop hook では、ターン終了時に独自のコマンドや評価処理を実行できます。

例えば、独自の検証スクリプトを実行し、その結果によって終了を許可するかどうかを制御する仕組みを構築できます。

/goal は、こうした Stop hook の考え方を、セッション単位で簡単に利用できるようにした機能と捉えると理解しやすいでしょう。


8. /goal の基本操作

基本操作も確認しておきます。

ゴールを設定する

/goal npm run build が成功するまで修正する

現在のゴールを確認する

/goal

実行中のゴール、経過時間、評価されたターン数、トークン消費量、評価モデルの直近の判定理由などを確認できます。

ゴールを解除する

/goal clear

/goal stop も解除の別名として利用できます。

新しいゴールに置き換える

/goal pytestがすべて成功するまで修正する

すでにゴールが存在している場合、新しいゴールが以前のゴールを置き換えます。

1つのセッションで有効にできるゴールは1つです。

非対話モードで実行する

Claude Code の CLI から実行することもできます。

claude -p "/goal npm run build が成功するまで修正する"

実行中のメッセージをストリーム形式で確認したい場合は、次のように指定します。

claude -p \
  "/goal npm run build が成功するまで修正する" \
  --output-format stream-json \
  --verbose

非対話モードは自動化との組み合わせに便利ですが、実行権限やコスト管理には注意が必要です。


9. 実務で利用する際の注意点

/goal は便利ですが、ゴールの設計を誤ると、望ましくない変更が発生する可能性があります。

9.1 テストを通すためだけの変更に注意

例えば、次のゴールです。

/goal すべてのテストを成功させる

これだけでは、テストの削除、スキップ、期待値の書き換えなど、望ましくない方向で作業が進むリスクがあります。

そのため、必ず制約を追加します。

既存テストの削除・スキップ・期待値変更によって
成功扱いにしてはならない。

完了条件と品質条件は別物です。

9.2 本番環境の自動変更を避ける

特に Terraform やデータベースマイグレーションでは注意が必要です。

/goal インフラを正常な状態にする

このようなゴールは範囲が広すぎます。

誤った変更を防ぐため、作業対象のディレクトリ、変更してよいファイル、実行してはいけないコマンドを明示します。

さらに、本番環境では権限設定によって危険な操作を実行できないようにすることが重要です。

プロンプトによる禁止事項は、OSやクラウドのアクセス権限による制御の代わりにはなりません。

9.3 トークン消費量に注意する

/goal はゴール未達成の間、複数ターンにわたって作業を実行します。

そのため、通常の単発指示よりもトークン消費量が増える場合があります。

評価モデル自体は小型高速モデルですが、メインモデルが繰り返しコードを解析・修正するコストは発生します。

実務では次のような工夫が有効です。

  • 最初は小さなゴールから始める
  • 変更対象のディレクトリを限定する
  • 検証に必要なコマンドを明示する
  • ターン数や時間の上限条件を加える
  • 長時間実行時は /goal で状態を確認する

9.4 Gitによる変更管理を徹底する

自律実行では、複数のファイルが連続して変更されることがあります。

そのため、作業前にGitの状態を確認し、専用ブランチで作業することをおすすめします。

git status

git switch -c feature/claude-goal-fix

作業後は、変更差分を確認します。

git diff --check

git diff --stat

git diff

必要に応じて、テスト・レビュー・Pull Requestの作成を行います。

/goal が成功と判定したことと、変更内容が本番環境に適していることは、必ずしも同じではありません。


10. /goal が変えるAI開発の考え方

従来のAIコーディングでは、開発者が一つひとつの作業を指示するケースが中心でした。

実装する
  ↓
人間が確認する
  ↓
エラーを見つける
  ↓
再びAIに指示する

/goal では、この考え方が変わります。

人間が要件を定義する
  ↓
人間が完了条件を定義する
  ↓
AIが実装・修正を繰り返す
  ↓
AIが検証結果をもとに達成を評価する
  ↓
人間が最終レビューする

つまり、開発者の役割が、個々の修正を繰り返し指示することから、何をもって完成とするかを定義することへと広がります。

これは、ソフトウェア開発における受け入れ条件(Acceptance Criteria)やテスト駆動開発(TDD)の考え方とも親和性があります。

ただし、/goal はそれらを置き換えるものではありません。

明確な要件、信頼できるテスト、レビュー体制が存在することで、/goal の価値がより高まります。


まとめ

Claude Code の /goal は、AI に明確な完了条件を与え、達成状況を評価しながら自律的に作業を継続させる機能です。

今回紹介した3つの例を振り返ります。

技術 活用例 完了条件
Next.js TypeScript・ビルドエラーの修正 build、tsc、lint 成功
FastAPI API実装・テスト修正 pytest、Ruff 成功
Terraform IaCの設定エラー修正 fmt、validate 成功

どのケースでも重要なのは、次の3点です。

1. 検証可能な完了条件を定義すること

「品質を改善する」ではなく、「pytest が終了コード0で成功する」のように具体的に指定します。

2. 制約条件を明確にすること

既存機能やテストの削除、セキュリティ設定の緩和など、許容できない変更を明示します。

3. AIの完了判定を最終承認と混同しないこと

自動テストや静的解析を通過した後も、人間による変更レビューや本番環境での確認は重要です。

/goal の本質は、単にAIを長時間動かすことではありません。

「作業」を指示するのではなく、「達成すべき状態」を定義する。

この考え方を取り入れることで、Claude Code を単なるコード生成ツールから、検証を伴う開発作業の実行エージェントとして活用しやすくなります。

参考資料

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?