下载地址
https://www.zhengdianxue.com/wp-content/uploads/skills/lexord-technology--progress-tracker.zip将提示词发送给你的 AI 安装该 skills
请根据 https://skillhub.cn/install/skillhub.md,安装 @lexord-technology/progress-tracker。【律令】(百分比/ETA/卡死检测)进度跟踪与进度条估算:给出百分比、双速率、ETA、心跳与卡死检测,支持多任务并行看板;算不出 ETA 时明确拒绝给数字。
阅读全文 (展开查看完整说明)
概述
本地运行,零网络请求、免 API Key、不主动外发数据。
四项诚实承诺:① 算不出就说算不出,绝不编造数字;② 高危动作强制人工确认;③ 幂等断点,绝不重复副作用;④ 全程留痕可审计。
边界说明:本包脚本自身不联网、不外发;若你把内容贴进 AI 对话,内容是否离开本机由你所使用的客户端决定,不由本包决定。
<!– WB-CLAIM-BOUNDARY v1 –>
任务进度追踪
运行方式
<!– WB-INVOKE-CONTRACT v1 –>
环境:Python 3.8+,仅标准库,无需安装任何依赖。
作用:任务进度追踪:百分比/双速率/ETA/心跳/卡死检测/多任务看板
命令(在技能目录下执行;<尖括号> 是你要替换的输入):
# 查看子命令帮助
python scripts/progress_tracker.py --help
# 按子命令执行(示例)
python scripts/progress_tracker.py init <参数>子命令:
| 子命令 | 说明 |
|---|---|
init | 建进度记录 |
tick | 推进进度(+n),同时打心跳 |
heartbeat | 只打心跳,不动进度 |
status | 单任务详情 |
eta | 只算 ETA |
watch | 多任务看板 |
close | 收尾 |
rm | 移除记录 |
list | 列出全部任务 |
选项:
| 选项 | 说明 |
|---|---|
--store STORE | 注册表路径(默认 ~/.lexord-progress-tracker/registry.json) |
退出码:0 成功 / 2 输入错误 / 3 鉴权失败 / 4 环境或依赖失败 / 8 部分成功。
输出:产物写入执行目录,源文件不改动;先跑预览确认,再加 --execute 落盘。
相邻路线转交
本包只做自己职责范围内的事,遇到下列情形直接转给兄弟技能:
| 用户要做的事 | 转交给 | 转交话术 |
|---|---|---|
| 中断后要从断点继续 | lexord-resume-runner | 「断点恢复交给 lexord-resume-runner」 |
| 要追踪一批并行任务 | lexord-batch-runner | 「批量调度交给 lexord-batch-runner」 |
| 进度异常/卡死 | lexord-task-recovery | 「体检与救援交给 lexord-task-recovery」 |
反向边界:算不出 ETA 时明确拒绝给数字,绝不编造进度。
你是一个长任务的仪表盘:告诉人「跑到哪了、还有多久、是不是卡了」。核心原则:算不出来就说算不出来、卡死判定优先于时间承诺、窗口速率比全程速率更可信。
环境准备
纯 Python 标准库,无第三方依赖。注册表默认在 ~/.lexord-progress-tracker/registry.json,可用 --store 指定。
python scripts/progress_tracker.py --store registry.json <子命令> [参数]子命令
| 子命令 | 作用 |
|---|---|
init | 建进度记录(--total N / --items 清单 / --from-state 状态文件) |
tick | 推进进度(+n),同时打心跳 |
heartbeat | 只打心跳,不动进度 |
status | 单任务详情 |
eta | 只算 ETA |
watch | 多任务看板 |
close | 收尾 |
rm | 移除记录 |
list | 列出全部任务 |
核心能力(全部实测通过)
1. status:同时给「窗口速率」与「全程速率」
python scripts/progress_tracker.py --store pt_registry.json status --id crawl-goods实测(爬取商品,200 项做了 100 项):
{ "percent": 50.0, "done": 100, "total": 200, "remaining": 100,
"overall_per_min": 10.0, "window_per_min": 10.0, "rate_source": "window",
"eta_s": 600.0, "eta_human": "10 分 0 秒", "eta_basis": "window 速率 10.0/分钟",
"eta_finish_at": "2026-09-23 11:38:45",
"heartbeat_age_s": 11.0, "heartbeat_age_human": "11 秒",
"stalled": false, "verdict": "进行中" }2. 窗口速率为 0 时拒绝给 ETA(本包最重要的立场)
任务刚卡下来:窗口内 0 推进,但全程速率还有 2.857/分钟。实测:
{ "remaining": 440,
"window_per_min": 0.0, "overall_per_min": 2.857, "rate_source": "window",
"eta_s": null, "eta_human": null, "eta_basis": "window=0",
"eta_unavailable": "最近窗口内没有推进(窗口速率 0),拒绝给出 ETA——全程速率此时没有参考价值,先看卡死判定" }刻意不退回全程速率:那会算出「2 小时 34 分」这种看起来精确、实际毫无意义的数字。null 和 0 必须分开对待——None 是「算不出」,0 是「算出了,就是没动」。
3. 心跳超阈值判卡死,并标记 ETA 不可靠
{ "stalled": true, "eta_reliable": false,
"heartbeat_age_s": 911.0, "heartbeat_age_human": "15 分 11 秒",
"stalled_reason": "心跳已停 15 分 11 秒(阈值 5 分 0 秒)——进程可能卡死或已退出",
"verdict": "疑似卡死" }此时即使还能算出 eta,也会带 eta_reliable: false——卡死判定优先于时间承诺。
4. done > total 也拒绝给 ETA
{ "done": 260, "total": 200, "over_total": 60, "percent": 100.0,
"warn": "已完成 260 超过总量 200(超出 60)——清单可能中途被改小,或存在重复计数",
"eta_basis": "over_total",
"eta_unavailable": "已完成数超过总量 60,ETA 无意义——先查清单为什么被改小或为什么会重复计数" }不给「0 秒」这种看似「马上完成」的假信号。
5. 已结束的任务不再估算
// complete
{ "verdict": "已完成", "eta_s": 0, "eta_basis": "complete" }
// failed
{ "verdict": "已失败", "failed": 3, "eta_s": null,
"eta_unavailable": "任务已标记失败,不再估算" }6. watch:多任务看板,卡死排最前
python scripts/progress_tracker.py --store pt_registry.json watch --md
summary = {'total_jobs': 7, 'stalled': 1, 'running': 5, 'complete': 1, 'failed': 1}
warn = 1 个任务疑似卡死——先看它们的心跳时间
| 任务 | 状态 | 进度 | 速率 | ETA | 心跳 |
|---|---|---|---|---|---|
| 疑似卡死的任务 | 疑似卡死 | 30.0%(30/100) | 3.0/分(窗口) | 23 分 20 秒 | 15 分 15 秒 |
| 重建文档索引 | 进行中 | 12.0%(60/500) | 0.0/分(窗口) | — | 1 分 55 秒 |
| 导出月度报表 | 进行中 | 50.0%(150/300) | 5.0/分(窗口) | 30 分 0 秒 | 45 秒 |
| 已超额的任务 | 进行中 | 100.0%(260/200) | 50.0/分(窗口) | — | 35 秒 |
| 爬取商品 | 进行中 | 50.0%(100/200) | 10.0/分(窗口) | 10 分 0 秒 | 25 秒 |
| 失败的任务 | 已失败 | 25.0%(20/80) | 4.0/分(窗口) | — | — |
| 已完成的任务 | 已完成 | 100.0%(50/50) | 10.0/分(窗口) | 已全部完成 | — |排序把卡死的排最前;已结束任务的心跳列留空(不再刷无意义的秒数);算不出 ETA 的显示 — 而不是编个数字。
7. 可直接接手批处理的状态文件
python scripts/progress_tracker.py --store pt_live.json init --id 批处理 --from-state b1.json
json
{ "total": 8, "done": 6, "failed": 2, "total_source": "from_state(b1.json)" }这样 lexord-batch-runner 跑完,lexord-progress-tracker 能立刻接手做全局看板,不用重跑一遍。也支持 --items 清单(含 GBK、表头)当总量来源。
8. 亚秒级推进的诚实标注
同秒内多次 tick 时窗口跨度为 0,实测会挂说明而不是假装精确:
{ "window_span_s": 3.0,
"rate_note": "窗口跨度仅 3.0 秒(<5 秒),算出的速率受进程启动开销影响很大,仅供参考" }样本上限 120 条(连续 130 次 tick 实测夹到 120 且保留基准首样本),防止注册表无限膨胀。
工作流建议
- 建任务时选对总量来源:能拿到清单就用
--items,能从上游状态文件接手就用--from-state——比手填--total可靠。 - 推进时顺手打心跳:
tick自带心跳;纯等待阶段用heartbeat单独打,否则会被误判卡死。 - 报进度前先看
stalled:卡死判定优先于 ETA。eta_reliable: false时不要把它当承诺告知用户。 - 交付时要说清楚:
eta_human为null/—时,必须说明原因(eta_unavailable),不能含糊成「快了」;- 带
eta_caveat/rate_note时提醒速率仅供参考; - 看板里有
stalled项时,先说卡死再说进度。
自检清单
- [ ]
eta_human为null时,是否把eta_unavailable的原因一并告知? - [ ] 若
stalled: true,是否先说卡死再谈 ETA?(eta_reliable为 false) - [ ] 若
over_total非空,是否提醒用户核对清单改动/重复计数? - [ ] 若有
rate_note/eta_caveat,是否说明速率仅供参考? - [ ] 多任务场景是否用
watch给了全局视图,而不是逐个status念?
任务进度追踪 · 律令科技(深圳)有限公司 (@lexord-technology) · Proprietary · © 2026
许可与版权
本 Skill 采用 BUSL-1.1 许可(源码可见,可自由使用)。
版权所有 © 2026 律令科技(深圳)有限公司(@lexord-technology)。
允许个人及企业内部免费使用、复制、修改,包括内部生产环境。未经书面许可,不得将本 Skill 或其修改版作为商业服务对外销售、转售或提供托管服务。各版本发布之日起 4 年后自动转为 Apache License 2.0。详见随包 LICENSE.md。
输出规范
- 交付形态:执行结果 + 变更清单,说清动了什么、没动什么。
- 必含字段:执行前状态 / 执行动作 / 执行后状态 / 失败项与原因 / 回滚方式。
- 留痕:产生副作用的执行必须写留痕文件(manifest / log),可回溯。
- 自检:失败项未列原因,或无可回滚路径,视为未完成。
版本:v0.1.5 · 出品:【律令】
反例对照(避开这些写法)
| ❌ 反例 | ✅ 正例 | 判据 |
|---|---|---|
| 高危动作直接执行 | 先 dry-run 预览,人工确认后再落盘 | 这一步做错了能不能一键撤回 |
| 失败只说「失败了」 | 失败项 + 失败原因 + 已回滚到什么状态 | 用户能不能据此判断要不要重试 |
| 重复执行已做过的动作 | 先查留痕文件,已完成的跳过(幂等) | 重跑一次会不会产生重复副作用 |
| 执行完不说改了什么 | 给出变更清单:动了哪些、没动哪些 | 用户能否核对结果 |
<!– WB-SELFCHECK v1 –>
交付前自检(必跑)
本包自带可执行自检脚本。在交付 / 打包 / 发布之前,必须运行并通过:
python scripts/selfcheck.py退出码语义(与本节末尾「退出码(脚本契约)」一致):
| 码 | 含义 | 你要做的事 |
|---|---|---|
| 0 | 全部通过 | 可以交付 |
| 2 | 用法错误 | 检查运行路径,用包根目录下 scripts/selfcheck.py |
| 3 | 门禁未通过 | 按 FAIL 项逐条修好再交付,不要带病交付 |
| 4 | 环境问题 | 检查 Python 版本(需 3.8+)与入口脚本是否可运行 |
| 8 | 部分通过 | 无 FAIL,但有 WARN;建议先修警告项再交付 |
自检覆盖:SKILL.md 与 frontmatter(name·description)/ 合规声明(frontmatter license 或 ATTRIBUTION.md,二者其一即可——第三方转化包常以后者记录归属)/ 必备章节 / 打包卫生(禁止 .pyc·__pycache__·.bak·.zip)/ 脚本可编译 / 入口脚本 --help 可运行。<!– /WB-SELFCHECK –>
退出码(脚本契约)
| 码 | 含义 | 你要对用户说的话 |
|---|---|---|
| 0 | 成功 | 直接给结果,不解释过程 |
| 2 | 输入错误(缺参数 / 格式不对 / 文件不存在) | 「你给的 <X> 不对,需要 <Y>」—— 说明正确格式,不要猜默认值硬跑 |
| 3 | 鉴权/授权失败(密钥缺失、无权限) | 「需要你先提供 <凭据>」—— 说明去哪里拿,不要跳过鉴权 |
| 4 | 服务/环境失败(网络不可用、依赖缺失) | 「这一步依赖 <X> 不可用」—— 给出替代路径或降级方案 |
| 8 | 部分成功(有成功项也有失败项) | 「N 项成功、M 项失败」—— 逐条列出失败项与原因,不要只报总数 |
脚本退出非 0 时:不要静默重试。先把该码对应的话告诉用户,再决定是补齐输入重试、还是换路径。
状态与断点
- 多阶段流程在执行目录写
outputs/.state.json,记录「当前阶段 + 已完成产物路径 + 时间」。 - 每个阶段结束后写一次;中途中断后重启,先读该文件,从断点阶段继续,不从头重跑。
- 状态文件只记阶段与产物路径,不记对话内容、不记敏感数据。
- 发现状态文件与实际情况不符(产物已不存在)时,以实际产物为准并重置状态。