新人笔记---hermes定时功能设计,具体讲解以及可优化点

该笔记篇主要是博主在设计自己Agent项目定时功能时的笔记篇,主要是学习,参照hermes成熟的cron设计体系,如何支持任务高度定制,风险管控,权限审批,消息溯源机制等等一系列cron功能设计的细节点,通过深入学习hermes的设计,可以深入理解他cron功能设计的精妙点,同时结尾附上博主自己项目的该功能的优化点以及设计思路方案,参考文档hermes定时功能深入讲解

1.hermes的cron是可以支持自然语言描述任务,不用手写cron表达式啥的,比如cron表达式,once表达式,相对延迟(30m,50h)之类的,对于任务时间的定义方式比较多

类型 说明 触发类型 写法示例 行为说明
相对延迟(one-shot) 多久之后跑一次 一次性 30m / 2h / 1d 从任务创建时刻开始倒计时;跑完任务直接消失,不会重复Hermes Age...
固定间隔(interval) 每隔多久循环跑 周期性 every 30m / every 2h 从创建时间起,每间隔固定时长执行;不是对齐整点
标准 Cron 表达式 传统 5 位 cron 周期性 0 9 * * * 分 时 日 月 周;对齐日历时间(每天 9 点),适合定点排班Hermes Age...
ISO 时间戳 指定一个精确时刻跑 一次性 2026-11-01T14:30:00 到这个绝对时间点执行一次,执行完任务销毁Hermes Age...

2.hermes-定时任务本身以JSON对象表达,落盘持久化,比如任务的定义,描述等存放在~/.hermes/cron/jobs.json,任务的输出产物存放在~/.hermes/cron/output/{job_id}/{timestamp}.md

  • 目标:服务重启、多进程并发访问的时候,定时任务不会丢失,调度可以持续跑

3.- 定时任务存储严格按profile隔离

  • 每个Hermes Profile拥有独立的 HERMES_HOME 目录
  • 🛡️ 安全价值:不同profile之间,凭证、配置不会互相泄露
    -核心作用:确保不同作用域范围的cron任务不会相互干扰,破坏安全性

4.Hermes 在读写 jobs.json (定时任务文件)时做了两层锁设计:跨进程锁 + 进程内递归锁,并且增加锁超时机制,防止死锁、多进程并发篡改定时任务。

👉 两层锁组合逻辑:

  1. 跨进程文件锁:拦住别的进程来改文件
  2. . 进程内递归锁:拦住本进程内部多个线程同时进入读写逻辑
    表格
锁类型 作用域 锁类型 解决问题
跨进程文件锁 机器内所有 Hermes 进程 文件排他锁(flock /fcntl) 不同进程同时打开、写入 jobs.json,文件撕裂
进程内递归锁 当前单个进程内部 递归互斥锁(ReentrantLock) 同一进程多个线程(多个协程 / 处理入口)同时调用读写;支持同一个线程重复加锁不阻塞
锁超时 两层锁都带超时 超时控制 防止某个线程 / 进程拿到锁后异常卡住不放锁,全局卡死调度
以一次要修改 jobs.json(新增 / 更新 / 删除任务)为例:
  1. 线程尝试获取【进程内递归锁】,带超时
    • ✅ 获取成功:进入下一步
    • ❌ 超时失败:直接抛锁获取超时异常,终止本次操作,不碰文件
  2. 在已经持有进程内递归锁的前提下,尝试获取【跨进程文件排他锁】,带超时
    • ✅ 获取文件锁成功:现在拿到双层锁保护,可以打开 jobs.json
    • ❌ 文件锁超时失败:释放递归锁,抛出异常,退出
  3. 安全执行文件逻辑:读取 json / 内存修改 / 序列化写回磁盘(一般会先写临时文件,rename 原子替换 jobs.json,进一步防文件损坏)
  4. 释放顺序:反向释放
    1)先释放跨进程文件锁
    2)再释放进程内递归锁(递归计数减一,计数到 0 才真正释放)

读操作:看实现,Hermes 这里文件锁一般也是排他锁(读写都加排他),简化模型;也有方案读共享写排他,Hermes 为简单稳定,读写统一排他。

5.Hermes 的 Cron 调度器运行在 gateway 进程内部,后台定时触发 tick 心跳扫描到期任务;通过tick全局锁 + Job认领+心跳保活整套机制,保证多进程场景下同一个定时任务不会被重复并发执行。

