ChatGPT、Codex实战:Scheduled Tasks怎么用?本地项目和Worktree到底该选哪个?

很多人第一次看到Codex里的Scheduled Tasks,会把它理解成:

定时运行一个Prompt。

比如每天检查一次项目、定时整理Commit、自动扫描测试失败。

但真正把Scheduled Tasks放进代码项目以后,最容易踩坑的其实不是“几点运行”,而是:

任务到底在哪里运行?

现在针对Git项目,Codex的Scheduled Task可以直接在本地项目目录中执行,也可以使用独立Worktree隔离执行。官方也明确建议:如果自动任务可能产生代码修改,Worktree能够避免Scheduled Task与开发者正在进行的本地工作互相冲突。

所以真正需要理解的是:

Scheduled Task ↓ Execution Environment ↓ Local Project / Worktree ↓ Tools ↓ Changes ↓ Verification

Scheduled Tasks不是普通提醒,而是一种自动执行工作流。


一、先理解Scheduled Task到底在自动什么

普通Codex任务通常是:

打开项目 ↓ 输入任务 ↓ Codex执行 ↓ 查看结果

Scheduled Task则把第一步变成自动触发:

Schedule ↓ Prompt ↓ Codex启动 ↓ 读取项目 ↓ 执行任务 ↓ 生成结果

比如:

每天上午检查CI失败;

每晚扫描TODO;

每周整理Release Notes;

定期检查依赖变化;

每天汇总最近Commit。

官方目前允许创建Scheduled Task时指定项目、Prompt、运行频率以及执行环境。

问题也正是在这里出现:

如果这个任务会修改代码,

它应该直接修改你现在正在工作的目录吗?

这就是Local和Worktree的核心区别。


二、Local Project是什么?

Local最容易理解。

假设你的项目目录是:

/my-project

你平时就在这里:

写代码 修改文件 运行测试 Git commit

Scheduled Task选择Local以后,它运行时使用的也是这个项目环境。

可以理解成:

Developer ↓ /my-project ↑ Scheduled Task

双方操作的是同一个工作目录。

它的最大优势就是:

环境最直接。

Agent可以看到你当前目录里的真实状态。

包括:

已经安装好的依赖;

本地配置;

当前文件;

甚至还没有提交的修改。

对于一些只读任务,这非常方便。

例如:

分析最近Commit
检查测试结果
生成项目摘要
扫描TODO

因为任务只是读取项目,并不会大量修改代码。

这种情况下Local通常足够。


三、Local真正危险的是“共享状态”

问题出现在Scheduled Task开始写文件以后。

假设你上午正在修改:

src/auth.ts

此时一个定时任务自动启动:

每天10:00 ↓ 检查认证模块 ↓ 自动修复问题

Agent也修改:

src/auth.ts

现在就出现了:

Human Change + Agent Change ↓ Same Workspace

可能产生:

覆盖;

冲突;

Diff混乱;

测试状态变化;

Agent基于半完成代码继续执行。

最麻烦的一种情况是:

开发者当前修改还没有Commit。

Agent看到的是:

Repository + Uncommitted Changes

它甚至可能把你的临时修改理解成:

项目原本状态。

于是任务输入实际上已经发生变化。

这就是共享Workspace最典型的问题:

Shared Mutable State。


四、Worktree解决的就是这个问题

Git Worktree可以让同一个Repository同时拥有多个独立Working Tree。

概念上可以理解成:

Repository ├── Main Workspace │ └── Developer │ └── Worktree └── Codex

开发者继续修改自己的目录。

Codex在另一份独立Working Tree执行。

官方目前也把Worktree作为Codex并行任务和Scheduled Tasks的重要隔离机制:对于Git Repository,Scheduled Tasks可以运行在专门的后台Worktree中,从而避免自动任务干扰当前正在进行的本地修改。

这里最关键的不是:

多复制了一份代码。

真正重要的是:

Execution Isolation。


五、什么时候优先选Local?

并不是Scheduled Task全部都应该使用Worktree。

Local有非常明确的适用场景。

1. 任务主要是读取

例如:

总结昨日Commit
检查项目TODO
生成代码质量报告

这种任务几乎不会修改代码。

使用Local简单直接。


2. 必须依赖当前本地状态

有些任务就是需要读取:

当前未提交修改

比如:

每天下班前总结我今天修改了什么。

