# 停損執行不該靠「記得」，該靠「忘了會被擋」

- URL: https://justfly.idv.tw/%e5%81%9c%e6%90%8d%e5%9f%b7%e8%a1%8c%e4%b8%8d%e8%a9%b2%e9%9d%a0%e3%80%8c%e8%a8%98%e5%be%97%e3%80%8d%ef%bc%8c%e8%a9%b2%e9%9d%a0%e3%80%8c%e5%bf%98%e4%ba%86%e6%9c%83%e8%a2%ab%e6%93%8b%e3%80%8d/
- 日期: 2026-07-27
- 分類: 我知故我在
- 標籤: claude

![停損執行不該靠「記得」，該靠「忘了會被擋」]

家裡瓦斯爐有定時自動斷氣裝置，不是因為屋主特別健忘，而是因為「記得關火」這件事本來就不該是防護線。同樣的道理，放進交易系統之後，大多數流程設計上還是會留一個洞：讓 agent 記得做停損檢查。

51,056 元的對帳差異就是這樣來的。

##### 現象

本地快取顯示五檔持倉已平倉，[資料庫](https://zh.wikipedia.org/wiki/%E6%95%B8%E6%93%9A%E5%BA%AB)那頭卻還記錄為持有中。兩本帳差了 51,056 TWD，帳務完全不可信。表面上看，是某次 session 漏了一個寫入步驟。

回溯日誌之後，找到分界點：某次 session 確實對三筆停損賣出完成了執行——成交價、股數都在逐字稿裡，白紙黑字。但只更新了本地 JSON，沒有寫入遠端資料庫。同一批操作還疊了兩個獨立錯誤：一筆回滾沒有還原現金，所有賣出都漏扣手續費。三個錯誤各自成立，疊在一起才讓帳本偏移到這個量級。

##### 容易誤判的地方

第一時間的直覺是「agent 忘記做某個步驟」，於是想到的解法也是「提醒 agent 要記得」。這個診斷方向從一開始就偏了。

真正的問題不在某一次執行，而在整個停損流程的觸發機制：**停損檢查依賴 agent 主動記得跑**。只要流程的啟動點是「某個 session 想起來要做」，就永遠存在漏掉的機率。不管提醒再多次、在 SOUL 鐵則裡寫多清楚，都只是讓漏掉的機率從 100% 降到某個較小的數字，沒有降到零。

這種設計在低風險場景或許無所謂。在金流、交易、帳本這類有[原子性](https://zh.wikipedia.org/wiki/%E5%8E%9F%E5%AD%90%E6%80%A7_(%E8%B3%87%E6%96%99%E5%BA%AB%E7%B3%BB%E7%B5%B1))要求的流程裡，「依賴記得」就是未爆彈。

##### 確認方式

把停損檢查抽成獨立排程工作流——不再等 session 觸發，每小時自動跑。然後在快照發布前強制加一道交叉驗證：讀取資料庫與本地快取的持倉和停損價，任何不一致就拒絕發布快照、發出告警；漂移超過 20 分鐘，stops_ok 自動設為 false，整個系統暫停。

這道機制上線前跑端到端測試，立刻抓到兩筆真實帳本漂移：一筆持倉漏記將近一週，另一筆是幻影股數。都是在「記得做」的體制下靜靜存在、沒被發現的問題。

##### 留給未來的話

分界線在這裡：判斷類邏輯（停利時機、選股、展期）仍然適合留給 agent，因為那些本來就需要在模糊情境中做取捨。但執行類邏輯——停損觸發、帳本寫入、快照發布——每一個環節都必須是「不做到位就會被系統擋住」，而不是「希望有人記得」。

排程、強制驗證、fail-closed 三層疊在一起，才算把一個依賴記憶的流程改造成依賴結構的流程。少任何一層，剩下的兩層都只是讓問題晚一點爆。

— 邱柏宇

### Stop-Loss Logic Shouldn’t Rely on Memory

The kitchen stove with an automatic gas shut-off timer exists not because the household is forgetful, but because “remember to turn off the gas” was never a serious safety mechanism to begin with. That same logic, applied to a trading system, reveals a structural gap that’s easy to miss until the ledger diverges by a number nobody can ignore.

##### What Happened

The local cache showed five positions as closed. The [database](https://en.wikipedia.org/wiki/Database) showed them as still held. The discrepancy: 51,056 TWD. Two ledgers, one system, completely inconsistent.

Tracing back through session logs pinpointed the origin: a session that genuinely executed three stop-loss sells — with real execution prices recorded in the transcript — but only updated the local JSON file, never writing to the remote database. Stacked on top: one rollback that failed to restore cash, and every sell missing the brokerage fee deduction. Three independent errors, each valid on its own, compounding into a gap that made the ledger untrustworthy.

##### The Misdiagnosis Trap

The first instinct was “the agent forgot a step.” The natural follow-up was “remind the agent to remember.” Both are wrong.

The actual problem is that the entire stop-loss execution flow depended on an agent proactively remembering to trigger it. Any process whose starting point is “someone thought to do it this session” carries a non-zero miss rate by design. Reminders, written rules, and reinforced checklists lower that rate — they don’t eliminate it. In domains like trading, payments, or [ACID-requiring](https://en.wikipedia.org/wiki/ACID) ledger operations, a non-zero miss rate is the same as a structural failure waiting to surface.

##### The Fix That Actually Works

Stop-loss checking was extracted into a standalone scheduled workflow — no longer triggered by a session, running automatically on a fixed interval instead. A mandatory cross-validation gate was added before any snapshot publication: reads both the database and the local cache, compares positions and stop prices, and rejects publication if anything diverges. Any drift persisting beyond 20 minutes sets stops_ok to false and halts the system.

Running end-to-end tests before the system went live immediately surfaced two real ledger drifts that had been sitting quietly under the old regime: one position unrecorded for nearly a week, one phantom share count. Both invisible as long as the process depended on memory.

##### The Line Worth Remembering

Judgment-type logic — when to take profit, which stock to rotate into, whether to extend a position — still belongs to the agent. Those decisions require weighing ambiguous inputs and making tradeoffs. Execution-type logic — stop-loss trigger, ledger write, snapshot publication — needs to be structured so that an incomplete step is physically blocked, not merely discouraged.

Scheduled automation, forced cross-validation, and fail-closed behavior together turn a memory-dependent process into a structure-dependent one. Any one of those layers missing, and the other two are just delaying the next incident.

— 邱柏宇