Claim(认领)就是:多个进程一起抢同一个到期定时任务,其中某一个进程成功给这个任务打上「我正在处理它」的标记,宣告所有权;拿到标记的进程负责执行,其他进程看到标记就跳过这个任务。

任务续命机制(heartbeat refresh):心跳线程相当于定时"打卡续命",任务活着就不断延长认领有效期;一旦进程挂掉打卡停止,认领自动失效留给别的实例接管。

核心作用是长定时任务执行期间可以不断续期,因为hermes每个任务都有租期,任务到期后没有续期,当前任务就会有可能被其他线程抢走,类似于看门狗机制(watch dog)

6.hermes通过run_job方法启动定时任务,任务以及执行结果是存放在磁盘文件中,cron的执行过程,也就是cron的Agent的执行过程是存放在sqlite中,具体流程如下

复制代码
调用 run_job()
    ↓为本次任务新建专属 SessionDB SQLite连接(带10s锁等待超时)    
    ↓启动Agent工作流执行    
    ↓任务快要结束、会话关闭前,写入唯一session标题存入数据库    
    ↓关闭会话、释放数据库资源

好处如下:

  1. 稳定性兜底(SQLite超时)
    SQLite锁阻塞是非常经典坑,Agent场景任务多很容易并发抢库,10s超时防止线程卡死,保护整个cron tick调度循环。
  2. 会话隔离(dedicated连接)
    每次定时任务独立数据库会话,任务之间数据库操作互相隔离,减少互相干扰。
  3. 可追溯可审计
    每一次定时任务运行都打上唯一会话标识,后续可以回溯完整Agent执行记录,适合生产环境排查Agent执行异常。

7.Hermes Cron 的 pin(固定绑定):创建定时任务的时候,可以硬性指定这个任务只能跑在某一组 provider(模型服务商) + model(模型名称) ;不绑定的任务,则会跟随全局配置动态选择模型,支持服务商故障自动切换。

简单说:就是可以为每个cron绑定自己的任务模型,用来执行cron任务

8.Hermes Cron 里面分为两大类定时任务:Agent Jobs(AI智能体任务) 和 No‑Agent Jobs(纯脚本任务,不用大模型)

  1. Agent Jobs(智能体任务)- 走 Hermes 完整的 AIAgent 核心工作流流水线- 会调用大模型(LLM),可以加载、使用各种Skill工具- 你写的prompt交给Agent,LLM自主思考、调用工具、完成复杂任务
  • ✅特点:需要模型,Agent自动规划执行 例子:每周定时让AI读取文档、分析数据、自动生成业务周报
  1. No‑Agent Jobs(无Agent脚本任务) - 通过底层函数 _run_job_script() 直接运行独立脚本
  • ❌完全不调用LLM,不消耗Token- 脚本运行后的标准输出(stdout)直接捕获保存
    • ✅特点:可以把任意代码作为定时任务跑 例子:定时运行python脚本备份文件、定时shell脚本拉取服务器监控指标

9.Hermes Cron 任务跑完之后,运行结果可以投递到3种不同目标位置:本地文件、原始对话会话、第三方消息平台,整套投递由网关适配器负责路由分发,同时做安全校验防止异常。

(1)本地文件形式:- 路径: ~/.hermes/cron/output/{job_id}/{timestamp}.md

(2)原始会话形式:自动把结果推送回最开始创建这条定时任务的那一条对话线程,- 底层依靠 _resolve_origin() 解析任务里面记录的来源会话信息,用户可以直接在原来聊天对话里面收到定时任务结果,上下文连贯,立刻看到输出

(3)第三方平台投递:通过网关平台适配器 + 凭据池,支持将定时任务推送到第三方的消息平台,比如X,telegram,飞书等等平台,hermes本地支持大量第三方消息平台配置

简单点理解:hermes已经内置好了对应平台的Api对接,当cron执行完后会调用该平台api推送消息,hermes就是做了平台与ai直接的通信机制,底层继续下面两套机制

  1. Gateway进程(网关)
    网关是长驻后台进程,所有第三方平台消息收发都由gateway统一接管,cron投递能力复用这套网关基础设施
    启动网关之后,各个平台适配器加载、连接IM服务,监听收到的消息,同时对外发送任务结果
  2. Platform Adapter 平台适配器
    每个IM平台单独一套adapter(telegram.py、matrix.py),封装该平台独有的SDK、API调用逻辑
  • 收消息:适配器接收平台消息,转成Hermes内部统一会话格式交给Agent
  • 发消息(cron投递):把cron任务输出,转换成对应平台消息格式调用API发送

