コンテンツにスキップ

Cursor やってみよう

じゃあ何すか、人間くんの書いたコードは無駄だったってことすか
じゃあ何すか、人間くんの書いたコードは無駄だったってことすか

Cursor とは何か

コーディングエージェントを搭載した VS Code 派生のテキストエディタや。 コーディングエージェントに全ベットしよう!という言説がある中、Cursor は生成 AI + テキストエディタなツールとして始めやすく嬉しいね、と言われている。

Cursor を実際に使って試そう。

その 1. 明らかに簡単なもの、poor-zundamonizer

最終的に俺がみたい画面
最終的に俺がみたい画面

まず、明らかに簡単なものを Cursor と一緒に作り、試す。 最近の俺のわがままとして、「Deep Research の調査結果、なんかいっぱい文字あってしんどい」というのがある。 俺もうダメなんすよ。

近年一番脳に優しい情報提示形式はずんだもん動画っす。 なんで、

  1. 文字まみれの調査結果を何らかの形式に変換させる
  2. 変換結果をずんだもん動画風に閲覧する

ということをしたい。俺はもうダメなので。

ずんだもん動画というのを乱暴に抽象化すると、後ろにプレゼンスライドがあり、前でずんだもんたちが喋っている。 したがって、スライドの内容 + そのスライドの前で喋らせる脚本 をひとまとめにする DSL 的なものがあると良い。 まず、単純にスライドを作成するためのツールを用意したい。 これはすでに世の中にたくさん存在しており、大変良い世の中や。 今回は、他と比べて比較的セットアップが簡単で扱いやすい Marp を利用する。 Marp

Marp は Markdown でスライドを作成できるツールである。 Marp にはスライド内の HTML コメントを presenter note として扱ってくれる機能がある。 こいつをずんだもん用の脚本に利用する。 要するに、以下のようにスライド内に脚本を埋め込みたい:

# Slide 1

- hoge
- fuga

<!-- ずんだもん(neutral): こんにちは、ずんだもんです -->
<!-- 春日部つむぎ(happy): 私は春日部つむぎです -->

---

# Slide 2

- 宿命
- 支配
- そして欺瞞

<!-- ずんだもん(neutral): 鋼の魂奪者なのだ -->
<!-- 春日部つむぎ(neutral): 無窮の闇、滅魂の一撃、不滅の鎧、死の呪縛、死の国 -->

で、この Markdown の中の脚本部分を取り出し、以下のようなデータを作る:

const events =  [
    {
        type: "speak",
        character: "zundamon",
        emotino: "neutral",
        text: "こんにちは、ずんだもんです"
    },
    {
        type: "speak",
        character: "tsumugi",
        emotion: "happy",
        text: "私は春日部つむぎです"
    },
    /**
     * ページ内のコメントを読み上げ終わったら次のページへ移動したい
     */
    {
        type: "nextSlide"
    },
    // ...
]

で、このデータを元に音声を作成したりしつつ画像をええ感じにしたりしつつ、スライドショーを再生するための HTML を作る、ということにする。

このようなツールを作るぞということで、まず README を作成した。 して、この README を元に実際に Cursor にやってもらったのは以下:

  • 出力ディレクトリに既存のファイル(俺が前もって用意したずんだもんの画像とか、css とか)をコピーするスクリプトを書く
  • local の VoiceVox サーバーへのリクエストを司るクラスを作ってもらう
  • 最後にコメントを書いてもらう

これらは結構うまく行った。 できたものはこれ: Demo 実際の AI Assistant との会話は ここ に残してある。

基本的には、

  • 実装内容が明確であり、インターフェイスも指定されている
  • そもそも各コンポーネントが小さい
  • しかたなく密結合になる部分は責任者(今回は天然高知能である俺)によって "ちゃんと" 管理されている

というのが効いたんかしらと思う。 しかたなく密結合になる 部分は生成された HTML だったりそこで読み込む pure js だったりする。 ここら辺は天然高知能の私がテキトーに作った。

