GitHub Copilot Agentで個人開発Javaプロジェクトのタスクをこなす

Cover Image for GitHub Copilot Agentで個人開発Javaプロジェクトのタスクをこなす

「GitHub CopilotをJavaのプロジェクトに対して適用してみたらどうなるか?」を検証してみたく、個人開発で作成していた以下のJavaプロジェクトに対してGitHub Copilotを利用していくつかタスクを実施してみました。
kemsakurai/Google-Search-Console-java-APIs-cli

結論として、あまり有効活用できたとは思えませんでした。しかし、どのような場面で活用できるかは知見が得られたので内容をシェアしたいと思います。また、公開まで少し時間がかかったため、Claude Sonnet 4Claude Opus 4などの現在(2025年6月)利用可能な最新モデルを使用しての検証は行っていません。実施期間での感想のスナップショットと考えてもらえればと思います。


実施したタスクと実施期間について

  • 実施したタスク 以下、タスクとして実施したことと、各タスクの定性的な評価です。
    静的解析ツールの警告対応にそれなりの時間を使いました。
タスク 評価 備考
自動テストの作成 🌤️ GitHub Copilot Agentを利用。一定の効果が得られた
Javaのバージョンアップ8→21 ☀️ GitHub Copilot Agentを利用。これが今回は1番うまくできた
静的解析ツールの警告対応 ☔️ GitHub Copilot Agentではうまく修正ができず、手動でハンドリングしながら、一部GitHub Copilot Editsで対応した
  • 実施期間

2025年5月1日〜2025年5月16日あたりの期間で作業を行いました。


事前準備

GitHub Copilotの登場以前に作ったJavaプロジェクトだったので、GitHub Copilotを利用する準備として以下を行いました。

.gitHub/copilot-instructions.mdの作成

GitHub Copilot Chatで@workspace でワークスペースの設定を分析してもらい、雛形ファイルを生成しました。雛形生成後に、GitHub Copilot AgentモードでもMemory Bankを使えるようにしてみる #AI - Qiita のメモリーバンクのプロンプトを追記してみました。(追記はしたけど、うまく使いこなせていないので、この記事ではとくに触れません。)作成したファイルは以下になります。

VS Codeのインタラクション設定の追加

以下のVS Codeのインタラクション設定のため、それぞれに該当するMarkdownファイルを作成しました。
github.copilot.chat.codeGeneration.instructions github.copilot.chat.testGeneration.instructions github.copilot.chat.reviewSelection.instructions github.copilot.chat.commitMessageGeneration.instructions
github.copilot.chat.pullRequestDescriptionGeneration.instructions

各インタラクションの設定は以下のドキュメントに記載されています。

これらのファイルも、GitHub Copilot Chatを使って雛形を生成しました。
作成したファイルは以下のディレクトリ配下に配置しました。


各タスクの記録

各タスクのIssueと、Pull Requestのリンクと作業実施時の手順を記載します。

自動テスト作成

Issue

Pull Request

作業手順

  1. 作業実施のための計画を、GitHub Copilotと、Perplexityに作成してもらう。
    • PerplexityはWeb検索により最新情報を取得しながら手順を考案します。そのため、現状(2025年06月)Web検索ができないGitHub Copilotよりも優れたアウトプットが得られると感じました。
  2. 作業計画にしたがって、GitHub Copilot Agent(モデルはClaude 3.7 Sonnet)にテストを実装させる。
  3. 以下のプロンプト(手抜き)でテスト実行失敗したテストコードの修正を行う。
#codebase 
 * ./gradlew clean test
 * 失敗するテストを修正してください。
  1. カバレッジ出力設定を追加してテストの網羅性を確認、網羅率が足りない箇所はテストケースを追加。

Javaのバージョンアップ8→21

Issue

Pull Request

作業手順

  1. 作業実施のための計画を、GitHub Copilotと、Perplexityに作成してもらう。
  2. 作業計画にしたがって、GitHub Copilot Agent(モデルはClaude 3.7 Sonnet)でJavaバージョンアップ作業を実施。
  3. Javaバージョンアップ後、ビルドを実行すると、ライブラリの互換性でコンパイルエラーとなり、ライブラリのバージョンアップも併せて実施。
  4. テストケースの再実行して失敗するケースについて、テストケース、もしくはプロダクションコードを修正。

静的解析ツールの警告対応

Issue

Pull Request

作業手順

  1. 作業実施のための計画を、GitHub Copilotと、Perplexityに作成してもらう。
  2. CheckStyle、PMD、SpotBugsの順にGitHub Copilot Agent(モデルはGPT-4o)で警告修正。
    • 5月のGWタイミングで、GitHub Copilotの料金改定があり、Claude 3.7 Sonnetの利用に制限が発生したので、GPT-4oを利用しました。
    • 修正順序は、コードフォーマットの修正、ソースコードの問題修正、コンパイルされたバイナリーの警告修正の順に実施するのが効果的であると考えたためです。
  3. テストが失敗するようになったので、テストの失敗を修正。
  4. テストの失敗を修正すると、再度警告が出るようになり、警告を修正すると、テストが失敗でループ。
  5. GitHub Copilot Agentを利用した修正は諦めて、人間主導で対応を実施。

