Agent Scirptでtopic遷移ができて何が嬉しいのか

こんにちは。エンジニアの和田です。

AgentforceのAgent Scriptでは様々な機能が追加されましたが、その機能の一つに「topicの遷移」があります。

従来のAgentforceでは、ユーザーから入力がある毎に、1つのtopicしか適用させることができませんでした。これが、状況によって途中で他のtopicへ遷移させることができるようになったのです。

すごそうに見える機能に思えますが、「実際のところ、途中で他のtopicへ遷移させることがあるのだろうか?」という疑問が出てきそうです。

この「topic遷移」機能は、ユーザーと何回かやり取りしていく中でtopicが変わっていく動きとは少し違います。従来のAgentforceでも、以下のような動きはできました。

  • ユーザー: 「〇〇の詳細について教えて」
  • agent: topic 「調査」を選択(→必要に応じてactionを呼んで、応答)
  • ユーザー: 「では、△△を登録して」
  • agent: topic 「登録」を選択(→必要に応じてactionを呼んで、応答)

つまり、ユーザーからメッセージが送られるたびにtopicを切り替える、ということは以前から可能だったわけです。

今回の機能はそうではなく、ユーザーが1回メッセージを送った後、agentが応答するまでの間に複数のtopicを遷移することが可能になる、というものです。

しかし、上の例を見ると、ユーザーが「詳細を教えて」と「登録して」を1つのメッセージの中で両方送るといったかなり特殊なケースでないと役に立たないように見えますね。

Agent Scriptでは、最初にTopic Selectorと呼ばれる特殊なtopic(start_agentが付与されたtopic)が選ばれ、ユーザーの入力内容に応じて各topicを選択します。このときにtopic遷移機能を使うので、その意味では(Topic Selectorに指示を書けるため)topic選択の指示文をカスタマイズしやすくなったという側面はあります。

しかし、topic遷移の恩恵はそれだけでしょうか? ここからは、別の視点から見たtopic遷移の嬉しさについてみていきたいと思います。

topic遷移の嬉しさ

その1: LLMに1回で送信するコンテキストを減らせる

例えば、冒頭の例で「〇〇の詳細について教えて」とユーザーが入力した場合、agentがきちんとした対応を行えるようにしようと思うと、agentが取り組む内容として以下のようなステップを設定することが考えられます。

  • ユーザーの入力に曖昧な点があれば、適宜聞き返す(「どの観点で知りたいですか?」など)
  • 曖昧な点がなければ、actionを実行して調査する。
  • 調査結果を踏まえて、それがユーザーの質問に本当に答えていることになるのか吟味し、必要があればユーザーに聞き返し、必要なければ回答する。

従来のAgentforceでは、これらをtopic「調査」の中で全てこなさなければならず、以上の指示を全て同じtopicに含める必要がありました。

しかし、Agent Scriptでは、例えば以下のようにtopicを分割し、それらを遷移させることが可能です。

  • ユーザーの入力を吟味するtopic
  • 聞き返すtopic
  • actionを実行するtopic
  • actionの回答を吟味するtopic
  • 回答するtopic

LLMへのプロンプト送信はtopic毎に行われます。したがって、topicを分割し、必要に応じて遷移させることで、1回にLLMに送信されるプロンプトを短くすることができます。すなわち、1回あたりのコンテキストが減るため、性能の向上が期待できます。特に、従来のAgentforceでは1つのtopicに指示がたくさん入りがちで、性能が落ちる原因の一つにもなっていました。必要な指示を必要な時だけLLMに送るようにすることで、性能低下を防止する効果が期待できるのです。

topicを分割すると、一つ一つのtopicに対してより細かな指示を書きやすくなります。たとえば、「ユーザーの入力を吟味するtopic」として切り出せば、どのような観点で吟味するのかを指定しやすくなります。topic遷移機能がないと、「調査」という一つのtopicに他の役割も含めて記述する必要があるため、性能を考慮すると、入力吟味の指示文は最小限にせざるを得ません。その意味でも、topic遷移機能によるtopic分割は、性能向上に寄与すると言えます。

その2: 再利用性

前述のステップで、「聞き返す」が複数回出てきました。もしかしたら、調査だけでなく登録の際にも、「聞き返す」必要が出てくるかもしれません。「聞き返す」指示が各topicに分散していると、聞き返し方を一括で変更したい場合、全ての箇所を修正する必要があります。

