把散落的養生建議換算成同一個單位——全因死亡率(ACM)——然後認真讀它。 15 章、54 個單元、348 支經過驗證的 YouTube 影片、54 則對回 PubMed 的證據查核。
線上課程:https://longevity-course.pages.dev
課程結構改編自 geekan/HowToLiveLonger (程序員延壽指南),用 curate-course 框架建置。
這不構成醫療建議。 本專案與任何醫療機構、影片創作者或保健品業者沒有合作、 授權或背書關係,也不販售任何東西。網站只存公開影片的連結與公開中繼資料, 不重製、不代管、不轉載影片內容。CH8 提到的二甲雙胍、亞精胺、葡萄糖胺、NMN 等, 多數在多數國家並未核准用於「延壽」這個適應症,自行服用可能有實質風險。 任何用藥、停藥或補充劑決定,請先諮詢你的醫師或藥師。
一、反方影片比任何一類都多。 359 個影片欄位裡有 96 支是 counter(機轉 74、
實作 78、劑量 59)。每個干預項目與爭議題都至少配一支唱反調的影片——找不到夠格的就
誠實留空並寫明搜過什麼,不拿無關影片湊數。
二、每個數字都對回原始文獻,對不上就直說。 每個單元有一欄 「宣稱效果量 vs 文獻原值」。實際查下來,來源指南有相當比例的數字站不住:
| 來源宣稱 | 文獻原值 |
|---|---|
| 超加工食物 -62% | 原文是 HR 1.62,方向寫反了(多吃 +62%) |
| 葡萄糖胺「效果與定期運動相當」 | 648 人的觀察性次族群;在自己的適應症上連 GAIT 主要終點都沒過 |
| 日照 -40% | VITAL/D-Health/ViDA 三個大型 RCT 在死亡率終點全部陰性 |
| 減重 -54% | 只在「肥胖→超重」這條軌跡成立;同一份研究另一條是 HR 1.12 |
| 酒精 +50% | 校正戒酒者偏差後低量飲酒 RR≈1.00;+50% 要到每日 ≥4.5 標準杯 |
| 亞精胺 -60%~-30% | 那三個數字是未校正的粗死亡率,不是效果量 |
| 「增加約 20 年壽命」 | 來自作者自擬、自註「歡迎優化」的公式,無實證地位 |
含糖飲料是唯一數字全中的一項。
三、先教怎麼讀數字,再談要不要做。 CH1 四個單元是必修:ACM 與 HR 是什麼、 為什麼觀察性研究只能講相關、為什麼各項降幅不能相加、相對風險與絕對風險的差別。 來源指南自己在第 4 節列了這些警告,但寫完之後整份表格照樣把 HR 當成「做了就能拿到的效果」 在排名——這門課把那三條警告搬到首頁。
四、連結真的活著。 make audit 離線查設定檔、配額、影片長度與實證欄位;
make verify 再對每個 YouTube 連結重打 oEmbed、對每個 PMID 重打 PubMed API。
不信任任何上游宣稱,包括 AI agent 自稱驗證過的。
| 章節 | 15(讀數字的方法 2 章 + 輸入 7 章 + 輸出 3 章 + 上下文 1 章 + 爭議與收尾 2 章) |
| 單元 | 54(40 個干預項目、5 個爭議題、4 個觀念、4 個族群與排序、1 個使用說明) |
| 影片 | 361 個欄位、348 支不重複、55 小時 14 分 |
| 項目類型 | 機轉 74 / 實作 78 / 劑量 59 / 反方 96 |
| 證據查核 | 54 則,全部對回 PubMed(97 個 PMID) |
| 分級 | 證據充分 9 / 中等 18 / 有限 16 / 互斥 11 |
| 驗證 | 稽核零錯誤、連結 348/348 有效、引用 106/106 存在且標題相符 |
設計文件:docs/plans/2026-07-31-longevity-course-design.md
本 repo 內含 curate-course 框架本身, 主題無關——換成吉他、統計、烘焙、電銲都一樣跑。以下是框架的說明。
需要 uv。建置腳本只用 Python 標準庫,沒有執行期相依。
git clone https://github.com/<you>/curate-course.git
cd curate-course
make build # course/ → dist/
make serve # http://localhost:8899看到的是現成的延壽指南課。接著換成你的主題。
你只需要動 course/,其他都是框架。
course/
├── course.config.json 站台設定、章節、配額、所有 UI 文案
├── data/ 策展資料(影片、實證、中繼資料)
└── taxonomy/ 選用:主題專屬的詞彙模組
course.config.json 裡沒有一個字是寫死在程式裡的——分頁名稱、篩選標籤、
統計欄位、證據分級的顯示文字,全部從這裡讀。
course/data/<source>.json,一章一檔:
{
"chapter": "CH1",
"units": [{
"id": "ch1-u1",
"name": "單元名稱",
"assessment": "讀者可以自己做的判斷方法",
"lesson": { "title": "…", "channel": "…", "url": "https://youtube.com/watch?v=…",
"why": "為何選這支" },
"drills": [{ "name": "…", "kind": "demo", "url": "…", "dose": "…" }]
}]
}make build && make audit && make serve配額不符、URL 格式錯誤、同單元重複影片會讓建置直接失敗。
make audit 再往下查一層——而且不打網路,同樣的輸入永遠得到同樣的報告:
設定檔 schema 拼字與型別、圖示有沒有打包、nav 有沒有漏章、佔位符會不會被替換
結構 各章配額、id 唯一、kind/type 是否已定義、每單元項目數是否失衡
影片 中繼資料覆蓋率、長度是否落在設定區間、宣稱長度與實際的誤差、觀看數低標、
留空的格子有沒有寫清楚原因
內容深度 自我評估夠不夠具體、evidence_grade 是否合法、PMID 格式、每類文獻篇數
門檻寫在 course.config.json 的 audit 區塊(影片長度區間、最低觀看數、每單元項目數
上下限…),不是寫死在程式裡。--json 給 agent 讀、--strict 讓警告也變成錯誤。
repo 內附一個 Claude Code skill。在 Claude Code 裡開這個專案,輸入:
/curate-course 幫我用這個框架做一門古典吉他入門課
或直接用自己的話說「幫我用這個框架做一門 X 的課程」,agent 會照著 skill 走完整流程: 談結構 → 定配額 → 並行策展 → 驗證連結 → 補中繼資料 → 加引用 → 稽核 → 建置部署。
Skill 本身採漸進揭露,主檔只有流程骨架,細節按需載入:
.claude/skills/curate-course/
SKILL.md 鐵則、七步流程、驗收清單
reference/config.md 設定檔欄位、schema、圖示、tone、詞彙模組
reference/curating.md 策展 agent 指示範本、oEmbed 驗證、資料格式、多語言
reference/evidence.md 單元/類別兩層實證、PubMed E-utilities 用法
reference/quality.md audit 與 verify 的分工、門檻怎麼調、踩過的坑
裡頭寫死了幾條不可退讓的規則,最重要的是:video ID 必須取自實際搜尋結果,
不可憑記憶拼湊;找不到合格影片就留空並在 note 說明原因——留空而不說明會被稽核擋下。
make build course/ → dist/,含配額驗證與 SEO 產出
make audit 離線稽核設定檔、配額、影片長度與實證深度(不打網路,可放 CI)
make test 前端純邏輯的單元測試(node:test,零依賴、不需要瀏覽器)
make e2e paywall 端對端流程並截圖(Playwright,需要 Chrome)
make verify 重驗每個影片連結與每個 PMID(打真實 API)
make serve 本機預覽
make icons 重新下載 Lucide 圖示並打包成內嵌 sprite
make og 重新產生社群預覽圖
make lint ruff 檢查
make check lint + test + build + audit,提交前跑這個
make deploy 部署到 Cloudflare Pages
多課程並存:COURSE=courses/guitar DIST=dist-guitar make build
四個檢視:
- 首頁 — 用法三步驟、立場摘要、章節總覽
- 課程內容 — 章節樹、自我評估、分面標籤、項目清單、證據註記
- 上課模式 — 左側嵌入播放(走
youtube-nocookie.com)、右側播放清單, 滿版高度、欄寬可拖曳、?tab=player&play=12深連結 - 立場 — 課程對自身限制的說明與原始文獻
外加:分面篩選、全文搜尋、localStorage 進度追蹤、深淺色主題、
YouTube IFrame API 快捷鍵(按 ? 看清單)。
每支影片一串討論:上課模式的動作列有「討論」按鈕,用
giscus 把留言存進 repo 的 GitHub Discussions,
data-term 綁 video id,所以同一支影片在不同單元共用同一串。
啟用方式:到 https://github.com/apps/giscus 安裝到你的 repo,
再把 repoId / categoryId 填進 course.config.json 的 discussions。
面板只在點開時才載入 giscus,不影響首屏。
選用的 0 元 paywall:course.config.json 加 paywall 區塊,就會多出「加入購物車 →
0 元結帳 → 解鎖」的流程:前幾章免費試看,其餘章節顯示鎖頭、點下去彈出結帳,
結完帳全部解鎖。金額真的是 0,被劃掉的原價是虛構的,介面上有一行字直接講明。
拿掉那個區塊就完全回到全站開放。設計與接真金流要補的東西見
docs/PAYWALL.md。
SEO:Course JSON-LD(含 syllabus 與 citation)、OG/Twitter 卡、sitemap、
robots、llms.txt。文案在建置時就注入 HTML,不等 JS 執行,首屏就有真實內容。
首屏零外部請求:Primer 設計語彙用 CSS 變數自行實作,Lucide 圖示打包成內嵌 sprite。 只有按下播放時才連 YouTube、點開討論時才連 giscus。
src/
build/
build.py 合併、配額驗證、中繼資料套用
seo.py JSON-LD / sitemap / robots / llms.txt / 模板注入
build_icons.py Lucide sprite 打包
audit.py 離線品質稽核(設定檔/配額/長度/實證)
course.schema.json 設定檔結構,編輯器自動完成 + 稽核擋拼字
verify_links.py YouTube oEmbed 驗證
verify_refs.py PubMed 引用驗證
web/
index.html 模板,{{token}} 於建置時替換
css/ js/ 前端
js/paywall-core.js 0 元 paywall 的純邏輯,被 node --test 直接載入
tests/
paywall-core.test.js 單元測試(零依賴)
e2e-paywall.cjs Playwright 端對端 + 截圖
docs/PAYWALL.md paywall 設計與接真金流的待辦
course/ ← 你的課程
dist/ ← 建置產物(gitignored)
框架不 import 任何主題詞彙。course/taxonomy/ 是可插拔的:
提供 extract() 就有分面篩選,提供 classify() 就能把引用掛在類別上,
兩個都不給也能跑。
course/ 現成的內容,改編自 geekan/HowToLiveLonger——
一份把養生建議全部換算成全因死亡率(ACM)來比較的文獻整理。設計文件見
docs/plans/2026-07-31-longevity-course-design.md。
| 章節 | 15(讀數字的方法 2 章 + 輸入 7 章 + 輸出 3 章 + 上下文 1 章 + 爭議與收尾 2 章) |
| 單元 | 54(40 個干預項目、5 個爭議題、4 個觀念、4 個族群與排序、1 個使用說明) |
| 影片 | 361 個欄位、348 支不重複、55 小時 14 分 |
| 項目類型 | 機轉 74 / 實作 78 / 劑量 59 / 反方 96 |
| 證據查核 | 54 則,全部對回 PubMed(97 個 PMID) |
| 分級 | 證據充分 9 / 中等 18 / 有限 16 / 互斥 11 |
| 驗證 | 稽核零錯誤、連結 348/348 有效、引用 106/106 存在且標題相符 |
反方影片比任何一類都多(96 支),這是刻意的。查證結果對來源指南不太好看,而這正是重點:
- 「增加約 20 年預期壽命」沒有實證支撐——它來自來源作者自擬、且自註「歡迎優化」的公式
- 超加工食物的「-62%」方向寫反了:原文是 HR 1.62,也就是「多吃增加 62%」
- 葡萄糖胺「效果與定期運動相當」出自 648 人的觀察性次族群,而它在自己的適應症 (膝骨關節炎)上連 GAIT 試驗的主要終點都沒達到
- 日照「-40%」的因果鏈被 RCT 切斷:VITAL、D-Health、ViDA 在死亡率終點全部陰性
- 減重「-54%」只在「原本肥胖、減到超重」這條軌跡成立;同一份研究裡另一條軌跡是 HR 1.12
這些全部寫在網站的「宣稱效果量 vs 文獻原值」欄位,contested 標籤直接顯示在單元標題列。
程式碼採 MIT,見 LICENSE。
影片著作權屬原 YouTube 頻道,本專案只存連結與公開中繼資料,不重製也不代管。 Lucide 圖示為 ISC。範例課程的內容為衛教與運動指引,不構成醫療建議。
{ "site": { "name": "…", "title": "…", "url": "https://…" }, "kinds": [ // 每個單元底下的項目分幾類 { "id": "demo", "label": "示範", "tone": "accent" }, { "id": "slow", "label": "慢速", "tone": "success" }, { "id": "practice", "label": "練習曲", "tone": "danger" } ], "chapters": [ { "code": "CH1", "title": "…", "icon": "guitar", "source": "ch1", "units": 4, "drills": 20 } // 配額:建置時強制檢查 ] }