6
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?

ユーザーの改善要望をAIが即座に実装する仕組みを作った話 - Claude Code × GitHub Actions

Last updated at Posted at 2025-12-23

はじめに

社内向けのツールを開発・運用していると、ユーザーから多くの改善要望が寄せられます。

「このボタンの位置を変えてほしい」
「この項目も表示したい」
「ソート機能がほしい」

こうした要望は対応が遅れるとユーザの不満につながるだけでなく、ユーザのエンゲージメントが低下して結果としてツールの利用率が低下、得たい成果が得られなくなることに繋がります。

AIの登場により実装速度は格段に上がりましたが、
要望整理・優先順位付け・レビューなど「人間の判断」が必要な工程が新たなボトルネックになっていました。

そこで 「簡単な機能要望なら、人間を介さず自動で実装できないか?」 と考えて、Claude Code GitHub Action を使って
ユーザの改善要望から、 実装計画 → 実装 → PR作成 → Slack通知までを全自動化した仕組みを紹介します。


この仕組みで実現できること

ユーザーがアプリケーション内で改善要望を投稿すると、以下が自動で実行されます。

  1. 実装計画の自動生成 - Claude Code がコードベースを分析し、JSONで計画を出力
  2. 自動実装 - 計画に基づいてコードを実装
  3. PR自動作成 - develop ブランチへのPRを自動生成
  4. 自動レビュー - Claude Code がPRをレビュー
  5. Slack通知 - 各ステップの完了をチーム全体に通知

システム全体像

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│   ユーザー   │────▶│ 改善要望画面 │────▶│ Supabase DB │
└─────────────┘     └─────────────┘     └──────┬──────┘
                                               │
                                               ▼
                                    ┌─────────────────────┐
                                    │ ステータス: reviewing│
                                    └──────────┬──────────┘
                                               │
                          ┌────────────────────┼────────────────────┐
                          ▼                    ▼                    ▼
               ┌──────────────────┐  ┌──────────────────┐  ┌──────────────────┐
               │ GitHub Actions   │  │ GitHub Actions   │  │  Slack通知       │
               │ 実装計画生成      │─▶│ 自動実装         │─▶│  (各ステップ)    │
               └──────────────────┘  └────────┬─────────┘  └──────────────────┘
                                              │
                                              ▼
                                    ┌──────────────────┐
                                    │  PR自動作成       │
                                    │  + 自動レビュー   │
                                    └──────────────────┘

改善要望の入力画面

ユーザーは専用の入力フォームから改善要望を投稿します。

image.png

入力項目は以下の4つです。

項目 必須 説明
課題の概要 何を改善してほしいか(500文字以内)
対象画面 - どの画面に関する要望か
修正案・改善案 - 具体的な改善案があれば(2000文字以内)
優先度 高/中/低

投稿された要望は管理者がレビューし、ステータスを reviewing(検討中) に変更すると自動実装フローが開始されます。

実装計画の自動生成

ステータスが reviewing に変更されると、Supabase Edge Function が GitHub Actions をトリガーします。

Claude Code がコードベースを分析し、JSON形式で実装計画を出力します。

image.png

出力される計画の形式

