T最新テックトレンド

AI時代のソフトウェア開発を再定義する:Zedが挑むLLMの「非決定性」との戦い

0:00--:--

AIが私たちの生活、そして特にソフトウェア開発の領域に革命をもたらしつつある現代。コードの生成からデバッグ、テストに至るまで、その可能性は無限大に見えます。しかし、大規模言語モデル(LLM)がもたらす「非決定性」という新たな課題は、従来のソフトウェア開発プロセスに根本的な変化を求めています。

本日、AI Engineer World's Fairで行われた、AI対応コードエディター「Zed」の共同創設者であるNathan Sobo氏のプレゼンテーションは、このAI時代の挑戦にどのように立ち向かうべきか、その具体的な戦略と哲学を鮮やかに示してくれました。本記事では、Sobo氏の洞察を基に、Zedが確立する革新的なテスト哲学、具体的な機能、そしてそれがビジネスに与える影響と将来性について深く掘り下げていきます。


Zedとは何か:AIネイティブなコードエディターの誕生

「ZedはVS Codeのフォークではありません。私たちはゼロから、Rustで完全にスクラッチで実装しました」。Sobo氏のこの言葉は、既存の枠にとらわれず、AI時代の開発者のために最適化されたエディターを創り出すという彼らの強い意志を物語っています。

Zedの設計思想は独特です。システム全体がまるでビデオゲームのように構築されており、GPU上で動作する約1200行のシェーダープログラムを中心に、驚異的な120フレーム/秒の滑らかな描画を実現しています。この徹底した最適化により、開発者はかつてないほど応答性の高い環境でコードを書くことが可能になります。

しかし、Zedの真価は、その高速性やモダンなUIだけではありません。AIを深く統合し、開発者の思考プロセスとシームレスに連携することで、コーディング体験そのものを再定義しようとしている点にあります。AIによるコード生成、リファクタリング、バグ修正の提案など、これまでのエディターにはなかった「エージェンティック(自律的)な機能」が、Zedの中核を成しています。


AI以前の信頼性構築:決定論的テストの極致

LLMが導入される以前から、Zedの開発チームはソフトウェアの信頼性に対して極めて厳格なアプローチを取ってきました。Sobo氏は、「経験的アプローチなしでは、Zedは8秒ごとにクラッシュしていたでしょう」と、開発初期の困難を振り返ります。

彼らは、数十万にも及ぶテストを実装し、徹底的にバグを排除してきました。そのテスト手法は、サーバーと複数のクライアントをシミュレートし、共有プロジェクト上での共同編集を再現するというものです。特に注目すべきは、シミュレートされたスケジューラを介して、可能な限りすべての同時実行のランダムなインターリーブ(処理の順序の入れ替わり)をテストする点です。もしエラーが発生した場合、その特定の実行シーケンスを繰り返し再現し、完全に制御された環境でデバッグすることで、「フタつきのテスト(flaky tests)」を排除してきたのです。

この時期のZedのテスト哲学は、**「非決定的な要素(ネットワークパケットの到着順序など)であっても、可能な限り決定論的に制御・再現し、問題を特定して解決する」**というものでした。これは、従来のソフトウェアエンジニアリングにおける「信頼性」を確立するための模範的なアプローチと言えるでしょう。


AI時代の到来:LLMの「非決定性」がもたらす新たな課題

しかし、LLMが開発プロセスに組み込まれることで、Sobo氏らが培ってきたこの決定論的テストの哲学は根本から揺らぎます。Sobo氏は「LLMが登場すると、これまでのアプローチは全て白紙に戻る」と語り、その理由を次のように説明します。

LLMの出力は本質的に「確率的」です。たとえ同じプロンプトを与えても、その都度わずかに異なる結果を返す可能性があります。さらに、入力トークンを一つ変更しただけで、モデルの出力は完全に異なるものになり得ます。このような非決定的な振る舞いは、従来の「入力Xには必ず出力Yが返る」という決定論的テストの前提を崩壊させます。

機械学習の分野では、LLMの評価は通常「Eval(Evaluation)」と呼ばれ、「入力と出力のペア」によってデータ駆動型で行われます。しかし、ソフトウェアの信頼性を保証するためには、単に「多くの場合、正しい出力をする」だけでは不十分です。バグが発生した際に、その原因を特定し、修正できる再現可能なテストが必要となるのです。