10.Hermes Cron 内置一套完整监控、诊断、故障巡检工具链,可以通过 CLI 查看任务状态、识别逾期任务,还提供 cron doctor 一键体检,用来排查配置、脚本、投递、调度存活等各类问题。

命令: hermes cron list

​- 功能:列出全部 cron 任务,展示任务状态标记:

​- enabled :启用

​- paused :暂停

​- completed :一次性任务已执行完毕​- 下次调度执行时间

11.因为 cron 定时任务是无人值守自动运行,Hermes 专门增加了一套安全防护机制,分为两套扫描函数,拦截提示词注入、机密外泄、敏感文件读取等高危行为,同时针对 Skill 拼接场景做策略折中,兼顾安全性与业务灵活性。

_scan_cron_prompt() 函数负责扫描,命中可疑恶意模式直接拒绝任务执行:

  1. 提示词劫持指令
    ignore previous instructions 、 disregard your rules 这类试图让Agent抛弃原有系统规则的注入指令
    2. 窃取机密并外发使用 curl / wget 携带认证请求头,向不可信外部主机上传、盗取内部密钥
  2. 读取系统敏感文件尝试读取 .env 、 .netrc 、 /etc/sudoers 这类存放账号密码、权限配置的敏感文件

通过他,可以在执行cron前拦截一些风险提示词的问题啥的,保证定时任务可以正常执行

_scan_cron_prompt() 底层是硬编码正则 / 硬编码危险关键词模式(黑名单)做匹配,属于基于规则的扫描,不是大模型语义扫描

_scan_cron_skill_assembled():专门给多个 Skill 自动拼接生成的提示词用的一套"宽松版安全扫描器",用来减少正常业务场景误拦截,但依然拦住提示词注入攻击。

简单说他就是专门审查skills,当ai启动时往系统提示词加载一堆skills,他会宽松审查skills,查找skills是否出现风险的提示词,指令啥的,但是策略比较宽松,也是为了进一步保证后台cron执行时安全可靠

12.hermes的cron功能本质就是在后台启动一个cron的agent,去帮我们执行任务,进行任务汇报等等,所以对于agent弹出的工具审批啥的,我们也是需要进行处理,让后台agent可以稳定运行

核心痛点:交互式聊天时遇到高危工具/Shell,可以弹窗等待人工审批;Cron是无人值守后台跑,没人在线点同意,必须一套独立的审批策略,配置项在 config.yaml 的 approvals.cron_mode

Cron专属两大审批模式(最核心)

复制代码
approvals:
  cron_mode: deny   # 可选 deny / approve

1.deny (默认推荐,出厂默认)

​- 当Agent在cron执行过程调用被标记为危险的工具、高危Shell命令时 → 直接拒绝执行,任务记录失败,不会卡住等待人工

​- ✅ 安全优先,适合绝大多数后台定时任务,防止无人值守场景自动执行高危操作

​2. approve (全自动放行模式)​- 遇到高危命令自动审批通过,无需人工干预,实现完整自动化跑Agent工作流

​- ⚠️ 高风险,只有充分评估任务Prompt、Skill边界之后才打开

Hermes 里所有工具调用有一套安全标签:

  • 工具 / Shell 脚本可以被标记为 高危(需要人工审批)
  • 正常交互式会话(人手动发起任务):遇到高危调用 → 阻塞、等待人点审批 / 拒绝,卡在那里等输入

但是!定时 Cron 任务是无人值守后台跑的 ,没人在线审批,所以单独分出 cron_mode 来定义「没人的时候遇到高危调用怎么办」。

表格

cron_mode 行为 阻塞? 结果记录 适用场景
deny(出厂默认推荐) 命中高危工具 / 高危 Shell → 自动拒绝 ❌ 不阻塞,直接拒绝 任务标记失败,写入日志,不再继续往下执行 绝大多数后台定时任务,安全兜底,防止定时任务偷偷执行高危操作
approve 命中高危工具 / 高危 Shell → 自动放行、自动审批通过 ❌ 不阻塞,直接执行 任务继续正常跑,流程走完 可控、经过审计的自动化流水线;风险极高

下面需要讲解一下他的approve模式:

先理清边界:approve 到底放开了什么,没放开什么

