Claude Code GitHub Actionsを使っていて、自分は以下のような2種類のタスクを依頼することが多い。
- 実装計画を立ててもらう
- 実装をしてもらう
Claude Codeであれば実装計画はOpusを使って、実装タスクはSonnetを使うみたいな使い分けが簡単にできるのにClaude Code GitHub Actionsではデフォルトだとそれができなかったのでちょっとやってみた。
具体的には、以下のようなclaude.ymlのWorkflowファイルを追加して、GitHub Issueなどのコメントで @claude このタスクの実装計画を Opus で立てて とコメント内にopus, sonnet, haiku のキーワードを含めることで指定したモデルでClaudeが動くようになる。
やっていることは単純で、メッセージ内にopusなどのキーワードをgrepで引っ掛けてmodelを決めているだけ。注意点としてはgrep '\bopus\b'で検索しているため、「このタスクをopusでお願い」ではマッチしないようになっている。かわりに「このタスクを opus でお願い」のようにopusの前後にスペースを入れる必要がある。
そんなわけでClaude Code GitHub Actionsからもモデルが指定できるようになりタスクが捗るようになった(気がする)
claude.yml
name: claude-code on: issue_comment: types: [created] pull_request_review_comment: types: [created] issues: types: [opened, assigned] pull_request_review: types: [submitted] jobs: claude: if: | (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) runs-on: ubuntu-latest permissions: contents: read pull-requests: read issues: read id-token: write actions: read # Required for Claude to read CI results on PRs steps: - uses: actions/checkout@v5 with: fetch-depth: 1 # Extract model from comment/issue body - name: Determine Claude Model id: determine-claude-model run: | # Get the comment/issue body based on event type if [ "${{ github.event_name }}" = "issue_comment" ]; then BODY=$(cat <<'EOF' ${{ github.event.comment.body }} EOF ) elif [ "${{ github.event_name }}" = "pull_request_review_comment" ]; then BODY=$(cat <<'EOF' ${{ github.event.comment.body }} EOF ) elif [ "${{ github.event_name }}" = "pull_request_review" ]; then BODY=$(cat <<'EOF' ${{ github.event.review.body }} EOF ) elif [ "${{ github.event_name }}" = "issues" ]; then BODY=$(cat <<'EOF' ${{ github.event.issue.body }} EOF ) fi # Convert to lowercase for case-insensitive matching BODY_LOWER=$(echo "$BODY" | tr '[:upper:]' '[:lower:]') # Determine model based on keywords if echo "$BODY_LOWER" | grep -q '\bopus\b'; then MODEL="claude-opus-4-1" elif echo "$BODY_LOWER" | grep -q '\bhaiku\b'; then MODEL="claude-haiku-4-5" else # Default to sonnet (including when 'sonnet' keyword is present) MODEL="claude-sonnet-4-5" fi echo "model=$MODEL" >> $GITHUB_OUTPUT echo "Selected model: $MODEL" - name: Run Claude Code id: run-claude-code uses: anthropics/claude-code-action@v1 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} # This is an optional setting that allows Claude to read CI results on PRs additional_permissions: | actions: read allowed_bots: "claude-bot,claude" claude_args: | --model ${{ steps.determine-claude-model.outputs.model }} --allowedTools "Agent" (必要に応じてMCPなどを設定)