そこで、聞き返しが必要になる処理を「聞き返す」topicに集約させ、必要に応じてこのtopicに遷移させる設計にすることで、保守性が向上します。

留意事項

ここまでご覧になって、プログラミング経験のある方はピンときたかもしれません。そう、クラスや関数の考え方に似ているのです。一つのtopicに一つの責任を持たせることで1回のコンテキストが限定されて性能が向上するとともに、保守性も上がるというわけです。

いくつか留意事項を記載します。

ユーザーがメッセージを送るたびにTopic Selectorから遷移し直すことになる

冒頭で述べた通り、ユーザーが入力すると、まずTopic Selectorからスタートして遷移していきますが、ここで注意点があります。

例えば、最初のユーザーからの入力に対して、Topic Selector → topic A → topic B と遷移してagentが回答したとします。追加でユーザーが入力すると、topic Bから再開するわけではなく、Topic Selectorからやり直しになります。

つまり、追加でユーザーが入力する場合に対応したいのであれば、追加入力に対して適切にTopic Selectorから目的のtopicへ辿れるように設計する必要があるというわけです。

この点、Cursorなどでscriptを自動生成しようとする場合に特に見落としがちなので、注意が必要です。

遷移でループを作らないようにする

topic Aからtopic Bへの遷移があり、topic B からtopic Aへの遷移もあるという状態は、無限ループに陥る恐れがあるため、極力避けたほうがよいです。

一応、双方向の遷移があったとしても、無限ループを防ぐ手立てはゼロではありません。例えば以下のような方法です。

  • 遷移を定義したreasoning action(topic.reasoning.actions で定義されるもの)で available when を用いて、遷移呼び出しに制約を付与する
  • カウント用の変数を定義しておいて、一定のカウントに達したら遷移をストップさせるようにする

しかし、処理が複雑になるため、双方向に遷移がある状態はそもそも作らない方が好ましいと言えます。(なお、2つのtopic間のループだけでなく、3つ以上のtopic間のループも同様です)

複雑な場合は状態遷移図を書く

次々とtopic遷移を記述していると、scriptを一目見ただけでは全体像がつかみにくいことがあります。

そこで、特に複雑な遷移を実装しようという場合、topicに関する状態遷移図を書くことをお勧めします。全てのtopicを図に並べて、遷移し得るtopic間を矢印で繋いで表現する、というものです。具体的には以下のようなものです。

topicの状態遷移図の例

このように状態遷移図を書いてみると、どのようにtopicを遷移していくのかが一目見てわかりますね。 また、ループになっていないかの確認もすぐにできそうです。

実装前に方針を立てる際に状態遷移図を作ってみると、見通しがよくなります。また、他の人が作ったscriptを読む際にも、scriptから状態遷移図を起こすと(Cursor等でLLMに自動生成させてもよいでしょう)理解しやすくなります。

topicを分割すればするほどよいとは限らない

1回にLLMに渡すコンテキストを減らすためにtopicを分割するのが有効だと述べましたが、分割すればするほどよいかというと、そうではありません。

topicに記載されているプロンプトは、当該topicに遷移してくるたびにLLMに送信されます。したがって、(完全に決定論的な記述しかない場合を除いて)topicを遷移するたびにLLMへのリクエストが発生することになり、その分応答が遅くなります。

あまりに細かく分割したtopicはそれはそれで問題、というわけです。

どの程度の分割が適切かというのはなかなか難しい問題であり、例えば上記で出したtopic分割例もあくまで説明用に用意した例であって、特にagentに他にたくさんの機能がある場合には細かすぎるケースも出てくると思います。この辺りは、実際のレイテンシーや性能を見ながら判断することになるでしょう。

「一つのtopicに一つの責任を持たせる」とは書きましたが、これは絶対的なルールではなく、細かすぎて応答が遅いといった場合には、個々の状況に応じてバランスを取ることになると思います。

まとめ

ここまで、topic遷移の利点と注意点について述べてきました。topic遷移と言うと、扱う内容を途中でガラッと変えるという印象を持ちがちですが、役割分担をしてリレーのように繋げていくことでコンテキストを分割し、性能向上を狙うといった使い方もできます。ただし、topicの分割数はレイテンシーとトレードオフの関係にあるため、分割の粒度については慎重な吟味が必要になります。

本記事が、Agent Scriptによる実装の際にお役に立てば幸いです。

最後までお読みいただき、ありがとうございました。