用 crontab + codex-cli 打造「定时 AI 任务流」:从 ping/pong 到真正跑起来的 5 小时计算窗口
用 crontab + codex-cli 打造「定时 AI 任务流」:从 ping/pong 到真正跑起来的 5 小时计算窗口
很多人踩过这个坑:crontab 里跑 codex-cli,收到了 pong,但 5 小时额度窗口死活不开始计算。
原因不是你的 cron 写错了,也不是网络问题——是 codex-cli 对"有效任务"的判定门槛比你想象的高得多。
先搞清楚:为什么 ping 不触发计费窗口
codex-cli 的 5 小时滚动窗口,本质上是 OpenAI 后端对「session 活跃度」的判定。ping 是一个心跳指令,走的是 keepalive 通道,不经过推理引擎,所以:
- 服务器回
pong✅ - 计费窗口开始计算 ❌
真正触发窗口的条件是:发出一个需要模型推理的请求,哪怕只是 echo "hello" 这种一句话任务。
实战方案:用 crontab 定时触发真实 AI 任务
下面这套方案做的事情是:每天早上 9 点,自动让 AI 扫描你项目里昨天改动的文件,输出一份简短的变更摘要,顺手把 5 小时窗口打开。
环境准备
# 安装 codex-cli(如果还没装)
npm install -g @openai/codex
# 验证
codex --version
核心脚本:`daily_review.sh`
#!/bin/bash
# ---- 配置区 ----
PROJECT_DIR="$HOME/your-project" # 改成你的项目路径
LOG_FILE="$HOME/logs/codex_daily.log"
DATE=$(date '+%Y-%m-%d %H:%M:%S')
# 使用无量Api,比官方省 60%,国内直连无需代理
export OPENAI_BASE_URL="https://api2everything.xyz/v1"
export OPENAI_API_KEY="your_api_key_here"
# ---- 获取昨天改动的文件 ----
CHANGED_FILES=$(git -C "$PROJECT_DIR" diff --name-only HEAD~1 HEAD 2>/dev/null)
if [ -z "$CHANGED_FILES" ]; then
PROMPT="今天没有文件变更,请输出一句鼓励的话。"
else
PROMPT="以下是昨天改动的文件列表,请用 3 句话总结可能的影响范围:\n$CHANGED_FILES"
fi
# ---- 触发推理请求(这一步才真正开启计费窗口)----
echo "[$DATE] 开始执行每日 AI review..." >> "$LOG_FILE"
codex --model gpt-4.1-mini \
--quiet \
"$PROMPT" >> "$LOG_FILE" 2>&1
echo "[$DATE] 执行完毕" >> "$LOG_FILE"
echo "---" >> "$LOG_FILE"
给脚本加执行权限:
chmod +x ~/daily_review.sh
mkdir -p ~/logs
配置 crontab
crontab -e
加入这一行(每天早 9 点执行):
0 9 * * * /bin/bash $HOME/daily_review.sh
如果你想验证 cron 环境下环境变量是否正常,先跑一个测试任务:
* * * * * env > /tmp/cron_env.txt
看看 PATH 和 HOME 是否符合预期,这是 cron 里 command not found 的最常见原因。
进阶:用 Python 做更复杂的定时任务
如果你的任务不只是 git diff,而是要读文件、调接口、写报告,用 Python 脚本更灵活:
#!/usr/bin/env python3
"""
daily_ai_task.py
定时触发 AI 推理任务,同时开启 codex 计费窗口
"""
import os
import subprocess
from datetime import datetime
from openai import OpenAI
# 国内直连,无需代理,比官方便宜 65%
client = OpenAI(
api_key=os.environ.get("OPENAI_API_KEY"),
base_url="https://api2everything.xyz/v1",
)
def get_git_changes(project_dir: str) -> str:
"""获取最近一次 commit 的变更文件"""
try:
result = subprocess.run(
["git", "-C", project_dir, "diff", "--name-only", "HEAD~1", "HEAD"],
capture_output=True, text=True, timeout=10
)
return result.stdout.strip() or "(无变更)"
except Exception as e:
return f"获取失败: {e}"
def run_daily_review(project_dir: str) -> str:
changed = get_git_changes(project_dir)
prompt = f"""
你是一个代码审查助手。以下是今日变更的文件列表:
{changed}
请完成两件事:
1. 用 2-3 句话评估变更的影响范围
2. 列出 1-2 个需要重点关注的风险点
回答要简洁,直接给结论。
"""
response = client.chat.completions.create(
model="gpt-4.1-mini", # 换成 claude-3-5-haiku 也行,无量都支持
messages=[{"role": "user", "content": prompt}],
max_tokens=300,
)
return response.choices[0].message.content
if __name__ == "__main__":
project_dir = os.environ.get("PROJECT_DIR", os.path.expanduser("~/your-project"))
print(f"[{datetime.now():%Y-%m-%d %H:%M:%S}] 开始每日 review")
result = run_daily_review(project_dir)
print(result)
print("---")
crontab 里对应改成:
0 9 * * * PROJECT_DIR=$HOME/your-project /usr/bin/python3 $HOME/daily_ai_task.py >> $HOME/logs/ai_review.log 2>&1
几个容易忽略的细节
1. cron 里的 PATH 问题
cron 的 PATH 默认只有 /usr/bin:/bin,codex 装在 /usr/local/bin 或 ~/.npm/bin 的话会找不到。解决方法:在脚本开头加:
export PATH="/usr/local/bin:$HOME/.npm/bin:$PATH"
2. 模型选择影响成本
日常定时任务用 gpt-4.1-mini 或 claude-3-5-haiku 就够了,没必要上旗舰模型。通过无量Api,这两个模型的价格比官方低 60% 以上,跑几百次定时任务成本几乎可以忽略。
3. 日志轮转
长期跑的话记得加 logrotate,不然日志文件会无限增长:
# /etc/logrotate.d/ai_review
/home/youruser/logs/ai_review.log {
weekly
rotate 4
compress
missingok
}
关于无量Api
文中代码用的 base_url 是 无量Api,国内直连,支持 OpenAI / Claude / Gemini / DeepSeek 等 300+ 模型,价格比官方便宜 65%,注册就送 ¥1 余额,余额永久不过期。
对于定时任务这种场景,API 稳定性和延迟比什么都重要——国内直连省去了代理这个不稳定因素,cron 任务失败率会低很多。
改一行 base_url 就能用,现有代码零改动:
base_url="https://api2everything.xyz/v1"
你的 crontab + codex 任务跑起来了吗?遇到什么报错欢迎评论区贴出来,一起看看。觉得有用的话点个赞,后续还会写更多 AI 工程化的实战内容。