はじめに
こんにちは。トライベック株式会社の鈴木です。
先日React NativeアプリをFlutterに移行する際に、初めてサブエージェントを使ってみました。結果はサブエージェントなしの方が精度が高かったという、なかなか苦い体験だったので備忘録として残しておきます。
やったこと
以下の4つのサブエージェントを作って実行しました。
① 調査エージェント:既存のReact Nativeアプリのソースコードを読み込み、仕様・設計を把握する
② テスト作成エージェント:①の情報をもとにFlutter用のテストコードを書く
③ 実装エージェント:①の情報をもとに、②のテストが通るまでFlutterで実装する
④ レビューエージェント:②③の成果物に対してコードレビューを行う
この手順で生成されたFlutterアプリを確認したところ、画面に必要なUI要素が欠けていたり、ビジネスロジックがほとんど反映されていない状態でした。
何が問題だったか
エージェント間のやり取りで情報が欠落してしまう
最初に疑ったのは「エージェント間の情報の受け渡し時に情報の粒度が落ち、③で実装できなかったのでは」ということでした。
実際、サブエージェントを使わずにうまくいったときは、AIにReact Nativeのソースコードを全て見せた状態で以下のように進めていました。
- まず全画面の移行計画をAIに立ててもらう
- 関連するReact Nativeのソースファイルをそのまま渡す
- 移行作業開始
実装時には元のソースコードが常にコンテキストにある状態なので、細かい挙動やエッジケースも見落としにくいです。
サブエージェントを用いた方法との違いはこの部分で、AIが一次情報に直接アクセスできるかどうかでした。
これはマルチエージェントのアンチパターンだった
調べてみると、この現象はマルチエージェント特有のよくある失敗パターンらしいです。
以下の記事によれば、現在のマルチエージェント・アーキテクチャは意思決定が分散しすぎて、エージェント間でコンテキストを十分に共有できないため、非常に脆弱なシステムになりやすいそうです。
つまり、実装エージェント(③)は元のReact Nativeコードに直接アクセスできない状態で、Flutterのコードを書かされていました。
この構造だと、③がテストを通らないとき、「なぜ通らないか」を元のReact Nativeコードに立ち返って確認することができません。
エラーの原因が上流にあってもエージェントがそのことに気づけない構造でした。
そもそもこのタスクはサブエージェント向きじゃない
サブエージェントが効果を発揮するのは「独立して並列実行できる」タスクのときです。
今回の設計は各ステップが強く依存していて、かつ元ソースコードという「全エージェントが参照すべき大きなコンテキスト」がありました。こういうケースは1つのエージェントが全コンテキストを持ち続けるほうが素直に強いようです。
サブエージェントの真価は「関係ない情報の混入を防ぐこと」であって、コンテキスト分離自体を目的にしてはいけないということを学びました。