先週 に引き続いて AI エージェントにコードを書かせてみた。
テーマとしてとてもとても典型的で既存のコード例がインターネットに溢れていそうな「テトリス」を選定した。
(選定したというか、職場の id:koudenpa さんが「テトリスでも作らせてみなはれ」と言ったので『いっちょやってみっか』となってやった)
というわけでブラウザで動くテトリスがここにある。(PC にしか対応していないので絶対にスマホでアクセスしないでほしい)
ソースコードはここ。
.cursorrules を辞めて Project Rules を使った
前回は .cursorrules ファイルに AI エージェントへの指示を書いていたが、今後非推奨ということで辞めた。
Project Rules を使うのがいいらしい。
作りたいもの (今回で云うとテトリス) を小出しで指示するのは面倒なので alwaysApply: true
なルールを用意して作りたいものを一通り書いておいた。
おかげで作りたいものの共通認識が取れた状態で実装を進められた気がする。が、これはテトリスがあまりにも一般的だったからかも知れない。
AI エージェントが訳分からなくならないために人間が訳分かってないといけない
AI エージェントと共にプロジェクトを始めると序盤のスピード感がすごい。"とりあえず動くもの" がすぐに出てくる。
そうすると人間サイドとして「なんか知らんけど動いてる!あとはこことここをちょっと変えて...」とノリノリで指示を出しがちである。そのとき目の前のコードをちゃんと読めてない。「なんか正しそうだな」ってくらいの認識で進めてしまう。
そうすると次第に AI エージェントが訳の分からないコードを書き始める。
だいたいは私のリクエストに対して既存コードの実装方針に無理があるのが原因。ようはリファクタリングが必要。AI エージェント的には「実装して」と言われたらリファクタリングではなく実装しようとなるので無理してゴリ押し実装することになる。そうすると正しく動かない。
それに対して「修正して」と言ってしまうとリファクタリングではなく修正しようとするので余計に訳が分からなくなる。
そうならないためには人間がちゃんとコードを読んで現状を把握しておく必要がある。
- いまどんなコードが目の前にあるか
- そのコードは簡素か、それともいびつか
- これからやろうとしていることに対して現状の実装は筋がいいか
このあたりは把握して指示出しが必要。人間が訳分かっていれば、AI エージェントが迷走しないように指示出しすることは可能。
問題は序盤の爆速コード生成のなかでどうやって落ち着いてコードを読むか、だろう。個人的には風呂入って一晩寝て起きて ダブルソフト のトースト食べてコーヒー飲んでからコードに向き合うと「次の指示出す前にコード把握するか」と思えがちだ。
「既存の挙動を変えないで」と言わないとついでにあれこれやりがち
ある程度コード生成して1ファイルが長くなってきたなと感じたので「コンポーネントを分割して」とか「使ってない変数とかあるのでリファクタして」とか指示出した。
そうしたらなんと!関数の挙動が変わったり CSS が書き換えられてスタイルが変更されていたりする。実に驚くべきことだ。
個人的には「コンポーネント分割」や「リファクタリング」というフレーズには "既存の挙動を変えないまま" というニュアンスを強く感じるのだが AI エージェント的にはその前提は無いっぽい。
「既存の挙動やスタイルを変えてしまわないように注意しながらコンポーネントを分割しよう」と言えば素直に分割だけをやってくれる。やれやれ。
ユニットテストや lint は効く
AI エージェントが生成した関数に不具合があることが分かった。そのまま「修正して」だけ言っても時間かかりそうだなと直感したので「修正したいけど、まずはユニットテストを生成して」と指示した。生成されたテストケース を読んだ。ちゃんと的を射ている。 その後、AI エージェント自ら「テストが通るように実装を変更します」と言い出して3回くらいリトライしながら修正していた。
実装しようとしている対象が複雑なとき、まず落ち着いてテストを書くというのは職業プログラマなら当たり前なのだが、AI エージェントにも有効な手法だとは驚いた。
- 一発でコード生成が難しい程度に複雑なロジックで
- とはいえテストケースを適切に出せる程度には AI エージェント側が機能を捉えられていて
- テストケースが相互に干渉しない程度のシンプルさ
そんな問題であれば、テストを書かせることで AI エージェントが訳分からなくなるのをマイルドに回避できる。
ロジックがもう少し複雑になればテストケースを書くのを人間がやったほうが効率的になるのかな、と想像したりする。
lint エラーやビルドエラーを見せて修正させるのも有効だった。AI エージェントが自分で問題を見つけるが困難でも。lint コマンドやビルドコマンドを提示して「このコマンドでエラーがなくなるように修正して」と言えば、AI エージェントが繰り返しコマンドを実行してエラーメッセージをヒントに修正をしてくれる。
favicon や og:image も生成してくれるが...
「<title>
を適切に設定して」とお願いしたら「favicon も適切なものを設定したいですね」とか返してきて favicon.svg を作ってくれたので驚いた。
「og:image も作って」と言ったらそれも SVG で作ってくれた。「SVG じゃダメで PNG にする必要があるみたい」と言ったら npx sharp-cli
コマンドでうまいことやってくれた。賢い。
さてこの画像が著作権的にセーフなのかというと (ほかの誰かの著作物をほぼそのまま持ってきたりしてないかと言うと)、それはどうなんでしょうね?
まとめ
次はぷよぷよを作ろうかな?
私からは以上です。