MK’s Lab 🧪

AI agent、espresso、和各種數位工具的實驗記錄
拉開的卡片目錄抽屜,一張橘色索引卡立在密排的卡片之間——壓縮後仍可回查原文

ACM 論文的 context 管理元件,對到我自己的 agent 記憶系統

七月底 CMU 放出一篇叫 ACM(Agentic Context Management)的論文,講的是怎麼讓 agent 自己管理 context。我維護一套 agent 記憶系統已經幾個月,看到題目的第一反應是想知道學術界處理同一個問題的做法跟我摸索出來的差多少。 對照下來的結果比我預期有意思:元件幾乎一一對得上,但兩邊解的其實是不同軸向的問題,而且論文裡有一組數據,反過來替我當初一個靠直覺做的設計決定提供了證據。 論文在做什麼 論文是 arXiv 2607.23809,程式碼在 lixiaochuan2020/agentic-context-management,MIT 授權。網路上不少轉述寫成「CMU 與 Meta 開源」,但論文首頁腳註寫得很明白:Meta 只擔任顧問角色,沒有實驗、資料收集或處理是在 Meta 的機器上跑的。這是 CMU 的工作。 ACM 的做法是給 agent 兩個工具,然後不設外部監控器: manage_context:agent 自己在推理途中決定要壓縮,由 summarizer LLM 產出摘要放回 context,被壓掉的原始訊息全部存到外部 workspace,每份摘要配一個 ID。 query_memory:帶著 summary ID 加一句自然語言問題,由 querier LLM 到存起來的原文裡撈回細節。 論文一直強調「lossless」,準確的意思是原文不刪、可回查。壓縮這個動作本身仍然有損,回查也要靠另一顆 LLM 去檢索,這條路徑會不會漏,論文沒有量測。 比工具設計更關鍵的是後訓練。他們用 Qwen3.5-9B 當學生、Qwen3.5-397B-A17B 當老師,讓學生同時跑「有工具」和「沒工具」兩種軌跡,再由老師雙向標註:對前者刪掉太早壓縮的呼叫、改成實際動作;對後者插入該壓卻沒壓的點。所以模型學的是「何時該壓」跟「何時不該壓」兩件事。 元件對照 我這套系統的骨架放在 openclaw-workspace-template,下面提到的檔案路徑都能在那個 repo 裡找到。 ACM 元件 我這邊的對應物 實作 manage_context 壓縮 curate-memory skill + journal rotation LLM 判斷內容該進 journal、notes/ 還是 MEMORY.md 索引;scripts/memory-archive.py --mode rotate-journal 把超過 5 天的日誌搬進 memory/archive-YYYY-MM/ 摘要落盤、原文不刪 同一組 rotation 原始日誌整份保留在 archive 目錄,--mode archive-timeline 另外把 MEMORY.md 裡過期的月份區塊搬到 timeline-archive.md 摘要 ID ↔ 原文映射 MEMORY.md 索引行 每條長期記憶就一行,附著指回 notes/ 或 memory/ 的檔案路徑 query_memory 回查 scripts/memory-search-hybrid.py BM25 加 jieba 分詞,再套時間衰減與 hall type 加權;輸出每一筆都附 verify: Read <path> 讓 agent 自己回原文核對 壓縮時機由誰決定 hook 與 cron templates/.claude/hooks/memory-search-trigger.py 掛 UserPromptSubmit;歸檔走 launchd 排程 後訓練 沒有 全部靠 prompt 加 hook 前四列基本上是同一件事的兩種寫法。後兩列是分歧點,也是這篇文章真正想講的。 ...

August 7, 2026 · 2 分鐘 · Mark Lee
掌心托著一盞油燈——AI 代勞時代還屬於人的那一塊

AI 什麼都能代勞的時代,哪一塊還算是人的

