HoRain云--Hermes Agent Session 生命周期与定时任务
Session 重置策略重置策略控制会话何时自动「失忆」——获得一个新的 session_id旧的上下文被归档。合理配置重置策略可以避免 Agent 上下文无限膨胀同时确保用户体验不受影响。四种重置模式模式行为适用场景none永不自动重置上下文仅由压缩机制管理需要长期连续上下文的场景idle闲置超过 N 分钟后自动重置偶尔使用的 Agentdaily每天在指定时间自动重置每日例行使用的 Agentboth闲置超时或每日重置哪个先触发就执行哪个大多数场景默认推荐配置重置策略实例# config.yaml - 全局重置策略session_reset:mode: both # none | idle | daily | bothat_hour: 4 # 每日重置时间凌晨 4 点本地时间idle_minutes: 1440 # 闲置超时1440 分钟 24 小时notify: true # 重置时通知用户# 按平台自定义重置策略platforms:telegram:session_reset:mode: idleidle_minutes: 720 # Telegram 会话 12 小时闲置后重置slack:session_reset:mode: none # Slack 会话永不自动重置重置效果当会话触发重置时会发生以下事情旧会话在 SQLite 中被标记为结束reason: session_reset生成新的 session_id格式YYYYMMDD_HHMMSS_8位随机hex新 SessionEntry 的 was_auto_reset 标记为 true缓存的 Agent 实例被清理用户在下一条消息中会收到「会话已重置」的提示有活跃后台进程的会话永远不会被重置。Hermes 会检查 has_active_processes 回调确保不会中断正在运行的任务。重启恢复机制Hermes Gateway 的重启恢复机制确保在意外崩溃或计划内重启后正在进行的会话不会丢失。两种恢复标记标记触发场景行为严重程度resume_pending崩溃恢复、drain 超时保留 session_id下次访问时继续对话软恢复suspended/stop 命令、3 次连续重启失败强制重置生成新的 session_id硬重置启动恢复流程当 Gateway 启动时恢复流程如下第一步检查 .clean_shutdown 标记。如果存在说明上次是正常关闭跳过恢复流程。第二步如果不存在 .clean_shutdown 标记说明上次是异常退出。Gateway 调用 suspend_recently_active()将最近 120 秒内有活动的会话标记为 resume_pending。第三步检测 stuck-loop卡死循环。如果某个会话在连续 3 次重启后仍然处于活跃状态说明它可能陷入了死循环Gateway 会将其标记为 suspended。第四步恢复待处理会话。Gateway 为每个 resume_pending 的会话合成一条 MessageEvent触发 Agent 自动继续。Drain 超时标记在正常关闭/重启过程中如果某个会话正在处理中但超过了 drain 等待时间Gateway 会将其标记为 resume_pending。不同场景的标记原因标记原因含义restart_timeout重启过程中 drain 超时shutdown_timeout关闭过程中 drain 超时restart_interrupted崩溃恢复从 suspend_recently_active 触发resume_pending 标记不会在 get_or_create_session() 时被清除——它会在下一次成功的 Agent 回复后被清除。如果恢复后的会话再次中断标记保留允许下次重启时重试。连续 3 次失败后升级为 suspended。消息队列机制当用户在 Agent 处理消息期间连续发送多条消息时Gateway 的消息队列机制确保消息不会丢失。队列结构Gateway 使用两级队列设计单槽 pending_pending_messages每个会话只有一个「下一条」槽位重复发送会覆盖溢出队列_queued_events当槽位被占用时后续消息追加到溢出队列尾部/queue 命令/queue 命令让你可以批量提交任务每个任务都会产生一个完整的 Agent 回合。实例# 在 Telegram/Discord 中发送/queue 审查 src/main.py 的代码风格/queue 为 src/utils.py 编写单元测试/queue 更新 README.md 中的安装说明队列中的每个任务按 FIFO 顺序依次执行每个任务产生一个完整的 Agent 回合不会合并。使用 /new 或 /reset 命令可以清空当前会话的消息队列。在 Agent 处理消息期间连续发送多条消息中间的会被覆盖只保留最后一条/queue 命令中的消息则不会被覆盖——每个 /queue 任务都会按顺序执行。定时任务CronHermes 内置了 first-class 的定时任务支持让你可以配置 Agent 定期执行特定任务。定时任务可以绑定 Skill并将结果投递到指定平台。配置定时任务定时任务在 jobs.json 中定义支持多种调度格式。{ jobs: [ { id: daily-news-summary, schedule: 0 8 * * *, description: 每天早上 8 点抓取 AI 行业新闻并生成摘要, skill: ai-news-summarizer, deliver_to: { platform: telegram, chat_id: -1001234567890 } }, { id: weekly-code-review, schedule: 0 10 * * 1, description: 每周一早上 10 点审查项目代码变更, skill: code-review-assistant, deliver_to: { platform: discord, chat_id: 123456789 } }, { id: health-check, schedule: */30 * * * *, description: 每 30 分钟检查服务器健康状态, skill: server-health-checker, deliver_to: { platform: telegram, chat_id: 123456789 } } ] }支持的调度格式格式示例说明Cron 表达式0 8 * * *标准 5 段 cron 表达式间隔30m每 30 分钟相对时间90s90 秒后执行一次重复次数repeat.times: 5执行 5 次后自动停止可以在桌面版配置, 点击左下角的排程点击新建定时任务创建任务定时任务绑定 Skill 后执行的输出会自动格式化为 Skill 定义的输出格式。这确保了定时任务的结果在投递到消息平台时呈现方式一致且可读。Chronos 托管 Cron进阶Chronos 是 Hermes 的托管式定时任务方案专为 scale-to-zero 部署模式设计。当你的 Gateway 在空闲时完全停止运行Chronos 仍然可以确保定时任务按时触发。为什么需要 Chronos内置的 cron ticker 需要 Gateway 进程持续运行——如果 Gateway 缩容到零定时任务就不会触发。Chronos 将定时任务的管理委托给 NASNous Account Service通过外部调度器在任务触发时唤醒 Gateway。Chronos 工作流程Chronos 的工作流程分为四个步骤第一步Agent 计算下次触发时间向 NAS 注册一个 one-shot 定时器。第二步NAS 使用外部调度器如 Fly Machines 的定时触发在指定时间触发回调。第三步外部调度器回调 NASNAS 生成一个短时效的 JWT Token。第四步NAS 使用 JWT Token 调用 Agent 的 /api/cron/fire 端点Agent 验证后执行任务并重新注册下一个 one-shot。At-most-once 保证Chronos 通过 store 级的 CASCompare-And-Set操作保证每个定时任务只执行一次。即使调度器因为网络重试发送了重复的触发请求Agent 也能通过 CAS 去重确保任务不会重复执行。配置 Chronos实例# config.yaml - Chronos 托管 Cron 配置cron:provider: chronos # 使用 Chronos 代替内置 tickerchronos:portal_url: https://portal.nousresearch.comcallback_url: https://my-agent.fly.dev # Agent 的公网可访问 URLexpected_audience: agent:inst_abc123 # JWT 验证的 audiencenas_jwks_url: https://portal.nousresearch.com/.well-known/jwks.jsonChronos 是托管 Hermes 部署的推荐定时任务方案。如果你使用自托管部署且 Gateway 不会缩容到零内置的 cron ticker 完全够用。如果 callback_url 为空或 Agent 没有 Nous 登录系统会自动回退到内置 ticker。