世界を動かす技術を、日本語で。

エージェントにはプロンプトを増やすのではなく、制御フローが必要です

概要

  • 信頼性の高いエージェント には 決定論的な制御フロー が必要
  • プロンプトチェーン は複雑なタスクでは限界
  • ソフトウェア的な構成 で予測可能性と検証性を確保
  • LLMは部品 として扱い、全体のシステムではない
  • エラー検出と検証 の仕組みが不可欠

複雑なタスクにおける信頼性と制御フロー

  • 複雑なタスク を扱うエージェントには 決定論的な制御フロー の実装が必要
  • プロンプトチェーン (MANDATORYやDO NOT SKIPなど)では 信頼性の限界 に直面
  • プログラミング言語で命令が「提案」にすぎず、関数が「Success」と返しつつ 幻覚応答 する世界の想像
  • 推論の困難化信頼性の崩壊、タスクが複雑になるほど顕著

ソフトウェアのスケーラビリティとプロンプトの限界

  • ソフトウェア再帰的な合成 (ライブラリ・モジュール・関数から構築)によって拡張
  • コード は予測可能な振る舞いを持ち、 局所的な推論 が可能
  • プロンプトチェーン はこの性質がなく、狭い用途では有用だが
    • 非決定論的
    • 仕様が曖昧
    • 検証が困難

信頼性向上のためのアプローチ

  • 信頼性向上 には 論理をプロンプトからランタイムへ 移す必要
  • 決定論的な足場 (明示的な状態遷移・バリデーションチェックポイント)の設計
  • LLMはシステムの一部品 として利用し、全体の制御はコードで管理

エラー検出と検証の重要性

  • 決定論的なオーケストレーション だけでは不十分
  • サイレントエラー が発生しやすい環境で、積極的な エラー検出 が不可欠
  • プログラムによる検証 がなければ、選択肢は3つのみ
    • ベビーシッター:人間が逐次監督し、エラーを事前に発見
    • 監査人:実行後にエンドツーエンドで徹底的な検証
    • 祈り:出力をそのまま受け入れる「祈る」運用

結論

  • 本質的な信頼性決定論的なソフトウェア設計プログラム的検証 によってのみ実現
  • LLMの活用 は「部品」としての位置づけが最適解

Hackerたちの意見

その気持ちはわかるけど、結論はちょっと変えるべきだと思う。プロンプトの限界に達したら、タスクを達成するためにLLMを使うのから、LLMを使ってソフトウェアを書く方向に移る必要があるよ。実行時のLLMの役割は、厳格なビジネスルールを具現化したソフトウェアシステムに対して、ユーザーが適切な入力を選ぶ手助けをすることに縮小されると思う。

このフォーラムでは、将来のソフトウェアは、genAIを使って実行時に作成・適応されるプログラムにあるという意見が出ているね。どれくらいその状態から遠いのかはわからないけど。

最近、仕事が少し暇だったから、エージェントを作業プロセスに取り入れることにしたんだ。メモ取り、タスク追跡、ドキュメント管理みたいなやつね。君のコメントは、まさに私の経験そのものだよ。1週目はどんどんプロンプトが広がって、パフォーマンスが落ちていった。2週目は、実際にオブジェクト(メモ、タスク、プロジェクト、人など)を正確に定義して、それに対して明確に定義された操作を行う方法を定義することに集中している。エージェントの表面は、君が指摘した通り、自然言語をコマンドや引数に変換する翻訳レイヤーに縮小された。

フルサークルのシステムプロンプトは、「自分の仕事を自動化して、できるだけ早く手放すチャンスを見つけること。コードで答えられる質問が来たら、その質問にコードを書いて実行して結果を得ること。」って感じかな。そんなLLMなら、いちごテストでももっと良い結果が出たかもね。

モデルが特定の問題解決モードにハマってしまって、新しいモードに移るためのちょっとした後押しが必要なケースを見たことがある。例えば、オーディオストリームのホットプラグ/アンプラグを処理するために、システムサービスの設定をいじるのではなく、実際には数十行のPythonを書くだけで済むことが必要だった。Claudeに、私のワークフローで効率的に解決できない一般的なケース(テストを実行するなど)を処理するためのシェルスクリプトをいくつか書かせたら、今では無駄に30分もぐるぐる回ることなく、そのツールを実行して設定するようになった。毎回、何かをするために一回限りのクレイジーなシェルやPythonのワンライナーを実行できるか聞いてくるたびに、代わりに自動承認できるツールを書かせるべきか考えるようになったよ。

