GitHub Copilotを使ったコーディング、レビューのワークフローを試験運用してみた

AI駆動開発では、コーディングエージェントによる自動コード生成によるコーディング効率化が着目されています。一方で、コードをデプロイするまでには設計やテスト、レビューといった他の工程も存在し、これらの工程も含めてどのように効率化できるかを考える必要があります。

コーディングエージェントによって多くのコードが生成されたとしても、それをレビューする人の負荷が増加し、かえって品質が低下する可能性もあると考えています。

そこで、コーディングを含めてDesign Docの運用と、それを活用したコーディング、レビューまでのフローを一通り実施し、得られた知見を共有したいと思います。

なお、今回はテストについては記載しません。別の機会に記載したいと思います。

また、この情報は執筆時点のものであり、GitHub Copilot(以下Copilotと記載)のPlanモードなどの最新機能は未検証です。

要約

本記事のポイントは以下の通りです。

  • AIコーディングエージェント導入でコーディング自体は高速化
  • Copilotを活用した開発フローを運用したが、「AIが指示を守らない」「コメントが少ない」といった課題も発見
  • プロセス改善やコーディング規約・コメント運用の見直しが今後のポイント

テンプレートの作成

Design Docテンプレートの作成

Design Docを作成するにあたり、異なるフォーマットで記載すると、作成する側もレビューする側も負荷がかかってしまうため、あらかじめテンプレートを用意しておきます。

今回の運用では、以下のようなテンプレートにしました。

# タイトル (Title)

# 背景・コンテキスト (Background / Context)

# 目標 (Goals)

# 非目標 (Non-goals)

# 要件 (Requirements): 機能 / 非機能(性能・可用性・セキュリティ等)

# 提案アーキテクチャ概要 (Proposed Design Overview)

# 処理・実装詳細

# 影響範囲 (Impact): 既存機能・API・データ・運用への影響

# 参照 / 関連 (References / Links): 関連 ADR・Issue・PR・図面等

copilot-instructions.mdの作成

copilot-instructions.mdにはCopilotへの指示やコンテキストを記載します。このマークダウンファイルに従ってCopilotにコーディングなどをしてもらいます。ファイルは.github/copilot-instructions.mdとして作成します。

なお、現在はAGENTS.mdという、他のAIコーディングツールと互換性のあるファイルに記載するのでも良いかと思います。

作成方法は以下のBonus tipを参考にしました。GitHub上でissueを作成し、Copilotをアサインすることで自動的に作成しました。

github.blog

社内プロジェクトのリポジトリで作成したため、詳細は記載できませんが、以下のようなものを作成しました。

# AI Chat - Coding Agent Instructions

## Project Overview

<ここにプロジェクトの概要と主なサービスが記載されます>

## Architecture & Components

### Core Services
<ここではコアとなるサービスの役割が記載されます>
1. **Backend Chat Service** (`backend/`) - Main chat API
2. **Document Indexer** (`Indexer/`) - Automated document processing and indexing service 

### Key Technologies / Tech stack in use
- **Runtime**: Python 3.11
- **AI Services**: Azure OpenAI (GPT models), Azure AI Search (cognitive search)

## Project Structure
<ここではディレクトリ構造とその役割が記載されます>
```
/
├──backend/           # Main chat API service
│   ├── ....
├── Indexer/              # Document indexer service
│   ├──  ....   
│   
├── tests/                # Unit tests (pytest-based)
└── .github/workflows/   # CI/CD pipeline
```

## Coding Guidelines

## General Principles
- **Clean Code:** Prioritize **readability, maintainability, and reusability**.
- **SOLID Principles**
  - **Single Responsibility:** Each module/class/function should have exactly one reason to change.
  - **Open/Closed:** Prefer extension points (polymorphism, hooks, registries) over modifying existing code; avoid type-based if/elif trees.
  - **Liskov Substitution:** Subtypes must honor the base contract (pre/post-conditions, invariants); do not narrow accepted inputs or weaken guarantees.
  - **Interface Segregation:** Depend on small, focused interfaces; in Python prefer typing.Protocol or ABCs with minimal method sets.
  - **Dependency Inversion:** Depend on abstractions (protocols/ABCs), inject dependencies via constructor or function parameters; avoid instantiating concrete dependencies inside units.
