当我们调用 Agent.run() 时,它会创建一个无状态、单一的 Agent 运行。

但是,如果我们想继续这次运行,例如进行多轮对话,该怎么办?这时就需要用到 sessions。Session 是一系列连续运行的集合。

实际上,Session 是用户和 Agent 之间进行的多轮对话。通过 session_id,我们可以在多次运行中连接对话历史记录和状态。

让我们概述一些关键概念:

  • Session: Session 是连续运行的集合,就像用户和 Agent 之间的多轮对话一样。Session 由 session_id 标识,每一轮是一个 run
  • Run: 与 Agent 的每一次交互(即聊天或轮次)都称为一次 run。Run 由 run_id 标识,调用 Agent.run() 时会创建一个新的 run_id
  • Messages: 是在模型和 Agent 之间发送的独立消息。Messages 是 Agent 和模型之间的通信协议。

让我们从一个使用 Agent 创建单次运行的示例开始。系统会自动生成 run_idsession_id(因为我们没有提供 session_id 来继续对话)。这次运行尚未与用户关联。

from typing import Iterator
from agno.agent import Agent, RunResponse
from agno.models.openai import OpenAIChat
from agno.utils.pprint import pprint_run_response

agent = Agent(model=OpenAIChat(id="gpt-4o-mini"))

# 运行 agent 并将响应返回给一个变量
agent.print_response("Tell me a 5 second short story about a robot")

多用户、多 Session 的 Agent

每个与 Agent 交互的用户都有自己的一组唯一的 Session,并且您可以让多个用户同时与同一个 Agent 进行交互。

设置 user_id 可以将用户与其在 Agent 上的 Session 联系起来。

在下面的示例中,我们设置了 session_id 来演示如何同时与多个用户进行多轮对话。在生产环境中,session_id 是自动生成的。

注意:多用户、多 Session 目前仅支持 Memory.v2,它将在下一个版本中成为默认的内存实现。

from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.memory.v2 import Memory

agent = Agent(
    model=OpenAIChat(id="gpt-4o-mini"),
    # 多用户、多 Session 仅支持 Memory.v2
    memory=Memory(),
    add_history_to_messages=True,
    num_history_runs=3,
)

user_1_id = "user_101"
user_2_id = "user_102"

user_1_session_id = "session_101"
user_2_session_id = "session_102"

# 开始与 user 1 的会话
agent.print_response(
    "Tell me a 5 second short story about a robot.",
    user_id=user_1_id,
    session_id=user_1_session_id,
)
# 继续与 user 1 的会话
agent.print_response("Now tell me a joke.", user_id=user_1_id, session_id=user_1_session_id)

# 开始与 user 2 的会话
agent.print_response("Tell me about quantum physics.", user_id=user_2_id, session_id=user_2_session_id)
# 继续与 user 2 的会话
agent.print_response("What is the speed of light?", user_id=user_2_id, session_id=user_2_session_id)

# 要求 Agent 对对话进行总结,这将使用之前消息中的历史记录
agent.print_response(
    "Give me a summary of our conversation.",
    user_id=user_1_id,
    session_id=user_1_session_id,
)

获取最近 N 个 Session 的消息

在某些场景下,您可能希望获取最近 N 个 Session 的消息,以提供上下文或对话的连续性。

以下是一个实现此目的的示例:

# 在运行脚本前删除临时数据库文件
import os

from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.storage.sqlite import SqliteStorage

os.remove("tmp/data.db")

agent = Agent(
    model=OpenAIChat(id="gpt-4o-mini"),
    user_id="user_1",
    storage=SqliteStorage(table_name="agent_sessions_new", db_file="tmp/data.db"),
    search_previous_sessions_history=True,  # 允许搜索之前的 Session
    num_history_sessions=2,  # 搜索时仅包含最近的 2 个 Session,以避免上下文长度问题
    show_tool_calls=True,
)

session_1_id = "session_1_id"
session_2_id = "session_2_id"
session_3_id = "session_3_id"
session_4_id = "session_4_id"
session_5_id = "session_5_id"

agent.print_response("What is the capital of South Africa?", session_id=session_1_id)
agent.print_response("What is the capital of China?", session_id=session_2_id)
agent.print_response("What is the capital of France?", session_id=session_3_id)
agent.print_response("What is the capital of Japan?", session_id=session_4_id)
agent.print_response(
    "What did I discuss in my previous conversations?", session_id=session_5_id
)  # 这应该只包含最近的 2 个 Session

要启用从最近 N 个 Session 获取消息,您需要使用以下标志:

  • search_previous_sessions_history: 设置为 True 以允许搜索之前的 Session。
  • num_history_sessions: 指定要在搜索中包含的过去 Session 的数量。在此示例中,它设置为 2,只包含最近的 2 个 Session。 建议目前将此数量保持为 2 或 3,因为较大的数量可能会填满模型的上下文长度,从而可能导致性能问题。

这些标志有助于管理上下文长度,并确保对话中只包含相关的 Session 历史记录。