AI 協作寫技術文,每一步留一個檔案:這樣擋得住什麼、擋不住什麼
這個部落格的寫稿流程有五步,每步產出一個檔案,出錯可以單獨重跑。Fable 寫大綱,也寫每節要查的問題(outline.md)。另一個模型只回答這些題目,每筆附上來源、日期和信心程度(facts.json)。再由一個模型照大綱和事實包撰稿,每個事實標上編號(draft.md)。審稿另開一個 session,意見分成 must-fix 和 suggested(review.json),最後只修一輪 must-fix(final.md)。每一步只讀前面的檔案。
更正(2026-11-15 01:45):Ubuntu CVE 頁不再寫固定的最後更新日,API 查詢的說明改為只涵蓋 Red Hat 已發布的 RHSA 與 Ubuntu source package 的發布紀錄,另調整數處語句。修正建議:Codex(gpt-6-astra)、Grok(grok-4.7),Claude 驗證。
保留每一步的輸入和產出,方便回查錯誤,也能抓出寫稿和潤稿時遺失的數字、連結和行內 code,但擋不住事實包查錯地方。11 月 4 日那篇 CVE-2026-98432 的文章就是這樣,兩處修補狀態寫錯,事實包和審稿兩步都有責任。
五步五檔
事實包按大綱列出的題目查資料,沒問到的就不查。撰稿的模型只能寫事實包裡有的事,查不到的標 missing,不准用記憶補。審稿另開一個 session,不帶前面的對話。
最近 Hacker News 上的〈Ask HN: What’s your current AI agentic setup?〉也有人談到類似的分工。gregwebs 寫「It uses Claude for planning, codex for reviewing, and deepseek for doing and orchestrating.」(Claude 規劃、codex 審查,deepseek 負責執行和協調)。chasd00 先跟模型一起寫 design doc,請模型檢查設計後,再請它「make a step by step implementation plan document」(寫出逐步實作計畫文件)。guhcampos 說兩個 harness 之間的交接「involve a lot of markdown」(大量用 Markdown 交接)。這些模型分工和檔案交接的方式,跟我類似。
那次怎麼寫錯的
CVE-2026-98432 那篇〈Linux TCP 漏洞 CVE-2026-98432:AWS 與 Ubuntu 公告說了什麼?〉標示的發布時間是 11 月 4 日 01:40。當時的流程是 Grok 先做事實包,Fable 寫大綱,Codex 撰稿,Grok 去 AI 化,最後 Fable 二審。修補狀態表裡有兩格錯了。
Red Hat 那列寫「RHEL 8、9、10 與 OpenShift,尚未列 RHSA」。表格上方有一行限定:「表中『未列』指該公告沒寫」,這裡的公告是 Red Hat 的 Security Bulletin(RHSB-2026-016)。RHSB 頁面確實沒列 RHSA,但 RHEL 8、9、10 主線的 RHSA-2026:93414、93412、93413 在 11 月 1 日就發布了。照 Red Hat 的說明,Security Bulletin 會針對需要更多背景資訊的漏洞,整理診斷工具和更新;RHSA 則記錄已發布的安全修正。bulletin 沒列,不代表沒有修補。
Ubuntu 那列,26.10 寫「兩頁說法不一」,正式可用寫「未確認」。11 月 6 日查核時,CVE 頁對 linux 26.10 仍顯示「Vulnerable work in progress in 7.3.0-10.10」(仍受影響、修正處理中),官方 blog 寫已修正,兩頁差異的原因尚未確認。Ubuntu 的 CVE 頁後來也將同一列標成「Fixed in 7.3.0-10.10」(已修正)。Launchpad 的發布紀錄則顯示 7.3.0-10.10 在 10 月 28 日(UTC)就進了 updates pocket,11 月 2 日(UTC)進了 security pocket。
Red Hat 已發布的 RHSA,以及 Ubuntu source package 的發布紀錄,可以分別從以下 API 查到:
set -euo pipefail
curl -fsS --max-time 30 'https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2026-98432.json' \
| jq -r '.affected_release[]
| select(.advisory=="RHSA-2026:93414" or .advisory=="RHSA-2026:93412" or .advisory=="RHSA-2026:93413")
| [.advisory, .release_date[0:10], .product_name] | @tsv' | sort -u
curl -fsS --max-time 30 'https://api.launchpad.net/devel/ubuntu/+archive/primary?ws.op=getPublishedSources&source_name=linux&exact_match=true&version=7.3.0-10.10' \
| jq -r '.entries[] | [.pocket, .status, .date_published] | @tsv'
RHSA-2026:93412 2026-11-01 Red Hat Enterprise Linux 9
RHSA-2026:93413 2026-11-01 Red Hat Enterprise Linux 10
RHSA-2026:93413 2026-11-01 Shadow Migration Toolkit for Virtualization for RHEL 10
RHSA-2026:93414 2026-11-01 Red Hat Enterprise Linux 8
Security Published 2026-11-02T12:22:33.379609+00:00
Updates Published 2026-10-28T22:19:26.172834+00:00
Proposed Deleted 2026-10-26T02:05:24.870112+00:00
Red Hat Security Data API 的 affected_release,每筆是某個產品已發布、並修正這個漏洞的 erratum,同一份 erratum 可以對應不同產品。Launchpad 的 getPublishedSources 用 pocket 和 date_published 記錄 source package 版本進入各 pocket 的時間,這次回應的時間是 UTC。這是 source 的發布紀錄,各架構的 binary 是否都可安裝,要另查。
那次事實包的 Red Hat 部分只讀了 RHSB 和 CVE 頁,記下「產品狀態表未出現在擷取結果」。Ubuntu 讀了 CVE 頁、tracker 和 blog,也記下同一個套件在不同頁面顯示 Fixed、pending、Vulnerable work in progress 三種狀態,CVE 頁的表格讀到約 30 KB 就截斷了。事實包已記下矛盾,卻沒往 archive 查,審稿也沒攔下這兩格,所以我認為兩步都有責任。現存紀錄無法還原二審開了哪些來源。
擋得住的
獨立審稿曾抓到錯誤。〈捐款異動詐騙信:公益團體冒名與個資事件整理〉那篇就抓到一個 BLOCKER:網銀資料該找的是帳戶所在的銀行,草稿寫成發卡銀行。〈收到 TWCA 換證通知後怎麼自己換〉那篇,審稿列了 9 個 BLOCKER,其中一項是憑證和金鑰檔案都讀取失敗時,兩邊算出相同的空輸入雜湊,讀者可能誤以為比對成功。修訂稿補上了 OpenSSL 和 nginx 的實測和輸出。
潤稿時用過的腳本會比對改寫前後數字、連結、行內 code 和 hash 的出現次數,減少就標記失敗。frontmatter 則排除更新日期,再逐行比對。去 AI 化常會刪字、併句;若版本號或網址在比對模式內,出現次數變少就會被抓到。它只比對字串,意思有沒有變,仍要人讀。
去 AI 化的檢核清單,用的是 Pangram 整理的九項訊號:Markdown、AI 慣用語、em dash、條列、三連、「Not just X but Y」(強調後半句的對比句型)、罕見 Unicode、AI 式標題和開場、emoji。Pangram 說,單一訊號不能判定是不是 AI 寫的,清單只用於檢查,不打分數。
擋不住的
每步存檔、可以重跑,前提是你知道要重跑哪一步。CVE 那次保留了事實包、撰稿和去 AI 化的檔案,草稿照其中的事實寫,修補狀態仍錯,因為查到的來源層級不夠。即使檔案分工清楚,查核若停在同一層資料,錯誤仍會一路帶到發布。
HN 那串的 smashed 談到反覆叫 agent 做 code review 時,寫了「There is really a point of diminishing returns.」(確實會到再多審一輪,收益卻愈來愈少的時候)。多審一輪仍看同一批資料,能抓到的錯誤有限。
那次之後,事實包和審稿兩步加了一條規則:只要文章寫到修補狀態,就要查勘誤和 archive。Red Hat 用 Security Data API 和 errata 頁,Ubuntu 用 Launchpad 的 getPublishedSources,CVE 追蹤頁只當參考。審稿要自己重開同一個 API,不能只確認草稿跟事實包一致。
錯了之後怎麼改
修正已發布的文章時,在開頭段落後加一行更正,寫明改動、建議和驗證的模型,時間記到分鐘,不解釋寫錯的原因。CVE 那篇在 11 月 5 日 03:45 加上的更正是:
更正(2026-11-05 03:45):修補狀態表原寫 Red Hat 尚未列 RHSA、Ubuntu 正式可用未確認,但 RHEL 8、9、10 主線 RHSA 在 11-01 已發布,Ubuntu 26.10 的 7.3.0-10.10 也已進 updates 與 security,均早於本文查核時間;另補上 MPTCP 緩解的生效條件與 AWS 受管服務不必立即動作的前提。修正建議:Grok(grok-4.7),Codex(gpt-6-astra)與 Claude Fable 驗證。
同時發了續篇〈「210 萬台裸跑」怎麼算出來的〉,重整掃描數字和修補狀態。發布前的查核沒擋下來,就靠發布後的重查和更正補上。Wikipedia 的 Fact-checking 條目用 ante hoc 和 post hoc 區分發布前和發布後的查核。
補充筆記
- 五步各一個檔案:
outline.md、facts.json、draft.md、review.json、final.md,哪一步出錯就從那一步重跑。 - CVE-2026-98432 那篇錯在用 Security Bulletin 和 CVE 頁判斷修補狀態。正確資料在 Red Hat Security Data API 的
affected_release和 Launchpad 的getPublishedSources。 - 事實包和審稿兩步都要查勘誤和 archive,審稿要自己重開 API。
- 字串計數能抓到改寫遺失的數字、連結、行內 code(限比對模式涵蓋的範圍),抓不到意思改變。
- 更正放在開頭段落後,只寫改動、時間,以及建議和驗證的模型。
延伸閱讀
- Red Hat〈Red Hat Security Data API〉:
/cve/<CVE>.json和affected_release的定義。 - Red Hat〈Explaining Red Hat Errata〉和〈Security Bulletins〉:RHSA 和 Security Bulletin 各自是什麼。
- Launchpad〈API reference: getPublishedSources〉:
pocket、status、date_published等欄位。 - Ubuntu〈CVE-2026-98432〉:本文引用的 26.10 狀態文字。11-06 查核時,頁面更新日是 2026-11-05,該列後來改為 Fixed(已修正)。
- Hacker News〈Ask HN: What’s your current AI agentic setup?〉:各種多模型分工和交接方式。
- Pangram〈Signs of AI writing〉:九項 AI 寫作訊號。Pangram 提醒,單一訊號不足以判定是不是 AI 寫的。
- Wikipedia〈Fact-checking〉:ante hoc 和 post hoc 的查核怎麼分,百科整理。
- 〈AI code review 的帳怎麼算〉:站內另一篇,談 AI 審查找到的 bug、誤報和人的時間。
想法與技術判斷出自 Sheng,和 Claude 一起起草 · 大綱 Claude Fable,本機紀錄查證 Codex(gpt-6-astra),Grok 的事實包這輪沒有完成,來源重查與撰稿 Claude Opus 5.5,二審 Codex(gpt-6-astra,codex-cli 0.166.0),調語氣 Grok(grok-4.7,grok 1.0.70);第二輪:取捨 Claude Fable、精簡 Codex(gpt-6-astra,codex-cli 0.166.0)、二審 Claude Opus 5.5、調語氣 Grok(grok-4.7,grok 1.0.70);API 查詢以 curl 8.7.1、jq 1.7.1 在 2026-11-09 03:43(台北)實測。