背景

某本地 AI 代理系统已经开始定期执行 HEARTBEAT 任务,并能够通过邮件发送状态报告。整体执行链路已经跑通:任务可以被触发,邮件可以正常发出,收件端也能收到报告。

不过在实际使用后,暴露出两个需要调整的问题:

第一,HEARTBEAT 执行频率过高。默认频率约为 30 分钟一次,对于日常状态汇总来说过于密集,容易造成邮件噪音。

第二,新闻摘要任务的输出质量不理想。虽然系统能够抓取公开 RSS 新闻标题并生成邮件,但内容基本停留在“标题列表 + 固定占位摘要”的层面,缺少真正可读的摘要信息。

因此,这次调整主要围绕两个目标展开:

  • 将 HEARTBEAT 频率从默认的高频检查调整为 6 小时一次。
  • 优化每日国际新闻摘要的输出格式,使其包含英文、中文、日文三种语言的标题与摘要。

问题一:新闻摘要内容过于粗糙

原先的新闻邮件结构大致如下:

国际新闻每日摘要(10条)

1. 标题:...
   来源:RSS
   时间:...
   链接:...
   中文摘要:基于公开标题的简要摘要,具体细节请点链接查看。

这种输出存在明显问题:

  • 每条新闻都有标题,但摘要几乎没有实际信息。
  • “基于公开标题的简要摘要”是重复模板句,不适合每天阅读。
  • 只有中文摘要,缺少英文原文标题对应的英文摘要,也缺少日语版本。
  • 对于学习语言、快速浏览国际新闻来说,信息密度不够。
  • 链接虽然存在,但邮件本身不能提供足够的阅读价值。

期望的格式是每条新闻形成一个小型三语新闻卡片,例如:

1. Title: Original English title
   Digest: Short English digest.

   标题:中文标题
   摘要:中文摘要

   タイトル:日本語タイトル
   要約:日本語要約

   source: original source URL

这种格式的优点是:

  • 保留英文原始标题,方便确认新闻原貌。
  • 增加英文 Digest,避免只看标题。
  • 提供中文标题和摘要,适合快速理解。
  • 提供日文标题和要约,兼顾日语阅读训练。
  • 每条新闻最后保留来源链接,方便追溯。

新闻摘要任务规则的修改

原来的任务说明只要求“发送一封简洁的中文新闻摘要邮件”,这会导致 AI 代理自然倾向于输出中文简报,而不是三语新闻卡片。因此,任务规则需要明确改写。

修改后的规则重点包括:

  • 每天选择 10 条重要国际新闻。
  • 每条新闻必须包含英文、中文、日文三种语言。
  • 英文部分包含原始标题和 1–2 句 Digest。
  • 中文部分包含自然翻译的标题和 1–2 句摘要。
  • 日文部分包含自然翻译的タイトル和 1–2 句要約。
  • 每条新闻必须附带对应的 source 链接。
  • source 链接必须与当前条目对应,不能串到其他新闻。
  • 如果 RSS 提供 description、summary 或 content 字段,应优先基于这些字段摘要。
  • 如果公开页面可以安全访问且不需要登录、不绕过付费墙,可以参考页面正文生成更好的摘要。
  • 如果只有标题和链接,不能假装知道正文细节,应明确说明来源没有提供足够信息。
  • 禁止使用重复占位句,例如“基于公开标题的简要摘要,具体细节请点链接查看”。

修改后的核心目标不是“多翻译几种语言”,而是让邮件本身变成可读、可用、可追溯的国际新闻摘要。

问题二:HEARTBEAT 默认频率过高

另一个问题是 HEARTBEAT 默认频率较高。系统状态检查本身已经正常执行,但 30 分钟一次对于当前用途来说没有必要。

经过只读检查后,确认当前系统并不是通过外部定时器或 cron 控制 HEARTBEAT,而是由 AI 代理自身的配置项控制。

检查结果显示:

  • 当前活跃配置文件位于用户级配置目录中。
  • 配置工具支持 get、set、patch、unset、file、schema、validate 等子命令。
  • 状态输出显示主代理的 HEARTBEAT 当前为 30 分钟一次。
  • 30 分钟对应的内部毫秒值为 1,800,000。
  • 配置文件中没有显式写死该值,说明这是默认值。
  • 默认配置代码中也能看到 HEARTBEAT 默认值为 30 分钟。
  • HEARTBEAT 间隔按 duration 字符串解析,例如 30m6h
  • 如果要改成 6 小时,最合适的写法是 6h,而不是 360m 或秒数。

因此,最终修改目标是:

默认 HEARTBEAT 间隔:30m
调整后 HEARTBEAT 间隔:6h
内部毫秒值:21600000

修改方式

修改前先进行了 dry-run,确认配置写入动作可以被接受。

示意命令如下:

<agent-cli> config set <heartbeat-interval-key> 6h --dry-run

dry-run 成功后,再实际写入:

<agent-cli> config set <heartbeat-interval-key> 6h

