惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
GbyAI
GbyAI
阮一峰的网络日志
阮一峰的网络日志
Cloudbric
Cloudbric
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
宝玉的分享
宝玉的分享
I
Intezer
Simon Willison's Weblog
Simon Willison's Weblog
博客园_首页
The Cloudflare Blog
C
Cisco Blogs
AWS News Blog
AWS News Blog
IT之家
IT之家
Cyberwarzone
Cyberwarzone
罗磊的独立博客
美团技术团队
V
V2EX
Project Zero
Project Zero
A
Arctic Wolf
C
Cyber Attacks, Cyber Crime and Cyber Security
大猫的无限游戏
大猫的无限游戏
博客园 - 叶小钗
月光博客
月光博客
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 聂微东
有赞技术团队
有赞技术团队
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
雷峰网
雷峰网
S
Schneier on Security
P
Privacy International News Feed
V
Visual Studio Blog
量子位
T
Tor Project blog
S
Securelist
腾讯CDC
A
About on SuperTechFans
T
Threat Research - Cisco Blogs
G
GRAHAM CLULEY
B
Blog RSS Feed
D
DataBreaches.Net
博客园 - 三生石上(FineUI控件)
B
Blog
NISL@THU
NISL@THU
L
Lohrmann on Cybersecurity
V
Vulnerabilities – Threatpost
人人都是产品经理
人人都是产品经理
博客园 - 【当耐特】
L
LINUX DO - 热门话题
Recorded Future
Recorded Future

BlogFinder

日常漫步 Vol.24 之漫步前山河 - 雅余 周报 #1-聊聊本周的收获 - Edwin's Blog 我的OpenCode必装插件与Skill Write Something 掌中之物未必在掌握之中 · CRIVU PiliNara,一个更顺手的 PiliPlus 分支 「NekoEcho」:做一个必有回响的猫娘主题博客 2026-05 书影音总结 简化博客主题 - 安迪 我第一次发布 npm 包 拾花小记#45:中考前的二三事 – 小改学习志 黛西花园5月游 #18 枇杷又熟了的五月月报 一些奇奇怪怪的需求?word仿方正书版的几个小操作 - Xiobb's Blog 0419 御温泉之旅 修复了一些bug,网站基本上趋于稳定了 - 新锐博客 又回到四十年前 如何定义成功 迷鹿屋2026已重新上线 科技冰火两重天+一周回顾 ${title} 热度退了,我反而用得更深了-咕咚同学 我到底该不该换个域名? 随身WIFI折腾记 - 安迪 博客撰写体验提升——hexo pro插件 为什么不用相机把屏幕上的接关密码拍下来? 国清寺与天台山 – Ouroboros ★★★★☆《挽救计划》——久违的经济上行感 - Davidの3号基地 删除右键“打开方式”里多余选项 第三周刊_No.53|一切都会被支付两次 安卓APP通话记录与录音上传踩坑记录 - 子舒的博客 天量下跌 inBox 笔记 2.3.8,把工具栏交给了你-咕咚同学 我把小龙虾搬到了微信-咕咚同学 安好 - 响石潭 Compound Engineering Plugin:让每个工程单元都比上一个更容易 MOSS-TTS Family:开源高质量语音与声音生成模型家族深度解析 Crawl4AI:专为 LLM 设计的开源 Web 爬虫与数据抓取工具 Build Your Own X:从零实现你最喜欢的技术——程序员进阶的终极资源清单 Anthropic Skills:用文件夹教 Claude 专业技能的开源框架 1年的去月球(下) - 梅之夏 欢迎回来。 简单讲讲 ASN.1 与 OID DTV - 直播聚合客户端 5.22-5.27 – 不兴江 还没去过鸭川 – 不兴江 张晶晶同学三刷林志颖 关于我 – 不兴江 爱与嫉妒 – 不兴江 港股被持续做空 备案码花了四百块-咕咚同学 一句话生成封面:我给公众号做了4种风格的AI封面生成技能 「官」方認證 再谈费曼学习法 2026-05-28T00:34:11+08:00 2026-05-28T00:28:45+08:00 离谱的英语学习指南:基于AI的英语进阶系统方法论 iii:零集成架构的后端统一运行时 Claude Code Harness:让 Claude Code 工作有迹可循的工程化框架 Heretic:全自动移除大语言模型审查机制的开源工具 MarkItDown:微软开源的万能文档转 Markdown 利器 Harness:让 Claude Code 秒变多智能体协作工厂 这段时间尽折腾AI Agent了,确实极大地提高了效率 近期动态:两个新站点正式上线啦 误判解除!zhouayuan.com 腾讯安全申诉成功 - 周阿源|玩具设计・插画日常・生活随笔 Ralph:让 AI 编码工具自主循环跑完所有 PRD 任务的量产神器 全都违法 – 个人工作记录 关于zhouayuan.com被误判 “含违规信息” 的说明与申诉记录 - 周阿源|玩具设计・插画日常・生活随笔 小米 MiMo v2.5 Pro 白嫖 最大的人间清醒,兜里有钱,但是不花。 夜晚靓歌(12):于文文现场solo - 王志勇的Blog 今日插画:风扬起的倔强 - 周阿源|玩具设计・插画日常・生活随笔 回门习俗 独立网卡 - 忘记了回忆 500亿入股人工智能企业 从命令行到桌面智能体-咕咚同学 第一性原理读书笔记 行者微评论223-加班の守株待兔-博客|政治与时事-风雨行者 ZOZO开源物理接触求解器:GPU加速的可扩展仿真引擎 OpenStock:开源股票市场交易平台技术深度解析 MoneyPrinterTurbo:基于AI的全自动短视频生成工具深度解析 Claude-Mem:为 Claude Code 构建的持久化记忆压缩系统 Twenty:可代码化定制的企业级开源 CRM 平台技术深度解析 2026-05-26T22:59:17+08:00 企业级开源大模型部署平台 GPUStack 实战教程 1年的去月球(上) - 梅之夏 Sevalla - 静态网站托管服务 不用翻墙、不用注册、不用月费,普通人也能用上 Claude Code 装修灯具要注意⚠️ 黄梅天先锋 - 游子微博 公安备案顺利办结,站点备案全部完成 - 周阿源|玩具设计・插画日常・生活随笔 第三次兑换天猫超市卡了宗宗酱-三维狐少儿编程 Don't think, feel. - Rolen's Blog 人这一辈子,到底图个什么 博客迁移 - Edwin's Blog 情感赛道写作模板 再现本轮行情的典型特征 裁员与平常心-咕咚同学 别让“偷懒”,成为隐私泄露的破绽 片刻 - Jdeal | Life is like a Design.
chat.nvim 定时任务的设计与实现
Eric Wong · 2026-06-27 · via BlogFinder

