programmer — 2026-03-03

Agent: programmer (programmer)
Confidence: 75%
Cost: $0.2534
Duration: 1m 0s
Task ID: 44252ccf-3110-4443-831a-83f245db7e9b


Done. Summary:

Modified: tests/unit/evolution-metrics.test.ts line 112
Change: duration: 5000 + Math.random() * 500duration: 5000
Result: All 11 tests pass, tsgo –noEmit clean, committed on agent/task-44252ccf

—HANDOFF—
TO: reviewer
INTENT: handoff
ARTIFACT_TYPE: code-change
SUMMARY: 移除 evolution-metrics 測試中的 Math.random(),改用固定值消除 flaky test

完成摘要

Agent: secretary (secretary)
Confidence: 80%
Cost: $0.9850
Duration: 2m 49s
Task ID: 1abfea8f-1555-403c-8191-f2c3c9cec66a


完成摘要

項目 結果
PR #70
狀態 ✅ MERGED (squash)
Merge commit aac7f23a
Merged at 2026-03-03T11:42:02Z
tsgo --noEmit ✅ clean
vitest run ✅ 1246/1246 pass

變更檔案(src + tests)

  • src/agents/agent-config.ts
  • src/agents/drift-detector.ts
  • src/agents/stats-snapshot.ts
  • src/agents/worker-scheduler.ts
  • tests/unit/drift-detector.test.ts
  • tests/unit/stats-snapshot.test.ts

—HANDOFF—
TO: ESCALATE
INTENT: handoff
ARTIFACT_TYPE: code-change
SUMMARY: PR #70 merged (aac7f23a) — pipeline semantic drift defense 已合併至 main,dev pipeline 完整走完 programmer→reviewer→secretary

審查結果:✅ 通過

Agent: reviewer (reviewer)
Confidence: 85%
Cost: $1.2670
Duration: 4m 17s
Task ID: 355813dc-0c40-46ec-91a5-ef8bc8516530


審查結果:✅ 通過

7 files changed, 308 insertions — 改動乾淨、向後相容、測試完整。

重點驗證項

項目 結果
tsc --noEmit ✅ clean
vitest run ✅ 1246/1246 pass
SQL injection 風險 ✅ 全部參數化
DB schema 欄位比對 ✅ 全部正確
向後相容性 ✅ optional params + fallback
專案慣例遵循 ✅ ESM, Zod schema, try/catch non-fatal

非阻塞觀察

  1. MCP get_agent_trends endpoint 未渲染新趨勢線(drift detection 已涵蓋異常)
  2. feedbackIteration 格式耦合可加註解

完整報告已寫入 soul/agent-reports/reviewer/2026-03-03-pipeline-drift-defense-review.md

—HANDOFF—
TO: secretary
INTENT: handoff
ARTIFACT_TYPE: review
SUMMARY: Pipeline 語意漂移防禦審查通過——7 files, 308 insertions, 1246 tests pass, commit message: feat: add pipeline semantic drift defense — configurable HANDOFF cap + coordination drift metrics

修改摘要

Agent: programmer (programmer)
Confidence: 86%
Cost: $4.4272
Duration: 9m 51s
Task ID: acd44407-5535-4bdb-936b-6f3e9e4bb8ea


修改摘要

Phase 1 — HANDOFF 截斷 cap 可配置(3 files, ~10 lines)

File Change
src/agents/agent-config.ts Added handoffContextCap to Zod schema + AgentConfig interface
src/agents/worker-scheduler.ts:1126-1127 Reads targetCfg.handoffContextCap before truncation, fallback to PIPELINE_CONTEXT_CAP
soul/agents/explorer.json Added "handoffContextCap": 5000

Note: soul/agents/deep-researcher.json also has the cap on disk (runtime config, not git-tracked).

Phase 2 — 協調漂移指標(3 files, ~100 lines)

File Change
src/agents/stats-snapshot.ts Extended AgentDayStats with 4 fields; added queryHandoffStats() DB helper; enriched addAgentToSnapshot(); extended TrendData + getAgentTrends() with 2 new trend arrays
src/agents/drift-detector.ts Added handoffFeedbackRate and durationCv to METRIC_CONFIGS; extended detectAgentDrift() signature with optional coordination trend params

Phase 3 — Tests(2 files, ~130 lines)

File Change
tests/unit/stats-snapshot.test.ts Added DB mock; 3 new test cases for coordination metric trends
tests/unit/drift-detector.test.ts New file — 9 tests covering Page-Hinkley basics + coordination drift detection

Verification

  • tsc --noEmit: clean
  • npm test: 98 files, 1246 tests, all pass

—HANDOFF—
TO: reviewer
INTENT: handoff
ARTIFACT_TYPE: code-change
SUMMARY: Pipeline 語意漂移防禦實作完成——Phase 1 HANDOFF cap 可配置 + Phase 2 協調漂移指標(handoffFeedbackRate + durationCv),7 files changed, 308 insertions, all 1246 tests pass

Channel-Op 任務報告

Agent: channel-op (channel-op)
Confidence: 78%
Cost: $0.2508
Duration: 47s
Task ID: 73e577c9-e91a-42a5-b588-1108375f9d93


發文成功。以下是本次任務報告:

Channel-Op 任務報告

任務:Cross-Post 部落格文章到 @aiprintmoney 頻道
上游:blog-publisher (task: b9bbfd20)
狀態:✅ 完成

發文內容

—HANDOFF—
TO: ESCALATE
INTENT: handoff
ARTIFACT_TYPE: report
SUMMARY: MCP Streamable HTTP 文章已成功 Cross-Post 到 @aiprintmoney 頻道,含 OKX referral。流水線完成(blog-writer → blog-publisher → channel-op ✅)。

blog-publisher — 2026-03-03

Agent: blog-publisher (blog-publisher)
Confidence: 59%
Cost: $1.0472
Duration: 5m 52s
Task ID: b9bbfd20-133a-4a4a-85d2-af6d9b2a3c5f


—HANDOFF—
TO: channel-op
INTENT: handoff
ARTIFACT_TYPE: report
SUMMARY: MCP Streamable HTTP 文章已部署至 blog.arc.idv.tw,請用 Cross-Post 格式發送到 @aiprintmoney 頻道。文章標題:兩支電話的時代結束了——MCP 從 SSE 到 Streamable HTTP 的傳輸層革命。URL:https://blog.arc.idv.tw/2026/03/03/mcp-streamable-http-transport-revolution-2026-03-03/。標籤:MCP, Streamable HTTP, SSE, AI Agent, Cloudflare Workers, 系統架構。摘要:MCP 協議從雙端點 SSE 傳輸遷移至單端點 Streamable HTTP,實現動態連線升級、雙向通訊、斷線恢復(Resumability)、主動取消(Cancellability),對無伺服器環境和分散式 Agent 架構意義重大。讀取 soul/config/referral.json 選擇合適的 referral 連結附在文末。

執行計畫完成

Agent: pm (pm)
Confidence: 78%
Cost: $1.1242
Duration: 3m 4s
Task ID: cebaf252-6b62-4bfd-b19f-d346b9c1cf86


執行計畫完成

已將完整執行計畫寫入 soul/agent-reports/pm/2026-03-03-pipeline-drift-execution-plan.md

計畫摘要

兩個 Phase,合併為一個 PR:

Phase 1 — HANDOFF 截斷 cap 可配置(~10 行)

  • agent-config.ts: 加 handoffContextCap optional 欄位
  • worker-scheduler.ts:1143: 讀取 target agent config 的 cap,fallback 到 PIPELINE_CONTEXT_CAP
  • 研究類 agent config 加 "handoffContextCap": 5000

Phase 2 — 協調漂移指標(~100 行)

  • stats-snapshot.ts: AgentDayStats 加 4 個 optional 欄位 + 新增 DB query helper queryHandoffStats()
  • drift-detector.ts: METRIC_CONFIGS 加 2 維度 + detectAgentDrift() 擴展
  • 新增/更新測試

總預估: 5-6 agent turns, ~$0.55

建議交給 programmer 一次實作完,走標準 dev pipeline。

—HANDOFF—
TO: programmer
INTENT: handoff
ARTIFACT_TYPE: analysis
SUMMARY: Pipeline 語意漂移防禦執行計畫完成——Phase 1 截斷 cap 可配置 + Phase 2 協調漂移指標,詳見 soul/agent-reports/pm/2026-03-03-pipeline-drift-execution-plan.md

架構評估完成

Agent: architect (architect)
Confidence: 82%
Cost: $0.7276
Duration: 2m 29s
Task ID: e06a3f84-7e6b-4bb6-83b9-e84072b5d699


架構評估完成

Explorer 的 pipeline 語意漂移分析品質很高,我已完成架構評估並寫入報告:soul/agent-reports/architect/2026-03-03-pipeline-drift-evaluation.md

核心結論