系统返回配置已更新,但同时提示需要重启 gateway 后生效。

这说明虽然此前从代码路径推测该配置可能属于可热重载范围,但实际 CLI 输出更可靠。最终判断应以运行环境中的明确提示为准:配置已写入,但需要重启 gateway。

重启时遇到的 systemd user service 问题

最初尝试用系统级 systemd 重启 gateway:

systemctl restart <gateway-service>

结果返回:

Unit not found.

这并不代表服务不存在,而是说明该 gateway 并不是系统级 service,而是用户级 systemd service。

正确方式是使用:

systemctl --user restart <gateway-service>

随后检查用户级服务状态:

systemctl --user status <gateway-service> --no-pager

状态显示服务已经重新启动并处于 active running。

这一步也确认了一个重要事实:该代理系统在当前环境中运行在用户级 systemd 下,而不是系统级 systemd 下。后续维护时需要区分:

系统级服务:systemctl ...
用户级服务:systemctl --user ...

生效验证

重启用户级 gateway 后,通过状态命令查看 HEARTBEAT 配置。

输出中可以看到:

"heartbeat": {
  "agents": [
    {
      "enabled": true,
      "every": "6h",
      "everyMs": 21600000
    }
  ]
}

这说明配置已经真正生效:

  • HEARTBEAT 间隔已经从 30 分钟变为 6 小时。
  • 内部毫秒值为 21,600,000。
  • gateway 已经加载新配置。
  • 不需要再额外修改 cron 或 systemd timer。

固定时间与固定间隔的区别

调整完成后,还需要明确一个概念:当前这个 HEARTBEAT 配置控制的是“间隔”,不是“固定时刻”。

也就是说,配置为 6h 后,系统逻辑更接近:

gateway 启动后,每隔 6 小时触发一次 HEARTBEAT。

而不是:

每天 06:00、12:00、18:00、00:00 固定触发。

如果 gateway 在 23:09 重启,那么下一轮 HEARTBEAT 很可能会接近:

05:09
11:09
17:09
23:09

但这只是基于间隔推算,具体触发时间仍取决于代理系统内部调度实现。

如果未来需要“每天固定时间发送新闻邮件”,不能只依赖 HEARTBEAT 间隔配置。更合理的方式是分层处理:

HEARTBEAT interval:控制代理多久醒来检查一次任务。
每日新闻任务 cadence:控制新闻任务每天执行一次。
固定时间发送:需要额外的定时触发机制,或代理系统本身支持固定时刻调度。

当前场景的目标只是降低 HEARTBEAT 频率、减少邮件噪音,因此 6 小时间隔已经足够。

本次调整后的最终状态

本次调整完成后,系统状态如下:

  • HEARTBEAT 已正常执行。
  • 邮件发送链路正常。
  • 每日国际新闻摘要规则已改为三语格式。
  • 新闻摘要不再接受固定占位句作为默认输出。
  • HEARTBEAT 频率已从默认 30 分钟调整为 6 小时。
  • gateway 已通过用户级 systemd 重启。
  • 状态输出确认 every = 6heveryMs = 21600000
  • 当前 HEARTBEAT 属于间隔触发,不是固定时刻触发。

经验总结

这次调整体现出几个重要经验。

第一,任务说明必须足够明确。
如果只写“发送中文新闻摘要”,系统就可能输出非常简略的中文标题列表。想要得到三语标题、三语摘要、来源链接和可读内容,就必须把格式和摘要规则写死。

第二,不能接受无信息量的占位摘要。
“基于公开标题的简要摘要”看似安全,但长期使用价值很低。更合理的做法是:有 RSS 摘要就用 RSS 摘要,有公开正文就参考公开正文,没有足够信息就明确说明信息不足。

第三,配置修改应先 dry-run,再实际写入。
这可以避免误改配置,也能确认配置工具是否接受目标路径和值。

第四,实际 CLI 输出优先级高于代码推断。
即使代码路径显示某配置可能支持热重载,只要 CLI 明确提示需要重启 gateway,就应按实际提示执行。

第五,要区分系统级 service 和用户级 service。
同一个服务如果运行在用户级 systemd 下,系统级 systemctl 会找不到对应 unit。遇到 Unit not found 时,应检查是否需要使用 systemctl --user

第六,固定间隔不等于固定时间。
6h 只能表示每隔 6 小时执行一次,不能保证每天固定几点执行。如果需要固定时间,需要额外调度机制或任务系统本身支持固定时刻。

结论

本次维护完成了两个层面的优化:一是提升每日新闻摘要邮件的可读性,二是降低 HEARTBEAT 执行频率,减少不必要的通知噪音。

最终效果是:系统仍然保持自动巡检和每日摘要能力,但执行频率更适合日常使用,新闻邮件也从简单标题列表升级为更实用的三语摘要卡片。整个过程没有依赖外部账号登录,没有绕过付费墙,也没有引入高权限自动化操作,符合低风险、可验证、可回滚的本地运维原则。

Leave a Reply

Your email address will not be published. Required fields are marked *