这次整理自动写作的本机材料,我停在了执行入口的一小段判断上。待写主题已经能排进队列,后面也接着正文、配图、预览和质量检查,但在真正开始前,程序还可以先看机器是否空闲。如果条件不满足,它会打印暂不执行的原因,然后退出。
这个动作看起来没有产出。文章没多写一个字,队列也没有往前走。但我越往下读,越觉得它值得单独拿出来说。自动写作解决了谁来写的问题,却没有因此解决什么时候适合开始。机器上有待办,不等于此刻就该把待办全部启动。
我关心的也从生成速度,转向了自动任务怎样进入日常工作。同一台电脑既服务于眼前的操作,也承接可以稍后完成的生产。后者如果只知道往前冲,省下来的操作可能又以干扰的形式还回来。
有任务,不等于现在就该跑
本地写作流程说明里,一个写作入口串起了多个阶段。正文只是其中一段,后面还有图片处理、本地预览和质量检查。所以,即使文字生成依赖外部服务,也不能据此认定整条流程对当前工作没有影响。判断执行时机,要看它会带动哪些动作。
最容易采用的捷径,是主题确定后立即启动,或者到了固定时间就启动。这两种安排都清楚,却没有回答机器此刻正在做什么。设想我正在操作界面,或者另一个任务还在持续运行,时间表照样会到点。这个例子说明的是调度风险,并不是这次已经发生过的事故。
待写队列保存了工作的意图,机器状态决定了这次是否适合启动。 把这两件事分开以后,推迟就不再等于遗忘。主题仍然留在队列里,暂时没有开始,只是在等待一个更合适的执行机会。
我更愿意把它理解为给工作排先后。可以延后的写作任务,应当为正在发生的操作留出位置。否则,每项自动化单独看都在节省时间,放到同一台电脑上,却可能一起争抢眼前最需要的资源。
空闲需要同时看人和机器
这份实现没有只看一个信号。它读取最近 1分钟和 5分钟的系统平均负载,也尝试读取桌面距离上次输入已经过去多久。前者帮助判断机器最近是否繁忙,后者帮助判断人是否仍在持续操作。它们回答的是不同的问题,不能彼此替代。
如果只看桌面输入,离开键盘就容易被理解为空闲。但人离开了,别的任务仍可能继续运行。如果只看负载,数值不高也不能说明人没有在使用电脑。一次点击、一次编辑可能不构成很重的计算,却仍然是应该被尊重的当前工作。
当前默认值要求桌面至少闲置 300秒。最近 1分钟的负载上限按处理器核心数的 0.75倍计算,最近 5分钟则按 0.9倍计算。这些是实现里的默认尺度,不是我测得的最佳配置,更不是适合所有电脑的经验定律。
同时看两个时间窗口,让眼前的变化和前一段时间的忙碌都进入判断。我不会把这种检查称为完整的资源评估,因为这个函数没有检测内存压力、磁盘空间或网络状态。空闲是依据有限信号作出的放行判断,不能被理解为对整台机器的全面保证。
这件事让我重新意识到,一个名字越容易理解,越要小心它带来的额外想象。「空闲执行」听起来像系统知道所有事情,实际代码只知道它采集到的那几项。使用者必须知道这个差别,才能给它合适的信任。
暂不执行,也要说清楚原因
检查不通过时,程序会列出超限原因,并输出负载、核心数,以及能够读取到的桌面闲置时间。这个细节比一句笼统的失败更有用。我可以据此分辨,是桌面仍有操作,还是系统负载还没有降下来,不必把没有文章产出一律当成写作故障。
检查的位置也很关键。它发生在任务被标为运行中之前。条件不满足,执行入口直接返回,不会在这条分支里把待写任务改成失败。真正进入写作后发生的异常,才会走失败记录。这样,尚未开始和已经尝试过但没有完成,保留了不同含义。
一次有理由的推迟,应该保留任务的待写状态,而不是制造一次写作失败。 否则,之后处理失败队列的人就得重新辨认哪些是内容问题,哪些只是当时机器正忙。状态混在一起,自动化没有减少判断,只把判断挪到了更晚的时候。
不过,退出也不代表程序在后台等待。就这段执行入口而言,没有条件不满足后持续轮询、等空闲再自动启动的循环。下一次检查需要再次调用。这里值得留下的方法是,把推迟说清楚,同时讲明白由谁负责再次尝试,不能让一个「稍后」变成没有下文的承诺。
开始前通过,不保证全程空闲
继续往下看,我发现空闲检查在整批任务循环之前,只执行一次。通过以后,程序逐个处理本次选中的主题。这个顺序有明确边界,它能限制一批任务是否开始,却没有在每篇之间重新检查,也没有在用户重新操作电脑时自动暂停的逻辑。
如果把批次放得很大,开始时的状态就可能被当成后面很长一段时间的依据。假设刚启动时桌面确实闲着,后来人回来了,先前那次检查并不会自动失效并中断任务。这是从执行顺序推出来的限制,不能写成已经具备随时让路的能力。
当前入口默认每次最多执行 1个主题。对我来说,这个默认值提供了一个容易理解的取舍。每次少放行一些,后续调用就能重新取得状态依据;一次放行很多,调用次数少了,却要接受状态变旧的风险。小批次并不等于持续监控,但可以缩短单次判断覆盖的工作范围。
启动检查能否保护当前工作,还取决于它放行了多大一批任务。 因而,我不会只讨论阈值该调高还是调低。批量大小和任务长度同样重要。一篇包含配图与检查的文章,和只写正文的任务,即便共享同一个入口,也不应凭名称就被视为相同的负担。
读不到状态,不能说已经确认
另一个容易被忽略的地方,是采集失败。桌面闲置时间的读取只在特定系统分支里进行;不支持、调用超时或没有匹配到结果时,函数返回空值。后续判断只在有值时检查桌面是否足够闲置,因此读不到这个信号,并不会单独阻止执行。
负载读取也有类似边界。出现代码捕获的读取异常时,两个负载值会被设为零。这个处理让流程能够继续,但也让「没有读到」与「读到低负载」在放行判断里靠得很近。仅凭最终通过,不能倒推出全部状态都已成功采集。
我不会据此宣称系统发生过误放行。手头的证据是实现,没有连续运行记录,也没有人在重新操作后受到干扰的实测数据。但它足以提醒我,检查报告必须结合采集结果来理解。某项数值缺失时,能够确认的范围就比全部数据齐全时更小。
我自己的取舍是,越依赖「不打扰当前工作」这一承诺,越不能把未知当成安心。遇到关键状态缺失,宁可先缩小批次或延后尝试。这是我从代码边界形成的使用原则,并不是现有实现已经采用了这样的保守策略。
下次我会怎么做
下次安排自动写作,我会先把执行范围说清楚,再看机器状态。只写正文还是继续处理配图,完成后停在哪里,都应该先确定。空闲检查只回答能否在此刻开始,不能替代内容质量检查,也不能扩大原本的发布授权。机器有空,不代表后面的每个动作都已经获准。
接着,我会采用较小批次,并查看这次检查实际拿到了哪些信号。如果暂不执行,就保留主题和原因,把再次调用的责任安排清楚。如果已经进入写作,就按照真实结果记录完成或失败,不用「可能是机器忙」掩盖内容流程里的异常。
最后,我会把判断范围写进对这项能力的描述里。它检查的是开始时的状态,不承诺全程守候;默认阈值是配置,不是测量结论;采集缺失是未知,不是闲置证据。这些说明看起来没有让自动化更强,却能让我知道什么时候可以放心交给它。
自动写作值得追求的效率,也包括让我少操心它会不会抢在不合适的时候开始。下一次,我会先确认它懂得如何暂缓,再把更多待写主题交出去。能解释为什么此刻不动,才有机会成为一个可以长期放在后台的工作习惯。