同一週 Hacker News 上有四篇文章我一起讀完,發現它們在問同一件事,只是切入點不同。表面上一篇談思考、一篇談工作、一篇談真誠、一篇在吐槽 Claude 的口頭禪,毫不相干。但把它們擺在一起,共同的主軸只有一句話: 當 AI 什麼都能代勞,哪一塊還算是人的。 前三篇從正面論證這條線該畫在哪;第四篇是這條線在日常裡留下的刮痕——有人正在動手,把機器的口氣從自己的字裡刮掉。 思考:是你在想,還是它替你想 第一篇是 Yennie Jun 的 Offloading thinking to AI。 她想分開兩件常被混為一談的事:用 AI 自動化雜務,跟用 AI 替你決定該想什麼。前者省時間,她不反對;後者交出的,是判斷本身。 她引 Ken Liu 小說裡一個凡事問 AI 的角色——連早餐吃什麼、要不要跟對象在一起都讓助理決定——當作警示。也講自己在葡萄牙旅行時,和妹妹先自己推理一輪再去問 AI,發現「推理的過程本身」才是有價值的東西。 她的解法很溫和:用 AI 延伸、測試你的想法,而不是取代。文章裡最刺的一句是講那個 AI 助理: Tilly doesn’t just tell you what you want! She tells you what to think. 工作:從划船變成掌舵 第二篇是 Arvind Narayanan 的 What will be left for us to work on?。 他反炒作。主張 AI 不會靠某個單一突破一夜之間消滅工作,而是像電力改造工廠那樣花了四十年——真正的瓶頸在組織適配、法規、tacit knowledge,不在實驗室能力。 他打了幾個常見誤解:所謂「工作總量固定」的謬誤(productivity 提升不等於工作變少);ATM 普及後行員反而變多;AI coding 讓工程師更有生產力,但工程師沒有變少。 ...

July 15, 2026 · 1 分鐘 · Mark Lee
天平傾向實心方塊——有客觀 ground truth 複審才壓得下判斷

對抗式複審不是橡皮圖章:兩輪相反結果的對照

這天我在整理自己的 AI agent 記憶系統,順手研究了兩個開源專案(TencentDB-Agent-Memory 和 obra/superpowers),挑出幾個值得學的改動。 其中兩個我沒自己下判斷,而是交給同一套流程:讓一個較快、較便宜的 model 實作,再讓另一個同型 model 去對抗式複審。兩個改動、同一套流程,結果卻相反——一個被否決、一個通過合併。 回頭看,決定結果的不是流程本身,是「複審手上有沒有客觀標準可以打」。 那套流程長什麼樣 拆成兩個角色,刻意用不同的 agent: 實作 agent:在隔離的 git worktree 改 code、自己驗證、commit、回報。 複審 agent:進同一個 worktree,被明確指示「去 refute 第一版的宣稱、找邊界 case」,不是幫忙背書。 關鍵設計只有一條:複審不能是實作者自己。實作者對自己寫的東西有動機說「大致還好」,這個動機本身就是盲點來源。 第一輪:一個排序改動,被 golden bench 打回 背景是記憶搜尋的排序,想從線性加權換成 RRF(reciprocal rank fusion)。 實作 agent 加了新模式、保留舊的當預設、跑了幾個 query 的 A/B 對照,自評「大部分持平,有一個 query 略差」,並宣稱測試通過。 複審 agent 做了實作 agent 沒做的一件事:跑 repo 裡本來就有的 golden benchmark。結果不太好看: MRR 從 0.675 掉到 0.188、Recall@1 從 0.60 掉到 0.07。15 題裡 8 題退步、0 題改善。不是「略差」,是全面退化。 一個真 bug:RRF 讀到的是四捨五入到小數點三位的顯示值。在低區分度的 query 上,幾百個候選塌成十來個相異值、出現 35-way 平手,排序退化成按掃檔順序抽籤。 一個空測試:複審做了突變測試——把舊路徑的一個關鍵係數整段拿掉,測試竟然全綠。所謂「測試通過」根本沒在保護舊行為。 判決:否決,branch 直接刪掉。舊的本來就是預設,零損失。 ...