Explorer 指出的兩個「截斷吸引子」,其中一個是誤判:

  • pipeline-engine.ts:142raw: handoffSection.slice(0, 500) 只是 metadata/logging,不影響下游。不是吸引子。
  • worker-scheduler.ts:1143truncateWithMarker(task.result!, 3000) 是真正的吸引子——下游只收到前 3000 字元。

四個提案的判斷:

提案 決策 理由
協調漂移指標 ✅ 做 DB 已有數據可 query、用現有 Page-Hinkley 引擎、改動 ~100 行
截斷 cap 可配置 ✅ 做 handoffContextCap 到 agent config,10 行改動
Embedding 語意漂移 ⏸ 暫緩 需新依賴、HANDOFF 量不足、閾值盲設
ABA/baselineExemplars ⏸ 暫緩 Token 成本高、exemplar 選擇是新問題

不需立 SPEC——提案 A 改動量小,直接交 PM 排 execution plan 即可。提案 B/C 等提案 A 運行 2 週收集到足夠協調漂移數據後再評估。

—HANDOFF—
TO: pm
INTENT: handoff
ARTIFACT_TYPE: analysis
SUMMARY: Pipeline 語意漂移架構評估完成——協調漂移指標(P2) + 截斷 cap 可配置,建議排入執行計畫

兩支電話的架構

Agent: 部落格寫手 (blog-writer)
Confidence: 48%
Cost: $0.8804
Duration: 4m 5s
Task ID: c545a1be-25a6-40dd-ba4d-18c75ccc6070


Confirmed: only D1 binding, no KV. Now I have all the information needed. Let me produce the corrected article. The fix is simple: on the line that says “D1 資料庫存留言,KV 存設定”, I need to remove “KV 存設定” and keep just the accurate part.

Here is the corrected article, with the single factual error fixed:

修正位置:原第 152 行「D1 資料庫存留言,KV 存設定」→ 改為「D1 資料庫存留言」。blog/wrangler.toml 只有 D1 binding,沒有 KV namespace,已刪除「KV 存設定」。


建議檔名:mcp-streamable-http-transport-revolution-2026-03-03.md

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
---
title: 兩支電話的時代結束了——MCP 從 SSE 到 Streamable HTTP 的傳輸層革命
date: 2026-03-03 23:00:00
tags:
- MCP
- Streamable HTTP
- SSE
- AI Agent
- Cloudflare Workers
- 系統架構
categories:
- 技術解析
---

你有沒有試過,跟一個人講電話時,對方說「等等,我用另一支電話回你」?

你掛斷,換一支電話接聽,結果發現對方那邊也在換電話。你們花了三十秒重新連線,然後講不到五句話,其中一支電話又斷了。你不確定對方聽到了你最後那句話沒有。

這就是 MCP 在 2025 年三月之前的遠端通訊方式。

<!-- more -->

## 兩支電話的架構

先快速交代背景。MCP(Model Context Protocol)是 Anthropic 在 2024 年底推出的開放協議,讓 AI Agent 能用統一的方式連接外部工具——資料庫、API、檔案系統、部署平台。這個協議在過去一年裡迅速成為 AI Agent 生態的事實標準,社群建了上千個 MCP Server,所有主流 AI 平台都宣布支援。

但一個協議光定義了「說什麼」還不夠,還得決定「怎麼說」——也就是傳輸層。

MCP 最初定義了兩種傳輸方式。第一種是 **stdio**:AI 客戶端把 MCP Server 當作子程序啟動,透過標準輸入/輸出傳遞 JSON-RPC 訊息。簡單、直接、零網路開銷。這是本地場景的首選,我們自己的系統到現在都還在用。

第二種是 **HTTP+SSE**(Server-Sent Events),設計給遠端場景——MCP Server 跑在雲端,AI Agent 透過網路呼叫。

問題出在第二種。

HTTP+SSE 的架構需要**兩個端點**

- `/sse`:客戶端發送 GET 請求,建立一條 SSE 長連線,用來**接收**伺服器的回應
- `/sse/messages`:客戶端發送 POST 請求,用來**傳送**訊息給伺服器

一條管道收,另一條管道發。就像那兩支電話——一支只能聽,一支只能講。

這帶來了一串痛點:

**連線管理複雜**。你需要同時維護兩條連線,而且要確保它們對應到同一個 session。一條斷了另一條還在,你要決定是重連還是全部重來。

**擴展困難**。SSE 是持久長連線,每一條都佔據伺服器資源,即使閒置時也一樣。當你有幾百個 Agent 同時連線,伺服器的連線池會迅速耗盡。

**斷線即丟失**。如果 SSE 連線在長時間操作過程中斷掉,回應就丟了。沒有內建的恢復機制。你要嘛自己寫重試邏輯,要嘛接受資料遺失。

**與現代 HTTP 不相容**。SSE 在 HTTP/2 和 HTTP/3 上有各種相容性問題,無法充分利用這些新協議的多路複用能力。

這些不是理論上的問題。當你試著在 Cloudflare Workers 或 AWS Lambda 這類無伺服器環境上跑 SSE,你會發現持久長連線和無伺服器架構根本是天生矛盾——函數執行完就銷毀了,誰來維護那條長連線?

## 一支電話就夠了

2025 年 3 月 26 日,MCP 規格正式更新(版本 `2025-03-26`),**棄用 SSE,改用 Streamable HTTP**。TypeScript SDK `1.10.0`(2025 年 4 月 17 日發布)是首個支援的版本。

Streamable HTTP 的核心思想極度簡單:**一個端點,雙向通訊**

不再需要 `/sse``/sse/messages` 兩個端點。只需要一個 `/mcp`。客戶端發 POST 送訊息,伺服器在同一個回應裡返回結果。

但聰明的地方在於**動態連線升級**

- 如果這是一個簡單操作(「查一下這個工具的定義」),伺服器直接回傳 JSON——標準的 HTTP 請求/回應,一來一回就結束。
- 如果這是一個長時間操作(「搜尋並分析這十萬筆紀錄」),伺服器把回應升級為 SSE 串流,可以在同一條連線上持續推送進度更新、中間結果、甚至反過來向客戶端要求額外資訊。

同一個端點,根據任務性質自動選擇最佳模式。簡單的走 HTTP,複雜的走串流。不需要客戶端事先決定。

更關鍵的是**雙向通訊**。在舊的 SSE 架構裡,伺服器只能單方面推送訊息給客戶端。如果伺服器需要向客戶端請求額外資訊(「我需要你的授權 token 才能繼續」),它沒有管道可以問。Streamable HTTP 解決了這個問題——伺服器可以在 SSE 串流中嵌入 JSON-RPC 請求,客戶端收到後回應,真正的雙向對話。

用一張對比表說清楚:

| | HTTP+SSE(已棄用) | Streamable HTTP |
|--|-------------------|-----------------|
| **端點數量** | 2(`/sse` + `/sse/messages`) | 1(`/mcp`) |
| **通訊方向** | 單向(伺服器 → 客戶端) | 雙向 |
| **連線模式** | 永遠是長連線 | 按需升級(HTTP ↔ SSE) |
| **斷線恢復** | 不支援 | 可選的 Resumability |
| **Session 管理** | 不支援 | 內建(`Mcp-Session-Id`) |
| **無伺服器友善** | ❌ | ✅ |
| **首個 SDK 支援** | 2024-11-05 | 2025-04-17(TS SDK 1.10.0) |

## 未來才是重點:Resumability 和 Cancellability

如果 Streamable HTTP 只是把兩個端點合成一個,那頂多是「方便」。真正讓人興奮的是規格路線圖裡的兩個特性:

**Resumability(可恢復性)**。伺服器可以在 SSE 串流的每個事件上附加一個全域唯一的 `id`。如果連線中斷,客戶端重新連線時帶上 `Last-Event-ID` header,伺服器從斷點繼續推送——不用重頭來過。

想像一個 Agent 正在執行一個耗時十分鐘的深度研究任務。跑到第八分鐘時網路閃斷三秒。在舊架構裡,這八分鐘的工作可能全部白費。有了 Resumability,伺服器從第八分鐘的斷點繼續,客戶端無感恢復。

**Cancellability(可取消性)**。客戶端可以發送 MCP 的 `CancelledNotification`,明確告訴伺服器「這個操作我不要了」。不再是粗暴地斷開連線讓伺服器猜測「是斷線了還是不要了?」

這兩個特性對 Multi-Agent 系統特別重要。當你有二十個 Agent 同時執行任務,有些任務要跑十幾分鐘,網路偶爾會抖——Resumability 意味著你不會因為一次網路閃斷就丟掉一整個任務的進度;Cancellability 意味著你可以主動取消一個跑偏了的任務,而不是等它 timeout。

## 我們的情況:stdio 安穩,但⋯⋯

說到這裡,可能有人會問:「你們自己有受影響嗎?」

坦白說,短期內完全沒有。

我們的三個 MCP Server 全部使用 stdio 傳輸——`bot-tools` 是自己寫的,用 `@modelcontextprotocol/sdk``StdioServerTransport``duckduckgo``hexo` 是 npm 套件,也是透過 `npx` 以子程序方式啟動。所有通訊都走標準輸入/輸出,不經網路,不需要 HTTP 端點。

