iT邦幫忙

2026 iThome 鐵人賽

DAY 19
0
AI 自動化

用 AI Agent 打造你的產品使用手冊產線系列 第 19 篇

[Day 19] 自動組裝產線 4:驗收與人工保護區

  • 分享至 

  • xImage
  •  

昨天讓 AI agent 寫出了一章正文,也把「好的正文」長什麼樣子寫進了 agent/STYLE.md。

但寫進文件,不代表 agent 一定會照做。Day 18 請 agent 寫完跑 npm run validate,但這個指令其實只檢查 manifest,正文就算引用了不存在的標號、漏放一張截圖,也照樣通過。另外還有一類內容,像法規聲明、安全警語,根本就不該讓 AI 改。

今天要處理的就是這件事:圈出 AI 不能碰的內容,再讓 validate 把正文也檢查一遍。

人工保護區

業務規則、法規聲明、安全警語、售後條款有一個共同特徵:它們的正確性,不是「讀起來合不合理」就能判斷的。AI 可以寫出一段非常像樣的隱私告示,但它不知道公司的法務立場。這些內容錯了,不是文章寫得不夠漂亮的問題,而是法律、安全上的實質風險。

所以這類內容要明確圈起來,AI 可以讀,但不能改。

範例專案 auto-manual-gen 的「新增攝影機」這一章剛好很適合。DemoStreamApp 是 AI 影像監控台,攝影機一啟用推論就會開始分析人員影像,真實產品裡一定會有一段法務審過的告示。所以在昨天那份正文的用途簡介後面,加上一段用 HTML 註解圈起來的內容:

# 新增攝影機

這一章說明怎麼在 DemoStreamApp 建立一台攝影機,並填入它的 RTSP 位址。

<!-- protected:start -->
> 重要:攝影機建立並啟用推論後,會持續拍攝並分析畫面中的人員影像。新增前,請確認安裝位置已依當地法規與場域規定設置監視告示,並取得場域管理者同意。未經同意的影像蒐集,由設置者自負法律責任。
<!-- protected:end -->

## 操作步驟
...

HTML 註解不會出現在最後的文件裡,但機器可以靠它辨認邊界。

(這段告示是我為了範例寫的,真實產品請找法務,千萬不要找 AI XD)

規則寫進 STYLE.md

跟昨天一樣,規則不寫在 prompt 裡,而是寫進 agent/STYLE.md:

## 人工保護區

- 原封不動地保留,包含標記本身、換行與標點。不改寫、不搬位置、不刪除、不合併進其他段落。
- 保護區不算骨架裡的小節,也不佔「注意」的三點額度;位置由人決定,重寫時照原位置放回去。
- 覺得保護區的內容或位置有問題,回報給人,不要自己改。
- 不要自己新增保護區。需要警語卻沒有資料時,回報給人。

第二條是為了跟昨天的固定骨架對齊。骨架說「不要自己增加小節」,如果沒講清楚保護區算不算小節,agent 很可能為了遵守骨架,把保護區搬進「注意」或乾脆刪掉。

不寫合併器,而是驗證結果

保護區常見的做法是寫一個「合併器」:先把保護區抽出來、讓 AI 改寫剩下的部分、再塞回去。

但 Day 18 的 agent 是直接寫整份 docs/50-camera-add.md。要加合併器,就得改變 agent 的工作方式,產線也會變得更複雜。(要加其實可以加,只是我不想而已XD)

所以範例專案選擇了另一條路:不限制 agent 怎麼寫,而是在它寫完之後驗證結果。validate 會拿目前的保護區,跟 HEAD 的同一份檔案逐字比對,只要有一個字不同就失敗。這也呼應了範例專案 README 裡的判準:AI 的輸出要嘛凍結成可審查的產物,要嘛被決定性的機制驗證。

讓 validate 也檢查正文

保護區只是其中一項。範例專案新增了 runner/docs.ts,npm run validate 在 manifest 通過之後,接著驗證對應的 docs/{order}-{id}.md:

檢查 等級 判定依據
docs/ 檔名對得回 manifest 的 {order}-{id} 錯誤 命名約定
{{legend.<key>}} 是本章 annotate 定義過的 key 錯誤 manifest
每張截圖剛好出現一次,沒有引用不存在的截圖 錯誤 manifest
保護區標記成對、沒有巢狀 錯誤 標記語法
保護區內容跟上一版完全相同 錯誤 git show HEAD:<file>
「」裡的名稱找得到出處 提醒 i18n、manifest、章節標題、示範資料

前五項都有明確的對錯,完全不需要 AI 判斷。Day 18 定下的 {{legend.*}}、{{screenshot:*}} 引用,在這裡就派上用場了:正因為正文不直接寫按鈕文字、不寫圖片路徑,而是引用 manifest 裡的 key,機器才有辦法一一對照。

最後一項為什麼只是提醒

正文寫了一個 App 根本沒有的按鈕,是最危險的錯誤。手冊可以順利產出、排版完全正常,讀者要到實際操作、找不到按鈕時,才發現手冊是錯的。

