コンテンツにスキップ

Claude Code 完全ガイド

Claude Sonnet 4 × GitHub Copilot実装完全ガイド:実戦で使える設定とコード例【2025年7月技術深掘り】

はじめに

Claude Sonnet 4 × GitHub Copilot Agent基礎ガイドで概要を紹介した次世代AI開発環境の、実際の実装方法と運用ノウハウを詳解します。

この記事では実戦レベルの設定例、実際に動作するコード、そして運用中に遭遇する問題の解決法まで、実装者が知りたい情報を網羅的に提供します。

この記事のポイント

  • 完全動作するワークフロー

    コピー&ペーストで即座に動作する実際の設定ファイルとコード例

  • 詳細設定テクニック

    パフォーマンス最適化、エラーハンドリング、セキュリティ考慮の実装

  • 実戦トラブルシューティング

    実際の運用で発生する問題と具体的な解決手順

  • 運用メトリクス取得

    パフォーマンス測定とボトルネック特定の具体的手法

詳細実装:GitHub Copilot Agent設定

本格的なワークフロー設定

# .github/workflows/copilot-agent-advanced.yml
name: Advanced Copilot Agent Automation
on:
  issues:
    types: [assigned, labeled]
  pull_request:
    types: [opened, synchronize]

env:
  CLAUDE_MODEL: claude-sonnet-4
  NODE_VERSION: '20'
  PYTHON_VERSION: '3.11'

jobs:
  copilot-agent-handler:
    runs-on: ubuntu-latest
    if: ${{ contains(github.event.issue.assignees.*.login, 'github-copilot[bot]') || github.event.label.name == 'copilot-agent' }}

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          fetch-depth: 0

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'

      - name: Setup Python
        uses: actions/setup-python@v4
        with:
          python-version: ${{ env.PYTHON_VERSION }}

      - name: Install Claude Code CLI
        run: |
          curl -sSL https://claude.ai/install.sh | bash
          echo "$HOME/.local/bin" >> $GITHUB_PATH

      - name: Configure Copilot Agent
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          CLAUDE_API_KEY: ${{ secrets.CLAUDE_API_KEY }}
        run: |
          # GitHub CLI認証
          echo "${{ secrets.GITHUB_TOKEN }}" | gh auth login --with-token

          # Copilot設定
          gh extension install github/gh-copilot --force
          gh copilot config set model ${{ env.CLAUDE_MODEL }}

          # Claude Code設定
          claude-code auth login --token "${{ secrets.CLAUDE_API_KEY }}"

      - name: Analyze Issue and Generate Solution
        id: analysis
        env:
          ISSUE_NUMBER: ${{ github.event.issue.number }}
          REPO_FULL_NAME: ${{ github.repository }}
        run: |
          # イシュー詳細取得
          ISSUE_BODY=$(gh issue view ${{ env.ISSUE_NUMBER }} --json body --jq '.body')
          ISSUE_TITLE=$(gh issue view ${{ env.ISSUE_NUMBER }} --json title --jq '.title')

          # Copilot Agent実行準備
          echo "issue_title=$ISSUE_TITLE" >> $GITHUB_OUTPUT
          echo "issue_body=$ISSUE_BODY" >> $GITHUB_OUTPUT

          # リポジトリ構造分析
          claude-code analyze-repo --output repo_structure.json

          # 実装計画生成
          claude-code generate-plan \
            --issue-title "$ISSUE_TITLE" \
            --issue-body "$ISSUE_BODY" \
            --repo-structure repo_structure.json \
            --output implementation_plan.json

      - name: Execute Implementation
        env:
          IMPLEMENTATION_PLAN: ${{ steps.analysis.outputs.implementation_plan }}
        run: |
          # 実装実行
          claude-code execute-plan implementation_plan.json \
            --auto-test \
            --auto-lint \
            --create-branch \
            --branch-name "copilot-agent/issue-${{ github.event.issue.number }}"

      - name: Run Quality Assurance
        run: |
          # テスト実行
          if [ -f "package.json" ]; then
            npm install
            npm test
          fi

          if [ -f "requirements.txt" ]; then
            pip install -r requirements.txt
            pytest
          fi

          # Linting
          if [ -f ".eslintrc" ] || [ -f "eslint.config.js" ]; then
            npx eslint . --fix
          fi

          if [ -f "pyproject.toml" ] || [ -f ".flake8" ]; then
            flake8 .
            black .
          fi

      - name: Create Pull Request
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          ISSUE_NUMBER: ${{ github.event.issue.number }}
        run: |
          # 変更確認
          if git diff --quiet; then
            echo "No changes to commit"
            exit 0
          fi

          # コミット作成
          git config user.name "github-copilot[bot]"
          git config user.email "github-copilot[bot]@users.noreply.github.com"

          git add .
          git commit -m "feat: Implement solution for issue #${{ env.ISSUE_NUMBER }}

          🤖 Auto-generated by Copilot Agent with Claude Sonnet 4

          Resolves #${{ env.ISSUE_NUMBER }}"

          # プッシュ
          git push origin "copilot-agent/issue-${{ env.ISSUE_NUMBER }}"

          # プルリクエスト作成
          gh pr create \
            --title "🤖 Auto-fix: ${{ steps.analysis.outputs.issue_title }}" \
            --body "$(cat <<EOF
          ## 🤖 Copilot Agent Auto-Implementation

          This PR was automatically generated by GitHub Copilot Agent using Claude Sonnet 4.

          ### 🎯 Resolves
          Closes #${{ env.ISSUE_NUMBER }}

          ### 🔧 Implementation Details
          - Automated code analysis and generation
          - Quality assurance with tests and linting
          - Claude Sonnet 4 powered solution

          ### ✅ Quality Checks
          - [x] Tests passing
          - [x] Linting completed
          - [x] Code review by Claude Sonnet 4

          ### 📋 Next Steps
          1. Review the generated code
          2. Test the implementation
          3. Merge if satisfactory

          ---
          🤖 Generated with Claude Sonnet 4 × GitHub Copilot Agent
          EOF
          )" \
            --assignee "${{ github.event.issue.assignees[0].login }}" \
            --label "automated,copilot-agent"

      - name: Update Issue Status
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          ISSUE_NUMBER: ${{ github.event.issue.number }}
        run: |
          gh issue comment ${{ env.ISSUE_NUMBER }} --body "🤖 **Copilot Agent Status Update**

          ✅ Implementation completed and PR created
          🔍 Please review the auto-generated solution
          🚀 Powered by Claude Sonnet 4

          [View Pull Request](/generative-ai/claude/${{ github.server_url }}/${{ github.repository }}/pulls)"