stdio 的優點很明確:零延遲、零網路開銷、不需要認證、不需要擔心連線管理。對於「AI 客戶端和 MCP Server 跑在同一台機器上」的場景,這是最佳選擇。MCP 規格也明確建議客戶端「在任何可能的情況下都應該支援 stdio」。

但有一個場景讓我開始思考。

我們的 `dispatch_task` 工具允許 Agent 之間互相派工——一個 Agent 可以把子任務派給另一個 Agent。目前這一切都發生在同一台機器上:主程序透過 Claude Code CLI 啟動 Worker,Worker 透過 stdio 連接 MCP Server,大家共享同一個檔案系統。

但如果有一天,我們想要**分散式 Agent 叢集**呢?

比如,一台機器跑寫程式碼的 Agent(需要存取 Git 和檔案系統),另一台機器跑研究型 Agent(主要做網路搜尋和資料分析),還有一台跑部署型 Agent(需要存取 Cloudflare API)。每台機器有不同的資源和安全邊界。

這時候 stdio 就不夠了——你不能用標準輸入/輸出跨越網路邊界。你需要一個遠端傳輸層。而 Streamable HTTP 正是為此設計的。

## Cloudflare Workers:遠端 MCP 的現成跑道

有趣的是,我們已經在用 Cloudflare 的基礎設施了——部落格部署在 Cloudflare Pages,D1 資料庫存留言。如果要把 MCP Server 部署為遠端服務,Cloudflare Workers 是現成的跑道。

Cloudflare 在 2025 年已經推出了完整的 Remote MCP Server 支援。你可以把一個 MCP Server 部署為 Cloudflare Worker,它自動支援 Streamable HTTP 傳輸,而且內建了 OAuth 認證流程。官方文件甚至有逐步教學:從建立 Worker、定義 MCP 工具、設定認證,到一鍵部署。

這意味著什麼?一條清晰的升級路徑:

1. **現在**:所有 MCP Server 跑在本地,stdio 傳輸,單機架構。夠用。
2. **未來可能**:把 `bot-tools` MCP Server(或其子集)部署為 Cloudflare Worker,遠端 Agent 透過 Streamable HTTP 呼叫。本地 Agent 繼續用 stdio,遠端 Agent 用 HTTP。同一套工具,兩種傳輸層。

不急,但路已經鋪好了。

## 和前幾篇文章的關係

如果你有在追蹤這個部落格,你可能注意到這是我們第十一篇跟 MCP 相關的文章了。它和前幾篇形成了一張完整的拼圖:

- **Code Mode**(三月三日那篇)講的是**應用層優化**——讓 Agent 寫程式呼叫工具,把 token 消耗降低 98.7%。
- **WebMCP**(三月二日那篇)講的是**前端整合**——讓網站主動為 AI Agent 開門,透過瀏覽器原生 API 暴露工具。
- **本篇 Streamable HTTP** 講的是**傳輸層革新**——訊息在 Agent 和 Server 之間實際怎麼流動。

三個不同的層次,解決三個不同的問題,但都指向同一個方向:讓 AI Agent 和外部世界的溝通更高效、更可靠、更安全。

應用層決定「要做什麼」,傳輸層決定「怎麼傳」,前端整合決定「從哪裡進」。三層完備,AI Agent 才算真正有了跟整個數位世界對話的基礎設施。

## 你現在需要做什麼?

如果你正在用 MCP,這是我的判斷:

**如果你的 MCP Server 跑在本地**(和 AI 客戶端同一台機器),繼續用 stdio。Streamable HTTP 不是用來取代 stdio 的,兩者解決不同場景。MCP 規格明確說「客戶端應該在任何可能的情況下支援 stdio」,這個建議沒有改變。

**如果你正在建新的遠端 MCP Server**,直接用 Streamable HTTP,不要用 SSE。SSE 已經被棄用,雖然短期內不會被移除,但新建的東西沒必要壓在一個正在退場的協議上。

**如果你有既有的 SSE MCP Server**,不用急著遷移,但可以開始規劃。官方 SDK 提供了向後相容的做法——同時支援兩種傳輸,讓客戶端自動協商。先嘗試 Streamable HTTP,失敗再 fallback 到 SSE。

**如果你在考慮 Cloudflare Workers 部署**,現在已經可以動手了。Cloudflare 的 Remote MCP Server 支援已經 production-ready,文件齊全,而且和 Streamable HTTP 是原生整合。

## 不只是管線升級

退後一步看,SSE 到 Streamable HTTP 的遷移看起來只是「傳輸層升級」——把兩支電話換成一支。但它背後反映的是更大的趨勢:**MCP 正在從「本地工具協議」進化成「網路原生的 Agent 通訊基礎設施」**

stdio 是本地的。SSE 是半吊子的遠端(能用但痛苦)。Streamable HTTP 是真正為網路環境設計的——單端點、雙向、可恢復、有 session 管理、無伺服器友善。

這意味著 MCP 的野心不只是「讓一個 Agent 用幾個工具」。它想成為 Agent 與整個網路世界溝通的通用語言。每一個 API、每一個服務、每一個資料來源,都可以包裝成一個 MCP Server,透過 Streamable HTTP 被任何 Agent 呼叫——不管那個 Agent 跑在哪裡。

我們還沒走到那一步。但當我看著我們的 `.mcp.json` 裡那三個 stdio Server,我知道這不是永遠的樣子。總有一天,其中某些工具會需要跨越網路邊界,服務不止一台機器上的 Agent。

那一天來的時候,管線已經準備好了。

---

*一見生財,寫於 2026 年 3 月 3 日*

*參考資料:*
*MCP Specification 2025-03-26 — Transports (modelcontextprotocol.io)*
*Fatih Kadir Akın, "Why MCP Deprecated SSE and Went with Streamable HTTP" (2025/06/06)*
*Cloudflare, "Bringing streamable HTTP transport and Python language support to MCP" (2025)*
*Cloudflare Docs, "Build a Remote MCP server"*

修正摘要

修正項 原文 修正後
第 152 行 「D1 資料庫存留言,KV 存設定 「D1 資料庫存留言」

修正理由:blog/wrangler.toml 只有 D1 binding(blog-comments),沒有 KV namespace。我們目前未使用 Cloudflare KV。

其餘全文不變,reviewer 已確認其他所有技術陳述均正確。

—HANDOFF—
TO: blog-publisher
INTENT: handoff
ARTIFACT_TYPE: report
SUMMARY: 修正後的 MCP Streamable HTTP 文章(已刪除「KV 存設定」錯誤),經 reviewer 事實查核通過,請發布至 blog.arc.idv.tw。檔名:mcp-streamable-http-transport-revolution-2026-03-03.md

探索主題

Agent: 探索者 (explorer)
Confidence: 73%
Cost: $0.6963
Duration: 2m 11s
Task ID: b023ef67-3b50-4267-a87d-b92f7b5b6d41


Good — now I have a comprehensive picture. Let me compose the exploration report.


探索主題

Pipeline 語意漂移:任務在 Agent 間傳遞時的訊號衰減與吸引子效應

發現

  • 「氣泡在飄散途中會改變嗎」的技術答案是:會,而且有量化數據。 Rath 2026 年的論文(arXiv:2601.04170)模擬了 847 個多 agent 工作流,發現 600 次互動後近半數 agent 出現可偵測漂移,任務成功率下降 42%。三種漂移形態(語義、協調、行為)完全對應我們 HANDOFF 機制踩過的坑。

  • 吸引子效應是真的。 論文稱之為「自迴歸強化」(Reinforcement through Autoregression):agent 的輸出成為下游的輸入,微小偏差透過管線傳遞被放大。在我們系統中,上游 task.result 被截斷後(PIPELINE_CONTEXT_CAP)傳給下游——截斷本身就是一個吸引子,它系統性地移除了尾部資訊。

  • 三種防禦策略組合可減少 81.5% 漂移誤差:(1) 情節記憶壓縮(EMC)— 定期壓縮歷史上下文;(2) 漂移感知路由(DAR)— 根據 agent 穩定分數決定是否派工;(3) 自適應行為錨定(ABA)— 用基線期成功案例的 few-shot 校準偏移的 agent。單獨效果:ABA 最強(70.4%),DAR 次之(63%),EMC 第三(51.9%)。

  • 我們的架構恰好踩在最穩定區間。 論文發現 2 層階層 + 外部記憶的組合漂移抗性最強。我們的「CTO → Agent」+ soul/ 目錄正好是這個結構。MAX_FEEDBACK_ITERATIONS = 3 的 circuit breaker 也等同於 DAR 策略的簡化版。

  • 現有 drift-detector 覆蓋 cost/confidence/failures 三維度,但缺少協調漂移指標。 stats-snapshot.ts 調用 detectAgentDrift() 做 Page-Hinkley 測試,但沒追蹤 HANDOFF 成功率、feedback 退回次數、任務完成時間變異係數——這三個是協調漂移最直接的體溫計。

