This page is only available in Chinese

進行中

Running Dashboard

我的個人跑步數據平台。把手錶的跑步紀錄集中整理在同一個地方,我自己翻得到每一天練了什麼,也方便給 AI Agent 看。

  • React
  • TypeScript
  • Vite
  • Recharts
  • Python
  • fitparse
  • GitHub Actions
  • Cloudflare R2
  • Cloudflare Pages
running-dashboard.ian-li.dev
2026 年 9 月的訓練月曆,每天一格,跑量越高顏色越亮,9 日的比賽是棋盤格

Running Dashboard 是我用來整理與保存跑步數據的小工具網站。我把手錶裡的訓練紀錄匯出來集中存放到雲端,也順便畫成網頁上的訓練月曆與配速圖表;做這件事真正的目的,是把數據從運動手錶的 App 裡解放出來,讓 AI Agent 以教練的身分看到我實際的訓練狀況。

目前我使用的是 Amazfit(華米)的運動手錶,主要用來記錄每一次跑步以及訓練過程中的配速與心率。雖然我認為手錶本身不錯,但配套的 Zepp App 在使用體驗上就不是很好。看最近幾天的訓練狀況很方便,但如果要回頭找幾個月前的某場比賽或某次課表,就得在清單裡一直往下滑載入,而且每次只會多載入兩三個月的紀錄。

不過翻找麻煩算是小問題,我之所以想把數據抽出來上雲儲存,是為了讓 Agent 能夠更方便地存取我的跑步數據。雖然我很早就讓 Agent 來協助我安排訓練,也讓 Agent 的記憶存下我的個人目標、時間表與訓練偏好,但每一次訓練的數據還是得靠我手動匯出再交給它,當下的感受則是直接口頭描述。

這一步數據匯出與提交算是整個流程阻力最大的地方:從規劃、訓練到回饋與調整,每一輪都得先過這一關。所以才會想自己整理一個簡單的數據平台,除了更容易把單次和歷史數據提供給 Agent,我自己也能用比手機 App 更方便的方式瀏覽訓練數據。

目前網站已經有一個很基本的雛形與工作流,我的習慣是大概一週手動整理一次,把當週訓練的 FIT 檔從手錶 App 匯出來、上傳到雲端,交給排程轉成網站用的資料長久保存。需要回頭翻舊紀錄、或是想看整個月的訓練全貌時,才到網站上找。

拿 10 月的訓練月曆,讓 Agent 當教練幫我看課表

持續把資料丟上去之後,首頁的訓練月曆就慢慢累積出完整的訓練軌跡。月曆上顯示當天的總跑量,跑得越多格子越亮;比賽日則另外用棋盤格標出來。點進有訓練的那一天,會直接打開當天的主課。

下面是 2026 年 10 月的月曆。這個月因為 10/15~10/20 出國停跑了約一週,回來之後緊接著就是長榮馬 10K 與華航馬 21K 的比賽。

2026 年 10 月訓練月曆

累積了這整個月的紀錄後,我嘗試將網站網址直接交給 Agent 分析我 10 月的跑量結構、強度訓練的狀況和有氧跑的比例,以及該改善的地方。

只要把完整數據攤開來,Agent 確實能給出更準確且包含更多上下文的訓練診斷,這點在意料之內。例如它從月曆上看出,我 10 月底急著想把出國那週少掉的跑量補回來,但停跑一陣子後又在短時間內灌進大量里程,有受傷風險;也點出以我半馬跑進 90 分鐘的目標來說,這個月間歇加上比賽的比例太高,反而少了關鍵的乳酸閾值訓練。

雖然這個實驗實際走了一次整個流程,但也暴露出網站目前最大的限制:對 Agent 還不夠友善。因為網頁打開之後,是由瀏覽器在前端另外載入數據、畫成月曆和圖表,所以 Agent 得能自己操作瀏覽器才看得到內容;如果是只拿網址去抓網頁原始碼的 Agent,就無法順利讀取數據。

上傳前,和 Agent 一起替訓練分類