AI 是被动的

你跟 AI 说”帮我改这段代码”,它秒回。你说”一小时后提醒我开会”,它说”好的”——然后就没有然后了。

这不是某个产品的 bug,而是大多数主流 AI 助手的通病:它们是被动的。 你问它才答,你不问它就沉默。它没有”时间”的概念,没有”未来”的概念,更没有”主动发起”的能力。虽然一些开源或闭源的 Agent 框架已经支持定时任务,但像豆包、DeepSeek 等主流 AI 助手,仍然不具备这一能力。

chat.nvim 新增了定时任务功能,目的就是给 AI 装上”时间感”——让它能在未来的某个时刻,主动找你。

核心思路

要打破 AI 的被动性,核心问题是:如何在未来的某个时刻,让 AI 像收到用户消息一样开始工作?

解法不复杂,就三步:

  1. 记住一个任务(什么时间、做什么)
  2. 到点触发
  3. 把消息注入会话,AI 像收到用户消息一样处理

思路简单,但魔鬼在细节。下面讲每个环节的设计取舍。

时间模型:统一为绝对时间戳

用户可以三种方式描述时间:

  • “1 小时后” —— 相对延迟
  • “明天早上 9 点” —— 绝对时刻
  • “每天晚上 10 点” —— 周期循环

三选其一,互斥。

无论用户怎么描述,内部统一转换为 Unix 时间戳。”1 小时后”变成 当前时间 + 3600,”每天”变成从创建时间起每 86400 秒一次。

为什么?因为调度引擎只需要处理一种时间模型,不需要区分”延迟”和”定时”,不需要为不同类型写不同逻辑。统一抽象,消灭分支。

