Solon v3.8.3

agent - 会话与记忆 (Session & Memory)

</> markdown
2026年1月14日 下午5:23:48

在多轮对话或复杂的团队协作中,智能体需要通过“记忆”来维持上下文的连贯性。Solon AI 通过 AgentSession 和 historyWindowSize 提供了灵活的记忆管理机制。

1、基础用法:开启记忆能力

通过关联 AgentSession 并设置 historyWindowSize,智能体即可自动加载并持久化历史对话。

示例:

// 1. 创建具备记忆窗口的 Agent
ReActAgent agent = ReActAgent.of(chatModel)
                .historyWindowSize(10) // 仅保留最近 10 条消息,防止 Context 溢出并降低 Token 成本
                .build();

// 2. 创建或获取会话(以 sessionId 隔离不同用户的记忆)
AgentSession session = InMemoryAgentSession.of("user_123");

// 3. 执行调用
String content = agent.prompt("我想延续上次的话题...")
                .session(session) // 关联会话上下文
                .call()
                .getContent();

每个内置的智能体,都支持 prompt, session 接口。

2、记忆管理机制

窗口化记忆 (History Window)。historyWindowSize 决定了发送给 LLM 的短期记忆深度。

  • 作用:自动截断过旧的消息,确保不超出大模型的上下文长度限制(Context Limit),同时节省费用。
  • 策略:建议根据模型能力设置,通常 5-15 之间较为理想。

会话隔离 (Session Isolation)。AgentSession 不仅仅是存储 ChatMessage 的集合,它还承担了状态机的职责:

  • 隔离性:不同 sessionId 之间的对话互不干扰。
  • 持久化:通过不同的实现类,可以将记忆存放在内存、Redis 或数据库中。

3、AgentSession 内置实现对比

实现类存储介质适用场景备注
InMemoryAgentSession本地内存 (Map)单机开发、单元测试、低频演示重启后记忆丢失,不适合生产环境
RedisAgentSessionRedis 数据库分布式环境、生产环境、高并发支持多节点共享记忆,支持 TTL 过期自动清理

最佳实践建议

4、高级扩展:AgentSession 接口定义

如果你需要将记忆存入自定义数据库(如 MongoDB, MySQL),可以实现 AgentSession 接口。它核心处理两类数据:对话历史 (History) 和 执行快照 (Snapshot)。

实践建议

  • 及时更新 Snapshot:在工作流(Flow)模式下,updateSnapshot 会保存当前变量池(Context)的状态,确保 Agent 在下次唤醒时能感知到之前的业务变量。
  • 分布式环境强制使用 Redis:在生产集群环境下,请务必使用 RedisAgentSession,否则由于负载均衡,用户的请求可能会落到没有记忆的节点上。
  • 结合 TeamAgent 使用:在团队协作模式下,AgentSession 会自动为团队内每个成员维护独立的子记忆,同时保持 Supervisor 的全局视图。
package org.noear.solon.ai.agent;

import org.noear.solon.ai.chat.message.ChatMessage;
import org.noear.solon.flow.FlowContext;
import org.noear.solon.lang.NonSerializable;
import org.noear.solon.lang.Preview;

import java.util.Collection;

/**
 * 智能体会话(运行状态与记忆中心)
 *
 * <p>核心职责:管理智能体的长短期记忆(History)与业务执行快照(Snapshot)。</p>
 * <ul>
 * <li><b>多轮对话:</b>按智能体维度隔离并持久化对话足迹。</li>
 * <li><b>状态机平衡:</b>通过 Snapshot 机制同步 Flow 工作流上下文。</li>
 * </ul>
 *
 * @author noear
 * @since 3.8.1
 */
@Preview("3.8.1")
public interface AgentSession extends NonSerializable {
    /**
     * 获取会话唯一标识符
     */
    String getSessionId();

    /**
     * 追加历史消息(存入短期记忆)
     *
     * @param agentName 智能体标识
     * @param message   消息内容
     */
    void addHistoryMessage(String agentName, ChatMessage message);

    /**
     * 提取最近历史消息(记忆加载)
     *
     * @param agentName 智能体标识
     * @param last      提取最近的消息条数
     * @return 历史消息列表
     */
    Collection<ChatMessage> getHistoryMessages(String agentName, int last);

    /**
     * 同步/更新执行快照
     *
     * @param snapshot 包含最新业务数据的上下文
     */
    void updateSnapshot(FlowContext snapshot);

    /**
     * 获取当前状态快照(用于状态回溯或持久化导出)
     */
    FlowContext getSnapshot();
}