Agno 2.x : エージェント – ストレージ

ストレージを使用して、エージェント・セッションと状態をデータベースやファイルに永続化します。
エージェントは一時的でステートレスです。エージェントを実行する場合、状態は自動的には永続化されません。本番環境では、エージェントを API 経由でサービス提供し、複数のリクエストにわたり同じセッションを継続する必要があります。

Agno 2.x : Learn : エージェント – ストレージ

作成 : クラスキャット・セールスインフォメーション
作成日時 : 10/29/2025
バージョン : Agno 2.2.1

* 本記事は docs.agno.com の以下のページを独自に翻訳した上で、補足説明を加えてまとめ直しています。スニペットはできる限り日本語を使用しています :

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

 

Agno 2.x : Learn : エージェント – ストレージ

ストレージを使用して、エージェント・セッションと状態をデータベースやファイルに永続化します。

何故、セッション・ストレージが必要なのでしょう?

エージェントは一時的 (ephemeral) でステートレスです。エージェントを実行する場合、状態は自動的には永続化されません。本番環境では、エージェントを API 経由でサービス提供 (or トリガー) し、複数のリクエストにわたり同じセッションを継続する必要があります。

ストレージはセッション履歴と状態をデータベースに永続化して中断したところから再開することを可能にします。

ストレージはまたエージェント・セッションを検査して評価し、few-shot サンプルを抽出し、内部的な監視ツールを構築するとも可能にします。ユーザにデータを見れるようにして、より良いエージェントを構築するのに役立ちます。

エージェント、チームやワークフローにストレージを追加することは、DB ドライバを提供するだけで非常に簡単で、残りの処理は Agno が行います。Sqlite, Postgres, Mongo やその他任意の希望のデータベースを使用できます。

以下は、実行サイクルに渡る永続性を実演する単純な例です :

Python

from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.db.sqlite import SqliteDb
from rich.pretty import pprint

agent = Agent(
     model=OpenAIChat(id="gpt-4.1"),
    # Fix the session id to continue the same session across execution cycles
    session_id="fixed_id_for_demo",
    db=SqliteDb(db_file="tmp/data.db"),
    # Make the agent aware of the session history
    add_history_to_context=True,
    num_history_runs=3,
)
agent.print_response("私の最後の質問は何でしたか?")
agent.print_response("フランスの首都はどこですか?")
agent.print_response("私の最後の質問は何でしたか?")
pprint(agent.get_messages_for_session())

出力例

