跳至主要內容
技術

用 Markdown 存狀態、漂亮的 HTML 給人看

用 Markdown 存狀態、漂亮的 HTML 給人看
Claude Code 自動化 第 1 / 1 篇 ,前往系列總覽

本篇是「Claude Code 自動化」系列的第 1 / 1 篇。你可以從系列總覽開始閱讀,也可以直接接著看本文。

先講結果:HTML 接手了要我做決定的頁面,Markdown 沒有變少

這篇是我自己的經驗分享。我的 Claude Code 工作流分成兩層:Markdown 存狀態,HTML 給人看。Anthropic 的 Thariq Shihipar 前陣子寫了一篇,講的習慣剛好跟我一樣。

這篇講實際用起來的樣子,先看數字,拿主 repo 最近七週跟前七週比:

項目6/15–8/28/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/8Thariq(X)HTML is the new markdown.
5/10電腦王阿達Claude Code 核心工程師呼籲:別再寫 Markdown 了,用 HTML 吧
5/11UXHack(Substack)Markdown is Dead? Why Claude is Pivoting back to HTML
5/1236氪Markdown 已死,HTML 当立?
5/20Anthropic 官方部落格刊出完整版,文末註明是個人意見

差別在這幾個地方:

  • 「呼籲」是要別人照做,原文只講他自己怎麼做。
  • 「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()))
artifactHTML文字倍數
確認清單32,701 B17,123 B1.9×
派工板(8 月版)168,173 B95,168 B1.8×
研發規劃50,491 B21,106 B2.4×
程式盲審報告154,172 B38,409 B4.0×
派工板(9 月版)55,952 B18,011 B3.1×
專案規劃28,862 B8,059 B3.6×
合計490,351 B197,876 B2.5×

另外兩頁靠 JavaScript 渲染,內容在 script 裡,這個量法不準,所以沒列。

我把「文字」當成同一份內容寫成 Markdown 的大小,因為 Markdown 的符號很少。換句話說,同樣的內容,HTML 大約是 Markdown 的 2 到 4 倍。

人讀一次的報告,多這些 token 沒什麼感覺,Thariq 說得沒錯。

但我在主 repo 每開一個 session,Claude 會先自動讀進三個 Markdown:

檔案大小內容
~/.claude/CLAUDE.md3,668 B全域規則
主 repo 的 CLAUDE.md2,497 B這個 repo 的規則
MEMORY.md21,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
人 → agentCLAUDE.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。

留言討論

esc
輸入關鍵字搜尋文章...
查看收藏 →