触发机制:不轮询,用定时器

最直觉的方案是轮询:每隔几秒扫描一遍任务列表,看有没有到点的。

这很浪费。100 个任务里有 99 个还在等待,你却每秒扫一遍。

更好的方案是每个任务一个独立定时器,到点才唤醒,不到点 CPU 零开销。这是事件驱动而非轮询驱动。

Neovim 内置 libuv,uv.new_timer() 就是干这个的,精确到毫秒级,而且不阻塞主线程。

周期任务的防漂移

周期性任务有个坑:如果 Neovim 中途重启了,恢复后下次触发时间怎么算?

直觉做法是”当前时间 + interval”。但这会导致节奏漂移——你设的每天 10 点,重启后变成 10:03,再重启变成 10:07……

正确做法是:基于创建时间和已执行次数算下次触发。

下次触发 = 创建时间 + (已执行次数 + 1) × 间隔

这样无论重启多少次,第 7 次执行永远在创建时间 + 7 × 间隔那个点。节奏锁定在创建那一刻。

24.8 天上限

libuv 的 timer 有个硬限制:最大超时 2³¹-1 毫秒,约 24.8 天。

如果用户设了一个 30 天后的任务,怎么办?

解法是分片。先设一个 24.8 天的 timer,到点后醒来一看——还没到真正的触发时间,重新算剩余延迟,再设一个新 timer。两次接力,覆盖任意时长。

上限设为 30 天,既覆盖合理需求,又不至于让一个 bug 任务永远挂在系统里。

调度与执行解耦

这是整个设计中最关键的决策。

调度引擎只负责一件事:到点,往消息队列里 push 一条消息。它不调用 LLM API,不关心 AI 是否在线,不关心网络状态。

为什么不直接到点调 API?因为职责一旦混合,复杂度就上来了:

  • AI 正在处理另一个请求怎么办?
  • 网络断了怎么办?
  • 会话被删了怎么办?
  • 用户正在打字怎么办?

解耦之后,调度引擎的逻辑极其简单:到点 → push → 完事。剩下的交给消息队列处理。

消息队列:等一个窗口

任务触发后,消息进入队列。队列负责在”合适的时机”把消息送给 AI。

什么是合适的时机?会话空闲的时候。

  • 如果 AI 没在忙,立即发送
  • 如果 AI 正在处理别的请求,排队等,每隔几秒检查一次,等它空闲了再注入

这就像同事给你发了消息,但你在开会——消息不会丢,等你开完会再看。

连续 3 次发送失败才丢弃,防止偶发故障吞消息。

持久化与恢复

Neovim 不是常驻进程,用户随时可能关掉。定时任务必须跨重启存活。

方案很直接:每次创建、取消、触发时,把全部任务写一份 JSON 到磁盘。下次启动时加载。

但有个细节:libuv timer 是内存对象,无法序列化。持久化时必须排除 timer 句柄,恢复时重新创建。

恢复时还有两条不同策略:

  • 过期的一次性任务:直接跳过。已经过了触发时间,没有意义了
  • 过期的周期性任务:必须恢复。周期任务还要继续执行,不能因为重启就断

一次完整流程

你说:"1 小时后提醒我开会"
    │
    ▼
AI 调用工具,计算 trigger_at = 当前时间 + 3600
    │
    ▼
调度引擎创建任务,写入磁盘,arm 一个 3600 秒的定时器
    │
    ···(1 小时后)···
    │
    ▼
定时器触发 → 往会话的消息队列 push "提醒我开会"
    │
    ▼
队列检测会话空闲 → 发送给 AI
    │
    ▼
AI 收到消息,像你亲自说的一样,回复提醒

怎么用

直接用自然语言跟 AI 说就行:

1 小时后提醒我跟进苏北人民医院的项目

AI 会自动计算时间并创建定时任务。

三种模式:

  • 一次性delay_seconds=3600trigger_at=1717200000
  • 周期性interval=86400(每天),可选 repeat_count=7 限制次数
  • 管理action="list" 查看,action="cancel" 取消
特性 说明
持久化 Neovim 重启后依然有效
最大延时 30 天
最小间隔 10 秒
精度 秒级(基于 Unix 时间戳)
依赖 零外部依赖,纯 Neovim + libuv