┏━ Message ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                                                                                                 ┃
┃ 私の最後の質問は何でしたか?                                                                                                                    ┃
┃                                                                                                                                                 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ Response (4.4s) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                                                                                                 ┃
┃ 申し訳ありませんが、私は現在のセッション内でのみ会話内容を把握できます。                                                                        ┃
┃ あなたがこのセッションで他に質問をしていない場合、「最後の質問」はありません。                                                                  ┃
┃ もし前回のご質問について知りたい場合は、もう一度内容をお聞かせいただけますか?                                                                  ┃
┃                                                                                                                                                 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ Message ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                                                                                                 ┃
┃ フランスの首都はどこですか?                                                                                                                    ┃
┃                                                                                                                                                 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ Response (2.8s) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                                                                                                 ┃
┃ フランスの首都はパリ(Paris)です。                                                                                                             ┃
┃                                                                                                                                                 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ Message ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                                                                                                 ┃
┃ 私の最後の質問は何でしたか?                                                                                                                    ┃
┃                                                                                                                                                 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ Response (2.0s) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                                                                                                 ┃
┃ あなたの最後の質問は「フランスの首都はどこですか?」です。                                                                                      ┃
┃                                                                                                                                                 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
[
│   Message(
│   │   id='949d09ed-68c7-4ef3-ba41-6496cdfe6ac9',
│   │   role='user',
│   │   content='私の最後の質問は何でしたか?',
│   │   name=None,
│   │   tool_call_id=None,
│   │   tool_calls=None,
│   │   audio=None,
│   │   images=None,
│   │   videos=None,
│   │   files=None,
│   │   audio_output=None,
│   │   image_output=None,
│   │   video_output=None,
│   │   file_output=None,
│   │   redacted_reasoning_content=None,
│   │   provider_data=None,
│   │   citations=None,
│   │   reasoning_content=None,
│   │   tool_name=None,
│   │   tool_args=None,
│   │   tool_call_error=None,
│   │   stop_after_tool_call=False,
│   │   add_to_agent_memory=True,
│   │   from_history=False,
│   │   metrics=Metrics(
│   │   │   input_tokens=0,
│   │   │   output_tokens=0,
│   │   │   total_tokens=0,
│   │   │   audio_input_tokens=0,
│   │   │   audio_output_tokens=0,
│   │   │   audio_total_tokens=0,
│   │   │   cache_read_tokens=0,
│   │   │   cache_write_tokens=0,
│   │   │   reasoning_tokens=0,
│   │   │   timer=None,
│   │   │   time_to_first_token=None,
│   │   │   duration=None,
│   │   │   provider_metrics=None,
│   │   │   additional_metrics=None
│   │   ),
│   │   references=None,
│   │   created_at=1761719258
│   ),
│   Message(
│   │   id='ec05ca93-c892-4202-8595-87e5f37461ab',
│   │   role='assistant',
│   │   content='申し訳ありませんが、私は現在のセッション内でのみ会話内容を把握できます。  \nあなたがこのセッションで他に質問をしていない場合、「最後の質問」はありません。  \nもし前回のご質問について知りたい場合は、もう一度内容をお聞かせいただけますか?',
│   │   name=None,
│   │   tool_call_id=None,
│   │   tool_calls=None,
│   │   audio=None,
│   │   images=None,
│   │   videos=None,
│   │   files=None,
│   │   audio_output=None,
│   │   image_output=None,
│   │   video_output=None,
│   │   file_output=None,
│   │   redacted_reasoning_content=None,
│   │   provider_data=None,
│   │   citations=None,
│   │   reasoning_content=None,
│   │   tool_name=None,
│   │   tool_args=None,
│   │   tool_call_error=None,
│   │   stop_after_tool_call=False,
│   │   add_to_agent_memory=True,
│   │   from_history=False,
│   │   metrics=Metrics(
│   │   │   input_tokens=17,
│   │   │   output_tokens=71,
│   │   │   total_tokens=88,
│   │   │   audio_input_tokens=0,
│   │   │   audio_output_tokens=0,
│   │   │   audio_total_tokens=0,
│   │   │   cache_read_tokens=0,
│   │   │   cache_write_tokens=0,
│   │   │   reasoning_tokens=0,
│   │   │   timer=None,
│   │   │   time_to_first_token=None,
│   │   │   duration=None,
│   │   │   provider_metrics=None,
│   │   │   additional_metrics=None
│   │   ),
│   │   references=None,
│   │   created_at=1761719258
│   ),
│   Message(
│   │   id='5fde6371-682a-4c38-b4cb-cc2b1dc73e6d',
│   │   role='user',
│   │   content='フランスの首都はどこですか?',
│   │   name=None,
│   │   tool_call_id=None,
│   │   tool_calls=None,
│   │   audio=None,
│   │   images=None,
│   │   videos=None,
│   │   files=None,
│   │   audio_output=None,
│   │   image_output=None,
│   │   video_output=None,
│   │   file_output=None,
│   │   redacted_reasoning_content=None,
│   │   provider_data=None,
│   │   citations=None,
│   │   reasoning_content=None,
│   │   tool_name=None,
│   │   tool_args=None,
│   │   tool_call_error=None,
│   │   stop_after_tool_call=False,
│   │   add_to_agent_memory=True,
│   │   from_history=False,
│   │   metrics=Metrics(
│   │   │   input_tokens=0,
│   │   │   output_tokens=0,
│   │   │   total_tokens=0,
│   │   │   audio_input_tokens=0,
│   │   │   audio_output_tokens=0,
│   │   │   audio_total_tokens=0,
│   │   │   cache_read_tokens=0,
│   │   │   cache_write_tokens=0,
│   │   │   reasoning_tokens=0,
│   │   │   timer=None,
│   │   │   time_to_first_token=None,
│   │   │   duration=None,
│   │   │   provider_metrics=None,
│   │   │   additional_metrics=None
│   │   ),
│   │   references=None,
│   │   created_at=1761719262
│   ),
│   Message(
│   │   id='d89185bf-31cf-42db-9d44-3860aa2ffd0a',
│   │   role='assistant',
│   │   content='フランスの首都はパリ(Paris)です。',
│   │   name=None,
│   │   tool_call_id=None,
│   │   tool_calls=None,
│   │   audio=None,
│   │   images=None,
│   │   videos=None,
│   │   files=None,
│   │   audio_output=None,
│   │   image_output=None,
│   │   video_output=None,
│   │   file_output=None,
│   │   redacted_reasoning_content=None,
│   │   provider_data=None,
│   │   citations=None,
│   │   reasoning_content=None,
│   │   tool_name=None,
│   │   tool_args=None,
│   │   tool_call_error=None,
│   │   stop_after_tool_call=False,
│   │   add_to_agent_memory=True,
│   │   from_history=False,
│   │   metrics=Metrics(
│   │   │   input_tokens=108,
│   │   │   output_tokens=14,
│   │   │   total_tokens=122,
│   │   │   audio_input_tokens=0,
│   │   │   audio_output_tokens=0,
│   │   │   audio_total_tokens=0,
│   │   │   cache_read_tokens=0,
│   │   │   cache_write_tokens=0,
│   │   │   reasoning_tokens=0,
│   │   │   timer=None,
│   │   │   time_to_first_token=None,
│   │   │   duration=None,
│   │   │   provider_metrics=None,
│   │   │   additional_metrics=None
│   │   ),
│   │   references=None,
│   │   created_at=1761719262
│   ),
│   Message(
│   │   id='cabdc860-ac6e-4e75-9d59-e34c28922cd4',
│   │   role='user',
│   │   content='私の最後の質問は何でしたか?',
│   │   name=None,
│   │   tool_call_id=None,
│   │   tool_calls=None,
│   │   audio=None,
│   │   images=None,
│   │   videos=None,
│   │   files=None,
│   │   audio_output=None,
│   │   image_output=None,
│   │   video_output=None,
│   │   file_output=None,
│   │   redacted_reasoning_content=None,
│   │   provider_data=None,
│   │   citations=None,
│   │   reasoning_content=None,
│   │   tool_name=None,
│   │   tool_args=None,
│   │   tool_call_error=None,
│   │   stop_after_tool_call=False,
│   │   add_to_agent_memory=True,
│   │   from_history=False,
│   │   metrics=Metrics(
│   │   │   input_tokens=0,
│   │   │   output_tokens=0,
│   │   │   total_tokens=0,
│   │   │   audio_input_tokens=0,
│   │   │   audio_output_tokens=0,
│   │   │   audio_total_tokens=0,
│   │   │   cache_read_tokens=0,
│   │   │   cache_write_tokens=0,
│   │   │   reasoning_tokens=0,
│   │   │   timer=None,
│   │   │   time_to_first_token=None,
│   │   │   duration=None,
│   │   │   provider_metrics=None,
│   │   │   additional_metrics=None
│   │   ),
│   │   references=None,
│   │   created_at=1761719265
│   ),
│   Message(
│   │   id='2d94cb54-4bb5-4510-be42-cd7bd3878fdf',
│   │   role='assistant',
│   │   content='あなたの最後の質問は「フランスの首都はどこですか?」です。',
│   │   name=None,
│   │   tool_call_id=None,
│   │   tool_calls=None,
│   │   audio=None,
│   │   images=None,
│   │   videos=None,
│   │   files=None,
│   │   audio_output=None,
│   │   image_output=None,
│   │   video_output=None,
│   │   file_output=None,
│   │   redacted_reasoning_content=None,
│   │   provider_data=None,
│   │   citations=None,
│   │   reasoning_content=None,
│   │   tool_name=None,
│   │   tool_args=None,
│   │   tool_call_error=None,
│   │   stop_after_tool_call=False,
│   │   add_to_agent_memory=True,
│   │   from_history=False,
│   │   metrics=Metrics(
│   │   │   input_tokens=140,
│   │   │   output_tokens=21,
│   │   │   total_tokens=161,
│   │   │   audio_input_tokens=0,
│   │   │   audio_output_tokens=0,
│   │   │   audio_total_tokens=0,
│   │   │   cache_read_tokens=0,
│   │   │   cache_write_tokens=0,
│   │   │   reasoning_tokens=0,
│   │   │   timer=None,
│   │   │   time_to_first_token=None,
│   │   │   duration=None,
│   │   │   provider_metrics=None,
│   │   │   additional_metrics=None
│   │   ),
│   │   references=None,
│   │   created_at=1761719265
│   )
]

