Ian Chou's Blog

張力句訓練器(Tension Trainer):讓未來的你找得到今天寫的東西

張力句訓練器:讓未來的你找得到今天寫的東西

「我買了一臺新車,我很喜歡。」

這句話沒有錯。但十年以後,如果我想找回「那陣子我在煩什麼」,這句話幫不上忙。它記下了買車這件事,沒記下為什麼換車、之前哪裡壞了、換了之後那個問題解了沒。

同一件事,另一種寫法:

舊車三天兩頭拋錨,害我上班遲到兩次;換了新車之後,這個月天天準時。

後面這句,十年後不管用什麼找——關鍵字、向量、AI——都能讀出整件事的形狀:想要什麼、被什麼擋住、做了什麼、擋住的那個東西退了沒。

這兩句的差別不是文筆。這是我這半年整理自己十五年筆記時撞到的問題,也是這篇文章要講的應用的由來。

同一件事,十五年裡發明了七次

我有一個三千篇的個人知識庫,從 2011 年記到現在。前陣子整理的時候發現:2011 年研究「未來教室」、2013 年想建「wiki 知識引擎」、2014 年裝 Evernote、2017 年找專案記錄工具、2021 年做時間管理、2023 年寫筆記卡片機器人、今年做語意地圖——七次在做同一件事,每次都不記得以前做過。

一開始我以為是記性問題。做了三個測試之後,才發現是文字本身的問題:

  1. 把這八篇筆記丟給向量檢索,它們彼此的相似度只比隨機基線高一點,浮不上來。
  2. 把八篇做詞性分析,共同的名詞只剩「資料」,共同動詞是零。每一篇寫的都是當次用的工具和對象;那個「想把散掉的東西留住」的問題本身,一次都沒被寫下來。
  3. 向量最會抓的是文體。叫它找跨年代的相似筆記,前四十名全是「週報配週報」——格式像,問題不像。

第三點有一個更直接的驗證。「我買了一臺新車,我很喜歡」和「我買了一臺新相機,我很喜歡」的向量相似度是 0.924,幾乎是同一句話。向量看見了句式(入手、喜歡),看不見「在解什麼問題」。它只能編碼你放進去的東西——你沒寫下來的,它永遠找不到。

缺的那一格,叫對手

把句子拆開,有用的結構其實只有四格:

「我買了一臺新車,我很喜歡」 「舊車拋錨…天天準時」
誰在做 我 ✓ 我 ✓
動作+對象 買了新車 ✓ 換了新車 ✓
被什麼擋 拋錨、遲到兩次 ✓
戰報 ✗(「很喜歡」是武器評語) 天天準時 ✓

缺的兩格都有名字。「被什麼擋」就是對手——在那個新工具出現之前,具體擋住你的東西。而「很方便」「很喜歡」「很順」是對武器的評語,不是戰報;戰報要能回答「對手退了沒」。

對手也不是隨便一個困難都算數,我給它設了三個測試:

  1. 之前壞了什麼——要有具體事件。「遲到兩次」算,「記性不好」不算。
  2. 可數、可輸——要量得出它退了沒。「這週漏了幾件事」可以量;「時間不夠」這種對手永遠贏不了,也就永遠收不到戰報。
  3. 換武器不變——把工具拿掉,這堵牆還在,才是問題的對手。「要用還得先打開電腦」只是上一個武器的摩擦,不算。

把這個做成練習工具

所以我想做一個訓練應用:任何人都可以用,不綁任何筆記軟體。核心循環一頁做完:

貼一句你自己寫的句子
   ↓
前置分類:這是哪一種書寫?
   ↓
四槽拆解 + 分岔探針(按類型走不同的橋,全部可跳過)
   ↓
你改寫
   ↓
前後對比:補上了哪幾格(核心成就感)
   ↓
(選看,預設收合)結構鏡像:跨領域孿生句 + 一題對位

裁判的部分已經實測過:文章開頭那句「武器日誌版」拿 2/4,回饋會直接指出「很喜歡是武器評語,不算戰報」;改寫後拿 4/4。每次檢查是一次 LLM 呼叫加一次 embedding,成本接近零。

設計定稿前被審閱打回來兩次,兩次都改了重要的地方,值得講一下。

