状态与会话管理¶
AgentScope 提供两个层级的状态管理:
Session(会话)(推荐):用于跨应用运行管理状态的高级 API
State(状态)(高级):用于细粒度控制的底层 API
本指南重点介绍 Session API,这是大多数使用场景的推荐方法。
什么是会话?¶
Session(会话) 为状态组件(智能体、内存、工具包)提供跨应用运行的持久化存储。它允许您:
保存和恢复完整的应用状态
从中断处继续对话
统一管理多个组件
在环境之间迁移状态
快速开始¶
保存状态¶
使用 SessionManager 保存智能体和内存状态:
import io.agentscope.core.ReActAgent;
import io.agentscope.core.memory.InMemoryMemory;
import io.agentscope.core.session.SessionManager;
import java.nio.file.Path;
// 创建并使用智能体
ReActAgent agent = ReActAgent.builder()
.name("Assistant")
.model(model)
.memory(new InMemoryMemory())
.build();
agent.call(msg1).block();
agent.call(msg2).block();
// 保存会话
SessionManager.forSessionId("user123")
.withJsonSession(Path.of("sessions"))
.addComponent(agent)
.saveSession();
加载状态¶
从保存的会话恢复智能体:
// 使用相同配置创建智能体
ReActAgent agent = ReActAgent.builder()
.name("Assistant")
.model(model)
.memory(new InMemoryMemory())
.build();
// 如果会话存在则加载
SessionManager.forSessionId("user123")
.withJsonSession(Path.of("sessions"))
.addComponent(agent)
.loadIfExists();
// 智能体从中断处继续
agent.call(msg3).block();
多组件会话¶
会话可以同时管理多个组件,保留它们之间的关系:
import io.agentscope.core.tool.Toolkit;
// 创建组件
ReActAgent agent = ReActAgent.builder()
.name("Assistant")
.model(model)
.build();
InMemoryMemory memory = new InMemoryMemory();
Toolkit toolkit = new Toolkit();
// 将所有组件一起保存
SessionManager.forSessionId("conversation-001")
.withJsonSession(Path.of("./sessions"))
.addComponent(agent)
.addComponent(memory)
.addComponent(toolkit)
.saveSession();
// 稍后,加载所有组件
SessionManager.forSessionId("conversation-001")
.withJsonSession(Path.of("./sessions"))
.addComponent(agent)
.addComponent(memory)
.addComponent(toolkit)
.loadIfExists();
会话操作¶
检查会话是否存在¶
boolean exists = SessionManager.forSessionId("user123")
.withJsonSession(Path.of("sessions"))
.sessionExists();
if (exists) {
System.out.println("找到会话");
}
带错误处理的加载¶
try {
// 如果会话不存在则抛出异常
SessionManager.forSessionId("user123")
.withJsonSession(Path.of("sessions"))
.addComponent(agent)
.loadOrThrow();
} catch (IllegalArgumentException e) {
System.err.println("未找到会话: " + e.getMessage());
}
条件保存¶
// 仅在会话已存在时保存
SessionManager.forSessionId("user123")
.withJsonSession(Path.of("sessions"))
.addComponent(agent)
.saveIfExists();
删除会话¶
// 如果存在则删除
boolean deleted = SessionManager.forSessionId("user123")
.withJsonSession(Path.of("sessions"))
.deleteIfExists();
// 或者如果不存在则抛出异常
SessionManager.forSessionId("user123")
.withJsonSession(Path.of("sessions"))
.deleteOrThrow();
会话存储¶
JsonSession(默认)¶
JsonSession 将状态作为 JSON 文件存储在文件系统中:
默认位置:
~/.agentscope/sessions/文件格式:每个会话一个 JSON 文件(以会话 ID 命名)
功能:自动创建目录、UTF-8 编码、格式化输出
import io.agentscope.core.session.SessionManager;
// 使用默认位置(~/.agentscope/sessions/)
SessionManager.forSessionId("user123")
.withDefaultJsonSession()
.addComponent(agent)
.saveSession();
// 使用自定义位置
SessionManager.forSessionId("user123")
.withJsonSession(Path.of("/path/to/sessions"))
.addComponent(agent)
.saveSession();
自定义会话后端¶
您可以通过扩展 SessionBase 实现自定义会话后端:
import io.agentscope.core.session.SessionBase;
// 示例:基于数据库的会话
SessionManager.forSessionId("user123")
.withSession(() -> new DatabaseSession(dbConnection))
.addComponent(agent)
.saveSession();
组件命名¶
组件会自动使用其 getComponentName() 方法或类名进行命名:
// 自动命名
SessionManager.forSessionId("user123")
.withJsonSession(Path.of("sessions"))
.addComponent(agent) // 命名为 "reActAgent"
.addComponent(memory) // 命名为 "inMemoryMemory"
.saveSession();
会话文件结构:
{
"reActAgent": {
"agentId": "...",
"memory": {...}
},
"inMemoryMemory": {
"messages": [...]
}
}
高级:底层状态 API¶
对于细粒度控制,您可以使用底层的 StateModule 接口:
手动状态管理¶
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;
// 手动保存状态
Map<String, Object> state = agent.saveState();
// 序列化为 JSON
ObjectMapper mapper = new ObjectMapper();
String jsonState = mapper.writeValueAsString(state);
// 保存到文件
Files.writeString(Path.of("agent-state.json"), jsonState);
// 手动加载状态
String jsonState = Files.readString(Path.of("agent-state.json"));
Map<String, Object> state = mapper.readValue(jsonState, Map.class);
// 恢复智能体
agent.loadState(state);
何时使用底层 API¶
在以下情况下使用底层 API:
自定义序列化格式(非 JSON)
与现有存储系统集成
部分状态更新
加载/保存期间的状态转换
完整示例¶
package io.agentscope.tutorial.task;
import io.agentscope.core.ReActAgent;
import io.agentscope.core.memory.InMemoryMemory;
import io.agentscope.core.message.Msg;
import io.agentscope.core.message.MsgRole;
import io.agentscope.core.message.TextBlock;
import io.agentscope.core.model.DashScopeChatModel;
import io.agentscope.core.session.SessionManager;
import java.nio.file.Path;
import java.util.List;
public class SessionExample {
public static void main(String[] args) {
// 会话 ID(例如,用户 ID、对话 ID)
String sessionId = "user-alice-chat-001";
Path sessionPath = Path.of("./sessions");
// 创建模型
DashScopeChatModel model = DashScopeChatModel.builder()
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
.modelName("qwen-plus")
.build();
// 创建智能体
ReActAgent agent = ReActAgent.builder()
.name("Assistant")
.sysPrompt("你是一个有帮助的助手。记住之前的对话。")
.model(model)
.memory(new InMemoryMemory())
.build();
// 尝试加载现有会话
SessionManager.forSessionId(sessionId)
.withSession(new JsonSession(sessionPath))
.addComponent(agent)
.loadIfExists();
// 与智能体交互
Msg userMsg = Msg.builder()
.name("user")
.role(MsgRole.USER)
.content(List.of(TextBlock.builder()
.text("你好!我的名字是 Alice。")
.build()))
.build();
Msg response = agent.call(userMsg).block();
System.out.println("智能体: " + response.getTextContent());
// 保存会话
SessionManager.forSessionId(sessionId)
.withSession(new JsonSession(sessionPath))
.addComponent(agent)
.saveSession();
System.out.println("会话已保存到: " + sessionPath.resolve(sessionId + ".json"));
}
}
最佳实践¶
使用有意义的会话 ID:使用用户 ID、对话 ID 或其他标识符
// 好的做法 SessionManager.forSessionId("user-123-conversation-456") // 避免 SessionManager.forSessionId("session1")
定期保存:在重要操作后持久化状态
agent.call(criticalMsg).block(); sessionManager.saveSession(); // 立即保存
使用
loadIfExists()实现优雅启动:不要在会话不存在时失败// 优雅 - 如果未找到则创建新会话 SessionManager.forSessionId(sessionId) .withJsonSession(path) .addComponent(agent) .loadIfExists();
清理旧会话:删除不再需要的会话
if (userLoggedOut) { SessionManager.forSessionId(sessionId) .withJsonSession(path) .deleteIfExists(); }
处理错误:对关键操作使用 try-catch
try { SessionManager.forSessionId(sessionId) .withJsonSession(path) .addComponent(agent) .saveOrThrow(); } catch (Exception e) { logger.error("保存会话失败", e); // 处理错误(重试、通知用户等) }
故障排除¶
会话未加载¶
问题:loadIfExists() 未恢复状态
解决方案:
验证会话文件是否存在:
sessionManager.sessionExists()检查保存和加载之间的组件名称是否匹配
确保使用相同的组件类型
状态损坏¶
问题:会话加载但智能体行为异常
解决方案:
验证会话文件格式(应为有效 JSON)
检查保存的代码版本和当前代码版本是否不匹配
如果损坏则删除并重新创建会话
文件权限错误¶
问题:无法写入会话目录
解决方案:
检查目录权限
确保父目录存在
使用绝对路径而不是相对路径