網站上的每一次訓練都標了類型:輕鬆跑、長距離、節奏跑、間歇或比賽。雖然只是個標籤,可是想要嘗試自動分類時才會發現很難用一個簡單的規則決定今天到底只是一場輕鬆跑,還是一場高強度的間歇。

不同跑步數據類型的方格

直覺上,最簡單的做法是看整趟的平均配速,但間歇會被平均掉:快跑段和中間的休息段做個平均之後,配速可能就跟輕鬆跑差不多。我在還沒寫下規則、讓 Agent 直接讀檔案分類時就踩過這個坑。例如 9 月 2 日那趟其實是 6 趟 1 公里的間歇,因為整趟平均 5:20/km,就被標成了輕鬆跑。反過來,輕鬆跑的配速也不會一直很平穩,偶爾會有幾段跑得比較快,不能因此就被當成間歇。

後來分類的判斷方式被我先整理成一份 Agent Skill,每次上傳前先讓它處理:透過不同練習的數據特點讓 Agent 為我做評估與判斷,並等到我確認之後才上傳。這一步我認為也有優化空間,但目前的流程阻力已經小了很多。

點進一趟間歇,把快跑和恢復拆開

分好類之後,被標成間歇的訓練還要多做一步。點進月曆上的某一天,可以看到那一次的摘要、心率區間與配速圖表;但對間歇跑這類訓練來說,真正要看的是快跑段有沒有跑到目標配速、站休或緩跑休時心率是否來得及回落,來判斷間歇強度與休息時間的設置是否恰當。

手錶 App 裡只會給出整趟的平均數字,以 2026 年 9 月 16 日這趟間歇為例,整趟平均配速看起來是 5:10/km,從表面數字完全看不出每一段快跑其實都落在 4:00~4:30/km 之間。

2026 年 9 月 16 日間歇的摘要與心率區間:7.83 公里、40 分 24 秒、平均配速 5:10/km,快跑步頻 179、恢復 110;右側是五段儲備心率區間

解決方法是改用每一秒的步頻和配速自己寫切分邏輯,判斷每一秒是在跑還是在休息,把「快跑」和「恢復」分開計算。這趟就切出了 6 段約 1.2 公里的快跑,摘要裡的快跑步頻 179、步幅 1.31 公尺就是分開算出來的結果。配速圖則畫出每一秒的配速,和手錶 App 一樣,一眼就看得出這趟跑了幾組。

同一趟間歇的配速與心率:配速圖上方是快跑段,恢復時掉到下方形成低谷;心率在快跑時爬升、恢復時回落

不過老實說,目前這套切分邏輯可能還太粗糙。它成立的前提是恢復時要明顯慢下來(像這趟是走路休息);但實際的訓練課表變化其實很多,不只是這種純粹的間歇——例如接近賽季時改用慢跑恢復取代走路或站著休息、或者像法特萊克那樣不停下來且高頻快慢交替的跑法(例如 1 分鐘快、1 分鐘慢),甚至是上坡間歇跑那種「配速數字看起來不快,但實際輸出功率與體感已經接近極限」的訓練,單靠目前的配速與步頻規則就很容易誤判。這一部分也是這個專案在數據處理與呈現上,接下來要優化的地方。


網站目前放在 running-dashboard.ian-li.dev,平常除了把訓練傳上去保存、偶爾回頭翻舊課表之外,寫跑步紀錄文章時我也會把當天的數據頁面附在文末。

現階段它還比較像是一個把跑步數據存下來、做初步嘗試的實驗基地。接下來的目標很明確:一方面是把提供給 Agent 的資料介面打通,讓 Agent 能更輕易地存取統計指標與單日訓練的詳細數據,真正把「規劃 → 訓練 → 回饋與調整」的循環串起來;另一方面則是繼續調整數據處理的邏輯,讓不同類型的課表也能被準確切分與判讀。

這個小專案還在邊跑邊改的階段,之後把 Agent 的串接或新的數據分析做上去時,我也會持續回來更新這篇介紹。