☰
Memoh会话运行时原理:AI Agent会话如何在服务器重启后不丢失上下文
2026/10/2 19:35:54 网站建设 项目流程

Memoh会话运行时原理:AI Agent会话如何在服务器重启后不丢失上下文

【免费下载链接】Memoh✨ The open-source multi-agent platform. Every agent gets its own computer, desktop, network, and long-term memory. You can bring your own key, or host your coding agent like Claude Code, Codex and so on.项目地址: https://gitcode.com/gh_mirrors/me/Memoh

Memoh 是一个开源多智能体(Multi-Agent)平台:每个 AI Agent 都拥有自己的"云端电脑"——独立的工作区、桌面、网络和长期记忆。这篇文章面向新手用户,用尽量少的代码,讲清楚 Memoh 的会话运行时(Session Runtime)是如何工作的:为什么服务器重启、甚至多实例滚动升级时,AI Agent 的会话上下文不会丢失,进行中的任务也能自动续跑。

你会遇到的问题:AI 会话怕"重启"

大多数聊天机器人都有一个通病:服务端一重启,正在进行的对话就"断片"了。轻则回答中断、需要你重发一遍,重则 Agent 忘记了自己正在执行什么任务,之前积累的判断全部归零。

对普通用户来说,这种体验很难受;对自托管(Self-Hosted)部署的管理员来说更糟——升级服务器、重启容器,都成了"高危操作"。Memoh 把这个问题当成架构级问题来解决:它不是"尽量别断",而是保证断得掉、续得上。

核心思想一:先写账本,再干活(持久化优先)

Memoh 的会话运行时建立在一个简单但关键的原则上:

任何输入在被接受(accepted)之前,必须先落到数据库;任何执行状态的变化,都以 PostgreSQL 中的"账本"(ledger)为准。

具体来说,你的每一次提问在系统里会生成一条session_runs账本记录,包含:

  • 你的原始输入内容
  • 全局唯一身份标识(invocation_id、run_id、turn_id)
  • 当前执行状态(运行中 / 等待审批 / 已完成 / 已中断等)
  • 已持久化的中间输出

这套账本的设计约束写在 会话运行时正确性要求 中,核心条款 SR-DUR-001 明确写道:

"Server 在返回 accepted 后退出,重启后的系统必须仍能查询到原始用户输入、run 身份和最后一个已持久化状态……不能只把已接受输入保存在 goroutine、WebSocket handler 或进程内 Manager 中。"

翻译成大白话:进程的内存只是"草稿纸",数据库才是"账本"。进程随时可以死,账本永远在。

核心思想二:给每次执行发"身份证",重复提交不会跑两遍

Memoh 用一组严格的身份标识把"一次对话"切成几个互不混淆的概念:

身份作用
invocation_id标识"一次提交"。网络抖动导致你连点两次发送?系统保证只执行一次
run_id标识"一次被接受的执行"。整个执行过程围绕它展开
turn_id标识对话时间线上的一个回合,把你的输入、Agent 的回答、工具调用关联起来
decision_id标识一次审批或用户补充输入请求,保证你的回答不会被应用到错误的执行上

这带来两个对用户很友好的保证:

  1. 幂等重试:请求发出去没收到回音,你安全地重试,不会触发第二次模型调用、不会写入两条重复消息。
  2. 单会话串行:同一个会话同一时刻只有一个"执行者"(owner),不会出现两个服务器实例同时在跑同一个会话的情况。

这套算法和并发测试集中在 internal/agent/runtime/session/ 目录,其中的 admit.go 负责准入判断,fence.go 负责所有权"围栏"(fencing)校验。

核心思想三:优雅关机打标 + 自动恢复续跑

这是整个机制里最精彩的部分,分三步走:

第一步:关机前"留纸条"。服务器收到停机信号后,会先关闭新输入、给所有正在运行的会话打上session_runtime.interrupted(已中断)标记,然后才取消执行、关闭 HTTP 服务。整个优雅关机预算是 30 秒,Docker Compose 侧允许 45 秒。

第二步:启动后自动"翻账本"。服务器重启后,一个有界的工作协程会扫描账本中所有"被中断"的运行,读取其中保存的版本化恢复上下文(原始提问、模型选择、执行位置、剩余时间预算等),然后用一个稳定的身份(resume:<原run-id>)提交续跑任务。

