讨论

运行计划负载检查器 - 训练计划审查的AI技能

来自 Wikiprompt,自由的提示词百科全书

Fatih Kadir Akın

2026年10月9日

运行计划负载检查器 - 训练计划审查的AI技能 一个完整的AI技能,用于制定和审查跑步训练计划,包括一个Python脚本,用于检查风险负荷跳跃,以及一个详细的工作流程。

提示词内容收藏

🌐
--- name: running-plan-load-checker description: 构建并审查针对5K、10K、半程马拉松和马拉松目标的跑步训练计划,,使用经过测试的脚本检查每周跑量跳跃、长跑占比与进展、高强度日与连续高强度训练、休息周与减量周、峰值时机以及赛前减量,然后用通俗语言解释风险并提出更安全的逐周计划。当跑者分享计划或询问“这个计划是否强度过大?”、“帮我制定一个12周半程马拉松计划”或“我应该如何增加跑量?”时使用。 --- # 跑步计划负荷检查器 你帮助普通跑者健康地到达比赛日。你构建循序渐进进展的计划,并审查现有计划中导致大多数过度使用损伤的负荷错误:做得太多、太快、恢复太少。 你是教练助理,不是医生。疼痛、疾病和医疗状况应交给专业人士(参见 `references/safety-and-red-flags.md`)。 ## 本技能中的文件 - `scripts/check_plan.py` - 解析计划表格(Markdown或CSV)并逐周检查负荷进展(仅使用Python 3标准库) - `references/training-principles.md` - 进展、强度平衡、长跑、减量周、峰值和赛前减量 - `references/safety-and-red-flags.md` - 何时停止、就医或调整计划 - `templates/training-plan.md` - 脚本读取的计划表格格式,以及审查布局 - `examples/example-half-marathon-review.md` - 一份草稿计划的审查与修正 ## 工作流程 ### 1. 获取跑者的背景信息 用一条简短消息询问或确认: - 目标比赛、距离和日期(或可用周数)。 - 当前跑步情况:过去4周的每周公里数、每周跑步次数、最近最长跑距离。 - 经验水平以及过去一年的受伤史。 - 可用天数,以及必须空闲的任何一天。 - 目标:舒适完赛,还是时间目标。 如果跑者有健康问题、正在从伤病中恢复、怀孕或刚开始运动,建议在遵循任何计划前咨询医生。 ### 2. 将计划放入表格格式 使用 `templates/training-plan.md`:每个训练课一行,包含 `week`、`day`、`type` 和 `km`。使用脚本识别的类型词(easy、recovery、long、tempo、intervals、hills、fartlek、race、cross、strength、rest)。 ### 3. 运行检查器 ```bash python3 scripts/check_plan.py plan.md --race half --level intermediate --current-km 20 python3 scripts/check_plan.py plan.csv --race marathon --level beginner --current-km 30 --json ``` 每周表格显示公里数、跑步次数、非跑步天数、长跑距离、长跑占比、高强度天数,以及与前三周最高值的对比变化。发现项为HIGH(使用计划前必须修复)或WARN(需审查并说明理由)。退出码1表示至少有一个HIGH发现项。 如果无法运行脚本,请使用 `references/training-principles.md` 手动应用相同检查,并说明情况。 ### 4. 修复并解释 对于每个发现项,修改计划而不仅仅是描述问题:平滑跳跃、插入减量周、将高强度训练分开、调整峰值、缩短比赛周。再次运行检查器,直到没有HIGH发现项,并且仅在有理由的情况下保留任何剩余的WARN(例如经验丰富的跑者恢复到熟悉的跑量)。 ### 5. 报告 使用 `templates/training-plan.md` 中的审查布局,如 `examples/example-half-marathon-review.md` 所示:更改了什么及原因、最终计划、生活变化时如何调整,以及安全注意事项。 ## 规则 - 距离使用公里,除非跑者使用英里;一个计划中绝不混用单位。 - 大多数跑步应感觉轻松(可对话)。用体感和说话测试描述强度,而不仅仅用配速。 - 不规定饮食、补剂或药物。 - 绝不让跑者带着尖锐、加重或导致跛行的疼痛继续训练。 - 错过一周是正常的:重复上一周而不是跳进。 FILE:references/training-principles.md # 检查器使用的训练原则 这些是休闲跑者的保守经验法则。它们是识别风险的指南,不是法律;经验丰富的跑者可以证明例外情况。 ## 每周跑量进展 - 将每周与**前三周的最高值**进行比较,而不仅仅是前一周,这样从减量周恢复到之前的跑量不会受到惩罚。 - 典型安全增幅:初学者约10%,中级跑者12%,高级跑者15%。脚本超过这些值会发出警告,并将超过25%、30%或35%的跳跃评为HIGH。 - 小的绝对变化(3公里或更少)被忽略,因为15公里周的10%太小,无关紧要。 - 第1周应从接近跑者当前水平开始。从远高于当前跑量开始是最常见的计划错误。 ## 减量周 - 每3到4周的建设期,减少约20%到30%的跑量一周,并缩短长跑。 - 脚本在连续五周建设期没有至少15%的下降时发出警告(减量周除外)。 ## 长跑 - 长跑建立耐力,但不应主导一周。使用的占比限制:每周低于30公里时50%,低于60公里时45%,以上时40%。比赛周除外。 - 长跑每次增加约1到3公里。脚本在增长超过3公里且超过之前最佳值20%时发出警告。 - 比赛周前的最长跑最低要求:5K为6公里,10K为10公里,半程马拉松为16公里,马拉松为28公里(初学者马拉松计划通常峰值在30到32公里)。 ## 强度平衡 - 约80%的跑步时间为轻松跑,20%为中等或高强度。 - 高强度训练:节奏跑或阈值跑、间歇跑、山坡跑、法特莱克跑、渐进跑、比赛。每周最大高强度天数:初学者1天,中级2天,高级3天。 - 除非跑者经验丰富且有意为之,否则不要将高强度训练或高强度训练与长跑安排在连续两天(脚本会发出警告)。 - 跨步跑(轻松跑后的短距离放松加速)计为轻松跑。 ## 休息 - 初学者和中级跑者每周至少需要一天非跑步日;3到4次跑步计划通常有2到3天休息。交叉训练和力量训练在表格中计为非跑步日。 ## 峰值与赛前减量 - 半程马拉松和马拉松:最大周应在比赛周前2到3周(脚本将最后两周内的峰值标记为HIGH)。 - 赛前减量:在最后1到3周逐渐减少跑量,同时保持一些短而快的跑步。在比赛周,除比赛本身外,目标约为峰值的40%到60%(脚本超过60%会发出警告)。 ## 单位 - 1英里 = 1.609公里。检查前转换整个计划;脚本只读取公里。 FILE:references/safety-and-red-flags.md # 安全与危险信号 在构建或审查计划时使用此列表。如有疑问,建议跑者去看医生、物理治疗师或运动医学专业人士。不要诊断。 ## 立即停止跑步并寻求医疗帮助 - 胸痛、压迫感或紧绷感;晕厥或近乎晕厥;异常气短;心跳过快或不规律。 - 热病迹象:意识混乱、停止出汗、恶心或呕吐、体温极高。 ## 停止本次训练并休息,如果持续则就医 - 尖锐、局限于骨骼某一点的疼痛,或导致跛行的疼痛。 - 跑步时加重,或次日早晨更严重的疼痛。 - 肿胀、麻木或夜间疼痛。 - 休息几天后仍持续的疼痛。 ## 减少或调整计划 - 异常疲劳持续几天以上、睡眠差、易怒,或静息心率明显高于正常:增加额外轻松日。 - 颈部以上轻度疾病(流鼻涕:轻松跑可能没问题;颈部以下疾病(发烧、胸闷、胃病)或发烧:休息。 - 错过一周:重复最后完成的周。错过两周或更长时间:将跑量退回两周前。 - 炎热、高海拔和山坡:按体感而非配速跑步,并在非常热的日子缩短训练。 ## 开始计划前要求进行医疗检查 - 刚开始运动、长时间休息后恢复,或超过40岁且之前不活跃。 - 已知心脏、肺部或代谢疾病,或心源性猝死家族史。 - 怀孕或近期分娩。 - 近期受伤,尤其是骨应力性损伤。 ## 补给与补水(仅一般性建议) - 对于超过约75到90分钟的跑步,在训练中练习携带水和一些碳水化合物,而不是在比赛日第一次尝试。 - 具体的营养、补剂或体重建议属于注册营养师或医生的职责。 ## 如何表达 要清晰且友善:“那种疼痛是停止并检查后再进行下一次跑步的理由。计划会等待;我们可以调整之后的几周。” FILE:templates/training-plan.md # 训练计划表格(scripts/check_plan.py 的输入) 每个训练课一行。休息日可以列为类型 `rest` 和公里数 `0`,或省略。 | week | day | type | km | notes | |---|---|---|---|---| | 1 | Tue | easy | 5 | conversational pace | | 1 | Thu | tempo | 6 | 2x8 min comfortably hard, 2 min jog between | | 1 | Sat | long | 10 | easy, practice drinking | | 1 | Sun | cross | 0 | bike or swim30 to45 min, optional | 列: - `week`:1、2、3 ... - `day`:Mon到Sun(或1到7) - `type`:easy、recovery、long、tempo、threshold、intervals、hills、fartlek、progression、race、cross、strength、rest - `km`:以公里为单位的距离(rest、cross、strength为0) - `notes`:可选;训练细节 运行:`python3 scripts/check_plan.py plan.md --race <5k|10k|half|marathon> --level <beginner|intermediate|advanced> --current-km <km>` --- # 计划审查:<runner> - <race> 于 <date> **跑者:** <当前每周公里数、每周跑步次数、最近最长跑、水平、受伤史> **目标:** <完赛 / 时间目标> **周数:** <n> **可用天数:** <days> ## 检查器结果(之前) <HIGH和WARN发现项,简短> ## 我更改了什么及原因 1. <更改> - 修复 <发现项>;<一行原因> ## 最终计划 <上述格式的表格> ## 检查器结果(之后) <“0个发现项”或剩余的WARN及其可接受的理由> ## 生活变化时如何调整 - 错过一次跑步:<规则> - 错过一周:<规则> - 感觉疲惫:<规则> ## 安全注意事项 - <来自 references/safety-and-red-flags.md 的相关要点> FILE:examples/example-half-marathon-review.md # 示例:审查一份10周半程马拉松草稿 **跑者:** “我每周跑约20公里,3次跑步,最长跑9公里。我在网上找到了这个10周半程马拉松计划。可以吗?”中级,过去一年无受伤,目标是强劲完赛。可用时间:周二、周三、周四、周六、周日。 **草稿计划(摘要):** 第1到9周从24公里增加到44公里,长跑每周增加1公里从12公里增至20公里,每周有节奏跑或间歇跑(第2周额外增加间歇跑,第6周增加山坡跑),没有减量周,第10周周日比赛。 **命令:** ```bash python3 scripts/check_plan.py draft.md --race half --level intermediate --current-km20 ``` **输出:** ``` WEEK KM RUNS REST LONG LONG% HARD CHANGE 1 24 3 4 12 50% 1 - 2 31 4 3 13 42% 2 +29% 3 28 3 4 14 50% 1 -10% 4 34 4 3 15 44% 1 +10% 5 37 4 3 16 43% 1 +9% 6 39 4 3 17 44% 2 +5% 7 40 4 3 18 45% 1 +3% 8 42 4 3 19 45% 1 +5% 9 44 4 3 20 45% 1 +5% 10 40.1 4 3 21.1 53% 2 -9% 发现项: 6 [HIGH] 第9周:峰值跑量(44公里)落在第9周,距离比赛周第10周太近;峰值应在2到3周前 [WARN] 第1周:第1周为24公里,而当前每周20公里 [WARN] 第2周:跑量31公里比近期最大值24公里高29%(目标为12%或更少) [WARN] 第2周:连续两天有高强度或长跑训练:3-4 [WARN] 第5周:连续五周没有减量周(每3到4周减少20%到30%的跑量) [WARN] 第6周:连续两天有高强度或长跑训练:4-5、5-6 ``` --- # 计划审查:12周半程马拉松 **跑者:** 每周20公里,3次跑步,最近最长跑9公里,中级,近期无受伤 **目标:** 强劲完赛 **周数:** 12(比赛移至第12周,提前两周开始) **可用天数:** 周二、周三、周四、周六、周日 ## 检查器结果(之前) 1个HIGH(峰值在比赛前一周,因此没有减量)和5个WARN(起始过高、第2周29%的跳跃、第2周和第6周连续高强度日、没有减量周)。 ## 我更改了什么及原因 1. 第1周从21公里开始 - 接近当前20公里,因此身体在第1周不会受到冲击。 2. 每周增加约2公里(6%到10%) - 消除了第2周的跳跃。 3. 第4周和第8周设置减量周(减少约20%,长跑回到10公里) - 让身体吸收训练。 4. 每周四进行一次质量训练,绝不在长跑前一天或后一天 - 修复了连续高强度日。 5. 峰值(36公里,长跑16公里)在第10周,然后是减量周(26公里)和轻松的比赛周 - 比赛时状态新鲜。 6. 从第2周起在周三增加第四次短距离轻松跑 - 在不加重长跑负担的情况下增加跑量。 ## 最终计划 | week | km | Tue | Wed | Thu | Sat | Sun | |---|---|---|---|---|---|---| | 1 | 21 | easy5 | - | easy6 + strides | long10 | - | | 2 | 23 | easy5 | easy3 | tempo5(2x8 min) | long10 | - | | 3 | 25 | easy6 | easy3 | tempo5(2x10 min) | long11 | - | | 4 | 20 | easy5 | - | easy5 | long10 | - | | 5 | 27 | easy6 | easy4 | intervals6(5x1 km) | long11 | - | | 6 | 29 | easy6 | easy4 | tempo7(3x10 min) | long12 | - | | 7 | 31 | easy6 | easy5 | intervals7(6x1 km) | long13 | - | | 8 | 25 | easy6 | easy4 | easy5 | long10 | - | | 9 | 34 | easy7 | easy5 | tempo7(2x15 min) | long15 | - | | 10 | 36 | easy7 | easy6 | intervals7(5x1.6 km) | long16 | - | | 11 | 26 | easy6 | easy4 | tempo5(20 min at goal pace) | long11 | - | | 12 | 30.1 | easy5 + strides | - | easy4 | - | RACE21.1 | 第5周周一还有可选的40分钟自行车骑行。 ## 检查器结果(之后) `python3 scripts/check_plan.py revised.md --race half --level intermediate --current-km20` -> `发现项: 0`,退出码0。 ## 生活变化时如何调整 - 错过一次跑步:跳过;不要将其挤入第二天。 - 错过一周:重复你完成的最后一周,然后继续。 - 感觉疲惫或酸痛超过两天:将质量训练替换为轻松跑或休息。 ## 安全注意事项 - 对于尖锐、单点或导致跛行的疼痛,或次日早晨更严重的疼痛,停止并就医。 - 从第9周开始在长跑中练习饮水(和少量碳水化合物零食),这样比赛日不会有意外。 FILE:scripts/check_plan.py #!/usr/bin/env python3 """检查跑步训练计划是否存在危险的负荷跳跃和结构缺失。 用法: python3 check_plan.py plan.md [--race5k|10k|half|marathon] [--level beginner|intermediate|advanced] [--current-km20] [--json] python3 check_plan.py plan.csv ... cat plan.md | python3 check_plan.py - ... 计划是Markdown表格或CSV,表头行至少包含 week、day、type和km(也接受:distance、dist。可选列 被忽略。每个训练课一行;休息日可以列出或省略。 day: Mon..Sun、Monday..Sunday或1..7 type: easy、recovery、long、tempo、threshold、intervals、hills、fartlek、 progression、race、cross、strength、rest (其他任何内容计为easy) km: 数字(rest、cross和strength使用0) 每周检查:与前三周最高值相比的跑量增加、长跑占周跑量的比例(低于30公里时限制50%,低于60公里时45%,以上时40%;比赛周除外)、长跑跳跃、高强度天数、连续两天的高强度或长跑训练、休息日,以及减量周。 计划级检查:第一周与当前每周跑量的对比、最长跑与比赛距离的对比、峰值周距离比赛日太近,以及减量。 退出码:0无HIGH发现项,1至少一个HIGH发现项,2用法或输入错误。 仅使用标准库。 """ import csv import io import json import re import sys DAYS = {"mon":1, "tue":2, "wed":3, "thu":4, "fri":5, "sat":6, "sun":7} HARD = {"tempo", "threshold", "intervals", "interval", "hills", "hill", "fartlek", "progression", "race", "speed", "track"} NON_RUN = {"rest", "cross", "strength", "off", "yoga", "bike", "swim"} RACE_KM = {"5k":5.0, "10k":10.0, "half":21.1, "marathon":42.2} MIN_LONG = {"5k":6, "10k":10, "half":16, "marathon":28} LIMITS = { # 每周增加警告、每周增加HIGH、最大高强度天数 "beginner":(0.10, 0.25, 1), "intermediate":(0.12, 0.30, 2), "advanced":(0.15, 0.35, 3), } def long_share_limit(week_km): """低跑量周自然会有更大的长跑占比。""" return 0.50 if week_km <30 else 0.45 if week_km <60 else 0.40 def usage(msg): print(f"error: {msg}\n", file=sys.stderr) print(__doc__.strip().split("\n\n")[1], file=sys.stderr) sys.exit(2) def read_rows(text): lines = [ln for ln in text.splitlines() if ln.strip()] if not lines: return [] if lines[0].lstrip().startswith("|") or sum(ln.count("|") >=3 for ln in lines) > len(lines) /2: rows = [] for ln in lines: if "|" not in ln or re.match(r"^\s*\|?\s*:?-{2,}", ln): continue rows.append([c.strip() for c in ln.strip().strip("|").split("|")]) else: rows = list(csv.reader(io.StringIO("\n".join(lines)))) header = [h.strip().lower() for h in rows[0]] out = [] for r in rows[1:]: out.append({header[i]: (r[i].strip() if i < len(r) else "") for i in range(len(header))}) return out def num(value): m = re.search(r"\d+(?:[.,]\d+)?", value or "") return float(m.group(0).replace(",", ".") if m else 0.0) def parse(rows): if not rows: raise ValueError("no table rows found") keys = rows[0].keys() kcol = next((k for k in ("km", "distance", "dist", "distance_km") if k in keys), None) for need, col in (("week", "week" in keys), ("day", "day" in keys), ("type", "type" in keys), ("km", kcol)): if not col: raise ValueError(f"missing column '{need}' (found: {', '.join(keys)})") sessions = [] for i, r in enumerate(rows,2): w = num(r["week"]) d = r["day"].strip().lower() day = DAYS.get(d[:3]) if d[:3] in DAYS else (int(d) if d.isdigit() and 1 <= int(d) <=7 else None) if not w or day is None: raise ValueError(f"row {i}: cannot read week/day from {r['week']!r}/{r['day']!r}") t = (r["type"].strip().lower().split() or ["easy"])[0] km = num(r[kcol]) sessions.append({"week": int(w), "day": day, "type": t, "km":0.0 if t in NON_RUN else km}) return sessions def analyze(sessions, race, level, current_km): warn_up, high_up, max_hard = LIMITS[level] weeks = {} for s in sessions: weeks.setdefault(s["week"], []).append(s) findings, table = [], [] def add(sev, week, msg): findings.append({"severity": sev, "week": week, "message": msg}) prev_long = [] week_nums = sorted(weeks) for idx, w in enumerate(week_nums): ss = sorted(weeks[w], key=lambda s: s["day"]) runs = [s for s in ss if s["km"] >0] total = round(sum(s["km"] for s in runs),1) run_days = sorted({s["day"] for s in runs}) longest = max((s["km"] for s in runs), default=0.0) hard_days = sorted({s["day"] for s in runs if s["type"] in HARD}) stress_days = sorted({s["day"] for s in runs if s["type"] in HARD or s["type"] == "long"}) ref = max((r["km"] for r in table[-3:]), default=None) change = None if not ref else (total - ref) / ref row = {"week": w, "km": total, "runs": len(runs), "rest_days":7 - len(run_days), "long_km": longest, "long_share": round(longest / total,2) if total else 0.0, "hard_days": len(hard_days), "change_vs_recent_max": None if change is None else round(change *100)} table.append(row) if change is not None and total - ref >3: if change > high_up: add("HIGH", w, f"volume {total:g} km is {change:.0%} above the recent max of {ref:g} km (limit {high_up:.0%})") elif change > warn_up: add("WARN", w, f"volume {total:g} km is {change:.0%} above the recent max of {ref:g} km (aim for {warn_up:.0%} or less)") is_race_week = bool(race) and idx == len(week_nums) -1 long_share = long_share_limit(total) share = round(longest / total,2) if total else 0.0 if total >=15 and not is_race_week and share > long_share: sev = "HIGH" if share > long_share +0.15 else "WARN" add(sev, w, f"long run {longest:g} km is {share:.0%} of the week's {total:g} km (aim for {long_share:.0%} or less)") if prev_long and longest > max(prev_long) +3 and longest > max(prev_long) *1.2 and not is_race_week: add("WARN", w, f"longest run jumps to {longest:g} km from a previous best of {max(prev_long):g} km (add1 to3 km at a time)") prev_long.append(longest) if len(hard_days) > max_hard: add("WARN", w, f"{len(hard_days)} hard days (days {', '.join(map(str, hard_days))}); {level} plans usually have at most {max_hard}") b2b = [(a, b) for a, b in zip(stress_days, stress_days[1:]) if b - a ==1] if b2b: add("WARN", w, "hard or long sessions on back-to-back days: " + ", ".join(f"{a}-{b}" for a, b in b2b)) if len(run_days) ==7 and level != "advanced": add("WARN", w, "no rest day this week") # 减量周:在任何连续5周的建设期中,期望至少有一周比前一周低15% build = [r for r in table] if race and len(build) >=3: build = build[:-2] # 将减量周排除在外 streak =0 for i, r in enumerate(build): if i and build[i -1]["km"] and r["km"] <= build[i -1]["km"] *0.85: streak =0 else: streak +=1 if streak ==5: add("WARN", r["week"], "five weeks in a row without a cutback week (drop volume20 to30% every3 to4 weeks)") streak =0 if current_km is not None and table: first = table[0]["km"] if current_km ==0 and first >10: add("HIGH", table[0]["week"], f"week1 starts at {first:g} km from no running; begin with run-walk sessions") elif current_km and (first - current_km) / current_km > high_up and first - current_km >3: add("HIGH", table[0]["week"], f"week1 is {first:g} km but current volume is {current_km:g} km/week ({(first - current_km) / current_km:.0%} jump)") elif current_km and (first - current_km) / current_km > warn_up and first - current_km >3: add("WARN", table[0]["week"], f"week1 is {first:g} km versus current {current_km:g} km/week") if race and table: peak = max(table, key=lambda r: r["km"]) last = table[-1]["week"] race_rows = [s for s in sessions if s["type"] == "race"] if not race_rows: add("INFO", last, "no session with type 'race'; the last week is treated as race week") build_long = max((r["long_km"] for r in table[:-1]), default=0) if build_long < MIN_LONG[race]: add("HIGH" if race in ("half", "marathon") else "WARN", None, f"longest training run before race week is {build_long:g} km; for a {race} aim for at least {MIN_LONG[race]} km") if len(table) >=3 and race in ("half", "marathon") and peak["week"] >= last -1: add("HIGH", peak["week"], f"peak volume ({peak['km']:g} km) falls in week {peak['week']}, too close to race week {last}; peak2 to3 weeks out") if len(table) >=2: race_km = sum(s["km"] for s in sessions if s["type"] == "race") race_week_other = table[-1]["km"] - race_km if peak["km"] and race_week_other >0.6 * peak["km"]: add("WARN", last, f"race week has {race_week_other:g} km beside the race ({race_week_other / peak['km']:.0%} of peak); taper to about40 to60%") return table, findings def main(argv): opts = {"race": None, "level": "intermediate", "current": None, "json": False} paths = [] it = iter(argv) for a in it: if a == "--race": opts["race"] = (next(it, "") or "").lower() if opts["race"] not in RACE_KM: usage("--race must be 5k, 10k, half or marathon") elif a == "--level": opts["level"] = (next(it, "") or "").lower() if opts["level"] not in LIMITS: usage("--level must be beginner, intermediate or advanced") elif a == "--current-km": v = next(it, "") try: opts["current"] = float(v) except ValueError: usage("--current-km needs a number") elif a == "--json": opts["json"] = True elif a.startswith("--"): usage(f"unknown option {a}") else: paths.append(a) if len(paths) !=1: usage("give exactly one plan file, or - for stdin") try: text = sys.stdin.read() if paths[0] == "-" else open(paths[0], encoding="utf-8").read() sessions = parse(read_rows(text)) except (OSError, ValueError) as e: print(f"error: {e}", file=sys.stderr) return2 table, findings = analyze(sessions, opts["race"], opts["level"], opts["current"]) order = {"HIGH":0, "WARN":1, "INFO":2} findings.sort(key=lambda f: (order[f["severity"]], f["week"] or0)) if opts["json"]: print(json.dumps({"weeks": table, "findings": findings}, indent=2)) else: print(f"Plan: {len(table)} weeks, {sum(r['km'] for r in table):g} km total | level={opts['level']}" f" race={opts['race'] or '-'} current={opts['current'] if opts['current'] is not None else '-'} km/week") print(f"\n{'WEEK':>4} {'KM':>6} {'RUNS':>4} {'REST':>4} {'LONG':>5} {'LONG%':>5} {'HARD':>4} {'CHANGE':>7}") for r in table: ch = "-" if r["change_vs_recent_max"] is None else f"{r['change_vs_recent_max']:+d}%" print(f"{r['week']:>4} {r['km']:>6g} {r['runs']:>4} {r['rest_days']:>4} {r['long_km']:>5g} " f"{r['long_share']:>5.0%} {r['hard_days']:>4} {ch:>7}") print(f"\nFindings: {len(findings)}") for f in findings: where = f"week {f['week']}" if f["week"] else "plan" print(f" [{f['severity']}] {where}: {f['message']}") if not findings: print(" none - load progression looks reasonable") return1 if any(f["severity"] == "HIGH" for f in findings) else0 if __name__ == "__main__": sys.exit(main(sys.argv[1:]))

登录以查看完整提示词

继续使用:

登录即表示你同意我们的 使用条款 和 隐私政策

用法

此提示词专为 productivity 设计。复制上方内容并粘贴到你常用的 AI 工具中。

为获得最佳效果,可将占位符(方括号或大写字母标示)替换为你的具体需求。

参考资料

分类:productivity| prompts.chat| running| training-plan

讨论