再実行時の出力例

┏━ Message ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                                                                                                 ┃
┃ 私の最後の質問は何でしたか?                                                                                                                    ┃
┃                                                                                                                                                 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ Response (3.0s) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                                                                                                 ┃
┃ あなたの最後の質問は「私の最後の質問は何でしたか?」です。                                                                                      ┃
┃                                                                                                                                                 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ Message ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                                                                                                 ┃
┃ フランスの首都はどこですか?                                                                                                                    ┃
┃                                                                                                                                                 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ Response (2.2s) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                                                                                                 ┃
┃ フランスの首都はパリ(Paris)です。                                                                                                             ┃
┃                                                                                                                                                 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ Message ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                                                                                                 ┃
┃ 私の最後の質問は何でしたか?                                                                                                                    ┃
┃                                                                                                                                                 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┏━ Response (3.0s) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                                                                                                                                                 ┃
┃ あなたの最後の質問は「フランスの首都はどこですか?」です。                                                                                      ┃
┃                                                                                                                                                 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

これを最初に実行する場合、「私の最後の質問は何でしたか?」への回答は利用可能ではありません。しかし再度実行すると、エージェントは正しく回答できるようになります。セッション id を固定したため、エージェントはスクリプトを実行するたびに同じセッションから継続できます。

 