Javaプロジェクト修正タスクでの気づき

以下各タスク実施していて気がついたことになります。

共通で実施する事前準備

  • 設定の重要性
    複数のVS Codeのワークスペースを設定する経験があまりなく、setting.json の設定をどのスコープで設定するかはとても重要に思いました。
    たとえば、MCPサーバーの設定であれば、ワークスペースを横断して設定するのが良さそうに思いました。
    "mcp": {
    
        "inputs": [
            {
              "type": "promptString",
              "id": "notion-api-token",
              "description": "Notion API Token",
              "password": true
            },
            {
                "type": "promptString",
                "id": "github_token",
                "description": "GitHub Personal Access Token",
                "password": true
            },
            {
                "type": "promptString",
                "id": "perplexity_api_key",
                "description": "Perplexity API Key",
                "password": true
            }
        ],
        "servers": {
            "notionApi": {
                "command": "npx",
                "args": ["-y", "@notionhq/notion-mcp-server"],
                "env": {
                    "OPENAPI_MCP_HEADERS": "{\"Authorization\": \"Bearer ${input:notion-api-token}\", \"Notion-Version\": \"2022-06-28\" }"
                  }
            },
            "playwright": {
                "command": "npx",
                "args": [
                    "@playwright/mcp@latest"
                ]
            },
            "github": {
                "command": "docker",
                "args": [
                  "run",
                  "-i",
                  "--rm",
                  "-e",
                  "GITHUB_PERSONAL_ACCESS_TOKEN",
                  "ghcr.io/github/github-mcp-server"
                ],
                "env": {
                  "GITHUB_PERSONAL_ACCESS_TOKEN": "${input:github_token}"
                }
            },
            "fetch": {
            "command": "docker",
            "args": ["run", "-i", "--rm", "mcp/fetch"]
            },
            "perplexity-ask": {
            "command": "npx",
            "args": [
                "-y",
                "server-perplexity-ask"
            ],
            "env": {
                "PERPLEXITY_API_KEY": "${input:perplexity_api_key}"
                }
            },
            "Context7": {
            "type": "stdio",
            "command": "npx",
            "args": ["-y", "@upstash/context7-mcp@latest"]
            }       
        }
    },

上記に対して、GitHub Copilotのインタラクションファイルの配置先はリポジトリごとに異なる気がするので、それらの設定はワークスペースレベルで管理するのが良さそうに思います。

    "github.copilot.chat.codeGeneration.instructions": [
        {
            "file": ".github/instructions/code-gen-instructions.md",
        }
    ],
    "github.copilot.chat.testGeneration.instructions": [
        {
            "file": ".github/instructions/test-gen-instructions.md",
        }
    ],
    "github.copilot.chat.commitMessageGeneration.instructions": [
        {
            "file": ".github/instructions/commit-message-gen-instructions.md",
        }
    ],
    "github.copilot.chat.pullRequestDescriptionGeneration.instructions": [
        {
            "file": ".github/instructions/pull-request-description-gen-instructions.md",
        }
    ],
    "github.copilot.chat.reviewSelection.instructions": [
    
        {
            "file": ".github/instructions/review-selection-instructions.md",
        }
    ],

個別で有効|無効を切り替えるフラグがあります。モノにもよりますが、ユーザーレベルで定義で良い気がします。

"github.copilot.chat.reviewSelection.enabled": true,
  • 初期設定ファイルの作成
    昔から存在するリポジトリにGitHub Copilotを導入する場合に備えて、インタラクションファイルを生成するための、プロンプトを準備しておくと、効率が良い気がしました。

  • 効果的なプロンプト準備

    • エージェントへの依頼プロンプトは雛形をAIに作成してもらうと効果的という印象を受けました。筆者はGitHub MCP Serverを稼働した状態で、手を抜いた以下のようなプロンプトでGitHub Copilot Chatに依頼して、GitHub Copilot Agentのプロンプトを生成してもらっていました。
      #get_issue
      以下のIssueのタスクを行いたいです。
      {IssueのURL}
      このタスクをGitHub Copilot Agentに指示するためのプロンプトを生成してください。
      
  • 作業計画の策定

    • Issueの作成などの作業計画の段階では、GitHub CopilotとPerplexityを併用していました。
      PerplexityはWebから最新情報を取得して回答します。そのため、探索的な調査において良い回答が得られると感じました。

