🐡

Mastraで複数エージェントを連携する - Agent.network()とAgent.stream()の比較

に公開

こんにちは!株式会社エクスプラザのShinです。
今回はMastraで複数のエージェントと連携を行う際のアプローチについて考えてみたいと思います。

背景

前回こちらの記事Agent.network()を使用した複数のエージェントとの連携についてご紹介しました。
Agent.network()を利用したアプローチはMastra公式で推奨されている方法です。

しかし最近のアップデートでAgent.stream()でもAgent.network()を利用した時のように複数のエージェントと連携がとれるようになっていました。
今回はAgent.stream()を利用した際の挙動の違いや、他のアプローチについて考えてみたいと思います。
Agent.generate()を使用した際もエージェント連携が可能となっていましたが、Agent.stream()と挙動が同じなため、今回の記事では割愛致します。

Agent.stream()を利用した実装

実装方法はAgent.network()を利用した時と同じで、呼び出す際にnetwork()stream()に変更するだけです。

// networkの場合
const result = await orchestratorAgent.network(messages)

// streamの場合
const result = await orchestratorAgent.stream(messages)

詳しいコードは前回の記事のAgent.network()を使った実装で記述しているのでこちらを参照してください。

この変更だけで、エージェント設定を変更せずに試すことができます。

挙動の違いについて

大きな違いは「サブエージェントの呼び出し方」にあります。
ではLangfuseでトレースしたデータを確認してみます。

  • Agent.network()のトレースデータ

  • Agent.stream()のトレースデータ

Agent.network()では、orchestrator-agentが直接サブエージェントを呼び出すのではなく、routing-agentが最適なサブエージェントを判断してツールとして実行します。
一方Agent.stream()ではorchestrator-agentが判断して、サブエージェントをツールとして実行しています。

またAgent.stream()の方がシンプルな構成なため、レスポンスの速度が向上する結果となりました。
上記の例では、Agent.network()33.31sだったのに対し、Agent.stream()24.32sという結果になりました。

Agent.network()の問題点

Agent.network()は最近リリースされた機能ということもあり、まだ不安定に感じる場面がありました。
以下は開発をする中で遭遇した問題点になります。

  • bedrockのモデルを指定すると、routing-agentでエラーが出る
  • maxStepsmaxRetriesがうまく機能せず、エージェントの呼び出しがループしてしまう
  • working memoryの更新がうまく動かない
  • チャット画面開発で利用したAI SDKのAI Elementsでうまくstreamingされない

これらの問題の多くは、Mastraが内部で利用しているrouting-agentがボトルネックになっていると推測しています。
そのためAgent.stream()で動作させると上記の問題は解決することができました。
エージェントの呼び出しがループするような問題はAPIの利用料に関わるので、実運用を考えるとなかなか厳しく感じました。

他のアプローチについて

Mastraが準備している機能を使わずに実装するのであれば、自前でサブエージェントを呼び出すツールを作成して、agentに持たせるアプローチもあると思います。
このアプローチでは、ツールの中でサブエージェントに渡すコンテキストやレスポンスの内容を細かく制御できるため、微調整などが行いやすいと感じています。

まとめ

ここまでMastraで複数のエージェントと連携を行う際のアプローチについて考えてきましたが、「結局どれがいいの?」と迷う場面が出ると思います。
個人的にですが、現段階ではAgent.stream()での実装が1番安定していて、Mastraの恩恵も受けられると感じています。
しかし現在Mastraではアップデートが頻繁に行われているため、今後Agent.network()の安定性が向上していくことが予想されます。
簡単なエージェントの連携ではシンプルでレスポンスが早いAgent.stream()で十分かもしれませんが、複数のエージェントと複雑な連携が必要な要件であればAgent.network()の方が適しているのかなと考えています。
また要件によっては、自前でサブエージェントを呼び出すツールを作成してagentに持たせるアプローチの方が調整が行いやすく、精度の向上が見込めるケースもあるかと考えています。

株式会社エクスプラザ

Discussion