高度なClaude Code設定

// ~/.claude/config.json
{
  "model": "claude-sonnet-4",
  "max_tokens": 8192,
  "temperature": 0.1,
  "tools": {
    "enabled": [
      "file_search",
      "code_analysis", 
      "web_search",
      "bash_execution",
      "git_operations"
    ],
    "parallel_execution": true,
    "timeout": 120
  },
  "agents": {
    "code_reviewer": {
      "model": "claude-sonnet-4",
      "system_prompt": "You are an expert code reviewer focused on security, performance, and maintainability.",
      "tools": ["static_analysis", "security_scan", "performance_check"],
      "auto_trigger": ["pre_commit", "pre_push"]
    },
    "documentation_generator": {
      "model": "claude-sonnet-4",
      "system_prompt": "Generate comprehensive technical documentation from code analysis.",
      "tools": ["code_parser", "markdown_generator", "diagram_creator"],
      "auto_trigger": ["post_commit"]
    },
    "test_generator": {
      "model": "claude-sonnet-4", 
      "system_prompt": "Generate comprehensive unit and integration tests.",
      "tools": ["test_framework_detector", "mock_generator", "coverage_analyzer"],
      "auto_trigger": ["on_demand"]
    }
  },
  "hooks": {
    "pre_commit": {
      "enabled": true,
      "agents": ["code_reviewer"],
      "fail_on_issues": true
    },
    "post_commit": {
      "enabled": true,
      "agents": ["documentation_generator"]
    },
    "pre_push": {
      "enabled": true,
      "agents": ["code_reviewer", "test_generator"],
      "parallel": true
    }
  },
  "mcp_servers": {
    "github_api": {
      "command": "npx",
      "args": ["@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
      }
    },
    "database_tools": {
      "command": "python",
      "args": ["mcp_database_server.py"],
      "env": {
        "DATABASE_URL": "${DATABASE_URL}"
      }
    }
  },
  "logging": {
    "level": "INFO",
    "file": "~/.claude/logs/claude-code.log",
    "max_size": "100MB",
    "retention": 30
  }
}

