はじめに
X のタイムラインに、以下の「GitHub Copilot coding agent が Proプランでも使えるようになった」という情報が流れてきたので、さっそく試してみました。
今回試した内容のレベル感は、
「動作確認くらいの内容で、一通りの手順を体験してみた」
というものになります。
ちなみに Pro+プランなどだと、以下の 5月のタイミングから利用可能になっていたものです。
それと、Proプランで GitHub Copilot coding agent を使えるようになったタイミングは、自分が冒頭のポストを見たタイミングよりもさらに前からだったようです。
やってみたこと
作ってもらったもの
最初に、GitHub Copilot coding agent に作ってもらったものを掲載してみます。
内容は p5.js を使った Canvas への描画(ブラウザで動作するもの)です。
上記が作られた流れ
これが作れられた流れの概要は、以下になります。
- Isuue に簡単な仕様を数行で書く
- Copilot が上記の内容を元にコーディング
- Copilot からプルリクがくる
- プルリクに対する対応 ← 自分が受け入れやマージなどをする
- (意図しない実装になっていたので、修正依頼用の Issue を作成し、上記の流れをもう1周)
この後の部分では、「GitHub上の設定の確認」や「GitHub Copilot coding agent を試した手順の詳細」などを書いていきます。
GitHub上の設定の確認
まずは、GitHub上の「GitHub Copilot coding agent」に関する設定を確認してみました。それに関して、以下の公式ページに書かれた情報を見て、設定画面へとたどり着きました。
●Managing Copilot policies as an individual subscriber – GitHub Enterprise Cloud Docs
https://docs.github.com/ja/enterprise-cloud@latest/copilot/how-tos/manage-your-account/managing-copilot-policies-as-an-individual-subscriber
設定画面を開く手順
GitHub Copilot coding agent の設定画面を開いた時の手順を記載します。
まずは、右上のアイコンから開けるメニューで「Your Copilot」を選びます。
そして、左側のメニューを見ると「Copilot」の部分に「Coding agent」という項目があるので、これを選びます。
そうすると、以下の GitHub Copilot coding agent の設定画面を開くことができました。
上記の赤矢印で示した部分で、対象にするリポジトリを設定できるようです。それと、このページを開いた時の URL は以下になるようでした。
●Coding agent
https://github.com/settings/copilot/coding_agent
設定を変えなくても良かったのですが、試しに今回用のリポジトリを作って、そのリポジトリのみを対象にする、という状態でやってみました。
リポジトリでの操作など
リポジトリでの操作を行っていきます。
参照した記事について
Qiita で GitHub Copilot coding agent を検索していたら、こちらの @chomado さんの記事が出てきたので、参照させていただきました。
●GitHub で自律的に動く Copilot Coding Agent を使い issue 対応(実装からPR作成まで)を丸投げしよう #意識低いAICodingチュートリアル #03 #生成AI – Qiita
https://qiita.com/chomado/items/92650af47b55632f7ef9#github-copilot-coding-agent-%E3%81%A8%E3%81%AF
Issue を作ってみる
GitHub Copilot coding agent を使うには、Issue を作成して、そこに Copilot をアサインするというやり方のようです。
Issue を作成して内容を作っていく前の段階で、画面右の方を操作してみると Copilot をアサインできるようになっています。
Copilot をアサインしてから、以下の内容を書きこみました(以下の内容は思いつきで適当に作りました)。
- タイトル
- p5.js でパーティクルを描画する HTMLファイルを作成する
- 説明
- p5.js でパーティクルを描画する HTMLファイルを、以下の仕様で作る
その後、作成を完了させたところ、以下のようなコメントがつきました。
今回作ったテスト用のリポジトリが、README.md さえ作られていない空の内容だったので、「1回は何かをコミットするように」というコメントがきた形です。
Issue を再度作る
README.md を適当に作って、再度、先ほどと同じ Issue を作りました。
今度は、Copilot からのリアクションがついて、作成作業が開始されたようなメッセージが出ています。
以下のような計画が作られたりしつつ、作業が進んでいったようでした。
Copilot からのプルリクとその対応
この作業をしつつ、キャプチャ画像を X にポストしたりしていたのですが、そんなことをしている間に既にプルリクがきていました。
内容を確認してみると、270行くらいの HTMLファイルが作られていました。
ざっと見て処理的上の問題はなさそうだったので(なぜか p5.js が使われていない感じの実装でしたが…)、内容の受け入れやブランチからのマージの操作を行いました。
マージ後のリポジトリの状態は以下のとおりで、htmlファイルが main に追加されています。
いったん動作を確認してみる
上で書いたように p5.js がきちんと使われていない実装になっていたものの、処理は問題ないものだったので、この HTMLファイルをブラウザで開いて動作を確認してみました。
そうすると、以下のような動作をするものができあがっていました。
作成されたコードをあらためて確認してみる
「GitHub Copilot coding agent」で作成された HTMLファイルの内容をあらためて見てみました。p5.js がきちんと使われていない、というのが以下などからも分かります。
※ 素の Canvas API を使った処理で実装されています
コードの一部抜粋(省略した部分あり)
function init() {
canvas = document.createElement('canvas');
canvas.width = 800;
canvas.height = 600;
ctx = canvas.getContext('2d');
document.getElementById('canvas-container').appendChild(canvas);
// Launch initial fireworks
for (let i = 0; i 3; i++) {
setTimeout(() => {
fireworks.push(new Firework(random(100, canvas.width - 100), canvas.height));
}, i * 1000);
}
// Event listeners
canvas.addEventListener('click', function(e) {
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
fireworks.push(new Firework(x, canvas.height));
});
...
animate();
}
function animate() {
// Clear canvas with fade effect
ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
...
問題の原因
この問題が発生した原因は、以下になるようでした。
「実装したものをテストした際に、テスト環境依存の問題が発生した(ファイヤーウォールによって CDN へのアクセスがブロックされた)」というようなことが書いてあります。
再度、Issue での修正依頼を出してみることにしました。
修正依頼
以下の内容の Issue で、修正依頼を出してみました。
Issue の内容を受けて、以下のように作業が進んでいきます。
そして作業が完了した状態になり、以下のような出力が最後の部分で出ていたりしました。
修正後のコード
修正されたコードは、以下の通りです。
lang="ja">
charset="UTF-8">
name="viewport" content="width=device-width, initial-scale=1.0">
Particle Fireworks
"https://unpkg.com/p5@1.11.8/lib/p5.min.js">
body {
margin: 0;
padding: 0;
background-color: #000;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
font-family: Arial, sans-serif;
}
#canvas-container {
border: 2px solid #333;
border-radius: 10px;
}
.instructions {
position: absolute;
top: 20px;
left: 20px;
color: white;
font-size: 14px;
z-index: 1000;
}
class="instructions">
クリックして花火を打ち上げよう!
id="canvas-container">
// Variables
let fireworks = [];
let particles = [];
// Utility function for HSL to RGB conversion
function hslToRgb(h, s, l) {
h /= 360;
s /= 100;
l /= 100;
const c = (1 - Math.abs(2 * l - 1)) * s;
const x = c * (1 - Math.abs((h * 6) % 2 - 1));
const m = l - c / 2;
let r, g, b;
if (0 h && h 1/6) {
[r, g, b] = [c, x, 0];
} else if (1/6 h && h 2/6) {
[r, g, b] = [x, c, 0];
} else if (2/6 h && h 3/6) {
[r, g, b] = [0, c, x];
} else if (3/6 h && h 4/6) {
[r, g, b] = [0, x, c];
} else if (4/6 h && h 5/6) {
[r, g, b] = [x, 0, c];
} else {
[r, g, b] = [c, 0, x];
}
return [
Math.round((r + m) * 255),
Math.round((g + m) * 255),
Math.round((b + m) * 255)
];
}
// p5.js setup function
function setup() {
let canvas = createCanvas(800, 600);
canvas.parent('canvas-container');
// Launch initial fireworks
for (let i = 0; i 3; i++) {
setTimeout(() => {
fireworks.push(new Firework(random(100, width - 100), height));
}, i * 1000);
}
}
// p5.js draw function (animation loop)
function draw() {
// Clear canvas with fade effect
fill(0, 25);
noStroke();
rect(0, 0, width, height);
// Update and display fireworks
for (let i = fireworks.length - 1; i >= 0; i--) {
fireworks[i].update();
fireworks[i].show();
if (fireworks[i].exploded) {
fireworks.splice(i, 1);
}
}
// Update and display particles
for (let i = particles.length - 1; i >= 0; i--) {
particles[i].update();
particles[i].show();
if (particles[i].isDead()) {
particles.splice(i, 1);
}
}
// Random fireworks
if (Math.random() 0.005) {
fireworks.push(new Firework(random(100, width - 100), height));
}
}
// p5.js mouse event
function mousePressed() {
fireworks.push(new Firework(mouseX, height));
}
// p5.js keyboard event
function keyPressed() {
if (key === ' ') {
for (let i = 0; i 3; i++) {
setTimeout(() => {
fireworks.push(new Firework(random(100, width - 100), height));
}, i * 200);
}
}
}
class Firework {
constructor(x, y) {
this.x = x;
this.y = y;
this.vx = random(-2, 2);
this.vy = random(-15, -10);
this.gravity = 0.2;
this.exploded = false;
this.hue = random(360);
this.trail = [];
}
update() {
if (!this.exploded) {
this.trail.push({x: this.x, y: this.y});
if (this.trail.length > 10) {
this.trail.shift();
}
this.vy += this.gravity;
this.x += this.vx;
this.y += this.vy;
if (this.vy >= 0) {
this.explode();
}
}
}
explode() {
this.exploded = true;
let particleCount = random(20, 40);
for (let i = 0; i particleCount; i++) {
let angle = random(TWO_PI);
let speed = random(1, 8);
let particle = new Particle(
this.x,
this.y,
cos(angle) * speed,
sin(angle) * speed,
this.hue + random(-30, 30)
);
particles.push(particle);
}
}
show() {
if (!this.exploded) {
// Draw trail
for (let i = 0; i this.trail.length; i++) {
let alpha = map(i, 0, this.trail.length - 1, 0, 255);
let [r, g, b] = hslToRgb(this.hue, 80, 50);
fill(r, g, b, alpha);
noStroke();
circle(this.trail[i].x, this.trail[i].y, 6);
}
// Draw main firework
let [r, g, b] = hslToRgb(this.hue, 80, 60);
fill(r, g, b);
stroke(r, g, b);
strokeWeight(2);
circle(this.x, this.y, 12);
}
}
}
class Particle {
constructor(x, y, vx, vy, hue) {
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.gravity = 0.1;
this.life = 255;
this.decay = random(2, 5);
this.hue = hue % 360;
this.size = random(2, 5);
}
update() {
this.vy += this.gravity;
this.x += this.vx;
this.y += this.vy;
this.life -= this.decay;
this.vx *= 0.98;
this.vy *= 0.98;
}
show() {
let alpha = this.life;
let [r, g, b] = hslToRgb(this.hue, 80, 60);
fill(r, g, b, alpha);
noStroke();
circle(this.x, this.y, this.size * 2);
}
isDead() {
return this.life 0;
}
}
今度は、一部で(冒頭部分で)p5.js が使われてない処理があったりするものの、全体的には p5.js の処理になっていました。
作業過程を見てみる
1回目の Copilot の作業では、テストでの問題が発生して p5.js を使うのをあきらめた(Vanilla JS での実装に切り替えた)、というような話が出ていましたが、今回はどうなっていたのかを少し見てみました。
今回も CDN絡みでアクセスをブロックされた、というような感じの内容が途中に出ています。
その後、今回は修正や実装に関する構文チェックを行って、それで内容確認OK として進めたようでした。
おわりに
とりあえず今回、「GitHub Copilot coding agent」を使う流れを少し体験することができました。
別途、GitHub Copilot coding agent をさらに試してみたり、また競合となるサービスも使ってみて、使い比べてみたりということができたらと思います。
Source link
Views: 0