项目 approve 是否放开
高危工具人工审批卡点 ✅ 放开(自动同意)
Skill / 工具本身的入参校验、白名单 ❌ 不放开
Shell 命令语法黑名单、命令过滤规则 ❌ 不放开
操作系统账号权限(uid、文件 DAC、sudo 权限) ❌ 不放开
资源限额(CPU / 时长 / 内存 / 输出大小) ❌ 不放开
任务沙箱隔离(如果开启沙箱) ❌ 不放开
日志审计、调用快照记录 ❌ 不放开(甚至会强制加强)
其他独立的全局安全策略 ❌ 不放开

通俗例子:

一个 Shell 工具标记为高危,正常交互式要等人工审批;

cron_mode=approve:不用等人,直接放行这个工具调用;

但是:如果这个 Shell 内置黑名单禁止 rm -rf /,或者运行账号根本没有 root,这条命令照样跑失败。

总结一下:放开approve权限不代表所有工具审批都同意,像claudecode,codex等都是有内置的指令黑名单,白名单啥的,即使放开了shell,但是shell如果命中指令黑名单,也是直接拦截不执行的,这一点需要清楚

13.定时工具博主总结的不同设计以及可优化点:

借助像claudecode,codex等agent的定时功能设计,我们其实还可以对cron功能设计更加精确化以及安全性管控,具体实施如下:

(1)可以对每个cron暴露指定的工具,不同工具集的cron具备不同能力,比如我们暴露只读工具,那么cronAgent在执行时只能做汇报类,暴露可写工具,那么就可以执行写操作,对于暴露了subagent子代里等工具,cronAgent就可以成为真实的agent,能够帮我们像真实Agent一样自动化处理复杂任务。通过对每个agent暴露不同工具集可以进行cron任务的个性化设计

(2)对于cron的审批机制,我们就可以融入codex的审批机制,将cron的审批分为用户审批与自动审批,

用户审批模式下,cron的特定权限审批(高风险指令)可以交给用户,用户代替审批,审批完后cron继续执行。
自动审批下,可以实现真正后台cron,有自动化审批agent收集cron上报的审批请求,自己审核后决定是否批准或拒绝

下面以博主自己的Agent项目讲解:

我们的每个任务可以进行个性化工具配置,提供基础任务(只读),工作区任务(暴露可写工具)与自定义工具组(自己定制cron可使用工具)

博主是将自己的Agent所有可调用的任务分为一组一组,成为能力组,勾选文件读取与检索,那么就会自动封装所有只读工具暴露给cron,勾选shell,cron就可以使用shell一类的所有指令,高度化自定义工具可以极大提升cron灵活性

同时我们将审批方式分为自动审批与人工审批,人工审批用于用户在使用Agent是可以手动审批cron权限,复用我们主Agent的权限系统,不新建第二套,同时极大提升我们对于cron的执行可控性,自动审批用户用户后台执行cron任务,让自动化审批助手去完成审批,对于自动审批功能的设计,可以学习codex的权限机制

至此,hermes的cron功能已经大体上梳理了一边,总结一下,hermes对于cron功能的实现还是挺完整的,不仅可以实现多种任务时间解析格式,多平台投递等任务设计与传递,还做了agent权限把控,cron风险管控,执行溯源机制,并发下的锁机制以及文件存储机制等多种防控措施,确保cron能够安全稳定,遇到意外情况也可以回复任务,继续执行等,如果自身项目有定时任务的需求,还是非常值得人学习的

相关推荐
Fluxproxy1 小时前
大模型批量数据采集:AI 自动化工作流搭建实战
大数据·人工智能·自动化
AAwangzong1 小时前
AI时代RPA技术解析:如何构建兼顾流程执行与智能决策的自动化平台?
人工智能·经验分享·rpa·智能体
ZWZhangYu1 小时前
从 Dify 实践理解大模型上下文缓存
java·后端·spring
达达表哥1 小时前
AI综合站商业分发系统v3.1纯净版发布 附完整安装教程(排版修正版)
人工智能
众壹新能源科技1 小时前
逆变器直流开关柜温度监测与预防:红外巡检发现3个120度热点
运维·人工智能·自动化
小羊没烦恼!1 小时前
关于分布式锁原理的一些学习与思考-redis分布式锁,zookeeper分布式锁
java·服务器·网络·学习·负载均衡
NeoGressAI外贸数字化1 小时前
外贸独立站robots.txt怎么写:6个AI爬虫放行规则
人工智能·爬虫
米软科技2 小时前
数字化转型:多元化集团如何构建高效的AI数字化中台?
大数据·人工智能
幼儿园蛋小黄2 小时前
从 STM32N647 的 AI 部署入门嵌入式:一条可落地的学习路线
人工智能·stm32·学习