天然高知能と人工知能の夢の共演で良かったです。 ところで、こんなんは AI 時代のソフトウェア開発 **とかそんな話ではなく** 、普通にソフトウェア開発する上で気をつけるべきことです。 人間クンたちわかっとるか??

その2. 複数の機能と抽象化、zondamonizer-ai-assistant

上のスライドショー生成くんはやることが明確に決まっており、機能を統合するダルい部分は俺の高知能でなんとかした。 結果、AI と気持ちよく会話できた。 やることがちょっと増えて、俺がサボるとどうなるか。

zudamonizer-ai-assistant では、

  1. Markdown 形式の文章を Marp のスライドにする
  2. Marp のスライドにずんだもん動画風のナレーションを埋め込む
というのを生成 AI 様にやってもらう。 それぞれについて、最初に作ったものを AI に評価させる -> AI による評価を踏まえて AI に改善させる というフィードバックループも実現したい。 したがって、

  • やることが 2 つある
  • フィードバックループという抽象化できそうな構造も持っている

ということになる。 俺の欲しいもの、わかるよね? AI くんは俺を気持ちよくできるのか。

Markdown 形式の文章をスライドにするくん

俺が実験がてら作成した以下のファイルを元に、「とりあえず頼む」でお願いしてみる:

  • evaluation.ts : スライドの評価・フィードバックを AI にお願いするくん
  • improve.ts : evaluation.ts で出力されたフィードバックを元にスライドの改善を AI にお願いするくん

お願いしたやりとりはこれ。 AI Assistant くんは元のファイルを参考に、

  • generate.ts : Markdown 形式の文章をスライドにする
  • cli.ts : 上の evaluation.ts / improve.ts / generate.ts を呼び出す用の CLI

を作ってくれた。 一旦ええやんという感じだが、 cli.ts において

  • export / preview / add-meta などの謎のメソッドを勝手に追加している
  • evaluation.ts / improve.ts / generate.ts を呼び出す際に bun run evaluation.ts を子プロセスとして生もうとしている

などしているのは、 ウザい!!!! 前者については、まあ単純に欲しくないんで、俺は。 既存のファイルを確認し、あるとよさそうなファイルを追加したり、既存のファイルを改善したりしてください としか指示していない俺が悪いっスか。

後者はなぜそんな難しいことをする?という感じだ。 各ファイルを `bun run` で実行できるようにしつつ、便利 entrypoint としての CLI を用意するのは良いと思う。 子プロセスとして呼び出すのはあんまりわからない。 強いて言えば呼び出し自体を抽象化できるなどの良さがありますか。 子プロセスとして呼び出すように作ると、子プロセスの stdout を親プロセスからも出してあげたくなる。 というのも、AI エージェントくんがデバッグする際に `bun cli.ts ` 実行して親プロセスの出力を見るので。 が、AI エージェントくんが書き散らした子プロセス利用コードを、人間様が(AI 野郎のために)更に修正するのは楽しくないっス。 結局ここらへんで子プロセスを利用 *しない* 形への書き直しを要求している。 "このリファクタリングにより、コードの品質と保守性が大幅に向上しました" などとうそぶいているが、ほなら最初からやってくださいよ。

が、(先の子プロセス利用コード同様)「なぜそんなことをする?」的な部分も気になり出す。 会話埋め込みについて色々なオプションを用意してくれたり、こっちでも preview などの謎メソッドを用意してくれたりなどの、AI 特有の余計な気遣いが変。 なんか知らんが春日部つむぎをお嬢様口調で喋らせようとしてくるのも変。

「キャラクター名のカスタマイズ」オプションは用意するものの、実際にキャラクターの振る舞いを指示するテンプレートの管理については人間様が指摘するまで整理しない、などのバランスの悪さも気になる。

上2つを合わせた全体的な開発体験