Zedの革新的なテスト哲学:確率的Evalと決定論的解決策の融合

Zedは、このLLMの非決定性という巨大な壁に対し、独創的かつ実践的なテスト哲学を構築しました。それは、確率的なテスト(Eval)から出発し、その中で発見された問題をアルゴリズム的解決策と決定論的テストに落とし込むという多層的なアプローチです。

6.1. データ駆動型Evalからプログラム的Evalへの進化

Zedの初期のEvalは、Sweetbenchのようなデータ駆動型で、プロンプトと期待される出力が記述されていました。しかし、このアプローチでは、LLMの非決定性により、なぜ失敗したのかという具体的な原因を特定することが困難でした。

そこでZedは、Evalをより「プログラム的」なものへと進化させました。LLMとの会話自体を関数として記述し、エージェント(LLM)の行動について直接アサーション(検証)を行うのです。例えば、エージェントが特定のファイルを読み込み、特定の箇所を編集し、最終的に特定の状態になる、といった一連のプロセスをコードで記述し、その結果を細かく検証できるようにしました。これにより、LLMの挙動をより詳細に、かつ再現可能に分析できるようになったのです。

6.2. 確率的テストによるアルゴリズム的課題の発見と解決

Zedは、LLMが関わる部分のテストとして、依然として確率的テストを活用しています。例えば、共同編集のシナリオをシミュレートするテストでは、サーバーやクライアントの起動、プロジェクトの構築、そしてユーザー間の同時編集といった一連の操作を、毎回異なるランダムな順序で50回繰り返します。

この確率的テストの過程で、Grepツールの初期実装における重要な問題が発見されました。モデルがテキスト内のfn runのようなパターンを検索する際に、検出されるマッチが期待される構文境界と一致しないというアルゴリズム的な不具合です。

この問題に対し、Zedはtreesitterというパーサー生成フレームワークを活用し、検索結果を構文木の境界に合わせて展開するアルゴリズム的解決策を導入しました。これにより、モデルの出力が多少曖昧であっても、正確なコードの範囲を特定できるようになりました。結果として、このアルゴリズム的改善は、確率的テストをより信頼性の高い「決定論的なテスト」へと回帰させることを可能にしたのです。特定の入力に対して、ツールが予測可能な出力を返すようになり、テストの安定性が大幅に向上しました。

6.3. ストリーミング編集における多様な課題と緻密な対処

エージェントがコードを編集する「ストリーミング編集」機能の実装は、さらなる複雑な課題をもたらしました。

  1. ツール呼び出しのストリーミング不可: 従来のLLMへのツール呼び出しは、JSON形式で入力が完結してから処理されるため、リアルタイムのストリーミング編集には不向きでした。

    • 解決策: Zedは、小さなツール呼び出しで編集の意図を記述させた後、LLMに対してold_textnew_textのXMLブロックをストリームするよう指示する方式に変更しました。これにより、モデルが編集を逐次的に送信し、エディター側でリアルタイムに適用できるようになりました。
  2. 構文解析の複雑性: old_textnew_textのXMLタグがネットワークパケットで任意に分割されて届くため、途中でタグが切れるなどの問題が発生します。

    • 解決策: エディター側では、これらの断片化されたXMLタグを正しく逐次的にバッファリングし、インクリメンタルに解析するロジックを開発しました。
  3. モデルの不完全な振る舞い: LLMは、ときに指示を完璧には実行しません。

    • 閉じるタグの誤り: </old_text>とすべきところで</new_text>と出力するなど、タグのミスマッチが発生しました。
      • 解決策: プロンプトに「常にすべてのタグを適切に閉じること」と明示的に指示することで、成功率を40%から95%に向上させました。さらに、残りの5%の失敗は、パーサーをより寛容にし、XMLが不完全でも編集イベントを抽出できるようにアルゴリズムを強化することで対処しました。
    • インデントや空白文字の不整合: コードのインデントレベルがずれるという問題も頻繁に発生しました。
      • 解決策: バッファ内の既存のインデントと、LLMが生成したテキストのインデントを検出・比較し、その差分(インデントデルタ)を計算するアルゴリズムを導入しました。これにより、インデントのズレを自動的に補正し、整合性を保つことができるようになりました。この解決策は、決定論的なテストで堅牢に検証されました。
    • エスケープ文字の問題: LLMは、XMLタグ内に含まれる引用符や改行文字などの特殊文字を、意図しない方法でエスケープすることがありました。
      • 解決策: プロンプトに「タグ内の引用符、改行、その他の文字をエスケープしない」という具体的な指示を追加することで、この問題を解決しました。

