iT邦幫忙

2026 iThome 鐵人賽

DAY 9
0
AI Engineering

《矽墟》:我把一部科幻小說當成軟體專案來管系列 第 9

Day 9|同一個檔案裡兩張狀態表,一張活到最後,一張在第 20 回就死了

  • 分享至 

  • xImage
  •  

模組二|敘事規格化(Day 5–9)

《矽墟》是我正在寫的一部科幻小說,拆成 200 回短篇連載,整部作品用管軟體專案的方式在管:敘事結構寫成規格檔,成品用腳本驗收。訂過的規則多半有效——句數守住了、追讀引擎跑起來了、完稿淘汰線壓出了每句 12 字的密度。

本篇講一個失敗的。我覺得它比那些成功的更有用,因為證據就在同一個檔案裡:兩張狀態表,一張完整活到第 20 章,一張在第 20 回就停更了。

同一個人寫的、同一份文件裡、同一段時間。差別只在設計。

問題:跨回的東西沒人記得

一回 20 句,處理一個立即問題。這個尺度很好寫。

問題是跨回的東西:

  • 上一回留的鉤子,這一回前 3 句要接住,是哪個鉤子?
  • 某個角色三十回前受的傷,現在好了沒?
  • 我在第 45 回讓兩個角色達成的默契,第 120 回還算不算數?

寫到第 150 回的時候,前面 149 回不在你腦子裡。你需要一個外部的狀態存放處。

這件事本身沒有爭議,大家都知道要記。難的是它怎麼樣才不會死。

活著的那張:二十章狀態台帳

Day 5 講過它,長這樣:

本章結束時隊伍狀態 本章新增/更新的問題 下一章不得忘記
01 調律者+焰刃;守前/報後成立 誰在追著回訊? 焰刃不是武器,是主動留下守人的人。
20 零式為缺席者答到,隊伍守住她 舊院未破、海霧與回收域未關 這是第一部結束,不是世界答案。

20 列,一列不缺,從第 01 章到第 20 章全部有內容。

死掉的那張:已落地連載狀態

同一個檔案,往下滾幾行,另一張表:

篇/回 已寫入的關係狀態 留給下一回的問題
01.01–01.05 調律者先替未知的過路人扶正警示牌,再為車底義體用掉最後半格電;他選擇接近,但不答陌生的呼喚。 主核為何知道他的名字?
01.06–01.10 焰刃醒後主動護人;兩人以「左砍、右報」建立第一個位置默契,並一起回山。 誰在夜市暗處學走他們的節拍?
02.01–02.05 焰刃替調律者守住第一個據點;調律者學會不替綠語說「放手」。 綠語醒後,會如何面對自己救不回來的東西?
02.06–02.10 綠語先問能不能碰,焰刃主動留下疤;三人把「記得」和「救回」分開。 殘塔為何比三人的心跳慢一拍?

四列。到 02.10 為止。

novel/短篇/ 裡實際有:

200 檔    61,405 字元    每回 20–21 句,全數完稿

這張表落後 180 回。

它下面還有一行字,寫著「實作位置:01.01_夜市失聲.md02.10_說好了.md」,那是它最後一次被更新時的狀態,然後就凍在那裡了。

我在寫這個系列之前,完全不知道它停在這裡。

為什麼一張活著、一張死了

我一開始的解釋是「回太多了,記不完」。但這個解釋不成立:那張表是 5 回一列,200 回只需要 40 列。章表有 20 列,40 列並沒有多到做不完。

真正的差別在別的地方。

差別一:一個是設計,一個是紀錄

我每次走過去都會踩到地上那塊踏板,牆上那塊我一次都沒碰過

章表是我排劇情的時候寫的。我要決定第 8 章誰加入、留什麼問題給第 9 章:寫這張表就是在做規劃工作本身。

回表是我寫完一回之後要回頭補的。那一回已經完成了,故事已經前進了,回去填表不會讓任何東西變好。

前者在工作路徑上,後者在工作路徑之外。

這就是全部的原因。任何需要「做完事之後額外回去補」的紀錄,都會死。不是因為人懶,是因為那個動作沒有任何當下回報:你填不填,下一回都照樣寫得出來。

差別二:一個有讀者,一個沒有

章表我會讀。執行表(NOVEL-STATE-SYSTEM.md,Day 2 講過的那份動筆前必讀的執行表)的固定流程第一步就寫著:

  1. 從台帳讀「本章結束狀態」與「下一章不得忘記」。

每次動筆前都會讀它,所以它壞了我馬上知道。

回表沒有出現在任何流程裡。它是「寫給以後的自己看的」,而以後的自己從來沒有被要求去看它。

沒有人讀的文件,不會有人發現它過期了。 它可以錯 180 回而毫無症狀——我今天是為了寫這篇文章去查,才發現的。

差別三:粒度選錯了