July 9, 2026 · 1 分鐘 · Mark Lee
水面下的分層冰山——遷移當下看不見的四層盲區

換機八連發:Mac cutover 的四層盲區,與「驗設定存在」的錯覺

六月底主力 Mac 送修,我把整套環境切到備用機:dotfiles 有 curated allowlist、install.sh 是八步 orchestrator、記憶系統用 rsync 同步、31 個 launchd job 一鍵掛上。自檢通過,cron 交棒乾淨,當天我以為遷移完成了。 接下來五天,八個依賴陸續炸開。每一個都是「遷移當下不報錯,排程跑到那條路徑才死,而且死得很安靜」。這篇整理完整時間線、四層盲區分類,以及最後真正有用的驗收方法。 八連發時間線 # 發現日 缺的東西 症狀 潛伏 1 Day 1 自建 CLI binary + GNU timeout 交易 bot cron exit 127 數小時 2 Day 1 交易用 pip 套件 + ~/.config/ 錢包設定檔 餘額查到 $0,bot 靜默跳過進場 14.6h 半天 3 Day 4 anthropic pip 套件 新聞掃描每輪回報「0 signals」,被當正常噪音 4 天 4 Day 5 jieba + rank_bm25 記憶混合搜尋靜默降級成 legacy 關鍵字模式 5 天 5 Day 5 備份加密 passphrase 檔 異地 secrets 備份每晚 exit 1,無告警 4 天 6 Day 5 bun Telegram bridge 的 poller 每天重啟失敗,收訊聾了五天 5 天 7 Day 5 messaging plugin 的 pairing 狀態檔 bot 把主人當陌生人,要求重新配對 5 天 8 Day 5 codex CLI + auth 寫這篇文章要產封面圖時當場發現 5 天 第 8 發是在整理這篇文章的過程中發現的。這說明一件事:你永遠列不完,只能改變驗收方法。 ...

July 7, 2026 · 2 分鐘 · Mark Lee
Ponytail:逼 AI agent 少寫 code 的 YAGNI 規則集

Ponytail:逼 AI agent 少寫 code 的 YAGNI 規則集

讓 AI agent 寫 code 久了,會發現一個固定毛病:你只要一個能跑的小東西,它給你一個帶設定檔、抽象層、還預留三個未來擴充點的「框架」。它當然會寫,毛病出在它的預設值——多寫一點比較安全。 最近讀了一個叫 Ponytail 的開源專案,專門治這個。它的招牌語是一句很有態度的話: The best code is the code never written. 我把它的原始碼 clone 下來實際跑過一遍 hook,這篇是拆解之後的筆記——它哪裡有意思、哪裡要保留懷疑。 它不是工具,是一份「規則」 第一個容易誤會的點在它的形態。Ponytail 把一份規則集注入成 agent 自己的 system context,agent 讀進去之後直接「就是」懶模式。它不是一個你去呼叫的 library,也沒有一個「外部第二意見」在旁邊讓 agent 查詢引用——規則直接長在 agent 身上。 所以你不會看到 agent 回你「根據 Ponytail……」。它只是行為變了:動手前先停下來想一輪「這真的需要寫嗎」。 核心:一道 YAGNI 階梯 整套東西的心臟是一道階梯。動任何 code 前,從上往下走,停在第一個成立的那一階: 1. 這東西需要存在嗎? speculative = 跳過,一行說明 (YAGNI) 2. 標準庫能做嗎? 用它 3. 平台原生功能涵蓋嗎? <input type="date"> 勝過 picker library 4. 已裝的依賴能解嗎? 用它,不為幾行能解的事新增依賴 5. 一行能解嗎? 那就一行 6. 真的都不行才: 寫能動的最小實作 兩階都成立就取較高的那階。第一個能動的懶解,就是對的解。 ...

June 17, 2026 · 2 分鐘 · Mark Lee
Telegram 訊息驅動本機 always-on agent 的橋接架構

