Large Language Model (大規模言語モデル、LLM)チャットボットにより革新的なソリューションへの扉が開かれる中で、SpotifyのエンジニアであるAtes Goral氏は、ユーザーエクスペリエンスを可能な限り自然なものにするために、レンダリングジャンクを防ぎ、待ち時間を減らすための具体的な取り組みが必要であると主張している。
LLMによって返されたMarkdownのレスポンスをストリーミングすると、*
のようなMarkdownの特殊文字は、完全な表現を受け取るまで、例えば終了する*
を受け取るまで曖昧なままであるため、レンダリングジャンクにつながる。同じ問題は、リンクや他のすべてのMarkdown演算子にも当てはまる。これは、Markdown式が完全になるまで正しくレンダリングされないことを示唆している。つまり、Markdownレンダリングが短期間の間、正しく行われないことになるのだ。
一方、遅延は、LLMのこの問題を解決するために、SpotifyはMarkdownの特殊文字の後の文字を一切出さず、完全なMarkdown表現が完了するか、予期せぬ文字を受信するまで待機するバッファリングパーサーを使用している。
ストリーミング中にこの処理をするには、文字を1文字ずつ消費できるステートフルなストリーム・プロセッサを使用する必要がある。ストリーム・プロセッサは、入ってきた文字を通過させるか、Markdownのような文字シーケンスに遭遇したときにバッファを更新する。
このソリューションは、原理的には手作業で比較的簡単に実装できるが、Markdownの完全な仕様をサポートするには、市販のパーサーを使う必要がある、とGoral氏は言う。
一方、遅延は、LLMの初期応答を拡張するための外部データソースを利用する目的で、LLMを何度もラウンドトリップする必要があることに起因する。
LLMは一般的な人間の言語や文化についてはよく理解しているが、最新で正確な情報源にはならない。そこで私たちは、LLMが把握しきれない情報を必要とするときは、ツールを使ってLLMに伝えるようにしている。
つまり、LLMが提供する初期応答には、不足している情報を得るために、ユーザーの入力に基づいて、どの他のサービスを参照すべきかも含まれる。それらの追加データを受信すると、LLMは完全な応答を作成し、最終的にユーザーに表示する。
Sidekickは、すべての外部サービスが応答するまでユーザーを待たせないように、プレースホルダーである"カード"の概念を使用している。Sidekickは、プレースホルダーを含め、LLMから受け取った初期応答をレンダリングする。追加リクエストが完了すると、Sidekickはプレースホルダーを受信した情報に置き換える。
Sidekickに実装されたソリューションは、このワークフローに内在する非同期性を完全に利用し、レスポンスのデマルチプレクス(逆多重化)のシステムをMarkdownバッファリングパーサーと統合している。Goral氏らによるソリューションの詳しい全容に興味がある方は、同氏のオリジナル記事をお見逃しなく。