AI・機械学習
LangGraphのゴッドノードのリファクタリングにおけるFableと他の10のLLMの比較
Comparing Fable and 10 other LLMs on refactoring a LangGraph god node (wtf.korridzy.com)
要約
この記事では、LangGraphエージェントの複雑な「ゴッドノード」をリファクタリングするタスクにおいて、Fableを含む11のLLMのコード再編成能力を比較評価しています。各LLMに提案を生成させ、互いに評価させ、さらに複数のアプローチで信頼性を検証することで、どのモデルがコード生成や評価に優れているかを分析しています。
全文翻訳
神々の黄昏。
コード再編成タスクにおけるFableとその他のLLM10種の比較。
比較
他の言語
この論文はロシア語でも利用可能です: 神々の黄昏。
資料と生データ
11モデルすべての提案、クロスレビュー、論文実行、ランキングスクリプトはここで公開されています: 資料と実験の再現。
これは、1つの実験の詳細なレポートです。
私は実際のLangGraphエージェントからゴッドノードを取り出し、まず5つのアメリカのモデルと6つの中国のモデルに、それを解きほぐす方法を提案させ、次に互いの提案を評価させました。その後、どのモデルを信頼できるかを判断するために3つの異なる方法を試しました。
目次
オリジナルの問題
ゴッドノードとは何か、なぜ危険なのか
プランノードが実際に行ったこと
レモンからレモネードを
なぜこれらすべてを行い、実験がどのように設定されたのか
ステージ1。モデルが提案を生成する
提案テーブル
各提案についてもう少し詳しく
ステージ2。モデルが提案を評価する
レビューテーブル
各レビューについてもう少し詳しく
ステージ3。濡れた水着コンテスト
何が得意か、誰が優れているかを決定する
アプローチ1。スコアは一致するか?
最適な提案を選択する
アプローチ2。論文によるレビューの比較
最適なアナリストを選択する
アプローチ3。意見の中心とメドイド
最適なアナリストを再度選択する
デウス・エクス・マキナ。最適なアナリストをもう一度選択する
テイクアウェイ
ジェネレーターとしてどのモデルを使用するか、エバリュエーターとしてどのモデルを使用するか、そしてどこに心の安らぎを見つけるか。
オリジナルの問題
ご存知の通り、Data Sanityのコースで仲間たちと練習用AIエージェントを構築していると、急速に機能が追加されていく中で、プロジェクトの内部エージェントの1つが次のような状態グラフ(LangGraph)を持っていることに突然気づきます。
flowchart TD
planner_start([START]) --> plan[plan]
plan -->|search| search[search]
plan -->|ask_user| ask_user[ask_user / interrupt]
plan -->|reflect| reflect[reflect]
plan -->|calculate| calculate[calculate]
plan -->|finish| finish[finish]
search -->|last_observation| observe[observe]
search -->|no hits / backend failure| plan
observe --> plan
calculate --> plan
ask_user --> observe_user[observe_user]
observe_user --> plan
reflect --> plan
finish --> planner_end([END])
一見すると、これはかわいい小さなタコですが、心配することはありません。しかし、このタコがその控えめな8本の足の頭の中にどれだけのロジックを保持しなければならないかを知ると、これがアンチパターンであることがすぐに明らかになります。この場合、それをゴッドノードと呼びましょう。
プランノードには、反復チェック、地域と通貨に関するブートストラップ質問、スキーマ準備、取得タスクルーティング、LLM呼び出し、その後の決定の修正など、約350行のロジックが隠されています。問題は、関数のサイズだけではありません。重要なオーケストレーションが単一のノード内に隠されていると、グラフはシステムの表現ではなくなります。説明が難しく、デバッグが難しく、テストが難しく、変更が危険になります。したがって、明白なタスクは単に「大きな関数をいくつかの部分に切り刻む」ことではなく、隠された制御ロジックをグラフレベルに引き上げることです。これにより、結果として得られるアーキテクチャがより明確になり、さらなる開発に適したものになります。
プランノードが実際に行ったこと
このグラフが記述することを意図していたエージェントは、広義には、さまざまなパラメータを収集して下流の計算に使用するビジネスを行っていました。これらのパラメータの一部はインターネットで巧妙に検索し、一部はユーザーに尋ねました。そして、それは完全には決定論的でないアルゴリズムによってこれらすべてを行いました。なぜなら、特定の会話のコンテキストに応じて、同じパラメータを取得するための正しい方法は大きく異なる可能性があるからです。以下は、プランノードに詰め込まれた実際の関数のセットです。
責任
プラン内に隠されていたロジック
反復ループ
反復回数を増やし、新しい計画ステップに入り、ステータス== "中止"と最大反復回数を確認する
地域ブートストラップ質問
_needs_region_question()チェックと、core.regionのためのask_userへの強制遷移
通貨ブートストラップ質問
_needs_currency_question()チェックと、core.currencyのためのask_userへの強制遷移
プロアクティブ分解
フィールドをコンポーネントに分解する必要があるための動的分解の生成
取得レシピのアセンブル
build_dynamic_recipes()を呼び出し、後続のフィールド収集のためのタスク構造を準備する
スキーマ準備
compose_ready_fields()を呼び出し、準備されたコンポーネントフィールドをアグリゲートにマージし、スキーマを更新する
計算機制限
計算機試行回数の上限、成功した計算または既に現在の計算、およびその他の停止条件を確認する
ブロックされた計算後の回復
ブロックされた計算機シナリオを処理し、次のデータ収集タスクを見つけ、必要に応じて問題フィールドのフォールバック分解を行う
一般的なデータ収集ルーティング
LLMなしで次のデータ収集タスクを選択する。既に開いているタスクとコンポーネントタスクの高速パスを含む
自動終了ロジック
すべてのソースデータが収集されたかどうか、アクションが必要なフィールドが残っているかどうか、および追加の手順なしでループを終了できるかどうかを確認する
LLM計画
プロンプトコンテキストを収集し、_llm().structured(...)を呼び出し、PlannerDecisionを取得する
LLM後の分解
モデルが選択したフィールドが分解される必要がある場合、追加の分解を生成する
決定のリダイレクトと正規化
派生フィールドの決定をリダイレクトし、検索経由でより良く見つかるフィールドのためにask_user -> searchを強制し、LLM後のその他の決定論的な書き換え
フィールドごとのリトライと制限
繰り返し検索、検索とask_userの制限を検出し、制限が尽きた後にask_user、reflect、またはfinishに切り替える
計算決定の修正
早期終了の修正:計算がまだ完了していない場合、決定はcalculateに書き換えられるか、追加の再評価ステップにルーティングされる
ブックキーピング状態管理
ノードからの戻り時に伴う、決定、決定元、llm_failed、ステータス、およびその他の一時的なフラグのリセットまたは更新
ログ記録とイベントディスパッチ
最終決定のログ記録、進捗イベントの発行、および戻る前に最終状態更新をアセンブルする
レモンからレモネードを
ですから、私たちは今日多くの人がよく認識する状況にいます。クロード氏がスパゲッティから傑作を彫り上げてくれました。レビューなしで次々と機能を追加するよりも、そのスパゲッティをほぐすのははるかに楽しくありません。しかし、それは、それを増大させたのと同じツールでエントロピーを減らすことができると気づくまでだけです。そして、それははるかに心地よい見通しです。
しかし、コードの解きほぐしを、機会があれば喜んで絡ませてしまうモデルそのものに任せることができますか?それに答えるために、私は異なるモデルからいくつかの独立したアーキテクチャ提案を収集し、それらを比較することにしました。
審査のために11のモデルがランウェイに招待されました。
GPT-5.4
GPT-5.5
DeepSeek-4-pro
Gemini-3.1-pro
GLM-5.1
Kimi-2.6
MiMo-2.5-pro
Opus-4.7
Qwen-3.6-plus
Qwen-3.7-max
Fable-5
まず、それぞれがプランを分割するための独自の提案を行いました。次に、モデルはエバリュエーターモードに切り替わり、完成したすべての提案を読み、それらをランク付けしました。
1つの幸運なテキストの繰り返しではなく、独立した意見を収集していることを確認するために、次の条件が強制されました。
提案が生成されている間、モデルはお互いの仕事を見ることができませんでした。
分析が生成されている間、モデルはすべての提案を見ましたが、他の分析は一切見ませんでした。
各実行は新しいセッションで行われました。
すべての作業は、OpenCodeでOh My Openagentプラグインを使用して、各モデルで最大の推論努力で行われました。
ステージ1。モデルが提案を生成する
最初のステージでは、各モデルはプランノードのロジックをグラフレベルに引き上げるための独自の方法を提案しました。
各提案を生成するために使用されたプロンプト(出力ファイル名のみが変更されました):
docs/planner-graph-ref/current-graph.mdを見てください。「plan」ノードにロジックが多すぎるようです。提案をしてください。