用 Markdown 存狀態、漂亮的 HTML 給人看
本篇是「Claude Code 自動化」系列的第 1 / 1 篇。你可以從系列總覽開始閱讀,也可以直接接著看本文。
先講結果:HTML 接手了要我做決定的頁面,Markdown 沒有變少
這篇是我自己的經驗分享。我的 Claude Code 工作流分成兩層:Markdown 存狀態,HTML 給人看。Anthropic 的 Thariq Shihipar 前陣子寫了一篇,講的習慣剛好跟我一樣。
這篇講實際用起來的樣子,先看數字,拿主 repo 最近七週跟前七週比:
| 項目 | 6/15–8/2 | 8/3–9/21 |
|---|---|---|
| 發佈的 HTML artifact | 沒有統計 | 至少 50 個 |
主 repo 新增或修改的 .md 檔(不含搬移) | 361 個 | 342 個 |
寫進 .md 的行數 | +64,050 | +86,155 |
主 repo 是我放 CLAUDE.md、待辦和專案筆記的那個。artifact 的數字是下限,因為清單一次只列得出 50 個。
HTML 接手的東西很明確:AI 整理好、要我讀完做決定的頁面。早上的決策清單、每天的待辦儀表板、給同事的確認清單,現在都是 HTML,也確實比 Markdown 好讀。
Markdown 並沒有因此變少。
改過的檔案數差不多,寫進去的行數還多了三成多。
所以我認同 Thariq 的做法,但不認同「Markdown 可以淘汰」這個說法。
而且這句話不是 Thariq 說的。他講的是自己幾乎不寫 Markdown,轉述之後才變成大家都別寫。
HTML 跟 Markdown 該怎麼分,看的是這份檔案寫給誰看。
Thariq 說的是他自己幾乎不寫 Markdown,轉述後變成大家都別寫
先把原文講準。
Thariq 是 Anthropic Claude Code 團隊的成員,官方部落格上的職稱是 member of technical staff。2026 年 5 月 8 日,他在 X 上發了這段:
HTML is the new markdown.
I’ve stopped writing markdown files for almost everything and switched to using Claude Code to generate HTML for me.
那篇長文的完整版,5 月 20 日刊上 Anthropic 官方部落格。第一句就交代了範圍:
Markdown has become the dominant file format used by agents to communicate with humans.
他談的是 agent 寫給人看的東西。
文末的 FAQ 被問到現在什麼時候還用 Markdown,他這樣回答:
I have honestly stopped using Markdown altogether for almost everything, but I’m probably far on the HTML maximalist side of things.
「幾乎不用 Markdown 了」是他自己說的,這點轉述的人沒有編。
但這句話有三個限定:主詞是「我」,程度是 almost,而且他自己說他站在 HTML 最極端的那一邊。官方版文末還加了一行,說這篇 “expresses his personal opinions”。
轉述的標題把這些限定都拿掉了:
| 日期 | 來源 | 標題 |
|---|---|---|
| 5/8 | Thariq(X) | HTML is the new markdown. |
| 5/10 | 電腦王阿達 | Claude Code 核心工程師呼籲:別再寫 Markdown 了,用 HTML 吧 |
| 5/11 | UXHack(Substack) | Markdown is Dead? Why Claude is Pivoting back to HTML |
| 5/12 | 36氪 | Markdown 已死,HTML 当立? |
| 5/20 | Anthropic 官方部落格 | 刊出完整版,文末註明是個人意見 |
差別在這幾個地方:
- 「呼籲」是要別人照做,原文只講他自己怎麼做。
- 「Claude is Pivoting」把一個人的習慣寫成產品轉向。
- 「已死」把原本正面講 HTML 的標題,改成負面講 Markdown。
這三篇都比官方完整版早了一週以上。
所以要講清楚:說 Markdown 要被淘汰的,不是 Thariq。
他講的是自己的習慣,還自己補了一句「我大概站在最極端的那邊」。把話講死的是一堆內容農場式的轉述文,標題一篇比一篇聳動:「已死」「呼籲」「轉向」。讀者還沒點進去,結論已經被標題決定了。
這就是標題殺人。被殺掉的,是原文裡那幾個限定詞。
讀得比較準的是 Simon Willison。他 5 月 8 日當天的短評說這篇讓他重新考慮,範圍講得很清楚:“especially for output”。
早上的決策:每件事一張卡,底下留一個輸入框
我現在的節奏是睡前在 Claude Code 開幾個長任務,用 agent team 或背景 agent 讓它們跑一整夜。早上起床,剩下的是審核跟做決定。
以待辦件數算,我體感大概八成是 agent 做完的。這個數字沒有統計過,是估計。
剩下兩成的麻煩在於:每件事的脈絡散在不同地方,Markdown 報告只能從上讀到下,回覆時還要自己對編號。
現在我會在 session 裡直接要一頁臨時的 HTML artifact。要它做出這種頁面,講清楚四件事就夠:
把今天需要我決定的事做成一頁 HTML artifact:
1. 每件事一張卡:發生了什麼、為什麼需要我、做決定需要的最小脈絡
2. 脈絡太長的用 <details> 摺起來,不要只給連結
3. 每張卡底下一個輸入框,讓我寫指令
4. 頁尾一顆「複製全部」,把填過的卡依 ID 串成一段 prompt
我是全部填完再一次送出,所以頁尾那顆「複製全部」最重要,寫法是這樣:
<button id="copy-all" type="button">複製全部</button>
<script>
document.querySelector('#copy-all').addEventListener('click', async () => {
const prompt = [...document.querySelectorAll('.decision')]
.map((card) => ({
id: card.dataset.id,
title: card.querySelector('h2').textContent.trim(),
note: card.querySelector('textarea').value.trim(),
}))
.filter((item) => item.note) // 沒填的卡不送出
.map((item) => `【${item.id}】${item.title}\n→ ${item.note}`)
.join('\n\n');
await navigator.clipboard.writeText(prompt);
});
</script>
貼回 session 的內容長這樣,每段都帶著卡片 ID:
【pr-142】首頁改用新的快取策略
→ 先不要合,把快取命中率的數字補上再說
【draft-17】部落格草稿要不要發
→ 發,標題改成講發現的句子
用 Markdown 的時候,我得自己寫「第 3 點先不要、第 5 點照辦」,對錯編號是常有的事。現在答案就寫在那張卡底下,對應關係由頁面帶著,我不用記。
這部分我沒有碼錶數據,只能講體感:省最多的是回覆那一步,閱讀反而是其次。
翻自己的 artifact 時,我還看到另一種做法。有一頁送出前的修改清單,把每一項的「已處理/不適用」存進 artifact 自帶的小資料庫(2026 年 9 月實測),Claude 那邊讀得到,連複製貼上都省了。
每日儀表板:還沒寫成 SKILL,每天用同一段話請 Claude 產生
另一頁每天會看的,是「今天要做什麼」。
它還不是正式的 SKILL.md。我每天早上用差不多的一段話請 Claude 產生,得到一頁只給當天用的 HTML:列出今天要處理的事,每件附一段寫好的提示詞,旁邊一顆「複製提示詞」。
點一下,切到 terminal 貼上,那個 session 就開工了。每件事要怎麼跟 Claude 開口,我不用再想一次。
如果要固化成 SKILL,最小版本大概長這樣:
---
name: daily-dashboard
description: 產出今天的 HTML 待辦儀表板,每件事附最小脈絡和「複製提示詞」按鈕。觸發:今日儀表板、今天要做什麼、daily dashboard
---
# 今日儀表板
1. 只讀不改:`TODO.md`、各專案的狀態檔、昨晚長任務的輸出。
2. 挑出今天要我處理的事,每件一張卡:
- 標題,加一句「為什麼是今天」
- 做決定需要的最小脈絡,放不下的用 `<details>` 摺起來
- 一段能直接貼回 Claude Code 開工的提示詞,旁邊放「複製提示詞」按鈕
3. 輸出單一 self-contained HTML 到 `~/today/YYYY-MM-DD.html`,存完用 `open` 打開。
頁首寫產生時間,以及每個來源檔的最後修改時間。
4. 不要把我的決定寫進 HTML。我貼回 session 的回覆,由你更新對應的 Markdown。
3 分鐘上手:
# 1. 建資料夾,把上面那段存成 SKILL.md
mkdir -p ~/.claude/skills/daily-dashboard
$EDITOR ~/.claude/skills/daily-dashboard/SKILL.md
# 2. 開新的 Claude Code session,輸入 /daily-dashboard
claude
最小可用流程:輸入 /daily-dashboard → 瀏覽器打開當天的 HTML → 按「複製提示詞」貼回 session 開工。卡片的脈絡不夠,就回 SKILL.md 第 1 步補來源檔。
第 4 步是我覺得最不能省的。HTML 每天重做,狀態留在 Markdown,隔天產生的頁面才會對。
token 成本:讀一次的頁面划算,每個 session 都要讀的檔案不划算
Thariq 在 FAQ 裡回應過成本:
While Markdown often uses fewer tokens, I’ve found that the added expressiveness of HTML and the much higher likelihood of me reading it means I get overall better output. With the 1MM context window in Opus 4.7, the increased token usage is not really noticeable in the context window.
這段我同意,前提是那份檔案只會被讀一次。
我量了自己 6 個靜態 artifact,也就是內容直接寫在 HTML 裡、不靠 JavaScript 渲染的那種。量法是比較整份 HTML,和拿掉標籤、CSS 之後剩下的文字:
# html_ratio.py:python3 html_ratio.py page.html
import re, sys
html = open(sys.argv[1], encoding="utf-8").read()
body = re.sub(r"<(script|style)[^>]*>.*?</\1>", "", html, flags=re.S | re.I)
text = re.sub(r"\s+", " ", re.sub(r"<[^>]+>", "", body))
print(len(html.encode()), len(text.encode()))
| artifact | HTML | 文字 | 倍數 |
|---|---|---|---|
| 確認清單 | 32,701 B | 17,123 B | 1.9× |
| 派工板(8 月版) | 168,173 B | 95,168 B | 1.8× |
| 研發規劃 | 50,491 B | 21,106 B | 2.4× |
| 程式盲審報告 | 154,172 B | 38,409 B | 4.0× |
| 派工板(9 月版) | 55,952 B | 18,011 B | 3.1× |
| 專案規劃 | 28,862 B | 8,059 B | 3.6× |
| 合計 | 490,351 B | 197,876 B | 2.5× |
另外兩頁靠 JavaScript 渲染,內容在 script 裡,這個量法不準,所以沒列。
我把「文字」當成同一份內容寫成 Markdown 的大小,因為 Markdown 的符號很少。換句話說,同樣的內容,HTML 大約是 Markdown 的 2 到 4 倍。
人讀一次的報告,多這些 token 沒什麼感覺,Thariq 說得沒錯。
但我在主 repo 每開一個 session,Claude 會先自動讀進三個 Markdown:
| 檔案 | 大小 | 內容 |
|---|---|---|
~/.claude/CLAUDE.md | 3,668 B | 全域規則 |
主 repo 的 CLAUDE.md | 2,497 B | 這個 repo 的規則 |
MEMORY.md | 21,055 B | 記憶索引,一條記憶一行 |
這 27 KB 每個 session 都要讀一次。照上面 2.5 倍推算,換成 HTML 大約是 68 KB。這是推算,不是實測。
這些檔也不是只讀的。8 月以來,70 個記憶檔有 46 個被改過。會一直被改的東西留在 Markdown,理由很實際:git diff 看得出 agent 昨晚改了哪一行,grep 一秒找到提到某條規則的地方,要改一小段也只要換掉那幾行。HTML 的巢狀標籤做這三件事都比較容易出錯。
所以 token 的帳要看讀幾次:只讀一次的頁面用 HTML 划算,每個 session 都要讀、還要一直改的檔案留在 Markdown。
反思
技術面
選格式時,我現在先看這份檔案是誰寫給誰:
| 方向 | 例子 | 我用的格式 |
|---|---|---|
| agent → 人 | 決策清單、每日儀表板、研究報告 | HTML |
| 人 → agent | CLAUDE.md、SKILL.md、提示詞 | Markdown |
| agent → agent(跨 session) | MEMORY.md、TODO.md、狀態檔 | Markdown |
Thariq 那篇的第一句講的就是第一列。轉述的標題把它套到了三列。
心態面
寫這篇查資料時,我順手看了本機的排程,才發現三個都壞了。
主 repo 的 nightwatch 每天 11:57 由 cron 叫起來。這是 9 月 17 日那次的 log(中間的 worktree 和通知訊息省略):
[Thu Sep 17 11:57:01 CST 2026] 起動物件:Cron Trigger -> nightwatch.sh
=== Iteration 1 of 5 ===
Not logged in · Please run /login
Claude 執行失敗 (可能遇到 5hr rate limit)。暫停 1 小時 (3600 秒) 後重試...
Not logged in · Please run /login
Claude 執行失敗 (可能遇到 5hr rate limit)。暫停 2 小時 (7200 秒) 後重試...
Not logged in · Please run /login
Claude 執行失敗 (可能遇到 5hr rate limit)。暫停 3 小時 (10800 秒) 後重試...
Not logged in · Please run /login
Claude 執行失敗 (可能遇到 5hr rate limit)。暫停 4 小時 (14400 秒) 後重試...
Not logged in · Please run /login
Claude 重試 5 次後仍失敗。
本輪沒有新 commit,回收 worktree 與分支。
[Thu Sep 17 22:46:41 CST 2026] 執行結束
8 月 4 日到 9 月 21 日的 38 次排程,沒有一次真的跑到任務。32 次卡在 Not logged in,5 次因為前一輪還在重試、拿不到鎖就結束,1 次連不上 GitHub。腳本把任何失敗都當成 rate limit 處理,每次白等 10 小時。
另外兩個 LaunchAgent 指向已經不存在的腳本。23:20 那個研究排程找不到 claude 執行檔,每天晚上產出一個 0 byte 的結果檔,log 照樣寫「結果已儲存」。
我一直沒發現,是因為我早就改成睡前手動開長任務,這幾個排程的結果沒人在看。它們的狀態都寫在 log 裡,而 log 我不會打開。
這剛好是這篇在講的事:要我注意的東西,得出現在我每天會看的那一頁。如果早上的儀表板有一列「排程狀態」,8 月 5 日我就會看到第一個失敗。
有趣發現
被轉述得最誇張的那句話,其實是 Thariq 自己說的:“I have honestly stopped using Markdown altogether for almost everything.”
轉述的人沒有編造句子,只是拿掉 almost、拿掉他說自己是極端派的那半句,再拿掉官方的個人意見註記,意思就差很多了。
這篇文章我用 Markdown 寫,你在瀏覽器讀到的,是部落格把它轉出來的 HTML。我的分法不會變:要留下來、會一直改的寫成 Markdown,要我讀完做決定的,請 Claude 做成 HTML。