一个AI代理最值得夸的功能,居然是"什么都不做"。这是Hacktoberfest开源AI挑战第三周"慢而稳"主题下的一个提交项目,名字叫Off-Peak。
![]()
作者手里有一叠十份始终没去总结的文档:会议记录、一张发票、一份睡眠研究、一篇存下来的论文、几张收据。最直观的解法是让代理立刻开跑。他把那种代理比作糟糕的室友——转着风扇、耗着电池,还要打断你告诉你它正在工作。
Off-Peak走的是反方向。你交给它一堆文件和一条截止时间,它盯着笔记本的空闲时间、电量和温度状态,预测这项工作要花多久,然后等你离开再动手。你提前回来,它在当前这一项做完后暂停;合上盖子,它从最后完成的那一项接着来。第二天早上,它留一份报告。
它是个调度器,不是聊天机器人。模型负责干活,调度器负责判断这活值不值得现在干。
演示跑出来的数字
录制的那次运行用了十份文档和一个被压缩的"一天"。人在午饭和傍晚两个时段离开。Off-Peak推迟了21次,只在这些离开的窗口里工作,在模拟的晚上10:30截止前完成了全部十份。
对照组130秒跑完,但有一份文档因为服务商的503错误丢了。Off-Peak在一天里累计用了398秒的模型时间。它更慢,而这正是重点——它把工作挪出了我用笔记本的时间。九次上下文切换变成了零次。
作者也把话说清楚了:运行期间Gemma 4 31B端点间歇性返回500/503。三份文档用了Gemma,其余回落到Gemini 3.8 Flash。路由器保住了队列不断,这正是持久化调度器存在的意义。仓库里还有一条完全本地的Ollama路径,默认模型是开放权重的Gemma 4 31B。
调度器的核心逻辑
核心代码短到可以直接读。当检测到用户在场、且配置为"仅在离开时运行"时,如果截止时间压力已经逼近最晚安全启动点,就返回"运行",理由写明是截止压力;否则返回"等待",理由是你正坐在键盘前。
另外三道闸门是电量、温度和窗口长度。全部通过后,工作进程每个周期最多处理两项,写出结果、给该项打检查点,然后让出。暂停在每一项开始前都会检查,所以回到桌前是软停止,不是丢掉一整批。
技术栈是Python 3.10、SQLite、psutil、Gemma 4 31B的Gemini API、作为本地路径的Ollama、一个标准库HTTP面板,以及13个测试。
队列与检查点方面,每个文件都是一个带状态的项目,输出先写、再把项目标记为完成。启动时任何处于运行中的任务都会变成暂停,工作进程从第一个待处理项恢复。休眠、崩溃或合盖,最多只损失正在处理的那一项。
遥测方面,macOS的空闲时间来自ioreg,电量和温度状态来自pmset,CPU和负载来自psutil;Linux用xprintidle和/sys。调度器只看到一个SystemState数据类,所以同一套策略既能跑真实遥测,也能跑压缩的那一天。
预测方面,默认预测器是一个透明的启发式公式,用代理自己的运行记录校准:项目数乘开销,加上字符数除以1000再乘每千字符秒数。仓库里还包含一个TabPFN适配器,用本地运行日志训练,并报告相对中位数基线的留出集平均绝对误差。本地TabPFN权重需要一次性许可令牌,没有令牌就用校准过的启发式。作者明确表示,没有为演示伪造一个学习型预测器。
模型路由方面,Gemma 4 31B是默认。路由器会从响应里过滤思考片段、解析严格JSON、对限流重试,并在服务商500/503时回落到Gemini 3.8 Flash。熔断器在失败后十分钟内跳过主模型,让队列其余部分不必再付一次超时的代价。每次运行都记录实际处理它的模型,回落会出现在报告里,而不是被藏起来。
面板是一个HTML文件、一个JSON端点,没有构建步骤,没有外部字体或脚本,读的是和命令行同一个SQLite文件。时间线就是审计日志:绿色是工作,灰色是等待,琥珀色是为你暂停。
踩过的坑
第一版把整堆文件立刻跑完,恰恰是作者想避免的行为。第二版在用户在场时暂停,但没有最晚安全启动的计算,任务可能永远等下去。截止时间的算法,才让"偷懒"变得安全。
Gemma端点是第三个意外:开放权重的模型并不自动比闭源模型更可靠。应对方式不是掩盖失败,而是绕开它并记录下来。
作者还列了几条关于开放创新的理由。决策层必须在本地——托管代理看不到我的电量、温度状态,也看不到我刚走回桌前。调度器是本地遥测之上的一小段策略,模型可以替换,上下文不行。耐心只有在开放权重下才是免费的:按量计费的API会让"夜里跑500个小任务"变成经济决策,而下载下来的模型让它变成调度决策,推迟的边际成本为零,代理才负担得起挑剔什么时候运行。模型是可替换的:走Gemini API的Gemma 4 31B求吞吐,走Ollama的Gemma求完全离线,或者同一个summarize接口后面的别的模型,策略不变。端点失败时,回落是一次配置,不是一次重写。文件始终归自己:Off-Peak从不上传文件,API模式下文档文本作为提示发给模型端点,队列、输出、遥测和历史都留在笔记本的SQLite里;Ollama模式下什么都不离开这台机器。失败是可检查的:端点返回500/503时,回落和检查点都在报告里可见,我能看到每份文档由哪个模型处理,没有不透明的服务在决定丢弃队列。
偷懒的回报
- 避免了9次打断
- 0分钟盯着进度条
- 约3.09 Wh的模型能耗被移出我的活跃时段
- 10/10份文档在截止前完成
- 这周我的笔记本做过最有生产力的事,是在我不在的时候
重点不是这个代理快,而是它有耐心。慢不是缺陷,是一个调度决策。
局限
录制的那一天是压缩的,能耗数字是根据模型时间和固定笔记本功率估算的。十份文档是演示,不是基准测试。Gemma端点不稳定,所以模型构成被如实报告。日历集成是空闲时间窗显而易见的下一步。
作者还说明了参赛类别:最佳Gemma使用,因为Gemma 4 31B是默认模型,录制运行在能用的文档上用了它,本地Ollama路径也用Gemma实现完全离线,调度器与模型无关,但Gemma让"不需要API密钥"这条路成为现实。他也报名了总奖,TabPFN适配器在仓库里,但他不申报那个类别,因为在这个环境里跑不了受限权重。
如果代理要替我干活,它至少该有礼貌,等我走了再动手。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.