ストレージを使用して、エージェント・セッションと状態をデータベースやファイルに永続化します。
エージェントは一時的でステートレスです。エージェントを実行する場合、状態は自動的には永続化されません。本番環境では、エージェントを API 経由でサービス提供し、複数のリクエストにわたり同じセッションを継続する必要があります。
Agno 2.x : Learn : エージェント – ストレージ
作成 : クラスキャット・セールスインフォメーション
作成日時 : 10/29/2025
バージョン : Agno 2.2.1
* 本記事は docs.agno.com の以下のページを独自に翻訳した上で、補足説明を加えてまとめ直しています。スニペットはできる限り日本語を使用しています :
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
◆ お問合せ : 下記までお願いします。
- クラスキャット セールス・インフォメーション
- sales-info@classcat.com
- ClassCatJP

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.
以上