実装:カスタムMCPサーバー

高度なMCPサーバー実装

# advanced_mcp_server.py
import asyncio
import json
import logging
from typing import Dict, List, Any, Optional
from mcp import MCPServer, types
import httpx
import sqlite3
from pathlib import Path

class AdvancedMCPServer(MCPServer):
    def __init__(self):
        super().__init__("advanced-development-tools")
        self.db_path = Path.home() / ".claude" / "mcp_cache.db"
        self.http_client = httpx.AsyncClient()
        self._init_database()

    def _init_database(self):
        """キャッシュ用データベース初期化"""
        self.db_path.parent.mkdir(exist_ok=True)
        conn = sqlite3.connect(self.db_path)
        conn.execute("""
            CREATE TABLE IF NOT EXISTS api_cache (
                key TEXT PRIMARY KEY,
                value TEXT,
                timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
            )
        """)
        conn.execute("""
            CREATE TABLE IF NOT EXISTS code_analysis (
                file_path TEXT PRIMARY KEY,
                analysis TEXT,
                timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
            )
        """)
        conn.commit()
        conn.close()

    @MCPServer.tool("github_api_advanced")
    async def github_api_advanced(
        self, 
        endpoint: str, 
        method: str = "GET", 
        data: Optional[Dict] = None,
        use_cache: bool = True
    ) -> Dict[str, Any]:
        """高度なGitHub API操作"""
        cache_key = f"github:{method}:{endpoint}"

        if use_cache and method == "GET":
            cached = self._get_cached_value(cache_key)
            if cached:
                return json.loads(cached)

        headers = {
            "Authorization": f"token {os.getenv('GITHUB_TOKEN')}",
            "Accept": "application/vnd.github.v3+json"
        }

        url = f"https://api.github.com/{endpoint.lstrip('/')}"

        try:
            if method == "GET":
                response = await self.http_client.get(url, headers=headers)
            elif method == "POST":
                response = await self.http_client.post(url, headers=headers, json=data)
            elif method == "PATCH":
                response = await self.http_client.patch(url, headers=headers, json=data)
            elif method == "DELETE":
                response = await self.http_client.delete(url, headers=headers)
            else:
                raise ValueError(f"Unsupported HTTP method: {method}")

            response.raise_for_status()
            result = response.json()

            if use_cache and method == "GET":
                self._cache_value(cache_key, json.dumps(result))

            return result

        except httpx.HTTPError as e:
            return {"error": str(e), "status_code": getattr(e.response, 'status_code', None)}

    @MCPServer.tool("code_quality_analysis")
    async def code_quality_analysis(self, file_path: str, force_refresh: bool = False) -> Dict[str, Any]:
        """コード品質分析"""
        if not force_refresh:
            cached = self._get_code_analysis(file_path)
            if cached:
                return json.loads(cached)

        try:
            # ファイル読み込み
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read()

            analysis = {
                "file_path": file_path,
                "lines_of_code": len(content.splitlines()),
                "complexity_score": self._calculate_complexity(content),
                "security_issues": self._check_security_issues(content),
                "performance_warnings": self._check_performance_issues(content),
                "maintainability_score": self._calculate_maintainability(content),
                "test_coverage_estimate": self._estimate_test_coverage(file_path)
            }

            self._cache_code_analysis(file_path, json.dumps(analysis))
            return analysis

        except Exception as e:
            return {"error": str(e)}

    @MCPServer.tool("database_schema_analyzer")
    async def database_schema_analyzer(self, connection_string: str) -> Dict[str, Any]:
        """データベーススキーマ分析"""
        try:
            # データベース接続(例:PostgreSQL)
            import asyncpg
            conn = await asyncpg.connect(connection_string)

            # テーブル一覧取得
            tables = await conn.fetch("""
                SELECT table_name, table_type 
                FROM information_schema.tables 
                WHERE table_schema = 'public'
            """)

            schema_info = {"tables": []}

            for table in tables:
                table_name = table['table_name']

                # カラム情報取得
                columns = await conn.fetch("""
                    SELECT column_name, data_type, is_nullable, column_default
                    FROM information_schema.columns 
                    WHERE table_name = $1
                    ORDER BY ordinal_position
                """, table_name)

                # 外部キー情報取得
                foreign_keys = await conn.fetch("""
                    SELECT kcu.column_name, ccu.table_name AS referenced_table,
                           ccu.column_name AS referenced_column
                    FROM information_schema.key_column_usage kcu
                    JOIN information_schema.constraint_column_usage ccu
                         ON kcu.constraint_name = ccu.constraint_name
                    WHERE kcu.table_name = $1
                """, table_name)

                schema_info["tables"].append({
                    "name": table_name,
                    "type": table['table_type'],
                    "columns": [dict(col) for col in columns],
                    "foreign_keys": [dict(fk) for fk in foreign_keys]
                })

            await conn.close()
            return schema_info

        except Exception as e:
            return {"error": str(e)}

    @MCPServer.tool("performance_profiler")
    async def performance_profiler(self, command: str, iterations: int = 1) -> Dict[str, Any]:
        """パフォーマンスプロファイリング"""
        import time
        import psutil
        import subprocess

        results = []

        for i in range(iterations):
            # システムリソース測定開始
            process = psutil.Process()
            start_memory = process.memory_info().rss
            start_cpu = process.cpu_percent()
            start_time = time.time()

            try:
                # コマンド実行
                result = subprocess.run(
                    command, 
                    shell=True, 
                    capture_output=True, 
                    text=True,
                    timeout=300
                )

                # 測定終了
                end_time = time.time()
                end_memory = process.memory_info().rss
                end_cpu = process.cpu_percent()

                results.append({
                    "iteration": i + 1,
                    "execution_time": end_time - start_time,
                    "memory_used": end_memory - start_memory,
                    "cpu_usage": end_cpu - start_cpu,
                    "return_code": result.returncode,
                    "stdout_lines": len(result.stdout.splitlines()),
                    "stderr_lines": len(result.stderr.splitlines())
                })

            except subprocess.TimeoutExpired:
                results.append({
                    "iteration": i + 1,
                    "error": "Command timed out",
                    "execution_time": 300
                })
            except Exception as e:
                results.append({
                    "iteration": i + 1,
                    "error": str(e)
                })

        # 統計計算
        successful_runs = [r for r in results if "error" not in r]
        if successful_runs:
            avg_time = sum(r["execution_time"] for r in successful_runs) / len(successful_runs)
            avg_memory = sum(r["memory_used"] for r in successful_runs) / len(successful_runs)
            avg_cpu = sum(r["cpu_usage"] for r in successful_runs) / len(successful_runs)
        else:
            avg_time = avg_memory = avg_cpu = 0

        return {
            "command": command,
            "iterations": iterations,
            "successful_runs": len(successful_runs),
            "failed_runs": len(results) - len(successful_runs),
            "average_execution_time": avg_time,
            "average_memory_usage": avg_memory,
            "average_cpu_usage": avg_cpu,
            "detailed_results": results
        }

    def _get_cached_value(self, key: str) -> Optional[str]:
        """キャッシュから値を取得"""
        conn = sqlite3.connect(self.db_path)
        cursor = conn.execute(
            "SELECT value FROM api_cache WHERE key = ? AND timestamp > datetime('now', '-1 hour')",
            (key,)
        )
        result = cursor.fetchone()
        conn.close()
        return result[0] if result else None

    def _cache_value(self, key: str, value: str):
        """値をキャッシュに保存"""
        conn = sqlite3.connect(self.db_path)
        conn.execute(
            "INSERT OR REPLACE INTO api_cache (key, value) VALUES (?, ?)",
            (key, value)
        )
        conn.commit()
        conn.close()

    def _get_code_analysis(self, file_path: str) -> Optional[str]:
        """コード分析結果をキャッシュから取得"""
        conn = sqlite3.connect(self.db_path)
        cursor = conn.execute(
            "SELECT analysis FROM code_analysis WHERE file_path = ? AND timestamp > datetime('now', '-1 day')",
            (file_path,)
        )
        result = cursor.fetchone()
        conn.close()
        return result[0] if result else None

    def _cache_code_analysis(self, file_path: str, analysis: str):
        """コード分析結果をキャッシュに保存"""
        conn = sqlite3.connect(self.db_path)
        conn.execute(
            "INSERT OR REPLACE INTO code_analysis (file_path, analysis) VALUES (?, ?)",
            (file_path, analysis)
        )
        conn.commit()
        conn.close()

    def _calculate_complexity(self, content: str) -> int:
        """コード複雑度計算(簡易版)"""
        complexity_keywords = ['if', 'elif', 'else', 'for', 'while', 'try', 'except', 'finally', 'with']
        return sum(content.count(keyword) for keyword in complexity_keywords)

    def _check_security_issues(self, content: str) -> List[str]:
        """セキュリティ問題チェック(簡易版)"""
        issues = []
        security_patterns = [
            ('eval(', 'Use of eval() function'),
            ('exec(', 'Use of exec() function'),
            ('subprocess.shell=True', 'Shell injection risk'),
            ('password', 'Possible hardcoded password'),
            ('secret', 'Possible hardcoded secret'),
            ('sql.*%.*%', 'Possible SQL injection')
        ]

        for pattern, message in security_patterns:
            if pattern in content.lower():
                issues.append(message)

        return issues

    def _check_performance_issues(self, content: str) -> List[str]:
        """パフォーマンス問題チェック(簡易版)"""
        issues = []
        if content.count('for') > 3 and 'nested' in content.lower():
            issues.append('Possible nested loop performance issue')
        if 'time.sleep' in content:
            issues.append('Synchronous sleep detected')
        return issues

    def _calculate_maintainability(self, content: str) -> float:
        """保守性スコア計算(簡易版)"""
        lines = content.splitlines()
        comment_lines = sum(1 for line in lines if line.strip().startswith('#'))
        total_lines = len([line for line in lines if line.strip()])

        if total_lines == 0:
            return 0.0

        comment_ratio = comment_lines / total_lines
        complexity = self._calculate_complexity(content)
        complexity_penalty = min(complexity / 100, 0.5)

        return max(0.0, min(1.0, comment_ratio * 0.5 + (1 - complexity_penalty)))

    def _estimate_test_coverage(self, file_path: str) -> float:
        """テストカバレッジ推定(簡易版)"""
        test_file_patterns = ['test_', '_test.py', 'tests/', 'spec/']
        project_root = Path(file_path).parent

        # テストファイル検索
        test_files = []
        for pattern in test_file_patterns:
            test_files.extend(list(project_root.rglob(f'*{pattern}*')))

        if not test_files:
            return 0.0

        # 簡易的なカバレッジ推定
        return min(1.0, len(test_files) / 10)  # 10ファイルあたり100%と仮定