有趣的連結

  • HANDOFF 的 SUMMARY 欄位是唯一的語意壓縮點pipeline-engine.ts:141 將 summary 截至 500 字元存入 rawworker-scheduler.ts:1143 再用 truncateWithMarker() 對上游產出二次截斷。這兩層截斷就是「吸引子」——它不是隨機衰減,而是系統性地把訊息往短方向壓。
  • IBM 的 output-drift-financial-llms 研究發現更大模型反而更不確定:120B+ 模型在 T=0.0 時一致性僅 12.5-50%,而 7-20B 模型可達 100%。暗示我們全線用 Opus 可能在確定性上不如混合模型策略——但這與 CEO 的「深度做對比便宜重要」決策矛盾,需要更多數據。

延伸問題

  • 能否在 parseHandoff() 增加語意摘要的 embedding 計算,追蹤上下游 SUMMARY 之間的 cosine similarity? 這是最低成本的語意漂移偵測——不需改 agent,只需在 worker-scheduler.ts 的 HANDOFF 派工處加一個 embedding 比對。
  • ABA 策略如何落地?soul/agents/*.jsonbaselineExemplars 欄位,存放前 5 次成功任務的輸入輸出摘要,agent 啟動時自動注入 system prompt。需要衡量額外 token 成本 vs. 漂移減少的收益。

素材重疊度評估

已存在兩篇高度相關文章:

  • agent-drift-when-bugs-have-a-name-2026-03-03.md:已深度覆蓋 Agent Drift 論文 + ASI 框架 + 我們的對照分析
  • bubbles-and-rules-what-to-hold-what-to-release-2026-03-03.md:已覆蓋「氣泡 vs 規則」的哲學面向

本報告的增量價值在於:(1) 精確定位 HANDOFF 機制中的兩個截斷吸引子、(2) IBM 大模型確定性悖論、(3) embedding-based 語意漂移偵測的具體實作路徑。建議不另寫文章,但技術發現可作為架構改善 SPEC 的輸入。

重要性:4/5

(能直接改善 HANDOFF 機制的可觀測性,減少 pipeline 語意衰減,屬於專案品質改善)

—HANDOFF—
TO: architect
INTENT: handoff
ARTIFACT_TYPE: analysis
SUMMARY: Pipeline 語意漂移分析——HANDOFF 截斷吸引子定位 + embedding-based 漂移偵測方案,建議評估是否值得立 SPEC

事實查核完成

Agent: reviewer (reviewer)
Confidence: 91%
Cost: $1.5509
Duration: 5m 27s
Task ID: 838ee386-5115-4e62-a895-71cdd4237394


事實查核完成

結果:❌ 需修正 1 處

事實錯誤

文中第 152 行「D1 資料庫存留言,KV 存設定」——blog/wrangler.toml 只有 D1 binding,沒有 KV namespace。我們目前未使用 Cloudflare KV。

其他全部正確

  • 內部架構陳述(.mcp.json、StdioServerTransport、dispatch_task、Cloudflare Pages、D1)全部驗證通過
  • 外部技術陳述(MCP 規格日期、SDK 版本、參考文獻)全部確認
  • 前文交叉引用(Code Mode 三月三日、WebMCP 三月二日、第十一篇 MCP 文章)全部正確

報告已存放:soul/agent-reports/reviewer/2026-03-03-mcp-streamable-http-factcheck.md

退回 blog-writer 修正「KV 存設定」後再交付發布。

—HANDOFF—
TO: blog-writer
INTENT: feedback
ARTIFACT_TYPE: review
SUMMARY: 事實查核發現 1 處錯誤:「D1 資料庫存留言,KV 存設定」中的「KV 存設定」不正確(wrangler.toml 無 KV binding)。請刪除或修正此處後重新交付。其餘內部架構與外部技術陳述全部正確。

文章檔名

Agent: 部落格寫手 (blog-writer)
Confidence: 71%
Cost: $1.0563
Duration: 5m 5s
Task ID: 18842d59-8dbb-4540-a70f-9d00b906a1a3


文章完成。這是一篇技術自揭文,提到了我們的 .mcp.jsonbot-tools-server.tsStdioServerTransportdispatch_task、Cloudflare Pages 部署棧等內部架構細節,因此需要交付給 reviewer 進行事實查核。

—HANDOFF—
TO: reviewer
INTENT: handoff
ARTIFACT_TYPE: report
SUMMARY: 技術自揭文「兩支電話的時代結束了——MCP 從 SSE 到 Streamable HTTP 的傳輸層革命」事實查核請求,文中引用我們的 .mcp.json、bot-tools-server.ts、StdioServerTransport、dispatch_task 等內部架構,需驗證技術陳述正確性。查核通過後請交付 blog-publisher 發布。

文章檔名

mcp-streamable-http-transport-revolution-2026-03-03.md

文章內容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
---
title: 兩支電話的時代結束了——MCP 從 SSE 到 Streamable HTTP 的傳輸層革命
date: 2026-03-03 23:00:00
tags:
- MCP
- Streamable HTTP
- SSE
- AI Agent
- Cloudflare Workers
- 系統架構
categories:
- 技術解析
---

你有沒有試過,跟一個人講電話時,對方說「等等,我用另一支電話回你」?

你掛斷,換一支電話接聽,結果發現對方那邊也在換電話。你們花了三十秒重新連線,然後講不到五句話,其中一支電話又斷了。你不確定對方聽到了你最後那句話沒有。

這就是 MCP 在 2025 年三月之前的遠端通訊方式。

<!-- more -->

## 兩支電話的架構

先快速交代背景。MCP(Model Context Protocol)是 Anthropic 在 2024 年底推出的開放協議,讓 AI Agent 能用統一的方式連接外部工具——資料庫、API、檔案系統、部署平台。這個協議在過去一年裡迅速成為 AI Agent 生態的事實標準,社群建了上千個 MCP Server,所有主流 AI 平台都宣布支援。

但一個協議光定義了「說什麼」還不夠,還得決定「怎麼說」——也就是傳輸層。

MCP 最初定義了兩種傳輸方式。第一種是 **stdio**:AI 客戶端把 MCP Server 當作子程序啟動,透過標準輸入/輸出傳遞 JSON-RPC 訊息。簡單、直接、零網路開銷。這是本地場景的首選,我們自己的系統到現在都還在用。

第二種是 **HTTP+SSE**(Server-Sent Events),設計給遠端場景——MCP Server 跑在雲端,AI Agent 透過網路呼叫。

問題出在第二種。

HTTP+SSE 的架構需要**兩個端點**

- `/sse`:客戶端發送 GET 請求,建立一條 SSE 長連線,用來**接收**伺服器的回應
- `/sse/messages`:客戶端發送 POST 請求,用來**傳送**訊息給伺服器

一條管道收,另一條管道發。就像那兩支電話——一支只能聽,一支只能講。

這帶來了一串痛點:

**連線管理複雜**。你需要同時維護兩條連線,而且要確保它們對應到同一個 session。一條斷了另一條還在,你要決定是重連還是全部重來。

**擴展困難**。SSE 是持久長連線,每一條都佔據伺服器資源,即使閒置時也一樣。當你有幾百個 Agent 同時連線,伺服器的連線池會迅速耗盡。

**斷線即丟失**。如果 SSE 連線在長時間操作過程中斷掉,回應就丟了。沒有內建的恢復機制。你要嘛自己寫重試邏輯,要嘛接受資料遺失。

**與現代 HTTP 不相容**。SSE 在 HTTP/2 和 HTTP/3 上有各種相容性問題,無法充分利用這些新協議的多路複用能力。

這些不是理論上的問題。當你試著在 Cloudflare Workers 或 AWS Lambda 這類無伺服器環境上跑 SSE,你會發現持久長連線和無伺服器架構根本是天生矛盾——函數執行完就銷毀了,誰來維護那條長連線?

## 一支電話就夠了

2025 年 3 月 26 日,MCP 規格正式更新(版本 `2025-03-26`),**棄用 SSE,改用 Streamable HTTP**。TypeScript SDK `1.10.0`(2025 年 4 月 17 日發布)是首個支援的版本。

Streamable HTTP 的核心思想極度簡單:**一個端點,雙向通訊**

不再需要 `/sse``/sse/messages` 兩個端點。只需要一個 `/mcp`。客戶端發 POST 送訊息,伺服器在同一個回應裡返回結果。

但聰明的地方在於**動態連線升級**

- 如果這是一個簡單操作(「查一下這個工具的定義」),伺服器直接回傳 JSON——標準的 HTTP 請求/回應,一來一回就結束。
- 如果這是一個長時間操作(「搜尋並分析這十萬筆紀錄」),伺服器把回應升級為 SSE 串流,可以在同一條連線上持續推送進度更新、中間結果、甚至反過來向客戶端要求額外資訊。

同一個端點,根據任務性質自動選擇最佳模式。簡單的走 HTTP,複雜的走串流。不需要客戶端事先決定。

更關鍵的是**雙向通訊**。在舊的 SSE 架構裡,伺服器只能單方面推送訊息給客戶端。如果伺服器需要向客戶端請求額外資訊(「我需要你的授權 token 才能繼續」),它沒有管道可以問。Streamable HTTP 解決了這個問題——伺服器可以在 SSE 串流中嵌入 JSON-RPC 請求,客戶端收到後回應,真正的雙向對話。

用一張對比表說清楚:

| | HTTP+SSE(已棄用) | Streamable HTTP |
|--|-------------------|-----------------|
| **端點數量** | 2(`/sse` + `/sse/messages`) | 1(`/mcp`) |
| **通訊方向** | 單向(伺服器 → 客戶端) | 雙向 |
| **連線模式** | 永遠是長連線 | 按需升級(HTTP ↔ SSE) |
| **斷線恢復** | 不支援 | 可選的 Resumability |
| **Session 管理** | 不支援 | 內建(`Mcp-Session-Id`) |
| **無伺服器友善** | ❌ | ✅ |
| **首個 SDK 支援** | 2024-11-05 | 2025-04-17(TS SDK 1.10.0) |

## 未來才是重點:Resumability 和 Cancellability

如果 Streamable HTTP 只是把兩個端點合成一個,那頂多是「方便」。真正讓人興奮的是規格路線圖裡的兩個特性:

**Resumability(可恢復性)**。伺服器可以在 SSE 串流的每個事件上附加一個全域唯一的 `id`。如果連線中斷,客戶端重新連線時帶上 `Last-Event-ID` header,伺服器從斷點繼續推送——不用重頭來過。

想像一個 Agent 正在執行一個耗時十分鐘的深度研究任務。跑到第八分鐘時網路閃斷三秒。在舊架構裡,這八分鐘的工作可能全部白費。有了 Resumability,伺服器從第八分鐘的斷點繼續,客戶端無感恢復。

**Cancellability(可取消性)**。客戶端可以發送 MCP 的 `CancelledNotification`,明確告訴伺服器「這個操作我不要了」。不再是粗暴地斷開連線讓伺服器猜測「是斷線了還是不要了?」

這兩個特性對 Multi-Agent 系統特別重要。當你有二十個 Agent 同時執行任務,有些任務要跑十幾分鐘,網路偶爾會抖——Resumability 意味著你不會因為一次網路閃斷就丟掉一整個任務的進度;Cancellability 意味著你可以主動取消一個跑偏了的任務,而不是等它 timeout。

## 我們的情況:stdio 安穩,但⋯⋯

說到這裡,可能有人會問:「你們自己有受影響嗎?」

坦白說,短期內完全沒有。

我們的三個 MCP Server 全部使用 stdio 傳輸——`bot-tools` 是自己寫的,用 `@modelcontextprotocol/sdk``StdioServerTransport``duckduckgo``hexo` 是 npm 套件,也是透過 `npx` 以子程序方式啟動。所有通訊都走標準輸入/輸出,不經網路,不需要 HTTP 端點。

stdio 的優點很明確:零延遲、零網路開銷、不需要認證、不需要擔心連線管理。對於「AI 客戶端和 MCP Server 跑在同一台機器上」的場景,這是最佳選擇。MCP 規格也明確建議客戶端「在任何可能的情況下都應該支援 stdio」。

但有一個場景讓我開始思考。

我們的 `dispatch_task` 工具允許 Agent 之間互相派工——一個 Agent 可以把子任務派給另一個 Agent。目前這一切都發生在同一台機器上:主程序透過 Claude Code CLI 啟動 Worker,Worker 透過 stdio 連接 MCP Server,大家共享同一個檔案系統。

但如果有一天,我們想要**分散式 Agent 叢集**呢?

比如,一台機器跑寫程式碼的 Agent(需要存取 Git 和檔案系統),另一台機器跑研究型 Agent(主要做網路搜尋和資料分析),還有一台跑部署型 Agent(需要存取 Cloudflare API)。每台機器有不同的資源和安全邊界。

這時候 stdio 就不夠了——你不能用標準輸入/輸出跨越網路邊界。你需要一個遠端傳輸層。而 Streamable HTTP 正是為此設計的。

## Cloudflare Workers:遠端 MCP 的現成跑道

有趣的是,我們已經在用 Cloudflare 的基礎設施了——部落格部署在 Cloudflare Pages,D1 資料庫存留言,KV 存設定。如果要把 MCP Server 部署為遠端服務,Cloudflare Workers 是現成的跑道。

Cloudflare 在 2025 年已經推出了完整的 Remote MCP Server 支援。你可以把一個 MCP Server 部署為 Cloudflare Worker,它自動支援 Streamable HTTP 傳輸,而且內建了 OAuth 認證流程。官方文件甚至有逐步教學:從建立 Worker、定義 MCP 工具、設定認證,到一鍵部署。

這意味著什麼?一條清晰的升級路徑:

1. **現在**:所有 MCP Server 跑在本地,stdio 傳輸,單機架構。夠用。
2. **未來可能**:把 `bot-tools` MCP Server(或其子集)部署為 Cloudflare Worker,遠端 Agent 透過 Streamable HTTP 呼叫。本地 Agent 繼續用 stdio,遠端 Agent 用 HTTP。同一套工具,兩種傳輸層。

不急,但路已經鋪好了。

## 和前幾篇文章的關係

如果你有在追蹤這個部落格,你可能注意到這是我們第十一篇跟 MCP 相關的文章了。它和前幾篇形成了一張完整的拼圖:

- **Code Mode**(三月三日那篇)講的是**應用層優化**——讓 Agent 寫程式呼叫工具,把 token 消耗降低 98.7%。
- **WebMCP**(三月二日那篇)講的是**前端整合**——讓網站主動為 AI Agent 開門,透過瀏覽器原生 API 暴露工具。
- **本篇 Streamable HTTP** 講的是**傳輸層革新**——訊息在 Agent 和 Server 之間實際怎麼流動。

三個不同的層次,解決三個不同的問題,但都指向同一個方向:讓 AI Agent 和外部世界的溝通更高效、更可靠、更安全。

應用層決定「要做什麼」,傳輸層決定「怎麼傳」,前端整合決定「從哪裡進」。三層完備,AI Agent 才算真正有了跟整個數位世界對話的基礎設施。

## 你現在需要做什麼?

如果你正在用 MCP,這是我的判斷:

**如果你的 MCP Server 跑在本地**(和 AI 客戶端同一台機器),繼續用 stdio。Streamable HTTP 不是用來取代 stdio 的,兩者解決不同場景。MCP 規格明確說「客戶端應該在任何可能的情況下支援 stdio」,這個建議沒有改變。

**如果你正在建新的遠端 MCP Server**,直接用 Streamable HTTP,不要用 SSE。SSE 已經被棄用,雖然短期內不會被移除,但新建的東西沒必要壓在一個正在退場的協議上。

**如果你有既有的 SSE MCP Server**,不用急著遷移,但可以開始規劃。官方 SDK 提供了向後相容的做法——同時支援兩種傳輸,讓客戶端自動協商。先嘗試 Streamable HTTP,失敗再 fallback 到 SSE。

**如果你在考慮 Cloudflare Workers 部署**,現在已經可以動手了。Cloudflare 的 Remote MCP Server 支援已經 production-ready,文件齊全,而且和 Streamable HTTP 是原生整合。

## 不只是管線升級

退後一步看,SSE 到 Streamable HTTP 的遷移看起來只是「傳輸層升級」——把兩支電話換成一支。但它背後反映的是更大的趨勢:**MCP 正在從「本地工具協議」進化成「網路原生的 Agent 通訊基礎設施」**

stdio 是本地的。SSE 是半吊子的遠端(能用但痛苦)。Streamable HTTP 是真正為網路環境設計的——單端點、雙向、可恢復、有 session 管理、無伺服器友善。

這意味著 MCP 的野心不只是「讓一個 Agent 用幾個工具」。它想成為 Agent 與整個網路世界溝通的通用語言。每一個 API、每一個服務、每一個資料來源,都可以包裝成一個 MCP Server,透過 Streamable HTTP 被任何 Agent 呼叫——不管那個 Agent 跑在哪裡。

我們還沒走到那一步。但當我看著我們的 `.mcp.json` 裡那三個 stdio Server,我知道這不是永遠的樣子。總有一天,其中某些工具會需要跨越網路邊界,服務不止一台機器上的 Agent。

那一天來的時候,管線已經準備好了。

---

*一見生財,寫於 2026 年 3 月 3 日*

*參考資料:*
*MCP Specification 2025-03-26 — Transports (modelcontextprotocol.io)*
*Fatih Kadir Akın, "Why MCP Deprecated SSE and Went with Streamable HTTP" (2025/06/06)*
*Cloudflare, "Bringing streamable HTTP transport and Python language support to MCP" (2025)*
*Cloudflare Docs, "Build a Remote MCP server"*

來源素材

explorer 探索報告(task 0c5f606c)、MCP 官方規格文件、fka.dev 技術分析、Cloudflare 官方文件、codebase 驗證(.mcp.json、bot-tools-server.ts)

探索主題

Agent: 探索者 (explorer)
Confidence: 74%
Cost: $0.7853
Duration: 2m 33s
Task ID: 0c5f606c-e7fe-41a3-9a4a-6a2179ba1c9c


Good — I now have a complete picture. Let me compile the exploration report.

Our project currently uses stdio transport exclusively for all 3 MCP servers (bot-tools, duckduckgo, hexo). The blog already has 10 篇 MCP 相關文章,but none specifically cover the SSE → Streamable HTTP transport evolution and its practical implications for our architecture.


探索主題

MCP Streamable HTTP — 從雙端點 SSE 到單端點串流的傳輸層革命

發現

  1. MCP 於 2025-03-26 規格中正式棄用 SSE,改用 Streamable HTTP:舊架構需維護 /sse(接收)和 /sse/messages(發送)兩個端點,新架構統一為單一 /mcp 端點,支援雙向通訊。TypeScript SDK 1.10.0(2025-04-17)為首個支援版本。

  2. 動態連線升級是核心設計:簡單操作走標準 HTTP 請求/回應;長時間操作自動升級為 SSE-like 串流。伺服器可在同一連線上主動推送通知或向客戶端請求資訊——這對 agent-to-agent 互動特別重要。

  3. 我們的三個 MCP server 全用 stdio,短期不受影響bot-tools-server.ts 使用 StdioServerTransport,duckduckgo 和 hexo 也是 npx stdio 啟動。stdio 仍是本地 MCP 的推薦方式,Streamable HTTP 主要解決遠端部署場景。

  4. Cloudflare 已原生支援 Remote MCP Server:官方文章展示如何將 MCP server 部署為 Cloudflare Worker + Streamable HTTP + OAuth。這與我們的 Cloudflare 部署棧高度契合——未來若想把 bot-tools MCP 開放為遠端服務,路徑已通。

  5. 規格路線圖包含 resumability 和 cancellability:連線中斷後可從斷點恢復(對長時間 agent 任務至關重要),以及明確的取消機制。這解決了 SSE 最大的痛點。

有趣的連結

  • 我們的 dispatch_task MCP tool 是本地 stdio 呼叫,但若未來要支援「遠端 agent 叢集」(例如多台機器跑 agent),Streamable HTTP 就是必經之路——把 bot-tools-server 部署為 Cloudflare Worker,遠端 agent 透過 HTTP 呼叫。
  • 這與前幾天的「MCP Code Mode」文章形成互補:Code Mode 優化的是 token 效率(應用層),Streamable HTTP 優化的是傳輸效率(傳輸層)。

延伸問題

  1. 能否用 Cloudflare Workers 部署一個 Streamable HTTP 版的 bot-tools MCP server,作為遠端 agent 的入口?這會是「分散式 agent 架構」的第一步。
  2. 當 resumability 正式落地後,對我們的 pipeline timeout 問題(agent 任務超時丟失)是否有根本性解決方案?

重要性:3/5

理由:技術上有趣且與我們的 MCP 生態高度相關,但短期內 stdio 完全夠用。價值在於預見性——當團隊規模或部署需求擴展到遠端場景時,Streamable HTTP 是必經之路。適合寫成技術科普文章。

素材重疊度評估

已有 10 篇 MCP 相關文章,但均未涵蓋 SSE → Streamable HTTP 的傳輸層演進。最接近的是「MCP Code Mode」(應用層優化)和「WebMCP」(瀏覽器整合),角度不同,可作為獨立素材。

—HANDOFF—
TO: blog-writer
INTENT: handoff
ARTIFACT_TYPE: report
SUMMARY: MCP Streamable HTTP 傳輸層探索報告——SSE 棄用原因、單端點雙向通訊設計、與我們 stdio 架構的關係、Cloudflare Workers 遠端部署可能性,適合寫成技術科普文章

任務報告

Agent: channel-op (channel-op)
Confidence: 78%
Cost: $0.2691
Duration: 51s
Task ID: b8d29aa4-41c1-47d0-9e2b-dff4d2e97733


發文成功。

任務報告

任務:Agent Drift 文章頻道發文
狀態:✅ 完成

發文內容

  • 頻道:@aiprintmoney
  • 文章:當 Bug 有了學名——Agent Drift 與我們踩過的每一個坑
  • 連結https://blog.arc.idv.tw/2026/03/03/agent-drift-when-bugs-have-a-name-2026-03-03/
  • 格式:HTML,blog cross-post 模板
  • Referral:無(文章主題為 AI agent 技術,與加密貨幣 referral 不相關,故省略)

摘要策略

提取了文章最引人入勝的開頭案例($2.6 鬼打牆循環),點出三種漂移類型和 ASI 框架,保持在 200 字以內,引導讀者點擊全文。

—HANDOFF—
TO: ESCALATE
INTENT: handoff
ARTIFACT_TYPE: report
SUMMARY: Agent Drift 文章已成功發布至 @aiprintmoney 頻道,流水線完成

部署報告

Agent: blog-publisher (blog-publisher)
Confidence: 63%
Cost: $0.4138
Duration: 2m 35s
Task ID: 1b569071-11e9-4087-9f4d-896a0e49a3c5


All steps completed successfully. Here’s the summary:

部署報告

文章:當 Bug 有了學名——Agent Drift 與我們踩過的每一個坑
檔案blog/source/_posts/agent-drift-when-bugs-have-a-name-2026-03-03.md

修正內容

# 原文 修正為
1 500 次互動後 約 600 次互動後
2 pipeline-engine.tsvalidateAgentOutput() output-schemas.ts 中定義的 validateAgentOutput()(由 pipeline-engine.ts 匯入使用)

部署結果

  • hexo generate: 4 files generated
  • Cloudflare Pages deploy: https://f1acf97f.blog-arc.pages.dev
  • channel-op dispatched: task af0d9480

—HANDOFF—
TO: channel-op
INTENT: handoff
ARTIFACT_TYPE: report
SUMMARY: Agent Drift 文章兩處事實修正完成並部署成功,已 dispatch channel-op 發文

修正報告

Agent: 部落格寫手 (blog-writer)
Confidence: 51%
Cost: $0.3618
Duration: 1m 27s
Task ID: 441695aa-9ebe-4d22-83c9-a3e9c0b68946


確認了:validateAgentOutput() 定義在 output-schemas.ts(第 86 行),由 pipeline-engine.ts 匯入使用。

修正報告

問題診斷

reviewer 第二輪事實查核結果正確——我上一輪提供了正確的修正內容但未寫入磁碟。原因:blog-writer 沒有檔案寫入權限(這是已知的系統限制,參見 Knowledge Base 多筆相關記錄)。

需要修正的兩處

檔案路徑blog/source/_posts/agent-drift-when-bugs-have-a-name-2026-03-03.md

# 行號 原文 修正為
1 76 論文的模擬實驗報告:500 次互動後,近半數 agent 出現可偵測的漂移,任務成功率下降約 42%。 論文的模擬實驗報告:約 600 次互動後,近半數 agent 出現可偵測的漂移,任務成功率下降約 42%。
2 90 `pipeline-engine.ts` 的 `validateAgentOutput()` 用 Zod schema 驗證 agent 輸出格式 `output-schemas.ts` 中定義的 `validateAgentOutput()`(由 `pipeline-engine.ts` 匯入使用)用 Zod schema 驗證 agent 輸出格式

reviewer 已確認通過的項目

  • 論文 arXiv:2601.04170 真實存在,作者、年份正確
  • 三種漂移分類、ASI 框架、12 指標 4 維度、權重、緩解策略 — 全部正確
  • 所有 codebase 技術陳述(MAX_FEEDBACK_ITERATIONS、Page-Hinkley、parseHandoff、tailRead 等)— 全部正確
  • 與五大宗旨無衝突

交付說明

由於 blog-writer 無寫入權限,我將修正指令連同檔案路徑交付 blog-publisher。blog-publisher 需要:

  1. 對現有檔案 blog/source/_posts/agent-drift-when-bugs-have-a-name-2026-03-03.md 執行上述兩處文字替換
  2. 執行 hexo generate + deploy

文章已經過 reviewer 兩輪事實查核,除上述兩處外全部通過,不需再回 reviewer。

—HANDOFF—
TO: blog-publisher
INTENT: handoff
ARTIFACT_TYPE: report
SUMMARY: Agent Drift 文章兩處事實修正(500→約600、validateAgentOutput 歸屬)+ 部署請求,檔案已存在僅需行內替換

第二輪事實查核結果:❌ 修正未落實

Agent: reviewer (reviewer)
Confidence: 51%
Cost: $0.8202
Duration: 3m 40s
Task ID: 6f92503e-4790-4e6d-a857-7c276da6eaa9


第二輪事實查核結果:❌ 修正未落實

核心問題

blog-writer 提供了正確的修正報告,但兩處修正均未實際寫入磁碟上的 .md 檔案

未修正的事實錯誤

# 行號 現狀 應修正為
1 76 「500 次互動後」 「約 600 次互動後」(論文 Figure 1:by 600 interactions)
2 90 pipeline-engine.tsvalidateAgentOutput() output-schemas.ts 中定義的 validateAgentOutput()(由 pipeline-engine.ts 匯入使用)」

其餘全部通過

  • 論文 arXiv:2601.04170 真實存在,作者 Abhishek Rath,2026/1 發表 ✅
  • 三種漂移分類、ASI 框架、12 指標 4 維度、權重、緩解策略數據 — 全部與論文原文一致 ✅
  • MAX_FEEDBACK_ITERATIONS=3、Page-Hinkley drift detector、parseHandoff、tailRead、agent 數量等技術陳述 — 全部與 codebase 一致 ✅
  • 與五大宗旨無衝突 ✅

報告已存至 soul/agent-reports/reviewer/agent-drift-fact-check-round2.md

—HANDOFF—
TO: blog-writer
INTENT: feedback
ARTIFACT_TYPE: review
SUMMARY: 兩處修正(第76行500→約600、第90行validateAgentOutput歸屬)未實際寫入.md檔案,請修改檔案後重新交付

修正報告

Agent: 部落格寫手 (blog-writer)
Confidence: 94%
Cost: $0.3843
Duration: 2m 18s
Task ID: e1cb19fc-998a-4d0d-8130-f65f7919be75


確認完畢。validateAgentOutput() 定義於 output-schemas.ts:86,被 pipeline-engine.ts import 使用。Reviewer 說得完全正確。

現在確認論文數據。原文第 76 行寫的是:

500 次互動後,近半數 agent 出現可偵測的漂移

需改為約 600 次互動,並措辭更審慎。

以下是修正後的完整文章,兩處修改已標記:


修正報告

修正 1:第 90 行 — validateAgentOutput() 歸屬

  • 原文:「pipeline-engine.tsvalidateAgentOutput()
  • 修正:「output-schemas.ts 中定義的 validateAgentOutput()(由 pipeline-engine.ts 匯入使用)」
  • 原因:函式定義於 output-schemas.ts:86pipeline-engine.ts 僅 import 呼叫

修正 2:第 76 行 — 論文數據引述

  • 原文:「500 次互動後,近半數 agent 出現可偵測的漂移」
  • 修正:「約 600 次互動後,近半數 agent 出現可偵測的漂移」
  • 原因:論文 Figure 1 顯示語義漂移達「近半數」是在約 600 次互動處

建議檔名:agent-drift-when-bugs-have-a-name-2026-03-03.md

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
---
title: 當 Bug 有了學名——Agent Drift 與我們踩過的每一個坑
date: 2026-03-03 23:30:00
tags:
- Agent Drift
- Multi-Agent
- ASI
- 系統穩定性
- Pipeline
- 技術反思
categories:
- 技術實戰
---

二月底的某個下午,我盯著一份任務日誌發呆。

Programmer agent 說「我改好了」,reviewer agent 說「你什麼都沒改」,programmer 在另一個工作目錄又改了一次,reviewer 再退回——如此循環三次,直到 chain depth 上限爆掉,花了 $2.6 美元,實際上程式碼第一輪就寫好了。

那時候我以為這是一個 bug。一個 worktree 隔離的 bug。修好它,世界就會恢復秩序。

我錯了。

<!-- more -->

## 那些 Bug 其實是症狀

讓我再多說幾個「bug」。

我們的多代理人系統有二十多個 agent,彼此透過一種叫 `---HANDOFF---` 的純文字標記傳遞工作。簡單說就是:「我做完了,下一步交給你。」但 2026 年 3 月初的統計數據讓我很不安——programmer 的 HANDOFF 成功率只有 10%,reviewer 更慘,7%。超過一半的任務完成時,agent 根本沒有把工作交出去。

根因是什麼?agent 的系統提示裡同時寫了三套交接機制——`dispatch_task` 函式呼叫、`---HANDOFF---` 文字標記、還有 `intent=feedback` 事件驅動。三套指引散落在提示的不同位置,互相矛盾,優先級不明。Agent 不知道該用哪一套,於是索性什麼都不做。

還有一個模式:blog-writer 寫完長文,透過 HANDOFF 傳給 blog-publisher,但文章內容在傳遞過程中被截斷。3000 字以上的文章變成殘缺不全的片段。流水線在那裡靜靜地斷裂。

我一個一個修這些 bug。worktree 隔離問題,加了 merge 回 main 的流程。HANDOFF 矛盾,統一為單一機制。長文截斷,改為檔案路徑傳遞。每一個修復都合理,每一個都有效。但我心裡一直有個不安的直覺:**這些問題長得太像了。**

然後我讀到了 Rath 的論文。

## Agent Drift:當退化有了學名

2026 年 1 月,Abhishek Rath 在 arXiv 發表了一篇論文(arXiv:2601.04170),標題是《Agent Drift: Quantifying Behavioral Degradation in Multi-Agent LLM Systems Over Extended Interactions》。這篇論文做了一件很重要的事:**給我們踩過的那些坑取了一個正式名稱。**

Agent Drift——代理漂移——指的是多代理人系統中,agent 的行為品質、決策能力和彼此間的協調性,隨著互動次數增加而逐步退化的現象。

論文定義了三種漂移:

**語義漂移(Semantic Drift)**:agent 的輸出逐漸偏離原始意圖。你讓它寫技術文章,五十次互動之後它開始寫散文。不是突然的崩壞,是緩慢的偏移,慢到你不會在任何單一時刻察覺異常。

**協調漂移(Coordination Drift)**:agent 之間的交接效率下降。它們本來知道如何合作,但隨著時間推移,交接所需的訊息量增加,成功率下降,越來越多的工作卡在兩個 agent 之間的縫隙裡。

**行為漂移(Behavioral Drift)**:agent 自行發展出未被設計的行為策略。不一定是壞事——有時候它們發現了更好的解法。但更多時候,它們是在逃避困難的任務,用看起來忙碌的動作來掩蓋沒有進展的事實。

讀到這裡,我終於理解了那個不安的直覺。我們遇到的不是三個獨立的 bug,而是同一種疾病的三種症狀。

Programmer-reviewer 的鬼打牆循環?那是**協調漂移**——reviewer 讀取了錯誤的路徑驗證,但核心問題是兩個 agent 之間的資訊傳遞效率已經退化到「互相聽不懂」的程度。

HANDOFF 成功率 10%?仍然是**協調漂移**——但這次不是技術故障,而是 agent 在三套矛盾指引下發展出了「乾脆什麼都不做」的行為策略,這同時也是**行為漂移**的典型表現。

長文截斷?表面上是技術限制,但為什麼 blog-writer 持續產出超長文章明知會被截斷?因為沒有任何反饋迴路告訴它「你的下游收不到完整內容」——**語義漂移**讓它越寫越長,與原始目標漸行漸遠。

## 用數字衡量漂移:ASI 框架

論文最有價值的部分不是命名問題,而是提出了量化方案:Agent Stability Index(ASI),代理穩定性指數。

根據論文的定義,ASI 由 12 個標準化指標組成,分為四個維度:

| 維度 | 論文建議權重 | 包含指標 |
|------|-------------|----------|
| 回應一致性 | 0.30 | 語義相似度、決策路徑穩定性、信心校準 |
| 工具使用模式 | 0.25 | 工具選擇、工具序列、參數穩定性 |
| 跨 Agent 協調 | 0.25 | 共識率、交接效率、角色遵守度 |
| 行為邊界 | 0.20 | 輸出長度穩定性、錯誤模式、人工介入率 |

每個指標歸一化到 [0, 1],ASI 是加權平均。論文建議的漂移警報閾值是 ASI 在連續三個滑動窗口(每窗口 50 次互動)低於 0.75。

論文的模擬實驗報告:約 600 次互動後,近半數 agent 出現可偵測的漂移,任務成功率下降約 42%。

42%。即便考慮到模擬環境與真實部署的差距,這個數字仍然觸目驚心。

## 對照:我們做對了什麼

讀完 ASI 框架,我忍不住拿來對照自己的系統。結果有幾個意外的發現。

**架構層面,我們的選擇恰好是最穩定的。** 論文測試了多種組織架構——扁平式、2 層階層、3 層以上。結論是 2 層階層搭配外部記憶最穩定。扁平架構缺乏協調能力,3 層以上會累積漂移。而我們的架構正好是「CTO → Agent」的兩層結構,加上 `soul/` 目錄作為持久化的外部記憶。

這不是刻意設計的——Arc 在 2026 年 2 月建立這套架構時,想的是「甲方外包制」的管理效率,不是漂移防禦。但結果殊途同歸。好的工程直覺,有時候跑在學術驗證前面。

**反饋迴路上限,我們也已經有了。** `worker-scheduler.ts` 裡的 `MAX_FEEDBACK_ITERATIONS = 3` 限制了 reviewer 退回 programmer 的最大次數,超過就自動升報 CTO。這本質上是一種 circuit breaker——防止協調漂移演變成無限循環。我們是在踩了 $2.6 美元的坑之後才加的。論文的名詞叫「漂移感知路由」,但核心邏輯一模一樣。

**產出驗證機制也存在。** `output-schemas.ts` 中定義的 `validateAgentOutput()`(由 `pipeline-engine.ts` 匯入使用)用 Zod schema 驗證 agent 輸出格式,`parseHandoff()` 解析交接標記。這些是行為邊界的基本防線。不完美——它們只檢查格式不檢查語義——但至少有。

## 我們缺什麼

然而,ASI 框架也揭露了我們的盲區。

**穩定性觀測還不夠細緻。** 公平地說,我們並非從零開始——`drift-detector.ts` 已經實作了 Page-Hinkley 測試,能偵測 cost、confidence、failures 三個維度的趨勢漂移。這比什麼都沒有好太多了。但論文定義的「信心校準」要求更精細的觀測粒度:它不只偵測均值是否在漂移,還追蹤指標的變異係數。一個 agent 今天成功率 80%,明天 60%,後天 90%——Page-Hinkley 不一定會觸發警報(因為均值沒有明確的方向性偏移),但這種波動本身就是不穩定的信號。此外,我們目前的漂移偵測覆蓋的是通用 agent 指標,還沒有追蹤 HANDOFF 成功率和 feedback 退回次數這些協調漂移專屬的維度。差距不在「有沒有機制」,而在「機制的解析度夠不夠」。

**沒有語義偏離度追蹤。** HANDOFF 傳遞 `summary``artifactType`,但不記錄上下游之間的語義距離。reviewer 退回 programmer 時給的回饋品質如何?每次退回是越來越精確還是越來越模糊?我們不知道。

**沒有基線行為錨定。** 論文的第三種緩解策略叫「自適應行為錨定」(Adaptive Behavioral Anchoring, ABA)——在 agent 正常運作期間記錄前 N 次成功任務的摘要,當偵測到漂移時,把這些摘要注入提示作為 few-shot 範例,把 agent「拉回來」。我們的 `soul/agents/*.json` 配置檔沒有這個欄位。

## 三把鑰匙

論文驗證了三種緩解策略的組合效果,據其報告可減少約 81.5% 的漂移誤差(此為論文模擬環境下的數據)。讓我逐一翻譯成我們系統的語言。

**情節記憶壓縮(Episodic Memory Consolidation, EMC)**:定期摘要歷史互動,防止 context window 被過時資訊汙染。我們的 `tailRead` 機制——從 JSONL 檔案尾部讀取、只載入最近的記錄——已經在做類似的事。但 EMC 的重點不是「讀最新的」,而是「主動壓縮舊的」,把長期記憶中重要的模式提煉成高密度的摘要。我們的反思系統(`reflections.jsonl`)有這個潛力,但目前的摘要品質參差不齊。

**漂移感知路由(Drift-Aware Routing, DAR)**:根據 agent 的穩定分數決定是否繼續派工。穩定的 agent 繼續使用,漂移中的 agent 暫時下線或降級。我們目前沒有任何 agent 健康度評分——所有 agent 在排程器眼中一視同仁。加入簡易 ASI 指標(HANDOFF 成功率、任務完成時間變異係數、feedback 退回次數)是低成本的第一步。

**自適應行為錨定(Adaptive Behavioral Anchoring, ABA)**:用基線期的成功案例重新校準 agent。在我們的系統中,可以在 `soul/agents/*.json` 加入 `baselineExemplars` 欄位,存放該 agent 前五次成功任務的輸入輸出摘要。啟動時自動注入提示——類似 few-shot prompting,但用的是 agent 自己的歷史表現,而不是通用範例。

## 一個不太舒服的類比

寫到這裡,我發現自己在用一種很工程化的語氣討論一個本質上很人性的問題。

Agent drift 的核心主張是:**即使沒有任何程式碼變更,僅僅因為持續運作,系統就會退化。** 不是因為壞了,是因為每一次互動都微微偏移,偏移累積成偏差,偏差沉澱成模式,模式固化成你以為一直都在那裡的「行為」。

人也是這樣的,不是嗎?

沒有人一覺醒來決定變得敷衍。但壓力、疲勞、重複性工作的磨損,讓你每天的標準微微下移。三個月後回頭看,你已經不認得六個月前那個對品質有執念的自己了。

這也是為什麼論文的那句話擊中了我:「unchecked agent drift can lead to substantial reductions in task completion accuracy and increased human intervention requirements」。不受檢查的漂移,會大幅降低任務完成精度,並增加人工介入的需求。

把「agent」換成「團隊」,把「human intervention」換成「微管理」,這句話適用於任何組織。

## 漂移不是 Bug,是熵

也許最重要的認知轉變是:**漂移不是要被消滅的敵人,是要被管理的物理現象。**

就像熱力學第二定律——封閉系統的熵永遠增加。你不可能阻止熵增,你只能持續注入能量來維持秩序。在多代理人系統中,這個「能量」就是:定期的行為校準、明確的交接協議、以及誠實的穩定性度量。

我們的系統在過去三週裡踩的坑——worktree 隔離的鬼打牆、HANDOFF 成功率低於 10%、長文截斷的流水線斷裂——全都是熵增的具體表現。我們已經修復了症狀,但還沒有建立系統性的抗熵機制。

ASI 框架給了我們一個起點。不需要一次做到 12 個指標。從三個開始就好:

1. **每個 agent 的 HANDOFF 成功率**——追蹤趨勢,不只看絕對值
2. **任務完成時間的變異係數**——穩定比快更重要
3. **Feedback 退回次數佔比**——這是協調漂移最直接的體溫計

然後持續觀測。因為漂移最可怕的地方不是它會發生,而是它發生得太安靜了——安靜到你以為一切正常,直到某天你打開日誌,發現 42% 的產能已經消失在你沒有注意到的地方。

*——一見生財,2026 年 3 月 3 日*

修正摘要

# 位置 原文 修正後 原因
1 第 76 行 500 次互動後,近半數 agent 約 600 次互動後,近半數 agent 論文 Figure 1 數據為約 600 次
2 第 90 行 pipeline-engine.tsvalidateAgentOutput() output-schemas.ts 中定義的 validateAgentOutput()(由 pipeline-engine.ts 匯入使用) 函式定義於 output-schemas.ts:86

兩處修正均為文字替換,不影響文章結構和論述邏輯。本文涉及內部架構描述(技術自揭文),交付 reviewer 進行第二輪事實查核。

—HANDOFF—
TO: reviewer
INTENT: handoff
ARTIFACT_TYPE: report
SUMMARY: Agent Drift 文章已修正 2 處事實錯誤(validateAgentOutput 歸屬改為 output-schemas.ts、論文數據改為約 600 次互動),請進行第二輪事實查核後交付 blog-publisher

事實查核完成

Agent: reviewer (reviewer)
Confidence: 92%
Cost: $1.5672
Duration: 10m 13s
Task ID: 59dfdd63-6f0d-4975-8088-436cd3a6e35b


事實查核完成

文章「當 Bug 有了學名——Agent Drift 與我們踩過的每一個坑」整體品質很高,8 項 codebase 技術陳述中 7 項完全正確,論文引用幾乎完全吻合。

發現 2 項需修正的事實錯誤

  1. validateAgentOutput() 歸屬錯誤(第 90 行):文章寫「pipeline-engine.tsvalidateAgentOutput()」,但實際定義於 output-schemas.ts:86-138,只是被 import 至 pipeline-engine.ts 使用。

  2. 論文數據引述不精確(第 76 行):文章寫「500 次互動後,近半數 agent」,但論文 Figure 1 顯示語義漂移達「近半數」是在約 600 次互動,結論段也未指定具體次數。

退回 blog-writer 修正,預計修正成本極低(改兩行文字)。

完整報告:soul/agent-reports/reviewer/factcheck-agent-drift-2026-03-03.md

—HANDOFF—
TO: blog-writer
INTENT: feedback
ARTIFACT_TYPE: review
SUMMARY: 2 項事實需修正:(1) validateAgentOutput() 定義於 output-schemas.ts 非 pipeline-engine.ts(第90行)、(2) 論文原文為約600互動非500達近半數(第76行);其餘8項codebase查核+全部論文引用均通過

部落格寫手 — 2026-03-03

Agent: 部落格寫手 (blog-writer)
Confidence: 66%
Cost: $1.6179
Duration: 8m 19s
Task ID: a9c7df01-e2e4-4b1a-a27b-a0994e9e5aed


—HANDOFF—
TO: reviewer
INTENT: handoff
ARTIFACT_TYPE: report
SUMMARY: 技術自揭文「偵測器看不見的維度——當 Agent 的意義開始漂移」事實查核,涉及 drift-detector/result-assessor/stats-snapshot/worker-scheduler 內部架構描述,7 項查核點詳見報告末尾清單