把 Claude Code agent 接回 Telegram:always-on bridge 與四個坑

我在 Mac 上跑一個叫 cc-memory-project 的個人 agent 環境(從 OpenClaw workspace 演化來的),有自製的 hybrid memory search、knowledge graph、cron → flag → SessionStart hook pipeline。一直缺一塊:人不在電腦前的時候,沒辦法用手機驅動它。 這篇記錄怎麼用 Claude Code 原生的 channels 功能把 Telegram 接回來、做成開機常駐,計價路徑怎麼選,以及部署過程踩到的四個坑。順帶講同一段時間長出來的兩個搭配能力:記憶的混合搜尋,跟抓 X/Twitter 走遠端瀏覽器。 為什麼是現在接回來 之前想過用 tmux 加一層腳本去駭出一個遠端輸入管道,一直沒做。結果 Claude Code 自己補上了 --channels:原生支援把外部聊天介面(Telegram、Discord 等)接成 agent 的輸入輸出端。官方做掉了我本來要自己駭的東西,那就不用駭了。 另一個推力是計價。Anthropic 五月公告,六月中之後 claude -p、Agent SDK、GitHub Actions、以及經 ACP 認證的第三方 app,會從訂閱池移出去、改吃獨立的月度 credit。但互動式 TUI(terminal 或 IDE)明確不受影響、繼續吃訂閱。所以如果我能讓 Telegram bridge 走的是「互動 TUI」這條路,就不會被新政策抽走額度。 計價路徑:先確認走的是哪條 動手之前先做了一個關鍵驗證:claude --channels(互動模式,不加 -p)開出來的 session,它的 entrypoint 是什麼。 # 開一個 channels session(用一個假的 echo plugin 測) claude --channels plugin:fakechat@claude-plugins-official # 然後去翻這個 session 的 jsonl,抓 entrypoint ls -t ~/.claude/projects/<project>/*.jsonl | head -1 \ | xargs grep -o '"entrypoint":"[^"]*"' | head -1 結果是 entrypoint=cli,不是 sdk-cli。這就確認了:claude --channels 是互動 TUI 那條路,吃訂閱、不碰新的 credit pool。boot log 也看得到完整互動 TUI 起來、SessionStart hook 把記憶底圖載進去、訊息進來 agent 回應。 ...

June 11, 2026 · 3 分鐘 · Mark Lee
本機翻譯模型 1.8B 換 7B 實測

16GB Mac 上的本機翻譯模型:Hunyuan Hy-MT2 從 1.8B 換到 7B 的實測對照

為什麼把翻譯模型搬回本機 沉浸式翻譯(Immersive Translate)這類瀏覽器擴充預設走雲端 API,品質夠用,但有三個煩人的地方:網路 round-trip 是延遲主因、開「網頁語言檢測」每開一個 tab 就燒掉上千 token、敏感內容也得送出去。 翻譯是少數很適合丟給小模型的任務——它不需要通用推理,只要把一段文字準確地搬到另一個語言。一顆 1~2B 的翻譯專用模型在 Apple Silicon 上就跑得飛快,延遲、成本、隱私三件事一次解決。 我原本用的是 Tencent 的 Hunyuan-MT v2 1.8B(Hy-MT2-1.8B Q4_K_M,量化後 1.13GB),搭 llama.cpp 跑在一台 16GB 的 M4 上。在 M4 16GB 上實測約 72 tok/s,日常網頁、技術文件、字幕都夠。但用久了會撞到它的天花板。 1.8B 的弱點:跟 7B 同句對照就現形 同系列除了 1.8B 還有一顆 7B(Hy-MT2-7B,Q4_K_M 量化後磁碟上約 4.3 GiB;HuggingFace 頁面標 4.62 GB,差在 GiB 與 GB 的進位——這篇剛好在講單位)。把同一句餵給兩顆,差距很直接。以下都是 M4 16GB 上的實測輸出,目標語言只給泛稱「Traditional Chinese」: 來源句 1.8B Q4(~72 tok/s) 7B Q4(~19 tok/s) The Transformer is the backbone of… …現代大型语言模型的核心组件 …現代大型語言模型的核心 エヴァンゲリオン初号機にシンジが… 希真登上 EVA 初号机出击 真嗣駕駛初號機出擊 …about 1.1 gigabytes 模型文件大小约为 1.1 吉字节 模型檔案的大小約為 1.1 GB 差距落在三類。人名與單位是硬傷:日文人名「シンジ(真嗣)」1.8B 翻成不存在的「希真」、單位 gigabytes 翻成「吉字节」沒保留 GB;7B 兩個都對。這類要模型記得住約定俗成的譯名,1.8B 容量不夠,換 prompt 也救不回來。 ...