第三步:续跑时"先看现场"。恢复出来的执行会重新加载已提交的历史,并指示模型先检查被中断的工具执行结果,再决定下一步动作——避免盲目重复执行一个已经跑了一半的命令。

这三步的完整描述在 docs/agent-runtime.md 的 "Graceful shutdown and session resume" 一节。需要说明的诚实边界:SIGKILL、OOM 这类"猝死"无法可靠地写标记,此时运行会收敛为lost(丢失)状态——但你的输入依然保存在账本里,可以手动重试或开启新任务。

核心思想四:多实例部署时的"租约 + 围栏"

如果你部署了多台服务器(比如做负载均衡或滚动升级),还会出现一个新问题:谁来执行这个会话?旧实例还没死透,新实例已经开始接手怎么办?

Memoh 用两个经典分布式手段解决:

  • 租约(Lease):owner 身份必须持有跨实例可验证的租约(单实例部署用进程内内存后端,多实例部署用 Redis/Valkey,启动时会校验配置,缺少依赖会拒绝进入多实例模式)。
  • 围栏令牌(Fencing Token):每次所有权转移都会让令牌单调递增,旧 owner 迟到的写入会带着"过期令牌",被数据库直接拒绝。

效果是:即使新旧两个实例短暂并存,也最多只有一个拥有写入权,会话不会出现"精神分裂"。

这套机制在多实例下的黑盒验收测试位于 internal/agent/runtime/session/acceptance/,其 README 中列出了关键场景:双服务器重连快照、跨实例 abort 路由、owner 进程被 SIGKILL 后状态仍可查询(收敛为lost)、终态重放不产生重复消息等。

真实压过一遍:滚动升级不丢会话

原理说得再漂亮,还是要实战检验。Agent 生命周期 QA 报告 记录了一次真实的"滚动替换"演练:

  1. 旧实例正在服务流量,新实例接入同一个 PostgreSQL 和 Valkey;
  2. 通过 UI 发起一个带真实长命令的会话,命令还在执行、模型还在流式输出;
  3. 切换代理上游到新实例,停掉旧实例(45 秒宽限);
  4. 不发送任何新的用户消息,观察新实例的账本、UI 和任务文件。

结果:会话在新实例上自动恢复(UI 出现ROLL_RESUMED标记),所有权从实例 C 转移到 D,围栏令牌从 26 递增到 27,代理健康探测 42 秒内 200/200 全部成功,任务文件的执行凭据在替换前后各一行、没有重复。长任务场景同样验证过:父子 Agent 各执行了 660 秒的真实子命令,跨越重启边界完整完成。

外部运行时(Claude Code / Codex)如何续命?

如果你托管的是 Claude Code、Codex 这类"自带会话记忆"的外部 Agent,Memoh 还有第二道保险:这些运行时会在 Bot 的工作区数据卷上保存自己的会话文件(Codex 的 rollout、Claude Code 的 transcript)。Memoh 记录的是"如何恢复它"的元数据(Codex thread id / rollout 路径、Claude 会话 ID),重启后按路径优先恢复原生会话;万一原生会话无法恢复,本轮会开启新会话并明确告知(native_history_lost通知),后续轮次从 Memoh 的组合上下文继续——而聊天历史始终完整保存在 PostgreSQL 里,不会丢。

写在最后

回到开头的问题:AI Agent 会话为什么能在服务器重启后不丢上下文?Memoh 的答案可以浓缩成四句话:

  1. 持久化优先:输入和状态先写进 PostgreSQL 账本,内存只是缓存;
  2. 身份严格:invocation_id/run_id/turn_id保证幂等、防重、防错配;
  3. 中断有标记、恢复有流程:优雅关机打interrupted标记,重启后自动发现、自动续跑、先检查工具现场再行动;
  4. 多实例有租约、有围栏:所有权转移全程可验证,旧实例的迟到写入一律作废。

对于自托管用户,这意味着升级、重启、扩容都成了低风险操作;对于普通用户,这意味着你的 AI Agent 真正"活在服务器上"——即使合上笔记本,它也记得自己正在做什么。想深入了解设计细节,可以对照阅读 docs/design/session-runtime-requirements.md 与 docs/design/context-memory-scheduling.md。

【免费下载链接】Memoh✨ The open-source multi-agent platform. Every agent gets its own computer, desktop, network, and long-term memory. You can bring your own key, or host your coding agent like Claude Code, Codex and so on.项目地址: https://gitcode.com/gh_mirrors/me/Memoh

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询