- **Composition over Inheritance:** Favor composing behavior over deep inheritance hierarchies.
- **Separation of Concerns:** Keep domain logic, I/O, configuration, and orchestration clearly separated.
- **YAGNI and KISS:** Implement only what is needed now; prefer simple, straightforward solutions.
- **Pythonic Practices:** Prefer EAFP over LBYL when appropriate; embrace duck typing with explicit protocols when static typing.
- **Immutability by Default:** Prefer immutable data (frozen dataclasses, tuples) for shared state; avoid global mutable state.
- **Side-effect Isolation:** Keep pure logic free from I/O; isolate side effects at boundaries for easier testing.
- **Conciseness:** Aim for concise and expressive code.
- **Descriptive Naming:** Use clear and descriptive names for variables, functions, components, and files.
- **DRY (Don't Repeat Yourself):** Extract reusable logic into functions or classes.
- **Modular Design:** Break down functionality into small, single-responsibility functions and classes.
- **Testable Code:** Design code to be easily testable.

### Python Code Style
- Follow PEP 8 conventions
- Use type hints consistently: `from typing import Any, Optional, List`
....
- Use Google style docstrings

### <使用したフレームワークに関するパターンや、環境変数、テスト、CI/CDといった部分>
<残りはプロジェクト固有の細かい部分となるため省略>

ここで、Coding GuidelinesGeneral Principlesは以下を参考に記載しました。

github.com

pull_request_template.mdの作成

ファイルは.github/pull_request_template.mdとして作成します。このファイルはPull Request(以下PRと記載)の説明を書く際のテンプレートファイルで、PR時に自動的に生成されます。

私たちのチームではレビュー時にCopilotが自動でPRの内容をレビューします。設定方法はここでは述べませんが、以下に記載があります。

docs.github.com

PRを出した際に、Copilotが自動でレビューしますが、Copilotのレビュー結果は英語で記述されます。チーム内から、Copilotが出すレビュー結果を日本語にして欲しいとの意見がありました。そのため、pull_request_template.md内にCopilotへの指示として、コメントで日本語でレビューしてくださいと記載しています。

変更タイプ分類は、レビュー時に大量の変更をしてしまうとreviewerのレビュー時間や負荷が増え、不具合の検出品質が低下する可能性があるため、できるだけ変更タイプを絞ってPRを出すようにしています。

参考として以下ではコードの変更量やレビュー時間の変化に対して、不具合の検出率がどのように変化するかについての記載があります。基本的な傾向としてコードの変更量が小さい方が不具合の検出率が高く、変更量が多くなるほど検出率が低下します。

zenn.dev

また、基本的にDesign Docを作成するため、Design Docの項目を記載しています。軽微な修正の場合はDesign Docを記載せず、概要に修正内容を記載します。

また、クラウドサービスで新たにリリースされた新しい機能など、これまで知見がなかったものは検証し、PRを出すときに# 7. 実装の根拠に検証した内容や参照先を記載します。

なお、このテンプレートに記載した項目は必要に応じて、追加・削除してレビューするようにしています。

<!-- for GitHub Copilot review rule -->
<!-- 日本語でレビューしてください -->
<!-- 
レビューする際は以下のprefixを付けてください。
[must] → かならず変更してね  
[imo] → 自分の意見だとこうだけど修正必須ではないよ(in my opinion)  
[nits] → ささいな指摘(nitpick) 
[ask] → 質問  
[fyi] → 参考情報
-->
<!-- 日本語でレビューしてください -->
<!-- for GitHub Copilot review rule -->


# 1. 概要

# 2. 変更タイプ分類
* [ ]  `Feature`
* [ ]  `Fix`
* [ ]  `Refactor`
* [ ]  `Perf`
* [ ]  `Security`
* [ ]  `Docs`
* [ ]  `Test`
* [ ]  `Build`
* [ ]  `CI/CD`
* [ ]  `Breaking`
* [ ]  `Chore`

# 3. レビューで確認してほしいこと

# 4. 仕様

# 5. Design Docs、ADR(Architecture Decision Record)

# 6. 設計書

# 7. 実装の根拠

# 8. issue

日本語でのレビューやprefixは以下を参考にしました。

zenn.dev

実運用

Design Docの作成とコーディング

以下のような手順でDesign Docの作成とGitHub CopilotのAgentモードでコーディングをしました。

※ 以降の手順ではGitHub CopilotのAgentモードことを、「Agent」と省略して記載します。また、以下の全ての手順で、モデルはGPT-5-Codexを使用しました。

  1. Design Docの記入
  2. コミット
  3. AgentによるDesign Docのレビュー/修正
  4. レビュー内容を反映してコミット
  5. AgentによるDesign Docを参照したコーディングの実施

各手順の詳細を解説します。

1. Design Docの記入

まず、Design Docのテンプレートに従って実装内容を記述します。

2. コミット

次の手順では、AgentによりDesign Docをレビュー/修正することになります。

意図しない大量の変更が発生してしまった場合に備えて、1.の状態に戻れるようにコミットをしておきます。

3. AgentによるDesign Docのレビュー/修正

AgentにDesign Docをレビューをしてもらいます。チャットのやり取り内で修正があった場合は、なるべくAgentに修正をしてもらうようにします。

Agentによるレビューをする中で、「DBにどのようなケースの場合はどの値を入れるか」など、期待する結果や、新しいライブラリを使用して既存の自作実装を置き換える際に依存していた部分の具体的な置き換え方法について記載するようAgentから指摘されることが多くありました。そのため、運用している中でDesign Docのテンプレートに「処理・実装詳細」の項目を追加しました。

また、DBを使用する場合はどのような値を入れるなどは、Agentが実装するときに必要であり、またPR時にreviewerにレビューしてもらうときにも必要があるため、具体的な設計を記載しました。

4. レビュー内容を反映してコミット

ここでも、Agentにより意図しない大量の変更があった際に戻れるように、コミットしておきます。

5. AgentによるDesign Docを参照したコーディングの実施

プロンプトとしては「Design Docに従って実装して」とチャットするだけで、基本的に上記の手順である程度意図したコードが生成されます。

チャットの応答としてAgentは最初に実装計画を提示し、私に確認を求めてきましたが、基本的に私が試したときは問題がなかったので、そのままAgentに実装してもらいました。

なお、Agentが書いたコードを修正したい場合は、できるだけAgentに修正依頼を行いました。また、Design Docに過不足がある場合は、その部分も基本的にはAgentに修正してもらいました。

実際の運用では、Agentが実装を進める際に必要な情報がDesign Docに不足しているケースがあり、その際は私からAgentに指示を出し、Design Docに必要な情報を追加させました。

レビュー

GitHubのPR時に自動でCopilotがアサインされる設定をしておきます。そのため、PRを出すタイミングで自動的にCopilotがレビューをしてくれます。revieweeはCopilotのレビュー内容を確認しつつ修正をします。これによりある程度誤字や簡単なバグなどを見つけてくれます。

なお、reviewerは上記のPRテンプレートに記載された内容などを確認しつつレビューをします。

課題と考察

上記のコーディングからレビューまでのフローを運用してみた結果以下の課題を感じました。

  1. copilot-instructions.mdに記載した内容が無視される部分がある。
  2. Agentがコーディングするとコメントが少ない。

それぞれについて解説します

copilot-instructions.mdに記載した内容が無視される部分がある

copilot-instructions.mdにかなりの量の指示やリポジトリ(プロジェクト)のコンテキストが書かれています。そのため、そもそもLLMが指示されたことをある程度守れる範囲で指示を絞って書いておくことが現状、必要だと感じました。

以下の資料ではreasoning modelでも指示の数を増やしていくごとに、徐々に精度が減少していくようです。

arxiv.org

そのため、どのようなデータを使用して学習しているかは分かりませんが、一般的に守られているであろうPEP 8に従ってコードを書くことは、明記しなくても良いと考えています。

また、指示としてUse Google style docstringsと記載しましたが、コードの一部にGoogle styleでない部分多く、In-context Learningによって文脈がGoogle styleではなく、既存のコードに応じた書き方になってしまったと考えています。

改善のまとめとしては、必要最低限の指示(コンテキスト)に絞りつつcopilot-instructions.mdを改善し、コーディングスタイルを統一してコーディング規約の順守を進めていくことが重要だと考えています。

Agentがコーディングするとコメントが少ない

こちらについてはreviewerから指摘を受けました。確かに、Agentが書くコードは自分が書くコードよりスマートな印象ですが、コメントが少なく、レビューする側の負荷が高いと感じました。

これについての対策はまだ試してはいませんが、以下を試してみたいと考えてます。

  • Agentにコーディングをしてもらいつつ、コメントも追加してもらう。
  • Agentが書いたコードをRevieweeが解釈し、その内容を基にコメントを書く。

Agentにコメントを書いてもらう方法はそもそも、どこに指示を書けばよいかが問題になります。copilot-instructions.mdに書けば指示通りなるのか?そうでない場合はAgentに毎回プロンプトで指示を出すのか?といったところを検証してみないといけないと考えています。

また、C#やC++ではコメント提案機能があるかと思いますが、私が使用しているPythonは特にこの機能はないようなので、Agentではなく、個々にチャットでコードを説明させてコメントを書かせる運用も考えられます。

docs.github.com

Revieweeが解釈した内容を基にコメントを書く場合は、分からない部分は実際に動かしてみた結果などを記載できればと考えています。これは下記書籍にある「学んだ教訓」コメントのようなイメージになるかと思います。

きれいなPythonプログラミング ~クリーンなコードを書くための最適な方法 | Al Sweigart, 岡田佑一 |本 | 通販 | Amazon

上記のように、Agentにすべて任せるのではなくコメント部分は自分で書くことで、コードを理解しつつRevieweeに処理内容への責任感を持たせることができると考えています。

まとめ

Agentを使用したことでコーディングのスピードは向上しました。しかし、コーディング規約の徹底やAgentが書いたコードにも分かりやすいコメントを書くことが重要であり、それを怠るとレビュー時の負荷が高くなるという、チーム開発の基礎的な部分の重要性を痛感しました。

筆者自体ソフトウェア開発の勉強をしていくことの重要性を感じたと同時に、LLMの特徴を理解し(すべての仕組みを解釈できているわけではありませんが)、Agentを用いたソフトウェア開発プロセスの改善を検証していくことが大切だと感じました。

また、スペック駆動開発(SDD)のもになってしまいますが以下のブログでは、Agentは簡単な問題を与えれば、暴走はしなかったといっており、複雑な要件を単純なものに分解した方がよいとの知見もあります。そのため、現状では単純な要件をAgentに提示し、現段階的にAgentによるコーディングを進めたうえで、人によるレビューを行う方法が適切であると考えております。

marmelab.com

ただ、年々モデルの性能が向上しており、複雑なタスクを分解、外部ツール選択などを評価するベンチマークも提案されています。これらのベンチマークなどを参考に、開発プロセスの改良を進める必要があると考えております。

arxiv.org

執筆担当者プロフィール
齊藤 泰一

齊藤 泰一(日本ビジネスシステムズ株式会社)

機械学習系ソリューション開発、開発環境自動化などを担当。

担当記事一覧