if __name__ == "__main__":
    import os

    server = AdvancedMCPServer()
    server.run(host="localhost", port=int(os.getenv("MCP_PORT", 8000)))

MCPサーバー設定ファイル

// ~/.claude/mcp_servers.json
{
  "mcpServers": {
    "advanced-development-tools": {
      "command": "python",
      "args": ["advanced_mcp_server.py"],
      "env": {
        "GITHUB_TOKEN": "${GITHUB_TOKEN}",
        "DATABASE_URL": "${DATABASE_URL}",
        "MCP_PORT": "8001"
      }
    },
    "github-official": {
      "command": "npx",
      "args": ["@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
      }
    },
    "filesystem-tools": {
      "command": "npx", 
      "args": ["@modelcontextprotocol/server-filesystem", "/path/to/project"],
      "env": {}
    }
  }
}

パフォーマンス最適化テクニック

Claude Sonnet 4最適化設定

# claude_optimization.py
import asyncio
from typing import List, Dict, Any
import time

class ClaudeOptimizer:
    def __init__(self):
        self.request_cache = {}
        self.rate_limiter = RateLimiter(requests_per_minute=50)

    async def optimized_batch_request(self, prompts: List[str]) -> List[Dict[str, Any]]:
        """バッチリクエスト最適化"""
        # 類似プロンプトをグループ化
        grouped_prompts = self._group_similar_prompts(prompts)

        results = []
        for group in grouped_prompts:
            # レート制限チェック
            await self.rate_limiter.acquire()

            # キャッシュチェック
            cache_key = self._generate_cache_key(group)
            if cache_key in self.request_cache:
                results.extend(self.request_cache[cache_key])
                continue

            # 並列実行で効率化
            batch_result = await self._execute_parallel_request(group)
            self.request_cache[cache_key] = batch_result
            results.extend(batch_result)

        return results

    def _group_similar_prompts(self, prompts: List[str]) -> List[List[str]]:
        """類似プロンプトをグループ化"""
        # 簡易的な類似度判定
        groups = []
        for prompt in prompts:
            added_to_group = False
            for group in groups:
                if self._calculate_similarity(prompt, group[0]) > 0.7:
                    group.append(prompt)
                    added_to_group = True
                    break

            if not added_to_group:
                groups.append([prompt])

        return groups

    def _calculate_similarity(self, text1: str, text2: str) -> float:
        """テキスト類似度計算"""
        words1 = set(text1.lower().split())
        words2 = set(text2.lower().split())

        intersection = words1.intersection(words2)
        union = words1.union(words2)

        return len(intersection) / len(union) if union else 0.0

    async def _execute_parallel_request(self, prompts: List[str]) -> List[Dict[str, Any]]:
        """並列リクエスト実行"""
        tasks = [self._single_request(prompt) for prompt in prompts]
        return await asyncio.gather(*tasks)

    async def _single_request(self, prompt: str) -> Dict[str, Any]:
        """単一リクエスト実行"""
        # Claude APIコール(実装例)
        # 実際のAPIコールをここに実装
        await asyncio.sleep(0.1)  # API呼び出しシミュレーション
        return {"prompt": prompt, "response": "Generated response", "tokens": 100}