{
  "summary": "サイドバーの開閉時にスムーズなアニメーション(ぬるっと動く)を追加。デスクトップ版の幅変化にもトランジションを適用し、メインコンテンツ領域も連動して滑らかに広がるようにする。",
  "scope": "サイドバーを使用するすべての保護されたページ(/projects、/users、/feature-requests、管理者ページなど)のサイドバー開閉動作に影響。既存の300msスライドアニメーションに加え、幅変化とオーバーレイのフェードイン/アウトを追加。",
  "affectedFiles": [
    "src/components/layouts/sidebar-nav.tsx",
    "src/components/ui/collapsible.tsx",
    "src/app/(protected)/layout.tsx"
  ],
  "newFiles": [],
  "steps": [
    {
      "order": 1,
      "description": "sidebar-nav.tsx: デスクトップ版サイドバーの幅変化にトランジションを追加。現在の `transition-transform` を `transition-all` に変更し、width, opacity, border の変化も滑らかにする。また、overflow: hidden を追加してコンテンツが幅変化時にはみ出さないようにする。",
      "files": ["src/components/layouts/sidebar-nav.tsx"],
      "estimatedMinutes": 20
    },
    {
      "order": 2,
      "description": "sidebar-nav.tsx: モバイル用オーバーレイにフェードイン/アウトアニメーションを追加。現在は即座に表示/非表示になっているが、opacity トランジションを使用してスムーズに表示されるようにする。React の状態管理で表示制御しつつCSSトランジションを適用。",
      "files": ["src/components/layouts/sidebar-nav.tsx"],
      "estimatedMinutes": 25
    },
    {
      "order": 3,
      "description": "layout.tsx: メインコンテンツ領域(<main>)にもトランジションを追加。サイドバーの開閉に連動して、コンテンツ領域がスムーズに広がる/縮まるようにする。flex-1 の領域が自然に変化するよう、親コンテナにもトランジションを適用検討。",
      "files": ["src/app/(protected)/layout.tsx"],
      "estimatedMinutes": 15
    },
    {
      "order": 4,
      "description": "collapsible.tsx: Radix UIのCollapsibleContentにアニメーションスタイルを追加。現在はデフォルトの動作だが、CSS変数とdata属性を使用してスムーズな高さ変化アニメーションを実現する。",
      "files": ["src/components/ui/collapsible.tsx"],
      "estimatedMinutes": 15
    },
    {
      "order": 5,
      "description": "動作確認とアニメーション調整。各ブレークポイント(モバイル、タブレット、デスクトップ)での開閉動作を確認し、duration-300(300ms)のタイミングが自然かどうかを検証。必要に応じて ease-in-out などのイージング関数を調整。",
      "files": ["src/components/layouts/sidebar-nav.tsx"],
      "estimatedMinutes": 15
    }
  ],
  "risks": [
    "オーバーレイのアニメーション実装時に、表示/非表示の状態管理が複雑になる可能性がある(ReactのconditionalレンダリングとCSSトランジションの両立)",
    "transition-all を使用すると、意図しないプロパティまでアニメーションされてパフォーマンスが低下する可能性がある。必要なプロパティのみ明示的に指定することを検討",
    "モバイルでのスクロール無効化(overflow: hidden)とアニメーションの組み合わせでちらつきが発生する可能性",
    "Radix UI CollapsibleContentのアニメーションはCSS変数を使用するため、ブラウザ互換性を確認する必要がある"
  ],
  "testingStrategy": "アニメーションはUIに関するため自動テストは実施しない。手動で以下を確認:1) デスクトップでのサイドバー開閉が滑らかに動作すること、2) モバイルでのオーバーレイ表示/非表示がフェードイン/アウトすること、3) 管理メニューの開閉アニメーションが滑らかであること、4) 各ブレークポイントでレイアウトが崩れないこと、5) アニメーション中にクリックしても正常に動作すること"
}

実装計画生成ワークフロー(generate-plan.yml)の詳細
name: Generate Implementation Plan

on:
  repository_dispatch:
    types: [generate-implementation-plan]

