🔖

LLMフローエンジニアリングの速度向上戦略

2024/08/09に公開

こんにちはPharmaXの上野(@ueeeeniki)です。

これまでLLMのフローエンジニアリングに関するシェアを何度か行ってきました。

https://zenn.dev/pharmax/articles/a6e6d4d167a4a4
https://zenn.dev/pharmax/articles/13a22c764f2df3

https://speakerdeck.com/pharma_x_tech/flow-engineering-in-multi-agent-llm-chat-application-03dd5337-87fd-4fa1-b4de-96cf9f50e001

LLMアプリケーションを作るうえで、フローエンジニアリングという概念は非常に有用であるにも関わらず、まだあまり認知を得られていないようなので、今後もしつこく扱っていきたいと思います 笑

そこで今回は、フローエンジニアリングの最大の課題である処理速度が遅くなってしまう問題の解決策を深堀りしてみたいと思います。

フローエンジニアリングとはなにか

フローエンジニアリングとは、あるタスクを1つのLLMエージェントですべて解かせるのではなく、そのタスクを細分化して、エージェントやアプリケーションの実装を組み合わせてどう解いていくかをデザインすることを指します。

私の理解では、タスクの分岐によっては、LLMに解かせるのを諦めて人が解くパターンが含まれるものもフローエンジニアリングと呼びます。
例えば、カウンセリングAIを作ろうとしているとしたら、普段はLLMエージェントが対応しつつ、自殺願望を仄めかすような発言をした場合には、人間が対応するモードに切り替わるというようなイメージです。

このようにエージェントの組み合わせ全体デザインし、目的とする処理系を作り上げることをフローエンジニアリングと呼びます。

例えば、社内のバックオフィス系の質問に答えるチャットボットを作成することを考えると、1つのプロンプトに分類とメッセージ作成をタスクをぶち込むアーキテクチャを図示すると下記のようになります。


1エージェントにすべてのタスクを任せる例

一方、下記のように質問内容を分岐して、その分岐結果に応じて次の質問回答をするプロンプトを呼び分けるアーキテクチャを取ることもできます。

タスクごとにエージェントを分けてフローエンジニアリングする例。この例では4エージェントある。

これがフローエンジニアリングの例です。

PharmaXでは、フローエンジニアリングという言葉が注目される前から、実質的にフローエンジニアリングを行っていましたが、
アプリケーションの実装コストが高いので、なかなか一般には受け入れられないだろうなと思っていました。

ですが、最近は、DifyやBedrock Studioのようなほぼノーコードなツールや、PromptFlowのようなローコードツールも人気を博し、徐々にフローエンジニアリングを実現しやすくなってきた印象です。

フローエンジニアリングのメリット

フローエンジニアリングの基本思想は、小さなエージェントを組み合わせることだと紹介しました。

単一の目的を上手くこなす小さなエージェントを組み合わせることで、処理系全体で精度を向上させることができることが一番重要なメリットです。

また、エージェントのタスクを単一にすることでプロンプトの肥大を避け、保守性を向上させることもできます。
下記の記事でもエージェント設計の基本原則として「エージェントがこなすタスクはできる限り小さく単一にする」を挙げています。

https://zenn.dev/pharmax/articles/ae19bafbcfeb23#エージェントがこなすタスクはできる限り小さく単一にする

詳しくはこちらの記事も合わせてお読みただければと思います。

フローエンジニアリングの課題

一方で、フローエンジニアリングにも下記のような課題はあります。

  • 実装コストが高い
  • 処理のトレーシング難易度が高い
  • 処理に時間がかかってしまう
  • プロンプトの数が増えて管理コストが増大する

詳しくは、『YOJOのLLMフローエンジニアリング・アーキテクチャを解説します』という記事をご覧ください。

今回は、この課題の中でも処理時間がかかってしまう問題の解決策を深堀りたいと思います。

フローエンジニアリングの速度向上戦略

フローエンジニアリングでは、最終的な出力までに複数の処理が行われるため、処理系全体のレスポンス速度は遅くなってしまう傾向にあります。

これを解決するためには、処理を投機的に並列実行することが重要になります。

上記でも紹介した、社内のバックオフィス系の質問に答えるチャットボットを作成することを考えましょう。


タスクごとにエージェントを分けてフローエンジニアリングする例。この例では4エージェントある。

上記の説明時には省略していましたが、今回はリアルタイムでの評価も入れてみました。
いわゆるLLM-as-a-Judgeで、リアルタイムで質問への回答を評価する想定です。

質問への回答を評価し、評価のスコアが特定の値を下回った場合は、作成された回答を修正して、再度LLMに回答させ直すような運用を想定しています。