class RateLimiter:
    def __init__(self, requests_per_minute: int):
        self.requests_per_minute = requests_per_minute
        self.requests = []

    async def acquire(self):
        """レート制限取得"""
        now = time.time()
        # 1分以内のリクエストをフィルタ
        self.requests = [req_time for req_time in self.requests if now - req_time < 60]

        if len(self.requests) >= self.requests_per_minute:
            sleep_time = 60 - (now - self.requests[0])
            await asyncio.sleep(sleep_time)

        self.requests.append(now)

実戦トラブルシューティング

よくある問題と解決法

#!/bin/bash
# troubleshooting_toolkit.sh

# Claude Code診断スクリプト
diagnose_claude_code() {
    echo "🔍 Claude Code診断開始..."

    # 認証状態確認
    if ! claude-code auth status; then
        echo "❌ 認証エラー: 再認証が必要です"
        echo "解決方法: claude-code auth login"
        return 1
    fi

    # 設定ファイル確認
    config_file="$HOME/.claude/config.json"
    if [ ! -f "$config_file" ]; then
        echo "❌ 設定ファイルが見つかりません: $config_file"
        echo "解決方法: claude-code config init"
        return 1
    fi

    # JSON設定検証
    if ! python -m json.tool "$config_file" > /dev/null 2>&1; then
        echo "❌ 設定ファイルのJSON形式が無効です"
        echo "解決方法: 設定ファイルを修正するか、claude-code config reset"
        return 1
    fi

    # MCP接続確認
    if claude-code mcp list | grep -q "No servers"; then
        echo "⚠️  MCPサーバーが設定されていません"
        echo "推奨: MCPサーバーを設定してください"
    else
        echo "✅ MCPサーバー設定を確認"
        claude-code mcp diagnose
    fi

    # リソース使用量確認
    memory_usage=$(ps -o pid,ppid,cmd,%mem --sort=-%mem | grep claude-code | head -5)
    if [ -n "$memory_usage" ]; then
        echo "📊 メモリ使用量:"
        echo "$memory_usage"
    fi

    echo "✅ Claude Code診断完了"
}