這種錯誤沒辦法百分之百靠機器判斷,但可以做一個預警。STYLE.md 規定畫面上的名稱要加「」,而且要照 zh-Hant.json 寫。反過來說,正文裡「」包起來的名稱,應該都找得到出處。

一開始我只拿 i18n 文案、manifest 和示範資料當出處。第一次對現有正文跑 validate,它就把 docs/20-live-monitor.md 裡的「儲存版面設定」標了出來。人看了一下,發現那句是「詳見『儲存版面設定』一章」,指的是另一章的標題,不是畫面上的按鈕。於是把章節標題也加進出處清單,這則提醒就消失了。

如果當初把它設計成錯誤,這次就會卡住整條產線,而且錯的是規則,不是正文;這種常誤判的規則,最後通常會被加進白名單或乾脆關掉。規則能不能明確判定,決定了它應該是錯誤還是提醒。 不確定的新規則,寧可先當提醒,跑過幾輪沒有誤判再升級成錯誤。

故意改壞一份正文

為了看看這些檢查實際擋得住什麼,我準備了一份故意改壞的正文 (tools/samples/day19-camera-add-broken.md),放了四個問題:

  1. 保護區被「潤飾」過:刪掉了「依當地法規」與最後一句責任聲明。
  2. 確認鍵寫成 {{legend.save}},但這一章的 key 是 confirm。
  3. 漏放最後一張截圖 camera-add-03。
  4. 在「完成後」多寫一句「可以點擊『快速匯出』把設定存成檔案」。

跑出來是這樣:

$ npm run validate -- --chapter camera-add

manifest 驗證通過(1 章)。
需要人工確認(1 則):
  - docs/50-camera-add.md: 「快速匯出」在 App 文案、manifest、章節標題與示範資料裡都找不到,請人工確認畫面上真的有這個名稱
正文驗證失敗(3 個問題):
  - docs/50-camera-add.md: 引用了不存在的 {{legend.save}},本章可用的有:name / zone / source / enabled / confirm
  - docs/50-camera-add.md: 漏放截圖 {{screenshot:camera-add-03}},manifest 裡的每一張都要出現一次
  - docs/50-camera-add.md: 第 1 個保護區跟 HEAD 不一致(開頭:「> 重要:攝影機建立並啟用推論後,會持續拍攝並分析畫面中的人…」)。保護區只能由人修改,請用 git diff HEAD -- docs/50-camera-add.md 確認差異,把原文還原回去

最值得一提的是保護區那一條。被改過的版本讀起來完全通順,甚至比原文更簡潔,人工 review 時很可能直接滑過去,但少掉的那一句正好是責任聲明。這種「改得很合理」的錯誤,最適合交給機器逐字比對,而不是靠人的眼睛。

錯誤訊息的寫法則沿用 Day 15 的原則:不只說哪裡錯,也說可用的有哪些、下一步該跑什麼。這些訊息主要是寫給 agent 看的,讀到之後它可以自己修正。

指令

範例專案 clone 下來、切到 chore/day19 分支,就能重現上面那次驗證:

npm run validate -- --chapter camera-add   # 審過的版本:通過

# 換成故意改壞的版本
cp tools/samples/day19-camera-add-broken.md docs/50-camera-add.md
npm run validate -- --chapter camera-add   # 三個錯誤 + 一則需要人工確認

git checkout -- docs/50-camera-add.md      # 復原

如果是在 Windows PowerShell 執行,-- 要加上引號,寫成 npm run validate '--' --chapter camera-add。沒加引號的 -- 會被 PowerShell 吃掉,--chapter 就變成傳給 npm 的參數,結果會驗證全部章節,跟上面的輸出對不起來。

也可以自己動手改改看,例如把保護區的 protected:end 刪掉,validate 會直接告訴你第幾行的 protected:start 沒有對應的結尾。

經驗分享

保護區的基準,是人 commit 的那一版

保護區是跟 HEAD 比的,所以人審過並 commit 之後,那一版就成為下一次驗證的基準。反過來說,如果 agent 改了保護區、人沒注意到就 commit 了,錯誤的版本也會跟著變成基準。

所以在 CI 裡驗證整個 PR 時,建議用 --base main 跟主分支比,而不是跟 PR 裡的上一個 commit 比。這樣就算 PR 中途有 commit 動過保護區,最後還是會被擋下來。

小結

今天用 HTML 註解圈出人工保護區,並讓 validate 在 manifest 之後接著檢查正文:有明確對錯的擋下來,判斷不了的只提醒。

讓 AI Agent 自動組裝產線的部分差不多到這裡結束。前面幾天建立了從畫面探勘、宣告式 manifest、agent 產出到驗收的流程。明天開始進入下一階段,把這些 Markdown 內容真正交付成客戶收得下的 Word 與 PDF 文件。


上一篇
[Day 18] 自動組裝產線 3:讓 AI Agent 寫正文
下一篇
[Day 20] 交付 1:用 pandoc 產出 Word 與 PDF
系列文
用 AI Agent 打造你的產品使用手冊產線 共 23 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言