セッションの利点

ストレージは通常はエージェント・エンジニアリングにおいてあまり議論されてこなかった部分でしたが、私たちはこれを本番環境のエージェント型アプリケーションの縁の下の力持ちと考えています。

本番環境では、以下の目的でストレージが必要です :

  • セッションの継続: セッション履歴を取得して中断したところから再開します。

  • セッションのリストの取得: 前のセッションを継続するには、そのエージェントで利用可能なセッションのリストを保持する必要があります。

  • 実行間でセッション状態を保存する: エージェントの状態をデータベースやファイルに保存し、あとでそれを検査できます。

But there is so much more:

  • ストレージは、検査や評価のために (セッションメトリクスを含む) エージェントのセッションデータを保存します。

  • ストレージは few-shot サンプルを抽出するのに役立ちます、これはエージェントの改良に使用できます。

  • ストレージは内部監視ツールやダッシュボードを構築するのに役立ちます。

 

セッション・テーブルのスキーマ

エージェント向けに構成設定された db がある場合、セッションはデータベースのセッション (sessions) テーブルに保存されます。セッション・テーブルのスキーマは以下のようなものです :

フィールド 説明
session_id str セッション用の一意の識別子
session_type str セッションのタイプ
agent_id str セッションのエージェント ID
team_id str セッションのチーム ID
workflow_id str セッションのワークフロー ID
user_id str セッションのユーザ ID
session_data dict セッションのデータ
agent_data dict エージェントのデータ
team_data dict チームのデータ
workflow_data dict ワークフローのデータ
metadata dict セッションのメタデータ
runs list セッションの実行
summary dict セッションのサマリー
created_at int セッションが作成された時のタイムスタンプ
updated_at int セッションが最後に更新された時のタイムスタンプ

This data is best displayed on the sessions page of the AgentOS UI.

 

以上