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 ↓ VerificationScheduled 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 commitScheduled 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 testStop 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-reviewSkill里面定义:
读取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会员订阅渠道。
