以下の内容はhttps://nikkie-ftnext.hatenablog.com/entry/strands-agents-agent-callback-handlers-default-printingより取得しました。


Strands Agents で Agent を呼び出しただけで回答がコンソールに出力されるのは、Callback Handlers による

はじめに

七尾百合子さん、お誕生日 288日目 おめでとうございます! nikkieです。

AWS ミリしらでも Strands Agents は使い出せます!
3行でAIエージェントを作ったときに引っかかったことを掘り下げました。

目次

入出力と計算の分離、してますか?

みのるんさんのハンズオン記事を元に Strands Agents を触りました。タキクゥーン

from strands import Agent
from strands.models.openai import OpenAIModel

agent = Agent(model=OpenAIModel(model_id="gpt-4o"))
agent("JAWS-UG主催のAI Builders Dayはどこで開催される?")

これだけで GPT-4o を使ったAIエージェントができたのですが、引っかかるポイントが。

ただ入出力と計算が分離できてないのはいただけないですね。
print(agent("..."))であってほしいです

要はagent("...")が中で OpenAI の API の呼び出しと、print をどちらもやっていて、返り値がないように見えたということです。
再利用しにくいのではないかという疑義が生じました。

Callback Handlers

上記コードの2行だと分かりづらいですが、結論としては入出力と計算は分離できています

agent = Agent(model=OpenAIModel(model_id="gpt-4o"))
agent("JAWS-UG主催のAI Builders Dayはどこで開催される?")

理解の肝は「Callback Handlers

strandsagents.com

デフォルトではPrintingCallbackHandlerとなります。
Agentcallback_handler引数にNoneを指定することで、callback handler を無効化できます。

agent = Agent(model=OpenAIModel(model_id="gpt-4o"), callback_handler=None)
agent("JAWS-UG主催のAI Builders Dayはどこで開催される?")

デフォルトのPrintingCallbackHandlerの代わりに無効化したので、このコードは(OpenAI API を呼び出してますが)なにも出力しません

入出力と計算が分離されていることを示す実装例です。

Agent.__call__()の返り値はAgentResultです1
その__str__()により、最終応答のテキストprintされます2

実装callback_handler.py

https://github.com/strands-agents/sdk-python/blob/v1.20.0/src/strands/handlers/callback_handler.py

This module provides handlers for formatting and displaying events from the agent.

3つの callback handler が実装されています。

  • PrintingCallbackHandler
    • verbose_tool_use引数がデフォルトでTrueです。「Tool #1」のような出力もしてくれます
  • CompositeCallbackHandler
    • 複数の callback handler を組み合わせられる仕組みが用意されています。拡張性3は申し分なし!
  • null_callback_handler
    • 何も出力しません

Agentの引数に応じて以下のように選択されます。
https://github.com/strands-agents/sdk-python/blob/v1.20.0/src/strands/agent/agent.py#L189-L198

if isinstance(callback_handler, _DefaultCallbackHandlerSentinel):
    self.callback_handler = PrintingCallbackHandler()
elif callback_handler is None:
    self.callback_handler = null_callback_handler
else:
    self.callback_handler = callback_handler
  • callback_handler引数が指定されていない場合4PrintingCallbackHandler
  • callback_handler引数がNoneと指定された場合、null_callback_handler
  • callback_handler引数がNone以外で指定されている(=ユーザがハンドラを渡している)場合、それが設定されます

ちなみにcallback_handlerが呼ばれているのはこちらです(stream_async())。
https://github.com/strands-agents/sdk-python/blob/v1.20.0/src/strands/agent/agent.py#L586-L598

終わりに

Strands Agents で Agent インスタンスagent("...") と呼び出しただけで回答が出力されるのは、Callback Handlers によるものでした。

  • Agent 初期化時に、デフォルトではPrintingCallbackHandlerが設定される
    • agent("...")で回答が出力されるのはこのため
    • agent("...")が LLM の呼び出しと返り値のprintどちらもやっているわけではないAgentResultを返している
  • Agent(callback_handler=None)で callback handler を無効化できる
    • その場合でも出力するにはprint(agent("..."))となる

懸念が解消したので、ガッツリ使っていけそうです。
samples にはいくつか callback handler の例もありそうでした




以上の内容はhttps://nikkie-ftnext.hatenablog.com/entry/strands-agents-agent-callback-handlers-default-printingより取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14