jobs:
  generate-plan:
    runs-on: ubuntu-latest
    environment: ${{ github.event.client_payload.environment || 'develop' }}

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Create plan output directory
        run: mkdir -p .github/plan-output

      - name: Run Claude Code for Plan Generation
        uses: anthropics/claude-code-action@v1
        with:
          claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
          claude_args: |
            --model claude-opus-4-5-20251101
            --allowedTools "Read,Glob,Grep,Write,Bash(mkdir:*),Bash(npm:*),Bash(git:*)"
            --max-turns 50
          prompt: |
            以下の改善要望に対する実装計画を作成してください。

            ## 改善要望
            **タイトル**: ${{ github.event.client_payload.title }}
            **対象画面**: ${{ github.event.client_payload.target_screen }}
            **修正案**: ${{ github.event.client_payload.suggestion }}

            ## 作業手順
            1. 関連するファイルを調査
            2. 具体的な実装計画を作成
            3. .github/plan-output/plan.json に出力

      - name: Send plan to webhook
        run: |
          curl -X POST "${{ secrets.SUPABASE_URL }}/functions/v1/implementation-webhook-handler" \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }}" \
            -d "{\"planId\": \"${{ github.event.client_payload.planId }}\", \"event\": \"plan_generated\", ...}"

自動実装

計画が生成されると、次のワークフローが自動でトリガーされ、実際にコードを実装します。

Claude Code は以下の作業を自動で行います。

  1. 機能ブランチの作成(feature/fr-xxxxxxxx-タイムスタンプ
  2. 計画に基づいたコード実装
  3. npm run lint:fix(コード品質チェック)
  4. npm run build(ビルド確認)
  5. npm run test(テスト実行)
  6. コミット&プッシュ
自動実装ワークフロー(feature-request-implementation.yml)の詳細
name: Feature Request Implementation

on:
  repository_dispatch:
    types: [feature-request-implementation]

jobs:
  implement:
    runs-on: ubuntu-latest
    environment: ${{ github.event.client_payload.environment || 'develop' }}
    permissions:
      contents: write
      pull-requests: write
      issues: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Create feature branch
        id: branch
        run: |
          BRANCH_NAME="feature/fr-$(echo '${{ github.event.client_payload.feature_request_id }}' | cut -c1-8)-$(date +%Y%m%d%H%M%S)"
          echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
          git checkout -b $BRANCH_NAME

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run Claude Code
        uses: anthropics/claude-code-action@v1
        with:
          claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
          claude_args: |
            --model claude-opus-4-5-20251101
            --allowedTools Write,Read,Edit,Glob,Grep,Bash(git:*),Bash(npm:*)
            --max-turns 30
          prompt: |
            以下の改善要望を実装してください。

            ## 要望タイトル
            ${{ github.event.client_payload.feature_request_title }}

            ## 実装計画
            ${{ github.event.client_payload.plan_content }}

            ## 実装時の注意事項
            - 既存のコードパターンに従ってください
            - CLAUDE.mdのガイドラインを遵守してください
            - 実装後は必ずlint、build、testを実行してください

      - name: Commit and push changes
        if: steps.changes.outputs.has_changes == 'true'
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git add -A
          git commit -m "feat: ${{ github.event.client_payload.feature_request_title }}"
          git push origin ${{ steps.branch.outputs.branch_name }}

      - name: Create Pull Request
        run: |
          gh pr create \
            --base develop \
            --head ${{ steps.branch.outputs.branch_name }} \
            --title "feat: ${{ github.event.client_payload.feature_request_title }}" \
            --label "feature-request,auto-generated"

PRの自動作成・レビュー

実装が完了すると、PRが自動で作成されます。

image.png

PRには以下の情報が含まれます。

  • 実装計画(JSON形式)
  • Feature Request ID
  • Plan ID
  • 「Generated with Claude Code」のラベル

Supabase Edge Functionsでのイベント連携

GitHub ActionsとSupabase間のイベント連携は、Edge Functionsで実装しています。

Webhookハンドラーの役割

  1. イベント受信: GitHub Actionsから各種イベントを受信
  2. DB更新: 実装計画のステータスを更新
  3. 次のワークフローをトリガー: plan_generated で自動実装をディスパッチ
  4. Slack通知: 各ステップの完了を通知
Webhookハンドラーの処理フロー
// supabase/functions/implementation-webhook-handler/handler.ts

export async function handleWebhookEvent(
  event: WebhookEvent,
  supabase: SupabaseClient,
  notifier: SlackNotifier
): Promise<void> {
  switch (event.event) {
    case "workflow_started":
      // ステータスを in_progress に更新
      await updatePlanStatus(supabase, event.planId, "in_progress");
      break;

    case "plan_generated":
      // 計画をDBに保存
      await savePlanContent(supabase, event.planId, event.planContent);
      // Slack通知
      await notifier.notifyPlanGenerated(event);
      // 自動実装ワークフローをディスパッチ
      await dispatchImplementation(event);
      break;

    case "pr_created":
      // PRのURLをDBに保存
      await updatePlanWithPR(supabase, event.planId, event.prUrl);
      // Slack通知
      await notifier.notifyPrCreated(event);
      break;

    case "pr_merged":
      // 完了ステータスに更新
      await updatePlanStatus(supabase, event.planId, "completed");
      // Feature Requestのステータスも完了に
      await completeFeatureRequest(supabase, event.planId);
      // Slack通知
      await notifier.notifyImplementationCompleted(event);
      break;

    case "workflow_failed":
      // エラー情報を記録
      await recordFailure(supabase, event.planId, event.errorMessage);
      // Slack通知
      await notifier.notifyImplementationFailed(event);
      break;
  }
}

Slack通知

各ステップの完了時にSlackに通知が送られます。

image.png

通知タイミング

イベント 通知内容
計画生成完了 要望タイトル、計画の概要
PR作成完了 要望タイトル、PRへのリンク
実装完了 要望タイトル、PRへのリンク
実装失敗 要望タイトル、エラーメッセージ
Slack通知の実装コード
// supabase/functions/implementation-webhook-handler/runtime-deps.ts

const notifier = slackWebhookUrl ? {
  async notifyPlanGenerated(event: PlanGeneratedEvent) {
    await fetch(slackWebhookUrl, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        blocks: [
          {
            type: "section",
            text: {
              type: "mrkdwn",
              text: "*[実装計画] 計画生成完了*"
            }
          },
          {
            type: "section",
            fields: [
              { type: "mrkdwn", text: `*要望:*\n${event.title}` },
              { type: "mrkdwn", text: `*概要:*\n${event.summary}` }
            ]
          }
        ]
      })
    });
  },

  async notifyPrCreated(event: PrCreatedEvent) {
    await fetch(slackWebhookUrl, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        blocks: [
          {
            type: "section",
            text: {
              type: "mrkdwn",
              text: `*[実装計画] PR作成完了*\n<${event.prUrl}|#${event.prNumber}>`
            }
          }
        ]
      })
    });
  },

  // notifyImplementationCompleted, notifyImplementationFailed も同様
} : null;

