ここ最近の自分のツイートを見るとほぼLLMの事しか喋っていない。それぐらい首っ丈である。暇があれば即座にLLMに何かお願いをしたり質問をしたりしている。特にエージェントにコードを書かせるのはもはや始めたてのソシャゲに寸暇を惜しんでのめり込んでいるかのようである。
エージェントを使ってコードを書かせるのは楽しい。RDBMSを作ってみているが「次何しようか?」「PostgreSQL互換インタフェースとか生やす?」「え?できるん?」「できたで!」ぐらいの感覚で次々と実装が生えていってしまう。もちろん、初めから完璧なものではないのでユニットテストを書かせたりするうちにどんどんとボロが出てくるのだが、それでもそれを補って余りある開発速度が出ている。何より仕事の片手間のチャット相手が1人増えたぐらいの負荷で10万行近いコードがシュッと生えてくるのは感動を通り越して畏怖がある。
SNS上で僕の言動を追ってた人はご存知であろうが、僕は長年ソフトウェア開発工学というものを信用していなかった。あれは一介のプログラマーが学んでどうこうするものではなく、プログラミングを集団で行う際の群体の挙動を対象としたエンジニアリングを行うための学問であり、千差万別なプログラミング現場全般において通用するか疑問だったというのが強い。しかし複数のエージェントを使役していると、コードを読まずしてバグの存在に当たりをつけるとか、信頼できる場所を徐々に広げていくといった感覚が必要になりおのずとソフトウェア開発工学的なアプローチを自分自身が取っている事に気づく。別にバグ密度だの収束曲線だのを取り入れている訳ではないのだが、俯瞰で見たらそう遠くない場所にいると自覚している。
素人であれば「バグがないソフトウェアを作れーー!!」とエージェント相手に叫んでしまうような場面であっても、ソフトウェアの心得をもって粘り強く指示を出し、投げ出された仕事に対しても対話を通して切り分け、改めて指示を出せば大抵の問題は解決する。そういう作業を繰り返すとこれまで培ってきた勘所は無駄ではなかったと安堵する一方でエージェントがこの程度の事は自発的に解決するようになるのは時間の問題であるという事はヒシヒシと感じてしまう。この点において僕はプログラマの仕事の未来についてだいぶ悲観的な見通しを持っている。
エージェントに書かせたコードは正直言って不気味の谷のようで、あんまり保守したいと思わせる物ではないのだが、そもそもの前提としてソフトウェアエンジニアというのはコードを保守したくないのである。仕事でそのコードが金を産むから仕方なく保守しているに過ぎなくて、コードを読むなんてのは保守の仕方としては最終手段ぐらいの立ち位置に置くのが職業プログラマである(職人プログラマがコード自体を目的として嬉々として特定のコードをいじくり回すのは好きにしたらいいと思う、僕も本性はそっち寄りだし)。プログラミングとは構築時の作業の事である一方で、ソフトウェアエンジニアリングとはそれが継続的に価値を生むように行う継続的な行いであり、誤解を恐れずに言えば読みたくもないコードをどうにか読まずに品質を保証するためにここ数十年かけて練られてきた努力の結晶である。