LLM-as-a-Judgeをリアルタイムで行う運用については下記をご覧ください。
https://zenn.dev/pharmax/articles/5ba7897613bae3

この処理を単純に直列で実行しようとすると、下記のようになります。


すべての処理を直列で実行するパターン

ここから処理時間を短くするために、評価を並列で実行する事を考えます。

評価を並列で実行するパターン

このパターンでは、無駄なく並列に実行することで処理時間を短くできていることが見て取れるでしょう。

もっと攻めた方法が投機的に並列実行するパターンです。


一部の処理結果を捨てる前提で並列実行するパターン

このパターンでは、質問の分類と3つの回答生成を同時に開始します。
この例では、質問分類で該当しなかった労務用の質問回答と総務用の質問回答は、作成したものの、必要がないので捨ててしまいます。

つまり、最初から作成した回答を1つ以外は捨てる前提で、フライングして回答を作り始めるということです。
それが"投機的に"という言葉の意味です。
質問分類の結果を待ってから回答生成を行わないので、その分処理の終了が早くなります。

もちろん、捨てられる回答がある分、余分にコストは掛かってしまうのがデメリットです。

このような工夫を行うことで、上から下に行くにつれて処理速度が劇的に短くなっていっているのが見て取れるでしょう。

フローエンジニアリングのコスト削減戦略

速度向上のために投機的に処理をすると、余分なコストが掛かってしまいます。
そのため、いかにコストを下げるのか?ということを考える必要も出てくるかもしれません。

そこで、一部の処理を機械学習モデル化あるいはfine-tuningすることを考えてみてもいいでしょう。

一部の処理は、データさえあれば、LLMである必要はなく、機械学習モデルで行うことは可能です。
例えば、質問分類はクラスタリングに過ぎないので、本来は機械学習で解ける問題です。
そして、一般的には、LLMを使わずにシンプルなの機械学習を使う方が、安く速くなるはずです。

LLMを使うにしても、GPT-4o-miniのようなある程度の賢く安価なモデルをfine-tuningするという手段も考えられます。

ただし、プロダクトの開発初期では、多くの処理に高性能なLLMを使う理由は十分にあると考えています。
LLMは、データがなくとも、プロンプトを調整するだけで速くPDCAを回すことができ、それでいてあらゆるタスクに対して、ある程度の精度を担保することができるからです。
言うなれば、データがなくても、ルールさえきちんと言語化できれば、人間の評価者と同じような判断をできることがLLMの強みです。

一方で、機械学習モデル化あるいはfine-tuningしようとすると、データセットの準備やモデルのチューニングなどに時間がかかってしまいます。
これが、機械学習におけるコールドスタート問題と呼ばれる問題です。

ある程度プロダクトが安定して、それなりの成果が見えてくれば、一部の処理から機械学習モデル化あるいはfine-tuningすることを検討してみるもの良いでしょう。

UXでの回避策

上記のような方法でかなり処理時間を短くすることは可能です。

ただし、ユーザーが出力を待っているような、文字通りのリアルタイム性を求められるようなサービスなら、1秒から数秒以内にレスポンスを返さなければ、使い物になりません。

どうしても複雑なフローが必要な場合、1秒などの短い時間で返すのはどう工夫しても難しくなってしまうかもしれません。

そのような場合は、発想を変えて、フローエンジニアリングの処理速度を向上させるという手段だけではなく、UXで処理時間を稼ぐことを考えてみると良いかもしれません。

出力の時間を稼ぐためにいわゆるフィラーのようなテクニックを駆使するという方法もあります。
「うーん」や「ええっと」、「なるほど」みたいなやつです。
あるいは、とりあえず相手が言ったことをオウム返しすることで時間を稼ぐという方法もあるかもしれません。
「〇〇にお悩みなのですね。」「〇〇ということ、大変お辛いですね。」のようなイメージですね。

このように、フローエンジニアリングを行っていくうえでは、UXも含めた総合格闘技的な闘いが求めらます。

まとめ

今回は、フローエンジニアリングの発展編として、フローエンジニアリングの速度向上の方法について考察しました。

これからはLLMのアプリケーションのPoCの段階が終わり、実際の開発・運用が本格化していくかと思います。
その際、フローエンジニアリングはかなり有効な手段になりますが、一方で、スピードの課題にはすぐにぶち当たるかと思います。
そこで今回は、フローエンジニアリングの速度向上施策を取り上げたという次第です。

PharmaXでは、ソフトウェアの実装力と設計力を武器に最高のUXを実現するLLMアプリケーションを一緒に作ってくれるエンジニアを募集しています。

もし少しでも気になった方がいらっしゃれば、是非カジュアルにお話できれば嬉しいです。

https://x.com/ueeeeniki

PharmaXテックブログ

Discussion