学び

  • claude codeに適切なツールの権限・許可を与える必要がある
    • →bash, npm, gitなど必要最小限のものを与えることで、意図しない挙動をしないように
  • 実装が困難な修正に関してはmax-turnsに達してしまい、修正が完了しない
    • →これはある程度仕方ないので、turn数が上限に近づいたらそこまでの情報を整理してWIPとしてPRを作成して通知する様にするなどの工夫を行う必要があります
  • 複雑な実装の場合、一発では完了しないこともまだ多い
    • → 今後のモデルの改善に期待しつつ、github actionを実行する時のpromptはまだ改善の余地あり

この仕組みの価値

ユーザーにとって

  • 改善要望が即座に反映される体験
    「要望を出したらすぐに対応してくれた」という満足感
  • 要望を出すモチベーションの向上
    「どうせ対応されない」という諦めがなくなる

開発者にとって

  • 細かい改善要望への対応コスト削減
    小さな修正の積み重ねが大きな負担になる課題を解消
  • “判断待ち”のボトルネック解消
    AIが実装を回し、人間は重要な判断に集中できる

組織にとって

  • GitHub管理されているツールなら同様の仕組みを適用可能
    非エンジニアの要望を自動で実装できる
  • 部署ごとに最適化されたツールを量産しやすい
  • 細かい改善の積み重ねでツール品質を底上げできる

今後の展望

より複雑な要望への対応

現在は「簡単な機能要望」に限定していますが、以下を検討しています。

  • ユーザの改善要望の情報が不十分な場合に自動でAIがヒアリングを追加して行う
  • 実装難易度をAIが判定し、難易度が高い場合は開発者にエスカレーション
  • Supabase / Vercel のログから自動でバグを検知し、バグ修正の計画を作成

まとめ

Claude Code GitHub Action を使って、
ユーザーの改善要望から実装・PR作成・Slack通知までを全自動化する仕組みを紹介しました。

AIの実装能力が向上しても「人間の判断・意思決定」がボトルネックになる問題は残りますが、この仕組みは、簡単な機能要望に限定することで、人間を介さず自動で改善を回すことを可能にしました。

これまでは開発工数の問題で対応出来なかった、数は少ない個別のロングテールなニーズに対応が行えるようにすることは、今後ますます重要になっていくと考えています。


参考リンク

6
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
6
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?