ルールは大きく変わったので活かせる物もあるし活かせない物もある、思いつく限り以下に現時点で僕が感じているコツを書いていく
コンテキストエンジニアリングとは組織論である
AIに書かせようがソフトウェアの普遍の真理は、コードは常に巨大化し続けるという事である。LLMのコンテキスト長も今後とも増えていくとは思うが、ソフトウェアのコードの成長速度は必ずそれを超える。LLMがコンテキストの問題を回避できたとしても結局うまくフォーカスできるコンテキスト範囲は有限であり、藁山から針を見つけるような問題は必ず付き纏う。もちろんプロダクションのコードの全容をチーム全員が頭の中に押し込む事はできないので誰に言われずとも役割分担をする事になる。その役割分担というのが見方を変えたコンテキストエンジニアリングである。 要するにプロジェクト全体像をコンテキストに投げ込むと大き過ぎて何も考えれなくなるので「この仕事ではこのモジュールのこの機能にこう言う機能を足して欲しい、そのタスクの遂行上不必要なことは知らなくていい」という仕事の切り分け方を行うのは大体の職種で新人に対して行われている事であり、AIエージェントに限った話ではない。 AIエージェントを使っているとわかると思うが、こいつらは0を1にするのが病的に速い。そういうベンチマークセットの上で育てられたのであって人間が苦悶するようなバグを代わりに解決するのはオマケに過ぎない。0を1にするのが速いのはそのタスクを遂行するために頭に入れておかないといけない既存コードがゼロだから接点について気にすることが極端に少ないからである。プログラマもコンテキストが小さい人間ほどマイクロサービスを作りたがる、なぜならマイクロサービスにすれば頭の中に入れておかないといけないコンテキストが小さくなるからである。 マイクロサービスは極端な例だが、ソフトウェアを構築する上で内部を切り分けるという行為は他人が気にしないといけない範囲を限定する事であり「関心の分離」と呼ばれてきたものはそのままエージェントの頭の中に放り込むべき情報の分離でもある。 「ソフトウェアアーキテクチャ」とは何なのかという話はいまだに完全なコンセンサスに至っていないが、僕の感覚としてはその上で働く人たちの脳内に放り込むべきコンテキストを切り分けたものである。鶴の一声で値オブジェクトを導入しても下っ端プログラマが頭の中に押し込むべきコンテキストは変わらないのであればそれはアーキテクトが正しい仕事をしたとは言えない。 エージェントが働きやすい形にタスクを切り分けるのと人間が働きやすい形にソフトウェア内部を切り分けるのは結構類似していると思っている。今の直感ではそこのレイヤーでは気にするべきことが想像より大きいのでコンテキストも大きくて賢いハイエンドモデルを用いるものだと思っているが、意外と調査エージェントなどにうまくオフロードすれば安いモデルでも上手くいくのかも知れない。
LLMは高い
ハイエンドモデルの方が明らかにいいコードを吐くとみんなが言っている一方で、ハイエンドモデルは1Mトークンあたりの価格が10ドル20ドルといった世界になっている。そのコンテキストを使って行われる仕事はプログラマの数時間分に及ぶだろうからペイするとは思うが、安いモデルに仕事を任せられるならそれに越したことはない。価格競争が進んだ果てに今のハイエンドモデル相当がめちゃくちゃ安くなって湯水のように使われるかも知れないがその頃にはその頃のハイエンドモデルが出てて、他では解けない難度の問題が解けると宣伝されていると思う。結果として、プログラムを書く際にそんなに難しくないタスクは安いモデルに書かせるという状態は未来でも続いていると思う。何なら安いモデルの極地であるところのローカルLLMはオフロード先として魅力的であり、ハイエンドモデルを使って定義を行ったタスクを下請けするローカルエージェント群というのは現実的な話だと思う、今現在でのローカルLLMがどこまで複雑なコーディングタスクをこなせるか分からないが、安いやつで書かせてデバッグできなくて匙を投げたらその知見と共に賢いモデルにエスカレートする、という話はそのうち常識になりそうだと思ってる。サブエージェント呼び出しの形でローカルとハイエンドが協調して仕事をするし、ソフトウェア開発会社は実際のところローカルLLMを大量に抱えて走らせ続ける数人のチームが完成系かも知れない。AMDのRyzen AI Max系もそのうちモリモリと価格が上がりそう、なんせ競合商品が血の通った人間プログラマなのだから。
AIエージェントは不安定
どこの実装がどう悪いのかよくわからないので断定的なことは言わないけど、原因不明の停止とか断続的なエラーとかよくわからないことは常に起き続けている。カーネルはクラッシュしないがエディタの反応速度が1分単位になったりなんて事すら珍しくない。また書き換えの品質もばらつきがすごくて書き換え先の行番号とかめちゃくちゃになってて大変な壊し方をよくしてしまう。壊れたら自発的に気づいて直しに行ったりするので別にそんなに致命的ではないのだけど、それはそれとして不安定なものを不安定なままに使うコツというのはあって、知る限りではラルフループとそれに伴う進捗トラッキングが有効である。

ラルフループとは一言で言うとエージェントの起動自体をループの中に入れてしまう事である。ただしプロンプトの中に今回の進捗をどこかに書き込むように指示し、ループの開始時にその進捗を読み込むようにする。そうするとエージェントは「今までの進捗」をコンテキストとして受け取った上で「今回のタスク」をこなすことになる。これの何がいいかというとエージェントが途中で停止してしまってもOOMで死んでもなんだかんだ走る事である。進捗メモがデカくなりすぎると問題だが、適宜要約して圧縮するようにプロンプトを書いておけばどうにでもなる。 ただ単一のループだとあらゆるタスクが単一の高価なモデルで実施されてしまうので、設計してタスクを切り分けるフェーズは高価なモデルに任せ、簡単そうに見えるタスクは安いエージェントにやらせるみたいな事を書き加えるなどしていくらでもそのループ自体の中身は複雑になっていく、そうやってコーディングエージェントを呼ぶかどうかをプログラムしているのだから立派にメタプログラミングである。僕はまだこの域に至ってはいないが…そのループ自体をLLMに改善させるのもそのうち当然の事となるだろう。
antirez氏がコードを高速化させるために出したプロンプトだが「5. Use this file to track progresses」と指示しているのが興味深い、作業が途中で終わっても同じテキストを参照して続行する以上はテキストの中に前回までの進捗が含まれているのはとても合理的である。
自己レビュー5回
コーディングエージェントの出力するコードは9割がた上手く動く、しかしまとまった量になると自己レビューさせる度に改善点が見つかる。初めからレビューの必要のない完全なコードを書いて欲しいとは思うが、人間にもそれが難しい以上LLMにも別の文脈でレビューをしないと見つからない欠点というのはあるのだろう。人間は自分の書いたコードを反省するのに時間がかかることもあるが、海外のエンジニアがコーディングエージェントに自己レビューさせた場合5回で収束に至ることが多いと書いている。
コスト面ではもちろん多大だが、それでも人間よりずっと安いし仕組みとして入れてしまえば人間が介入する余地はなくなる。5という数字に何か具体的な意味があるかわからないし将来的には別の数字になっていると思うが、体感としてもエージェントに書かせたコードは数回レビューさせても改善点はいくらでも出てくる、LLMの特技は反省である。(対話を成立させるために難癖のようにつけているレビューコメントも見受けられるのでレビューコメント自体のレビューも必要かも知れない)。コーディングエージェントが書いたコードもプロダクションで使うなら最後は人間がレビューせよというのはまだしばらく続きそうであるが、それはそれとして人間がレビューする前に機械自身でN回レビューするというのは常識になりそうである。どうにも創造する側と咎める側とが分かれているとお互いを高め合っていくものらしい。複数の会社のエージェントでレビューするのも新しい観点が出てくるかも知れない。
ちょっと長くなり過ぎたので一旦この辺で投稿する。