# GitHub Copilot診断
diagnose_copilot() {
    echo "🔍 GitHub Copilot診断開始..."

    # GitHub CLI認証確認
    if ! gh auth status > /dev/null 2>&1; then
        echo "❌ GitHub CLI認証エラー"
        echo "解決方法: gh auth login"
        return 1
    fi

    # Copilot拡張確認
    if ! gh extension list | grep -q "gh-copilot"; then
        echo "❌ Copilot拡張がインストールされていません"
        echo "解決方法: gh extension install github/gh-copilot"
        return 1
    fi

    # Copilot Agent設定確認
    if ! gh copilot config get model; then
        echo "⚠️  Copilotモデル設定を確認してください"
        echo "推奨: gh copilot config set model claude-sonnet-4"
    fi

    # API制限確認
    api_limit=$(gh api rate_limit | jq '.rate.remaining')
    if [ "$api_limit" -lt 100 ]; then
        echo "⚠️  GitHub APIレート制限に近づいています: $api_limit requests remaining"
    fi

    echo "✅ GitHub Copilot診断完了"
}

# ワークフロー診断
diagnose_workflow() {
    echo "🔍 GitHub Actionsワークフロー診断開始..."

    # ワークフローファイル確認
    if [ ! -d ".github/workflows" ]; then
        echo "❌ .github/workflowsディレクトリが見つかりません"
        return 1
    fi

    # YAML構文チェック
    for workflow in .github/workflows/*.yml .github/workflows/*.yaml; do
        if [ -f "$workflow" ]; then
            echo "📄 検証中: $workflow"
            if ! python -c "import yaml; yaml.safe_load(open('$workflow'))" 2>/dev/null; then
                echo "❌ YAML構文エラー: $workflow"
            else
                echo "✅ YAML構文正常: $workflow"
            fi
        fi
    done

    # Secrets確認
    echo "🔐 必要なSecretsリスト:"
    echo "  - GITHUB_TOKEN (通常自動設定)"
    echo "  - CLAUDE_API_KEY"

    # 最新実行結果確認
    if command -v gh > /dev/null; then
        echo "📊 最新のワークフロー実行結果:"
        gh run list --limit 5
    fi

    echo "✅ ワークフロー診断完了"
}

# メイン実行
main() {
    case "$1" in
        "claude")
            diagnose_claude_code
            ;;
        "copilot")
            diagnose_copilot
            ;;
        "workflow")
            diagnose_workflow
            ;;
        "all"|"")
            diagnose_claude_code
            diagnose_copilot
            diagnose_workflow
            ;;
        *)
            echo "使用方法: $0 [claude|copilot|workflow|all]"
            exit 1
            ;;
    esac
}

main "$@"

パフォーマンス監視スクリプト

# performance_monitor.py
import json
import time
import psutil
import requests
from datetime import datetime, timedelta
from pathlib import Path

class PerformanceMonitor:
    def __init__(self):
        self.metrics_file = Path.home() / ".claude" / "performance_metrics.json"
        self.metrics_file.parent.mkdir(exist_ok=True)

    def collect_metrics(self):
        """パフォーマンスメトリクス収集"""
        metrics = {
            "timestamp": datetime.now().isoformat(),
            "system": {
                "cpu_percent": psutil.cpu_percent(interval=1),
                "memory_percent": psutil.virtual_memory().percent,
                "disk_usage": psutil.disk_usage('/').percent
            },
            "claude_code": self._get_claude_metrics(),
            "github_api": self._check_github_api_status()
        }

        # メトリクス保存
        self._save_metrics(metrics)
        return metrics

    def _get_claude_metrics(self):
        """Claude Code固有メトリクス"""
        claude_processes = []
        for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
            if 'claude' in proc.info['name'].lower():
                claude_processes.append(proc.info)

        return {
            "process_count": len(claude_processes),
            "total_cpu": sum(p['cpu_percent'] for p in claude_processes),
            "total_memory": sum(p['memory_percent'] for p in claude_processes)
        }

    def _check_github_api_status(self):
        """GitHub API状態確認"""
        try:
            response = requests.get("https://api.github.com/rate_limit", timeout=5)
            if response.status_code == 200:
                data = response.json()
                return {
                    "status": "healthy",
                    "rate_limit_remaining": data['rate']['remaining'],
                    "rate_limit_reset": data['rate']['reset']
                }
        except Exception as e:
            return {"status": "error", "error": str(e)}

        return {"status": "unknown"}

    def _save_metrics(self, metrics):
        """メトリクス保存"""
        # 既存データ読み込み
        if self.metrics_file.exists():
            with open(self.metrics_file, 'r') as f:
                data = json.load(f)
        else:
            data = {"metrics": []}

        # 新しいメトリクス追加
        data["metrics"].append(metrics)

        # 古いデータ削除(7日分保持)
        cutoff = datetime.now() - timedelta(days=7)
        data["metrics"] = [
            m for m in data["metrics"] 
            if datetime.fromisoformat(m["timestamp"]) > cutoff
        ]

        # 保存
        with open(self.metrics_file, 'w') as f:
            json.dump(data, f, indent=2)

    def generate_report(self):
        """パフォーマンスレポート生成"""
        if not self.metrics_file.exists():
            return "メトリクスデータがありません"

        with open(self.metrics_file, 'r') as f:
            data = json.load(f)

        metrics = data["metrics"]
        if not metrics:
            return "メトリクスデータがありません"

        # 最新24時間のデータ分析
        last_24h = datetime.now() - timedelta(hours=24)
        recent_metrics = [
            m for m in metrics 
            if datetime.fromisoformat(m["timestamp"]) > last_24h
        ]

        if not recent_metrics:
            return "最新のメトリクスデータがありません"

        # 統計計算
        avg_cpu = sum(m["system"]["cpu_percent"] for m in recent_metrics) / len(recent_metrics)
        avg_memory = sum(m["system"]["memory_percent"] for m in recent_metrics) / len(recent_metrics)

        claude_metrics = [m["claude_code"] for m in recent_metrics if m["claude_code"]["process_count"] > 0]
        avg_claude_processes = sum(m["process_count"] for m in claude_metrics) / len(claude_metrics) if claude_metrics else 0

        github_healthy = sum(1 for m in recent_metrics if m["github_api"]["status"] == "healthy")
        github_uptime = (github_healthy / len(recent_metrics)) * 100

        return f"""
📊 パフォーマンスレポート(過去24時間)

🖥️  システムリソース:
   CPU使用率平均: {avg_cpu:.1f}%
   メモリ使用率平均: {avg_memory:.1f}%

🤖 Claude Code:
   平均プロセス数: {avg_claude_processes:.1f}

🐙 GitHub API:
   稼働率: {github_uptime:.1f}%

📈 データポイント数: {len(recent_metrics)}
最終更新: {recent_metrics[-1]["timestamp"]}
        """

if __name__ == "__main__":
    import sys

    monitor = PerformanceMonitor()

    if len(sys.argv) > 1 and sys.argv[1] == "report":
        print(monitor.generate_report())
    else:
        metrics = monitor.collect_metrics()
        print(f"メトリクス収集完了: {metrics['timestamp']}")

運用ベストプラクティス

セキュリティ設定

# .github/workflows/security-scan.yml
name: Security Scan for AI Development Environment
on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 2 * * 0'  # 毎週日曜日午前2時

jobs:
  security-audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Secret Scan
        run: |
          # API キーやトークンの漏洩チェック
          if grep -r "claude.*api.*key" . --exclude-dir=.git --include="*.py" --include="*.js" --include="*.yml"; then
            echo "❌ Potential API key leak detected"
            exit 1
          fi

          if grep -r "github.*token" . --exclude-dir=.git --include="*.py" --include="*.js" --include="*.yml"; then
            echo "❌ Potential GitHub token leak detected"  
            exit 1
          fi

      - name: Dependency Audit
        run: |
          # Python依存関係脆弱性チェック
          if [ -f "requirements.txt" ]; then
            pip install safety
            safety check -r requirements.txt
          fi

          # Node.js依存関係脆弱性チェック
          if [ -f "package.json" ]; then
            npm audit --audit-level high
          fi

      - name: Claude Code Configuration Audit
        run: |
          # Claude Code設定の安全性チェック
          config_file="$HOME/.claude/config.json"
          if [ -f "$config_file" ]; then
            # デバッグモード無効化確認
            if grep -q '"debug": true' "$config_file"; then
              echo "⚠️  Debug mode is enabled in production"
            fi

            # 適切な権限設定確認
            permissions=$(stat -c %a "$config_file")
            if [ "$permissions" != "600" ]; then
              echo "⚠️  Configuration file permissions are too permissive: $permissions"
            fi
          fi

まとめ

Claude Sonnet 4とGitHub Copilot Agentの実装では、以下の点が重要です:

  • 段階的導入: 小規模プロジェクトから開始し、徐々に機能を拡張
  • 監視体制: パフォーマンスメトリクスとエラーログの継続的監視
  • セキュリティ: API キーの適切な管理と権限設定の最小化
  • 最適化: バッチ処理とキャッシュ活用による効率化

この実装ガイドにより、理論だけでなく実際に動作する環境を構築できるはずです。

関連記事