だから、私は「次世代AI」と呼ぶことが多いんだ。単なるLLMじゃないやつね。LLMはかなりクールだし、今後も基盤となる進展がなくても、もっと面白い使い方がされて、最適化されていくと思う。今のモデルがそのまま凍結しても、まだまだ価値を引き出せる方法があるはず。でも、いくつかは次世代の基盤的な改善が必要だと思う。LLMが「絶対にXをするな」をぼやかしてしまうのは、彼らの仕組みの根本的な部分に関わっている気がする。私たちが彼らの可能性を探っている初期段階だからこそ、見失いやすいけど、LLMはAIに求めているすべてではないと思う。「絶対にXをするな」を人間のように扱えるようなアーキテクチャが必要だよね。「コンテキストウィンドウ」の代わりに、私たちのようなメモリ階層を持つアーキテクチャが必要だと思う。もし二人が最初は同じAIと十分に長い会話をしたら、結果として二つのAIはコンテキストウィンドウだけでなく、実際に二つの個体になってしまう。もちろん、これがどうなるかは私も他の誰もわからないけど、LLMがAIの最後の答えだとは思わない。

これ面白いよ! https://www.youtube.com/watch?v=kYkIdXwW2AE&t=315s

問題の一部は、そもそもLLMの誤用にあるんじゃないかな。どこかで言われていたけど、エージェントのプロンプトは、できるだけ繰り返し可能で検証可能、決定論的な方法でタスクを達成するためのコードを書くことにすべきだと思う。これにはエージェントの出力の検証も含まれるといいね。全体の目標は、LLMがプログラム的にもっと効率的(かつ正確に)処理できることを避けることだと思う。

そうだね、エージェントについての標準的な考え方は逆で、コストがかかりそう。LLMを使ってスクリプトを書いて、それを自分のループハーネスに入れて、最後に決定論的な検証が難しい部分はLLMに呼び出すって感じかな。

問題は、プログラムが解釈を必要とするエッジケースに遭遇することが多いってことだね。その時、LLMにそのエッジケースを処理させたくなる。そうすると、全体のループをLLMに任せて、ツールコールもやらせたくなるんだ。

100%同意。90%の確率で正しい非決定論的なものを使って、100%の確率で正しい決定論的なものを生成するっていうのがいいよね。プロンプトに追加する重要なことの一つは、「- あいまいなエッジケースに遭遇したら相談してね」ってこと。AIを直接APIコールで動かすのは良くないと思う。アプリがAIを使うべき唯一のケースは、読んだり分類したりする時だけだね。要するに、古いCRUDアプリの「R」を置き換える感じ。もしその新しいAIベースの「R」エンドポイントを使って、「C」、「U」、「D」を自動で埋めるのはいいけど、人間がレビューする前に顧客のために何かを変更するべきじゃない。基本的にCRUDアプリはCRUDアプリのままだし(これは永遠に変わらない)、ただ非常に賢い「R」エンドポイントがあって、顧客のためにフォームを自動で埋めたり(内部ツールやJenkinsパイプラインなど)、アクションを提案したり(でも実行はしない)するって感じ。

ほとんどの組織では、流れがこうなってると思う:LLM -> プロンプト -> 結果 LLM -> プロンプト + スキルとしてエンコードされたプロンプト -> 結果 LLM -> プロンプト + スキルとしてエンコードされた決定論的コード -> 結果 早い段階でコードを生成するためにプロンプトを使うことで、その決定論的コードへの道をショートカットできると思うけど、基本的には非決定論的なラッパーの中に決定論的なコードを埋め込んでる感じだね。多くの場合、長期的なタスクを成功させるために必要な決定論的な層が欠けてる。エージェントループやフレームワークを通じて、非決定論的な境界の外に決定論的なコードが必要だよ。これによって、非決定論的な意思決定が決定論的な層の間に挟まれることになる:決定論的なエージェントフロー -> 非決定論的な意思決定 -> 決定論的なツール。これは私の実験で非常に強力なパターンで、エージェントがauto-researcherのようなツールを使って自分の決定論を構築することで、さらに強力になる。

Hacker Newsで議論の続きを見る