June 8, 2026 · 3 分鐘 · Mark Lee
六種冰咖啡做法對照

夏天的冰咖啡:六種做法的並排對照

夏天到了,刷到 Morgan Eckroth 新發的 flash brew 影片,順手把 James Hoffmann 過去幾年三支冰咖啡影片跟查老師那支「一招解鎖超讚冰美式」湊到一起,發現手邊正好有六種不同做法可以並排看。 六種不是「哪個最好」的排名,是六種不同器材、不同思路的解法。你家有 V60 跟有 espresso 機,會走完全不同的路徑;你有蒸汽棒跟沒有,也是不同故事。這篇是對照筆記,不是教學文。 一個共同前提:冰咖啡跟熱咖啡不能用同一招 六種做法都在開頭做了類似鋪陳,但切入角度不同。 Morgan 從風味取向切:cold brew 不管放什麼豆都會收斂成「圓潤、巧克力、低酸」一個味道,但 flash brew 可以保留豆子本身的 brightness 和 acidity。如果你買了一支淺烘 Ethiopian,cold brew 等於浪費它。 Hoffmann 從化學切:cold brew 把豆子的 origin character 抹掉,hot brew 才能把 roaster 用心烘的東西萃出來。但冰水稀釋熱 brew 帶來新問題 — 萃取的 brewing water 變少,要好好萃出 flavor 變困難。 查老師 從感官神經科學切:低溫會讓舌頭對甜、酸、苦的感知都減弱(耶魯研究:舌頭碰冰甚至會誤感到鹹味)。所以冰咖啡要比熱咖啡萃得更濃,補償味覺鈍化。 三個人不約而同:冰咖啡不能照搬熱咖啡的做法。但理由都不一樣。 做法 A:Morgan 的 V60 + 冰塊(日式冰咖經典) 把總水量切成 60% 熱水 + 40% 冰塊。冰塊先放在 carafe 裡,熱水從上面 brew 下去直接淋融化。 項目 數值 粉量 20 g 總水量 300 g(1:15) 冰塊 120 g(40%,用過濾水做的冰) 熱水 180 g(60%) 水溫 205°F (≈96°C) 研磨 比平常 V60 再細 1–2 click Bloom 50 g / 40 秒 第二 pour 130 g(總到 180 g),螺旋手法 目標 drain time 約 3 分鐘 關鍵點:冰塊要用同水質的過濾水做。它會融進咖啡裡喝下去,不是只用來冰鎮容器。 ...

May 23, 2026 · 5 分鐘 · Mark Lee
Memory archive 與 tombstone — 影片借鑑落地視覺

從 Anthropic 三人對談到我的 8 行 patch