ややコード内容に気になる点は増えてきたものの、

  • そもそも両者を一旦動くところまで作り上げるのが速い
  • 全部通しで動かすための( marpify/cli.tszundamonizer/cli.ts を両方ええ感じに使う) "一気通貫ワークフロー" を作る、などの雑用も素早くやってくれる
  • 一気通貫フローを実際に使うための example を追加するのも良い感じにやってくれた

ということで、実際に動かすまでラクに進んだのはめちゃくちゃ良いと思った。 特に今回のツールについては、いろいろ動かしてみてプロンプト調整するという段も存在したんで、この利点を感じやすかった。

Q. どうだったかな? A. よかったよ

全体として、俺はめっちゃ良いと感じたっス。 とりあえず動くもん作って自分で試して改善してみる、というソフトウェア開発の初期衝動みたいなもんを思い出せた気がする。 作ったもんは以下:

ちょっと一瞬ポエムを挟みます。 俺はもう7年だか8年だか働いており、ソフトウェア開発を完全に仕事にしてしまった。 結果、最近はくだんねーもんを作らんくなってしまった。 コードを書くということが金銭に結びつきすぎており、趣味のクソ開発中に「じゃあ何すか、俺くんの書いてる趣味コードは無駄ってことすか」みたいなつまらねー考えに囚われる。 自分の人生をつまらなくしてしまっている。

じゃあ何すか、俺くんの書いてる趣味コードは無駄ってことすか
じゃあ何すか、俺くんの書いてる趣味コードは無駄ってことすか

コーディングエージェントは、とにかくものが動くまでをあり得ん速度でやってくれる。 結果、つまんなオジサン人間の俺は、つまらねー考えに囚われる前に「ギャハハ!おたくクンの作ったもん意味ねーじゃん!もっとこうしなよ!」という WANIMA モードになれる。 冷笑の時代は終わり、「やってみよう」の時代が訪れる。 「やってみよう」とかいうの、もうn年前の曲ではありますが。

やってみよう
やってみよう

ポエム じゃない 方の話としては、「コードを生み出すための自然言語(てか要件定義)」に対する能力が今後いっそう重要になってきそうっスね、ソフトウェア開発において。 まあこれ、「そんなん知ってるワイ!」とか言われそうですけど、実際自分でやってみるとおもろいっスね。

また、とにかく実装が早いんで、「作って動かす」行為を要件ブラッシュアップのためのステップにしやすいのもスゲー良いと思った。 人間の主観マシマシのガバ要件を元にコードを書かせ、実際に作らせてみて、ダメなもんが出てきたらまた要件定義からやり直すみたいなパワー感のある開発を個人レベルでもできる。 ていうか、やった。

今回の記事作成にあたって実装したツール群は、元はWeb アプリケーション上で

  1. ずんだもん立ち絵素材PSD / スライド用Markdown 読み込み
  2. ずんだもん画像 / スライド画像生成
  3. Canvas 上での画像配置
  4. 音声・動画再生

をやろうとしていたが、AI の認知能力と俺の管理能力を超えて破綻した。 破綻したんで、「今すぐ欲しい最終成果物は何か」の見つめ直しに迫られた。 結果、今すぐずんだもん動画風のもんが欲しいっスと思ったんで、上述の構成にした。

故 RICH-zundamonizer
故 RICH-zundamonizer

個人の体験を膨らませてチーム開発のことを考えると、コーディングエージェントとの対話ログの管理などは生成 AI 時代のチーム開発における関心事になるかも。 commit message とか PR description とかよりも、エージェントとの対話ログが変更の意図を雄弁に語る気がする。 「このコード、俺が何を言ってしまったせいで発生したんや?」というのを対話ログで確認することが何度もあった。 今回俺は SpecStory という拡張を使って対話ログを残したが、対話ログ管理基盤は(今後コーディングエージェントの利用が一般化するにあたって)いろいろ充実してきそうな感じだ。

全体として、コーディングエージェントは楽しいっス最高っスという感じだし、チーム開発……とかいうやつの未来、についてもちょっとした気持ちを得られたのでよかった。 みんなもやってみよう。