# Coding Agent 記住上次怎麼改程式，就能省 Token 嗎？拆解 Singularity 的檢索邏輯

> Canonical: https://vxi.me/zh-tw/posts/singularity-agent-memory-cue-matching/
> Locale: zh-tw
> Published: 2026-10-12
> Updated: 2026-10-12
> Markdown: https://vxi.me/zh-tw/posts/singularity-agent-memory-cue-matching.md

同一個程式庫，昨天才請 Coding Agent 加過鍵盤快捷鍵，今天又要它改一個類似功能，它卻可能重新搜尋檔案、閱讀測試、再踩一次相同的坑。第一次探索當然要花成本；問題是，第二次為什麼還得付同樣的學費？

最近在 [Show HN 原始討論](https://news.ycombinator.com/item?id=50004683) 看到一個名為 [Singularity](https://github.com/pandacover/singularity) 的開源專案。它想把已完成的程式修改整理成可重複使用的工作流程，記住該到哪些位置、如何驗證、先前有哪些陷阱。當新的任務出現，就先比對可能用得上的步驟，再交給 Agent。

這個方向很吸引人。但我更在意的是：**記憶被找出來之後，我們憑什麼確定它仍適用於眼前的任務？**

我把研究固定在 Singularity 的 [commit `9d241f2`](https://github.com/pandacover/singularity/tree/9d241f23d351452f1c3c42800f0c1fdc5d57d66e)，讀了原始碼，也做了一組不使用模型的輕量合成測試。先說明範圍：這不是安裝 Singularity 後的端對端實測，更不是 Claude Code 或 Codex 的 Token 成本對照。它檢驗的是根據原始碼獨立改寫的比對規則，以及這些規則可能誤判的地方。

## 記住的不是聊天紀錄，而是做事的路徑

依照固定版本的 [README](https://github.com/pandacover/singularity/blob/9d241f23d351452f1c3c42800f0c1fdc5d57d66e/README.md)，Singularity 會在成功完成程式修改後累積經驗，再由模型將多次經驗歸納成工作流程。工作流程可能告訴 Agent：某種功能通常要改哪些檔案、應該執行哪些測試、之前在哪裡失敗過。

這與把完整對話存進長期記憶不同。原始聊天內容很長，其中不少嘗試只有在當下有用；工作流程則試著留下值得重複的操作順序。這篇文章討論的是工作流程步驟與線索的重用，並不是對這個專案是否採用其他快取機制的全面稽核。即使記憶曾指出精確的檔案位置，程式庫結構變了之後，還是得重新確認。

費用也有兩筆。**學習**工作流程可能需要呼叫模型；**使用**已產生的工作流程線索挑選步驟，則未必需要模型。專案中的 `workflows-cues` 路徑就是後者。

但這不表示 Singularity 所有路徑都沒有模型成本。固定版本的評估程式 [`StepSelector.ts`](https://github.com/pandacover/singularity/blob/9d241f23d351452f1c3c42800f0c1fdc5d57d66e/apps/cli/src/eval/StepSelector.ts) 會呼叫模型判斷哪些步驟適用；而 [`Memory.ts`](https://github.com/pandacover/singularity/blob/9d241f23d351452f1c3c42800f0c1fdc5d57d66e/apps/cli/src/eval/Memory.ts) 則將 `workflows-cues` 描述成不需模型的線索選取。兩條路徑的成本結構不同，但我沒有針對真實任務測量延遲或 Token 差異，因此不能推論哪一條整體更划算。

## 不呼叫模型的比對，到底做了什麼

接著看 [`apps/cli/src/workflows/Cues.ts`](https://github.com/pandacover/singularity/blob/9d241f23d351452f1c3c42800f0c1fdc5d57d66e/apps/cli/src/workflows/Cues.ts)。

核心邏輯相當直接：先將任務文字轉成一致的大小寫，嘗試移除含有 `not`、`never`、`without` 等字詞的否定子句，再檢查剩下的文字是否包含工作流程預先產生的線索短語。命中允許線索、又沒有命中排除線索，才選取這個工作流程；個別步驟還可以依自己的線索再次篩選。

這個模組沒有請模型判斷「兩個任務在語意上是否相似」。它比較像整理過的字串規則表。優點是便宜、快速、容易重現；缺點是，**文字重複不代表意圖相同**。

假設觸發詞是 `keyboard shortcut`。「Add a keyboard shortcut」理應命中；「Review keyboard shortcuts in documentation only」雖然含有同一個詞，卻不代表使用者想修改功能。

原始碼確實處理了一部分明確否定，但不能因此認為它理解所有複雜否定、暗示條件或跨句意圖。比對器負責找出候選記憶，無法光靠這個步驟證明操作正確。

## 五組人工輸入，測試這條界線

我參考固定提交的 `Cues.ts`，將文字正規化、否定子句過濾，以及允許與排除線索的核心判斷，**手動獨立改寫**成只使用 Node.js 標準函式庫的測試。這不是官方測試套件，也不保證涵蓋上游所有邊界情況。測試沒有安裝 Singularity、連接模型或操作真實程式庫。

測試腳本與結果清單保留在私人研究紀錄，沒有提供公開下載副本。以下列出全部五組觀察值。這是**根據原始碼規則做的合成重現**，不是上游 CLI 的端對端行為報告。

| 人工任務輸入 | 比對結果 | 觀察重點 |
| --- | --- | --- |
| 新增鍵盤快捷鍵 | 命中 | 正常召回 |
| 修復資料庫連線 | 不命中 | 排除無關任務 |
| 明確要求不要新增快捷鍵 | 不命中 | 簡單否定有效 |
| 只檢查文件中的快捷鍵敘述 | 命中 | 字面相似造成誤召回 |
| 要新增快捷鍵，但記憶指向的舊檔已刪除 | 命中 | 比對不會檢查檔案是否還存在 |

這些預期結果是在執行前依據簡化規則設定的：相關任務應命中，無關任務與明確否定應落空；只討論文件卻含有觸發詞的任務仍可能命中，而宣告舊路徑失效的文字，也不會讓比對器檢查檔案系統。

五個斷言都符合事先預期。但最後兩項是**刻意設計的不理想結果**。所以「5/5 通過」不是準確率，更不是五個真實任務都被正確處理的證據；它只證明這組獨立合成規則的預測與觀察一致。

最後一個案例尤其重要。只看文字線索，`cueChoice` 無法得知檔案是否已被搬移、刪除或重構。後續 Agent 或許會重新確認檔案，但過時路徑仍可能先被召回。**記憶命中是一項提示，不是當前程式庫狀態的證明。**

## README 的 Token 節省數字該怎麼看

作者公開了一組 Excalidraw 任務對照。在某個與記憶高度相關的長任務中，報告中的 Token 數由約 **190 萬降至 42.3 萬**，成本由約 **0.81 美元降至 0.30 美元**，回合數中位數由 **28.5 降至 9.5**。每組只有大約 **3–4 次執行**，實驗主要集中在少數程式庫。

數字值得追查，但它們仍是**作者報告的特定任務結果**。碰到沒學過的新型修改，或很小的一次性修補，收益可能趨近於零；學習工作流程本身也會產生成本。

減少讀取檔案的 Token，未必等於降低整體工程成本。如果召回錯誤步驟，Agent 可能花更多時間修正；如果程式經過大幅重構，舊記憶反而可能增加排查負擔。

我沒有重跑作者的模型對照，也沒有測量真實 Token 或美元成本，因此不提供獨立節省百分比。要估出有意義的數字，至少要讓同一批任務在有記憶與無記憶的條件下對照，並計入學習呼叫、錯誤召回修復及任務完成的總成本。這次測試沒有那些資料。

## 我會怎麼使用這類記憶

對於重複任務多、目錄結構相對穩定、測試流程明確的程式庫，工作流程記憶值得嘗試。但我會把它視為**待確認的索引**，不會讓 Agent 盲目照著執行。

比較實際的作法是替每條記憶附上來源提交、涉及路徑、最近驗證日期與適用條件。使用前確認檔案仍存在、測試命令仍有效；如果連續幾次召回都需要人工糾錯，就重新學習或停用該記憶。這是我的建議，**不是**宣稱 Singularity 已完整實作這套失效偵測。

是否安裝記憶系統，也不應只看宣傳的 Token 節省幅度。如果每次都在不同程式庫、語言與問題間切換，維護記憶的成本未必划算。

我更期待下一輪公開對照：固定同一批真實任務，同時記錄**有效召回率、誤召回次數、過時記憶、學習費用與最終總成本**。只有這樣，才能分辨記憶是真正省下重複探索，還是只把探索成本轉成維護成本。

參考資料：[Singularity 專案](https://github.com/pandacover/singularity) · [固定版本的線索比對原始碼](https://github.com/pandacover/singularity/blob/9d241f23d351452f1c3c42800f0c1fdc5d57d66e/apps/cli/src/workflows/Cues.ts) · [作者的實驗與限制](https://github.com/pandacover/singularity/blob/9d241f23d351452f1c3c42800f0c1fdc5d57d66e/README.md)