章表的粒度是「章」:一個章結束時,隊伍狀態確實有一個明確的變化,值得記一列。

回表的粒度是「5 回」,但 5 回這個切法是我硬分的,它不對應任何自然的狀態變化邊界。有時候一個關係變化橫跨 8 回,有時候 2 回就跳兩次。5 回一列,記的內容永遠是勉強湊出來的。

粒度如果不對應真實的變化邊界,填表就會變成一件感覺不對的事,而感覺不對的事最容易被跳過。

那應該怎麼做

我還沒改,但方向想清楚了,寫在這裡當作紀錄。

方向一:把它從手寫改成生成。

「留給下一回的問題」其實就是每一回的最後一句。而最後一句在檔案裡,可以直接抓出來:

# 每回最後一句 = 那一回留的鉤子
for f in novel/短篇/*.md; do
  echo "$(basename $f .md)  $(grep -v '^#' "$f" | grep -v '^>' | grep . | tail -1)"
done

跑一次就有 200 列,而且永遠不會過期,因為它是從內容算出來的,不是另外維護的。

能推導的東西不要手動維護:這條在寫程式上是常識,我在文件上卻犯了。

方向二:手寫的部分只留推導不出來的。

「已寫入的關係狀態」這欄推導不出來,它需要判斷。那就只留這一欄,而且粒度改成「每次關係真的變化時記一列」,不是每 5 回記一列。

表格的列數應該由事件決定,不是由固定間隔決定。

方向三:讓它進入流程,否則不要做。

如果一張表不會出現在「動筆前要讀什麼」的清單裡,那它遲早會死。與其留一張過期的表誤導未來的自己,不如不做。

過期的狀態表比沒有狀態表更危險,因為你會相信它。

代價

我踮著腳,拿還在走的錶去對那個早就停掉的鐘

代價一:我現在有一張錯的表在 repo 裡。

它看起來很正常——格式整齊、內容正確、只是停在 02.10。如果我沒有去數 novel/短篇/ 有幾個檔案,我會以為它是對的。

這種「正確但過期」的文件,殺傷力比明顯錯誤的文件大得多。

代價二:生成方案會失去人的判斷。

自動抓最後一句,抓到的是「文字上的最後一句」,不是「我當初想留的那個問題」。有些回的鉤子藏在倒數第三句,最後一句只是收尾。

自動化會讓表永不過期,但也會讓它變笨。 這是個真實的取捨,不是免費升級。

代價三:我到現在還沒修。

寫完這篇的今天,那張表還是四列。修它要重讀 180 回的內容,那是好幾天的工作。

我把它列進待辦,但我不確定會不會做——而這個不確定本身,就是「工作路徑之外的事會死」最好的例證。連寫了一整篇文章講它,都不保證我會去做。

帶走什麼

一、狀態紀錄要長在工作路徑上,不能掛在旁邊。

判斷句:做這件事的時候,我是不是本來就得產出這個東西?

  • 是 → 它會活(章表:排劇情就是在填它)
  • 否 → 它會死(回表:寫完還要回去補)

會活的東西的例子:PR 模板裡的必填欄位、CI 產出的報告、commit message、規劃階段的設計文件。

會死的東西的例子:寫完程式再補的架構圖、上線後才寫的 runbook、「記得更新」的 changelog。

不是紀律問題,是位置問題。 換一批更自律的人來,結果一樣。

二、沒有讀者的文件會靜默過期,而且無法察覺。

每一份文件都應該能回答:誰、在什麼時候、會被要求讀它?

答不出來的,就是準備要過期的。而它過期時不會有任何症狀,這是最危險的部分。

我的回表錯了 180 回,repo 完全正常、文章照樣產出、沒有任何東西壞掉。它只是安靜地在那裡等著誤導未來的我。

三、能推導的不要手動維護,這條在文件上跟在程式上一樣。

我們都知道不該把 derived state 存起來手動同步。但換到文件、表格、清單上,就會忘記這條。

先問:這一欄能不能從既有內容算出來? 能的話寫個五行腳本,比維護紀律可靠一百倍。

推導不出來的那些欄位,才是真正需要人的地方,而那時候你要維護的東西已經少很多了。


模組二到此結束。五天講的是同一件事:把主觀品質變成可判定的規格,定義單位(Day 5)、寫成位置(Day 6)、串成引擎(Day 7)、用刪除測試驗收(Day 8),以及知道哪些規格其實不會被執行(Day 9)。

明天進模組三,題目換到 AI 生圖產線。第一篇先講整體架構:為什麼我用三個不同的模型做三件事,而不是找一個最強的打天下。


上一篇
Day 8|完稿淘汰線:不問「這樣好不好」,問「刪掉會不會壞」
下一篇
Day 10|三個模型做三件事,而不是找一個最強的打天下
系列文
《矽墟》:我把一部科幻小說當成軟體專案來管11
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言