用户先说“订单 A1042 需要申请退款”,隔一会儿问“处理到哪里了”。Agent 必须知道两次调用属于同一会话,但仅仅记住对话,仍然不能证明退款已经执行。
AgentScope Java 适合用来观察 Agent 的调用状态如何加载、使用和保存。本篇沿这个过程读源码,再把会话状态与业务状态的边界说清。
RuntimeContext 把哪一次调用定位到哪一份状态
RuntimeContext 携带 user ID、session ID 等运行信息。状态存储以用户和会话的组合寻址,避免同名会话在不同用户之间混淆。
// 身份应由服务端认证结果提供;此处 alice 只是教学用户,不能照搬为登录方案。
RuntimeContext context = RuntimeContext.builder()
.userId("alice")
// sessionId 关联对话;退款 taskId 与 operationId 仍由业务系统单独维护。
.sessionId("order-A1042")
.build();
相同 session ID 不等于相同业务操作。一段对话可能讨论多个申请;一个申请也可能被不同会话查询。让 session ID 直接兼任所有退款幂等键,会把这两种关系混在一起。
沿一次 call 看状态装载
源码解读固定提交 7d321e2。在 ReActAgent.java中,activateSlotForContext 从上下文取得用户与会话,定位对应槽位。
配置 stateStore 时,它读取带版本的状态,更新缓存,并基于加载的权限上下文建立调用需要的 PermissionEngine;没有存储时则使用本地缓存路径。这样可以理解为什么仅仅“同一个 Java 对象还活着”与“换进程后能加载状态”是不同条件。
返回的 CallExecution 将本次状态、权限引擎、槽位和加载版本关联起来。阅读时继续追踪调用生命周期,而不是只看 builder 中是否出现一个 storage 参数。
源码注释也需要核对实现
该快照中 activateSlotForContext 附近的注释提到了 acquireExecution 锁,但 AgentBase.java里的 acquireExecution 当前只是检查是否仍接收请求并返回实例,不能据此宣称它提供了互斥锁。
这个细节说明源码解读不能只复述注释。要沿实际方法、调用上下文和存储契约确认保证;更不能把单实例中的生命周期控制推导成多副本分布式锁。
保存接口是否真的防止覆盖
AgentStateStore.java提供普通保存与版本相关接口。值得重点阅读 supportsVersioning、getVersioned 和 saveIfVersion。
默认 supportsVersioning 为 false;默认 saveIfVersion 会退化为普通保存。这意味着“接口里有 CAS 名字”不等于所有后端都具有 CAS 保证。
例如两个服务副本都读到版本 5,一个添加审批消息,另一个添加工具结果。支持版本比较的后端可以拒绝第二个旧版本写入,让应用处理冲突;无版本后端可能让后写者覆盖先写者。
真正选择存储时,应检查具体实现、冲突策略和失败返回,而不只看接口名称。源码阅读清单同时列出内存与 JSON 文件实现,帮助比较适用范围。
AgentState 保存了什么,还缺什么
Agent 状态可以包含消息、工具相关上下文和权限信息。这些对继续模型循环很重要,但外部订单和支付账本仍有自己的权威来源。
如果用户说“记录一下已经退款”,Agent 将这句话写入记忆,不应让业务数据库自动变为 completed。第二次询问时,回答应查询业务 task ID 与支付回执,再解释当前状态。
相反,支付成功但 Agent 状态保存失败,业务系统也不能因为对话记忆缺失就重复退款。业务 operation ID 与账本对账解决这类问题,AgentStateStore 只承担它定义的状态存储责任。
配套 Java 示例应该怎样读
RuntimeSessionDemo.java下载保留现有 Maven 2.0.1 工程,在同一 RuntimeContext 下进行两次调用,并补充详细注释。它只展示会话延续,不提交退款,也不声称证明跨进程业务恢复。
源码分析使用固定提交,Maven 示例使用已有发布依赖,两者刻意标明版本,不将新快照中的接口直接复制到旧依赖里。运行前需要按 README 配置模型凭据;运行条件与验证范围在指南中单独记录。
真正接到退款系统时,可以提供一个只读 query_task 工具,按认证身份查询任务;另一个 submit_refund_request 工具只创建待审批申请;最终支付由受控业务执行器处理。这样对话与交易通过明确接口连接。
多副本需要补齐哪些设计
首先保证所有副本访问相同权威状态后端。其次确定同一会话是否允许并发,如果允许,怎样合并或拒绝冲突。再检查取消、异常与关闭时是否保存了正确调用实例的状态。
多副本共享文件路径不自动解决锁、损坏和故障恢复。将文件换成数据库也不自动赋予外部支付原子性。框架状态与业务账本分别有自己的并发和事务设计。
这篇项目解读的价值,在于让读者知道如何从调用上下文一路追踪到存储语义。后续遇到其他 Agent SDK,同样可以问:状态键是什么,何时加载,何时提交,冲突怎样发现,哪些事实根本不属于这个存储。