把本机 Codex 的原始 JSONL 会话日志整理成一份可审计、可打印、按模型拆分的 token 消费收据。
这个项目最适合这些场景:
- 你想知道某个时间段内 Codex 到底消耗了多少 token。
- 你需要把 Windows 和 WSL 里的 Codex 使用量一起统计。
- 你想按模型列出输入、缓存命中、输出 token 和估算成本。
- 你要生成一份面向人看的收据、费用报告、PDF 或黑白打印件。
- 你希望模型在统计前先确认时间段,避免把“最近”“这个月”这类口径算错。
说明:这是本地估算收据,不是 OpenAI 官方税务发票。项目默认只读取本机日志,不会上传你的日志内容。
- 从原始 Codex JSONL 日志统计
token_count事件。 - 默认扫描 Windows 用户目录和 WSL Ubuntu root 目录。
- 按模型汇总:
- fresh input tokens
- cache-hit input tokens
- output tokens
- reasoning output tokens
- usage event count
- model-specific estimated USD cost
- 支持当前 Codex rate limit 快照:
- primary window used / remaining
- secondary window used / remaining
- reset time
- 每次统计时从 models.dev 实时获取模型价格,也支持命令行显式覆盖。
- 用 Python 从统计 JSON 自动生成 LaTeX,保证每次收据样式和字段映射一致。
- 优先编译 LaTeX 生成漂亮的 PDF;如果没有 LaTeX,可以降级为 Python 纯文本收据。
- 可以作为 Codex skill 使用,也可以直接运行脚本。
codex-usage-receipt/
├── SKILL.md
├── README.md
├── scripts/
│ ├── codex_usage_summary.py
│ ├── render_latex_receipt.py
│ └── render_text_receipt.py
├── tests/
│ └── test_models_dev_pricing.py
└── evals/
└── evals.json
SKILL.md 是给 Codex/Claude 使用的工作流说明。
codex_usage_summary.py 负责读取 JSONL 日志并输出结构化统计 JSON。
render_latex_receipt.py 负责把统计 JSON 自动填充到统一 LaTeX 收据模板。
render_text_receipt.py 负责把统计 JSON 渲染为纯文本收据,作为没有 LaTeX 时的可靠 fallback。
仓库地址:wangling-miao/codex-usage-receipt
把本仓库放到你的 Codex skills 目录下:
cd $env:USERPROFILE\.codex\skills
git clone https://github.com/wangling-miao/codex-usage-receipt.git目录名应保持为:
codex-usage-receipt
安装后,可以在 Codex 里自然地说:
打印 2026-05-23 以来的 Codex token 消费收据,Windows 和 WSL 都要算上,黑白打印。
或者:
帮我统计 Codex token 消耗,做成收据。
如果你没有给出明确时间段,skill 会先问你要统计哪段时间。
先生成统计 JSON:
python scripts\codex_usage_summary.py `
--since 2026-05-23 `
--until 2026-07-05 `
--timezone +08:00 `
--output work\codex-usage-summary.json再生成 LaTeX 收据:
python scripts\render_latex_receipt.py `
work\codex-usage-summary.json `
--output outputs\codex-usage-receipt.tex如果机器安装了 TeX Live、Tectonic 或其它可用 LaTeX 工具,可以把 .tex 编译成 PDF。
如果没有 LaTeX,再生成纯文本收据:
python scripts\render_text_receipt.py `
work\codex-usage-summary.json `
--output outputs\codex-usage-receipt.txt如果只想看 JSON,可以省略 --output:
python scripts\codex_usage_summary.py --since 2026-05-23 --until 2026-07-05--since 是必填项。
--until 是可选项,省略时表示统计到当前时间。
为避免“只查今天”仍读取全部历史日志,脚本会先排除修改时间早于统计起点五分钟以上的 JSONL 文件,再按事件时间做精确过滤。
日期可以写成:
2026-05-23
也可以写成带时间的形式:
2026-05-23T00:00:00
如果 --until 只给日期,例如 2026-07-05,脚本会把它当作当天 23:59:59。
默认时区是 +08:00,可以通过 --timezone 覆盖。
脚本默认扫描这些位置:
%USERPROFILE%\.codex\sessions
%USERPROFILE%\.codex\archived_sessions
\\wsl.localhost\Ubuntu\root\.codex\sessions
\\wsl.localhost\Ubuntu\root\.codex\archived_sessions
如果你的 WSL 用户不是 root,或者发行版不叫 Ubuntu,可以用 --root 加额外路径:
python scripts\codex_usage_summary.py `
--since 2026-05-23 `
--until 2026-07-05 `
--root "WSL home=\\wsl.localhost\Ubuntu\home\<linux-user>\.codex\sessions" `
--output work\codex-usage-summary.json--root 支持两种写法:
label=path
path
带 label 时,输出里的 by_source 会使用这个名称。
脚本默认使用 event_msg 中的 payload.type == "token_count" 事件,并读取 info.last_token_usage。
这样做是因为 total_token_usage 是累计值,在会话压缩、续写或恢复时可能重置或重复。如果直接把累计值相加,容易把 token 数放大。
核心计算公式:
fresh_input_tokens = input_tokens - cached_input_tokens
cost =
fresh_input_tokens / 1_000_000 * input_rate
+ cached_input_tokens / 1_000_000 * cache_hit_rate
+ output_tokens / 1_000_000 * output_rate
+ cache_creation_tokens / 1_000_000 * cache_creation_rate
脚本每次运行都会请求 https://models.dev/api.json,默认读取 openai provider,并按下面的规则映射价格(单位:USD / 1M tokens):
cost.input→ fresh inputcost.cache_read→ cache hitcost.output→ outputcost.cache_write→ cache creation
仓库中不再维护写死的价格表,也不会在网络失败时静默回退到旧价格。接口不可用、响应无效或找不到 provider 时,脚本会以明确的 pricing error 退出。当前收据结构按模型保存一组基础价格,因此 models.dev 的 context-tiered 价格暂不应用,相关说明会写入输出 JSON 的 notes。
如需使用 models.dev 兼容镜像、切换 provider 或调整超时:
python scripts\codex_usage_summary.py `
--since 2026-05-23 `
--pricing-url https://models.dev/api.json `
--pricing-provider openai `
--pricing-timeout 15如需人工覆盖某个模型的实时价格,可以用 --price:
python scripts\codex_usage_summary.py `
--since 2026-05-23 `
--until 2026-07-05 `
--price gpt-5.3-codex-spark=1.75,0.175,14,0 `
--output work\codex-usage-summary.json格式为:
model=input,cache_hit,output,cache_creation
覆盖会在实时目录获取成功后应用。如果省略第四项,cache creation 默认是 0。
codex_usage_summary.py 输出的 JSON 主要包含:
generated_at:生成时间。since/through:统计时间段。first_event/last_event:实际命中的第一条和最后一条使用事件。files_found:扫描到的 JSONL 文件数量。included_sessions:实际包含使用量的 session 数量。models:按模型拆分的 token 和成本。total:总 token、总成本、缓存命中率和成本组件。by_source:按日志来源拆分,例如 Windows 和 WSL。rate_limits:从日志里读到的最新 Codex 限额快照。里面保留raw_used_percent便于审计;面向收据展示的used_percent和remaining_percent已按用户期望的展示口径交换。pricing_source:models.dev URL、provider、获取时间、目录模型数量和人工覆盖项。pricing:本次从 models.dev 获取并应用人工覆盖后的价格表。notes:方法说明和注意事项。
LaTeX 只是编译 PDF 的首选,不是硬依赖。即使没有 LaTeX,也可以先用 render_latex_receipt.py 生成 .tex,但无法在本机编译成 PDF。
如果没有安装 TeX Live、Tectonic 或其它 LaTeX 工具,直接用纯文本 fallback:
python scripts\render_text_receipt.py `
work\codex-usage-summary.json `
--output outputs\codex-usage-receipt.txt在 Windows 上可以直接打印文本:
Get-Content outputs\codex-usage-receipt.txt | Out-Printer -Name "<Printer Name>"如果需要 PDF,但没有 LaTeX,可以让 Codex 使用 Python、浏览器打印、ReportLab、Pillow 或系统已有工具生成替代版。不要为了生成 PDF 自动安装大型依赖,除非用户明确同意。
生成 PDF 或 PNG 后,建议转成灰度再打印。
如果系统有 pdftoppm:
pdftoppm -singlefile -png -gray -r 300 receipt.pdf receipt-print打印后检查队列:
Get-PrintJob -PrinterName "<Printer Name>" -ErrorAction SilentlyContinue
Get-Printer -Name "<Printer Name>" | Select Name,PrinterStatus,JobCount,WorkOffline如果队列未清空或打印机离线,应明确告知用户,不要假装已经打印成功。
- 脚本只读取本机 JSONL 日志。
- 默认不会上传日志、token 明细或生成的报告。
- 如果你把生成的报告提交到 GitHub,请先确认其中没有私人路径、账户信息、用量细节或其它敏感内容。
- 本仓库只应提交工具代码、skill 文档和示例,不应提交真实收据、真实日志或
outputs/目录。
这个项目的目标是从原始 Codex JSONL 日志重建账单口径。CC Switch、截图或其它工具可以用来交叉验证,但不应作为默认来源。
Codex 可能在 Windows 和 WSL 中各自产生日志。只看 %USERPROFILE%\.codex\sessions 可能漏掉 WSL 中的大量使用量。
因为它是会话累计值。会话压缩、恢复、重试或上下文切换时,累计值可能重置或重复。默认使用 last_token_usage 逐事件累加更稳定。
不要静默套用别的模型价格。应该:
- 在报告里标记为 unpriced;或
- 询问用户价格;或
- 在确认价格后用
--price显式覆盖。
语法检查:
python -m py_compile scripts\codex_usage_summary.py scripts\render_latex_receipt.py scripts\render_text_receipt.py价格目录单元测试:
python -m unittest discover -s tests -v查看命令帮助:
python scripts\codex_usage_summary.py --help
python scripts\render_latex_receipt.py --help
python scripts\render_text_receipt.py --help测试用例在:
evals/evals.json
它覆盖三类关键行为:
- 用户已给明确时间段时直接执行。
- 用户未给时间段时先询问。
- 没有 LaTeX 时 fallback 到纯文本。
- LaTeX 报告必须由 Python 模板渲染器从 summary JSON 生成。