这时候如果使用独立Worktree,

Agent看到的反而可能不是你当前真实工作状态。

Local更加合理。


3. 本地环境非常复杂

例如项目依赖:

本地数据库;

特殊环境变量;

本地Service;

复杂开发工具链。

如果新的Worktree需要大量初始化成本,

Local有时候会更省事。

所以可以简单记成:

Read Current State ↓ Local

六、什么时候应该优先选Worktree?

一旦任务会:

修改代码,

Worktree的价值就明显提高。

例如:

自动修复Lint
自动补测试
处理简单Bug
更新依赖
定期重构某类代码

这类任务如果直接运行Local,相当于:

后台Agent会自动进入你正在工作的目录写代码。

风险明显更高。

使用Worktree以后:

Main Workspace ↓ Developer继续工作

同时:

Background Worktree ↓ Scheduled Task执行

两边可以相互隔离。

因此一个很实用的判断方式是:

只读任务 → Local 写代码任务 → 优先Worktree

当然不是绝对规则,但作为默认策略非常实用。


七、Worktree也不是完全“零成本”

Worktree虽然解决隔离问题,但也带来新的工程成本。

其中最明显的是:

Environment Setup。

创建一个新的Worktree以后,它拥有代码文件。

但不一定自动拥有完整运行环境。

例如:

node_modules

可能不存在。

Python虚拟环境可能需要重新配置。

某些:

.env

文件可能没有进入Git。

还有:

本地数据库;

缓存;

生成文件;

私有证书。

也可能不存在。

所以:

Git Worktree ≠ 完整可执行环境

这也是为什么Codex的本地环境支持配置Setup Script,用来准备Worktree所需要的环境。

例如逻辑可能是:

Create Worktree ↓ Install Dependencies ↓ Load Environment ↓ Run Task

如果没有这一层,常见结果就是:

Local里运行正常,Worktree里全部报错。


八、Scheduled Task最容易出现的错误:Prompt写得太宽

比如创建一个任务:

每天检查项目并优化代码。

看起来很合理。

实际上非常危险。

因为“优化代码”没有边界。

Agent可能今天改:

auth

明天改:

database

后天又去:

refactor utils

于是Scheduled Task从:

Automation

慢慢变成:

Unbounded Agent。

自动任务尤其需要明确:

Scope

比如改成:

每天检查src/api目录中的ESLint错误,仅修复能够通过现有测试验证的问题,不修改公共接口。

现在边界就清楚很多。


九、一个好的Scheduled Task至少要有5个部分

我建议自动任务不要只写一句Prompt。

最好至少定义:

Goal Scope Action Verification Stop Condition

例如:

Goal

检查新增代码中的Lint问题。

Scope

只允许修改:

src/

Action

修复明确且低风险的Lint错误。

Verification

运行:

npm run lint npm test

Stop Condition

如果测试失败或者需要修改公共API:

停止并报告。

于是完整逻辑变成:

Find ↓ Analyze ↓ Modify ↓ Verify ↓ Stop / Report

而不是:

Find ↓ 随便改

这才是真正适合自动执行的任务。


十、Scheduled Task一定要考虑Verification

人工启动Codex时,我们会自然查看结果。

但Scheduled Task最大的不同是:

执行发生时,人可能根本不在电脑前。

所以Verification必须提前写进任务。

例如自动补测试:

不要只写:

给没有测试的代码补测试。

应该变成:

发现缺失测试 ↓ 创建测试 ↓ 运行相关测试 ↓ 确认通过 ↓ 报告修改文件

如果测试失败:

不要继续扩大修改范围 ↓ 保留Evidence ↓ 报告失败

所以Scheduled Task真正重要的不是:

自动运行。

而是:

自动运行 + 自动验证。


十一、自动任务不能把“Done”定义得太简单

Agent执行结束并不等于任务完成。

例如:

文件修改成功

不代表:

功能正确

所以可以把自动任务的完成条件分成三层。

Execution Done

代码修改完成。

Verification Done

测试通过。

Acceptance Done

结果符合任务目标。

完整状态应该是:

Execute ↓ Test ↓ Validate ↓ Done

如果没有Verification,

Scheduled Task只是:

Scheduled Modification。

而不是:

Scheduled Engineering Workflow。


十二、频繁Scheduled Task还要注意Worktree数量

Worktree还有一个很实际的问题。