第一次:不是每個人貼上來的都是「武器日誌」。 原設計偷偷假設了輸入的樣子,但真實使用者更常貼情緒句(「今天開會好累」)或抽象結論(「溝通不良是認知落差」),四槽在第一步就拆不動。現在裁判會先判斷這是哪一種書寫,探針按類型走不同的橋:情緒句問「這個感覺擋住了你想做什麼?」,抽象結論問「這個結論是從哪件事來的?」。如果是純抒發,就溫柔放行:「這句不需要對手,它是抒發。」——有些句子本來就不缺格,缺席是合法的。

第二次:獎勵放錯了位置。 原本的主獎勵是「跨領域孿生句」:改寫完成後,LLM 現場生成一句完全不同領域、同一個問題形狀的句子。實測時它給買車句配的孿生是:

舊灌溉馬達三天兩頭罷工,害我兩批秧苗缺水枯黃;換了新馬達之後,這個月天天準時供水。

買車句和一句農業灌溉句被認成同一件事,第一次看到確實很驚喜。但第二輪審閱(認知心理學角度)指出兩個問題:被動展示一句配好的類比,不會觸發基模抽取(Gentner 的類比學習研究:要抽出結構,人得自己動手對齊);而且孿生句展示的是「你的句子和另一句很像」,不是「你的改寫好不好」——它不是對改寫品質的回饋。

所以主獎勵換成補槽的前後對比:你親手把缺的格補上,成就感來自自己的增量。孿生句留著,但降級成「結構鏡像」——預設收合,點開才看,展開後附一題可跳過的對位(「灌溉馬達的『枯黃』,對應你句子裡的哪個字?」點選即答),把被動展示變成一次最小的主動對齊。生成自檢也保留,改成點開時才跑:孿生句自己先過一次四槽裁判,對不上就重生成,擋下只換名詞的假孿生。順便省了每次循環的生成成本。

幾件我最擔心做壞的事

設計過程中找過四個 AI 各自獨立審一輪,加上兩輪外部審閱,有幾條是反覆被指出的:

分數不能當目標。 你一顯示 2/4,使用者就會去湊 4/4——而 LLM 裁判會被「補上它要的詞」滿足,不需要背後真的有想法。這樣做出來的是教人填模板的工具。所以主輸出是探針問句,分數要點兩下才看得到;只獎勵改寫的增量;永遠不給範例句。

LLM 裁判會漂移、會討好。 同一句話兩次評分可能不一樣,而且傾向給鼓勵性的高分。使用者發現「寫什麼都 3 分」的那天,信任就歸零了。防法有四條:評分標準裡釘死 0 到 4 分各一則錨定範例;溫度設 0;回饋必須引用原文的字詞才准出分(引不出來,代表沒讀懂);每次改提示詞都用固定測試集跑回歸。

教練不代寫。 它只指出缺哪一格、引用你的字詞給回饋,不替你寫。東西要自己寫出來才是自己的。

探針是邀請,不是審訊。 對「最近常失眠」追問「哪一次出事」,是在逼人量化自己的痛苦,那是最快的流失點。所以探針一律兩段式,先承認再邀請(「聽起來這陣子很耗。想看看是什麼擋著嗎?」),全部可跳過;量化問句放軟,問「這週有幾晚?」而不是「出事是什麼時候?」。

架構:一個人養得起

決定 內容 理由
形態 網頁應用 受眾是任何人;CLI 只剩工程師,編輯器插件要養好幾套
前後端 靜態前端 + Cloudflare Pages Functions 代理 金鑰只存伺服器端,不進前端
進度資料 瀏覽器本地,一鍵匯出 JSON 第一版不做帳號;使用者貼的是私人書寫,伺服器不存原文
成本 一循環 = 兩次 LLM + 一次 embedding 接近零

不做帳號這條多說一句:對單人工程師,帳號系統(註冊、密碼重設、客訴、個資責任)是純負債;而「你的句子不會留在我的伺服器上」對使用者反而是賣點。

還不知道的事

最後

筆記軟體這十年都在教「怎麼存」,比較少人教「怎麼寫才找得回來」。而我自己的實測結論很簡單:再好的檢索也找不到你沒寫下來的東西;寫作當下多寫一句「之前壞了什麼」,是整條鏈上最便宜的一步。

下一步的建議(是建議,不是時程表):把這個循環做成 v1,先限定「解決問題型」的書寫——決策、工具、解法復盤這類,四槽模型本來就是從這類書寫實測長出來的,先把窄域的裁判精度做好,再談通用。然後自己先練三十天,只看一個數字:**第二次寫的時候,障礙槽出現的比率有沒有上升。**驅動這個改變的是探針問句的精準度和前後對比,不是孿生句。