これらの事例は、LLMの非決定性や不完全な振る舞いに直面した際、単にプロンプトを調整するだけでなく、根本的なアルゴリズム的解決策と、それを検証するための堅牢な決定論的テストが不可欠であることを示しています。


AI時代のテストモデルの評価と今後の方向性

Sobo氏のプレゼンテーションでは、Zedが様々なLLMモデル(Gemini-1.5 Pro、Claude-3 Opus、GPT-4.1など)と連携してコード編集を行う際のパフォーマンス比較も示されました。特に、AnthropicのClaude 4モデルのような最新技術により、Rustのような言語で「アジェンティック(自律的)」なコードを非常に効率的に記述できるようになったとSobo氏は語り、その成果に喜びを表明しました。これは、AIモデルの進化が、開発者の生産性を飛躍的に向上させる可能性を示唆しています。

Zedの経験から得られた教訓は、AI時代におけるソフトウェア開発の信頼性確保に不可欠な指針となります。

  1. 厳格な自動テストは、信頼性の高いソフトウェアの構築に不可欠である。 これはAI時代でも変わりません。
  2. 言語モデルは、経験的かつ統計的なアプローチを必要とする。 非決定的な振る舞いを理解し、確率的な評価を導入することが重要です。
  3. 有用なAI対応ソフトウェアは、確率的コンポーネントと決定論的コンポーネントの相互作用で成り立っている。 両者のバランスと連携が成功の鍵です。
  4. 信頼性の高いAI対応ソフトウェアは、複数のレイヤーからなるテスト戦略を必要とする。
    • 確率的回帰テスト(Eval): LLM全体の振る舞いを確率的に評価し、大きな後退がないかを確認します。
    • 確率的ユニットテスト: 特定の非決定的な挙動を持つコンポーネント(例:ストリーミングデータ処理)を、ランダムな入力で広範にテストします。
    • 決定論的ユニットテスト: 特定のアルゴリズム的解決策やエッジケースを、予測可能な入力で厳密にテストします。

Sobo氏が強調するように、これらのアプローチは、特別な外部ツールやEvalフレームワークに依存するものではなく、既存のテストスイート内で、従来のソフトウェアテストで培われたスキルを多く活用しています。LLMがもたらす「非決定性」は新たな挑戦である一方で、それを克服するための知恵と工夫は、ソフトウェアエンジニアリングの根源的な部分にこそ宿っているのです。


まとめと将来性

Zedの取り組みは、AIが組み込まれた次世代のソフトウェア開発がどのような姿になるのか、その一端を垣間見せてくれます。LLMの持つ予測不可能性という課題に対し、彼らはプロンプトエンジニアリング、アルゴリズム的解決策、そして多層的なテスト戦略を組み合わせることで、信頼性と生産性を両立させる道筋を示しました。

このようなアプローチは、AIモデルを活用するあらゆるソフトウェア開発プロジェクトにとって、貴重な洞察となるでしょう。AIの力を最大限に引き出しつつ、システムの安定性と予測可能性を確保すること。これは、AIが社会インフラやビジネスの中核に深く食い込む中で、ますます重要になるテーマです。

Zedはオープンソースプロジェクト(GPLライセンス)として公開されており、Sobo氏自身もコミュニティからの貢献を歓迎しています。AIとソフトウェアエンジニアリングの最前線で、このエキサイティングな挑戦に参加する機会は、誰にでも開かれているのです。Zedの進化は、AI時代のソフトウェア開発における新たな標準を確立し、開発者の創造性と生産性の限界を押し広げていくことでしょう。