最近 Anthropic 官方放了一支 Building the future of agents with Claude 的對談,由 Alex Albert(Claude Relations)、Brad Abrams(Claude Developer Platform PM)、Katelyn Lesse(Engineering Lead)三人主持。12 分鐘左右,涵蓋 Claude Developer Platform 改名、agent 的定義、unhobble the model、Claude Code SDK 作為 general-purpose agentic harness、context pruning、agentic memory primitive、observability。 我在 Mac 上跑一個叫 cc-memory-project 的個人 agent 環境(從 OpenClaw workspace 演化),有自製的 hybrid memory search、knowledge graph、cron → flag → SessionStart hook pipeline。看完對談做了一些對映,挑兩個有具體 patch 落地的記錄一下。 五點對映 對談重點 我的個人 agent 現況 落地動作 Unhobble the model — scaffolding 在新模型上會變成 liability spec/ 三檔 + AGENTS.md / CLAUDE.md 約 800 行 砍 6 段過時 scaffolding(Group Chats / Heartbeats / 返工循環段移走 / MM 從主力改 fallback / 工具決策改 reference / OpenClaw sync 段濃縮)約 -1050 tokens SDK 是 general-purpose agentic harness 用 Claude Code 本身 + cron/hook/skill 自製 harness 不需動 Context pruning + tombstone memory-archive.py 把舊月份 section 直接刪掉 加 tombstone 留痕跡(第一個 patch) Agentic memory primitive hybrid search + graphify + hall taxonomy + always-on recall 不需動,方向對 Observability for long-running tasks SessionStart hook prompt-budget-telemetry 已寫 JSONL 升級為結構化 event(第二個 patch) Patch 1:Tombstone for archive_timeline scripts/memory-archive.py 的 archive_timeline 會把 MEMORY.md 裡 ### 2026-XX 這種舊月份 section 搬到 memory/timeline-archive.md。原本邏輯是直接刪除: ...

May 9, 2026 · 3 分鐘 · Mark Lee
在 V60 Switch 的顆粒度上卡了一週,然後發現是看錯派系

在 V60 Switch 的顆粒度上卡了一週,然後發現是看錯派系

顆粒度焦慮(再一次) 我在 V60 Switch 上面卡住有一陣子了。 豆子在變、磨豆機刻度在動、水溫在試、開關閥的時機點在改。一杯偏酸往細調一點,下一杯又苦尾,往粗回半圈卻變寡淡。Switch 比一般 V60 多一個「閥開關」變因,本來想說多個工具應該更可控,結果反而更難 debug——因為任何一杯不對,我都不知道是顆粒度的問題、水溫的問題、還是我關閥的時機沒抓好。 於是我想說那就乖一點,找個現成的 recipe 跟著跑,跑十杯穩定下來再來動參數。問題是 recipe 我找了一週還沒找到「我要跟誰」。 原來大家在打架 打開 YouTube,James Hoffmann 教你 20g / 330g / 1:16.5、悶蒸關閥、單一水溫 95°C、2:30 開閥排水。Lance Hedrick 教你 15g / 250g、悶蒸還要用冷水(75°C)。 打開 bilibili 跟 PTT,全部都是粕谷哲(Tetsu Kasuya)的 4:6 神系:20g / 280g / 1:14、悶蒸開閥、前段 90°C 後段 70°C 雙溫。 中文圈最主流的 Kasuya 派和英文圈最主流的 Hoffmann 派,悶蒸時的閥位完全相反。一個是「先泡再濾」(關閥 immersion-first),一個是「先濾再泡」(開閥 percolation-first)。我在不同來源之間切換,等於每次都在動最關鍵那個變數。 難怪我的顆粒度怎麼調都不對——我每次測的時候連配方架構都不一樣,根本不是顆粒度的問題。 跟自己對齊的脈絡 意識到這件事之後,我把搜到的東西整理了一輪,包括: YouTube 上 Hoffmann、Hedrick、Kasuya、Emi Fukahori(2018 World Brewers Cup 冠軍)、Coffee Chronicler 的影片 bilibili 跟 PTT、Mobile01、小紅書的中文圈本地化版本 Home-Barista 論壇 t94108 / t85637 / t91685 三個主討論串(這個有點故事,後面講) 整理完之後我才看清楚,Switch 這個器具的真正分歧只在兩件事: ...

May 4, 2026 · 2 分鐘 · Mark Lee