自動テスト作成

  • Java特有の利点 Javaはディレクトリ構造の流派が少なく、TypeScriptなどと比べて「手抜きした指示」でもテスト作成が可能という印象を受けました。
    TypeSriptだとテストディレクトリの指定をしないと、期待しないディレクトリにテストケースを作成することがありました。

  • カバレッジ出力重要 GitHub Copilot Agentに既存Javaのクラスに対するテストケースを作成してもらいました。さらに、カバレッジを取得し、カバレッジ80%以上などの指示を出すことで、網羅性のあるテストケースを生成してくれました。     

  • GitHub Copilot Agentのパフォーマンス Javaのテスト実行速度はNext.jsに比べてやや早い気がしましたが、gradleからのテスト実行時にログ量が多く解析に時間がかかっているように思えたので、以下のような設定をbuild.gradleに追加して、テストケース失敗時のみログを出力するようにしました。

    testLogging {
        events "skipped", "failed"
        exceptionFormat "full"
        showStandardStreams = true
    }
    

Javaのバージョンアップ8→21

  • ライブラリのバージョンアップも一括で行うことになった Javaのバージョンアップ→ライブラリのバージョンアップを切り離して実施したかったのですが、ライブラリの互換性の問題でコンパイルエラーが発生したため、段階的な移行が難しく、ライブラリのバージョンアップも実施する必要がありました。

  • GitHub Copilot Agentの効果 Javaのバージョンアップ、ライブラリのバージョンアップ、コンパイルエラー修正の一連のタスクはとてもスムーズに進んだ気がします。この辺りの作業は得意分野のように思われました。

  • テストケースの修正
    既存のテストケースが失敗するようになったとき、失敗したテストケースを修正して くらいの指示だと、無理矢理失敗を修復するような修正を行うことがありました。この辺りの修正は人間が主導して実施するか、もっと細かい指示をプロンプトから実施すべきと感じました。


静的解析ツールの警告対応

  • 複合的な課題

    • CheckStyle、PMD、SpotBugsなど複数ツールの警告対応が必要で、それぞれ個別で対応を行いましたが、CheckStyleの警告を修正すると、PMDの警告が復活する。テストケースが動作しなくなる。という状況になりました。
  • OpenRewriteでルールが存在する場合はそれを利用する

    • Copilotに修正をお願いしても中々直せない警告がありました。具体例を挙げるとImportOrder - Checkstyle Javaルール です。最終的にImportOrderは、Order imports | OpenRewrite Docs を利用して対応しましたが、なんでも生成AIで修正するのではなく、ルールベースで対応可能なものをルールベースで修正した上で生成AIに修正させるのがトークン消費という面で効果的に思えました。
  • ルールセットの準備

    • 警告出力にしたがって、生成AIにファイル修正を行なってもらうので、ルールファイル自体が妥当なものでないと、意味がありません。ルールの精査をせずにアドホックに作業をはじめていましたが、ルールの精査をまずしたうえで生成AIに修正を依頼するのが、効率的に思いました。ちなみに、エージェントの判断でルールファイルの変更をしたりもするので、プロンプトからルールファイルの修正はするなといった指示もした方が良い気もしました。
  • 生成AIでは対応が難しい警告

    • PMDのAvoidCatchingGenericException という警告は、GPT-4oではうまく修正できず、手修正に切り替えて対応しました。警告が出ているファイルの内容の読み取りだけでは、何を例外としてCatchすべきかの判断が難しい部類の警告なので、作業実施時のモデルの性能では難しいのかなと思われました。警告の修正判断がファイル単体できるのか?できないのか?はあらかじめ切り替えて生成AIに修正をお願いするのが良さそうです。
  • VS Codeのバージョンアップによるコード品質の変化

    • 作業期間中にVS CodeのバージョンアップApril 2025 (version 1.100)が発生しましたが、このリリースでGPT-4oのコード品質が上がったように感じました。モデルだけでなく、エディター側のリリースでも出力が変化するという学びがありました。

まとめ

作業に時間はかかりましたが、個人的には生成AIを利用したほうが作業が早いという印象を持ちました。とくにバージョンアップ作業に関しては、リポジトリの規模が小さいからか、大きな問題はなく進んだ気がしています。静的解析ツールの警告修正に関しては、次回やるなら以下は意識して進めていきたいと感じました。

  • ルールファイルを事前に精査、作成しておく。
  • OpenRewriteのレシピで修正可能なものはそれを利用する。
  • ファイル単体のコンテキストで修正可能な警告と不可能な警告を切り分けして、ファイル単体のコンテキストで修正可能な警告修正を生成AIに依頼する。
  • 手動で修正する切り替えの判断基準を持つ。

1、2か月後に同じことをやると結果が違いそうなくらいにはAIの進化スピードが早そうですが、2025年5月中旬の切り取りとしては以上です。