如果任务频率很高:

每小时运行一次

并且每次都创建独立Worktree,

时间长了可能累积很多工作树和任务记录。

OpenAI官方文档也专门提醒:频繁运行的Scheduled Tasks如果使用Worktree,可能随着时间产生较多Worktree,需要定期管理和归档已经不需要的运行。

所以不是:

Worktree越多越安全

而应该根据任务生命周期设计。

例如:

每天一次:

通常问题不大。

每小时一次:

就应该考虑:

是否真的需要Worktree?

是不是只读任务?

运行结果是否需要长期保存?

否则自动化系统自身就会产生新的维护成本。


十三、Scheduled Tasks更适合哪些任务?

一个任务越符合下面几个条件,就越适合自动化。

重复

每天或者每周都做。

边界明确

输入范围和修改范围清晰。

验证明确

可以用测试或者规则判断成功。

风险较低

失败不会产生严重后果。

例如:

Lint检查
测试扫描
Commit摘要
Release Notes
依赖变化分析

都比较适合。

反过来:

重新设计认证架构
大规模重构核心模块
修改生产数据库

就不应该因为“Scheduled Tasks可以运行”而直接自动化。


十四、Skills和Scheduled Tasks放在一起会更有价值

如果一个任务经常重复,真正成熟的做法不是:

每一个Scheduled Task里面写几十行Prompt。

而是把稳定流程抽成:

Skill。

例如创建:

ci-failure-review

Skill里面定义:

读取CI ↓ 分类错误 ↓ 定位代码 ↓ 运行相关测试 ↓ 输出报告

Scheduled Task只需要负责:

什么时候运行 + 调用哪个Workflow

于是系统变成:

Schedule ↓ Skill ↓ Execution ↓ Verification

官方当前Scheduled Tasks也支持配合Skills使用。

这时候:

Scheduled Task解决When。

Skill解决How。

两个概念就彻底分开了。


十五、Local、Worktree到底怎么选?

可以直接使用下面这套判断。

任务是否需要修改代码?

如果:

优先考虑:

Local

继续判断:

是否必须读取当前未提交修改?

如果是:

Local更加合适。


如果:

继续问:

开发者是否可能同时修改这个项目?

如果:

优先:

Worktree

然后检查:

依赖 环境变量 Setup Script 测试环境

能否在Worktree里正常工作。

最终可以抽象成:

Read Current State → Local Modify Shared Repo → Worktree Need Current Uncommitted State → Local Background Code Changes → Worktree

十六、一套可以直接使用的Scheduled Task检查表

创建任务前先检查:

① Goal 这个任务到底要完成什么?
② Scope 允许读取和修改哪些目录?
③ Environment Local还是Worktree?
④ Dependencies 新Worktree能否正常运行项目?
⑤ Permission 任务需要哪些文件、Shell和网络权限?
⑥ Verification 修改以后运行什么测试?
⑦ Stop Condition 什么情况下必须停止?
⑧ Evidence 运行结束以后留下什么结果?

真正可靠的Scheduled Task应该形成:

Schedule ↓ Environment ↓ Execute ↓ Verify ↓ Evidence

最后

Scheduled Tasks真正有价值的地方,并不是:

Codex终于可以定时运行Prompt了。

而是:

一些边界清楚、可以验证的软件工程任务,开始能够从人工触发变成后台持续执行。

但自动执行同时意味着:

Agent可能在你没有看着的时候:

读取项目;

执行命令;

修改文件;

运行测试。

因此:

Execution Environment就变得非常重要。

Local的优势是:

简单;

直接;

能够看到当前真实状态。

Worktree的优势是:

隔离;

并行;

不会轻易污染开发者正在进行的工作。

所以不要简单理解成:

Local = 初级 Worktree = 高级

真正应该根据任务状态判断:

当前状态是否需要共享? ↓ 修改是否需要隔离? ↓ 环境能否独立运行? ↓ 结果能否自动验证?

当Scheduled Task真正进入开发工作流以后,我们需要设计的就不只是:

什么时候运行。

而是整个:

Automation Execution Boundary。

这也是Codex从“人工调用的AI工具”走向“可以持续运行的工程执行系统”以后,一个越来越重要的能力。

持续更新Codex、大模型开发相关技术内容。

长期使用各类代码大模型,整理了稳定的AI会员订阅渠道。