iT邦幫忙

2026 iThome 鐵人賽

DAY 26
0
AI Engineering

一天一個 PR,讓我告訴你嵌入式開發的殘酷:如何為 AI Agent 建立可信的工程閉環系列 第 26

Day 26 - Memory 都接上了,養了一個星期,Agent 怎麼還是一樣笨?:Wake-up 不等於 Recall

  • 分享至 

  • xImage
  •  

系列說明 >> 本系列大部分 PR 來自私人或公司專案,部分程式碼、環境設定與實作細節不便公開。

我只能保證文中提到的 PR 與問題皆為真實案例,但會經過必要的匿名化與內容調整。

本系列主要分享問題如何被發現、背後的思考方式,以及解法如何形成,不會深入討論完整實作與部署細節,敬請見諒。

Today’s Change

  • Base Repo: paulshaclaw

  • Change Ref: PR #80-feat(stage2): 記憶讀回-wake-up 注入、hybrid 專案解析與 codex hook 部署 → PR #156-feat(memory): 記憶消費迴路(task-conditioned 檢索 → native Read → read-based 歸因)

  • Issue: D23~D25 已能 Capture、Atomize、整理與搜尋 Knowledge,PR #80 也已在 Claude/Codex/Copilot 的 Session Start 注入非空 Wake-up Brief;但實際接入工作一段時間後,Agent 仍反覆需要人提醒先查過往經驗,舊版 Usage Ledger 的 cited/matched 也持續為空。

  • Root Cause: Wake-up Brief 主要提供 Project MOC 標題與一行摘要,WikiLink 在 Agent CLI 裡不能直接開啟;而 Session Start 發生時,使用者本輪 Task 還沒出現。舊 Usage 邏輯又從回答文字裡的 Slice ID、標題與字串重疊猜測使用,既沒有真正遞送相關 Knowledge,也沒有觀察 Agent 是否實際開檔。

  • Solution: 保留 Session-start Wake-up Brief 作為 Project Orientation;等 User Prompt 到達後,再依當前 Task 產生少量 Knowledge Shortlist,提供標題、摘要與可直接 Read 的 Absolute Path。Agent 實際使用 Read Tool 開啟 Knowledge File 時,由 PostToolUse Hook 留下 Read Attribution。

  • Evidence: PR #80 的 Memory Suite 為 618 passed, 1 skipped, 87 subtests,三家 Hook 手動執行均輸出非空 Brief;PR #156 的 Memory Suite 為 767 passed, 1 skipped,OpenSpec 25/25,並在 Review 後修正 Policy Boundary 與 Symlink Path Attribution Finding。這些證據支持 Project Orientation、Task-conditioned Retrieval 與實際 Read Event 已成立;它不代表 Agent 已採用內容,更不代表 Memory 改善了工程結果。


Memory 接上的第一天,小bu還是老樣子

上一篇,Knowledge 已經有 MOC,也能 Search。

接下來,我把它真的接進 Agent。

PR #80 在 Claude、Codex、Copilot 的 Session Start 都加了一條 Hook:每次新 Session 啟動時,自動把一份簡短的 Project 導覽送進 Agent Context。

這張導覽叫 Wake-up Brief

它會先告訴 Agent:

目前在哪個 Project
這個 Project 有哪些 Memory 入口
需要時可以從哪裡繼續找

三家實機測試都很正常:

brief 非空
exit 0
hooks.log 無 WARN

很好。

Memory 接上了。

第一天真的拿來工作,小bu還是老樣子。

前面明明整理過的 Boundary,換一個 Task 又重新猜;該先看看以前有沒有踩過的地方,還是直接往下做。

我仍然得提醒:

「這個前面處理過,先去查一下 Memory。」

也不是不能理解。

Memory 才剛開始跑,資料可能還不夠多,Agent 也許還沒養熟。

先讓它多吃幾天。


養了一個星期,它還是每次都像第一次來

接下來一個星期,我又開了幾個 Session。

結果差不多。

新的 Task 進來,舊的學費繳了,但經驗還是沒有跟著到場。

該重問的重問。

該重新猜的重新猜。

我一開始還替它找理由:

Capture 還在累積
Slice 還不夠多
MOC 需要時間整理
Agent 還不習慣使用 Memory

老Go看我又把同一段 Boundary 解釋一次。

「一個星期了。」

「你確定它有吃到?」

欸,好問題,你知道,我知道,獨眼龍知道,不代表它也知道!!!

Memory 不一定會讓 Agent 立刻變聰明。

但跑了一個星期,至少不該每隻都像第一次聽到。

普通工程師的直覺告訴我,這裡有鬼。

Target

Hook 每次都準時上班,Usage Ledger 卻乾淨得像沒開張

第一層先查最簡單的:Brief 到底有沒有送進去?

有。

三家 Hook 都有觸發,Brief 也不是空的,Log 沒有 Error。

從部署表面看,Memory 每次都準時上班。

那 Agent 到底有沒有往下用?

我打開 Usage Ledger。它是一份事件帳本,用來記錄系統有沒有觀察到 Memory 使用訊號。

舊版主要看兩個欄位:

  • cited:Agent 回答裡有沒有明確引用 Slice ID 或標題。

  • matched:回答文字是否與某則 Memory 的標題/內容重疊,足以推測它可能用過。

結果連續幾個 Session 都是:

cited: []
matched: []

我第一個懷疑,是 Agent 有看,只是沒有照規定回報。

小bu委曲地說:

「我真的有,那不然把 Citation 提示寫清楚一點。」

如果只是忘記引用,這確實是最便宜的修法。

我正準備把提示加粗,小re先把 Brief 裡的一個連結貼回來。

Target


小re把 WikiLink 貼回來:這個你自己打得開嗎?

Brief 裡的 Memory 入口長得像:

[[slice-name]]

在 Obsidian 裡,這是可以點開筆記的 WikiLink

到了 Claude Code、Codex、Copilot 的 Context 裡,它通常只是一段長得像連結的文字。

小re丟給小bu:

「你自己看看,這個能打開嗎?」

不能。

而當時的 Brief 主要只有 MOC 標題索引與一行摘要,並沒有把 Slice 內文真正送進 Agent Context。

也就是說,我正準備要求 Agent:

引用一份它其實沒有讀到的 Knowledge。

再往下看,cited/matched 也只是從回答文字猜測使用。

Agent 就算真的吸收到某個概念,只要沒有逐字抄出 Slice ID 或標題,Ledger 仍然可能是空的。

很好。

不是 Memory 還沒養熟。

是我們把一張圖書館導覽,當成 Agent 已經拿到書。

Citation Prompt 先不加粗了。


再塞一點 MOC 也沒用,Session Start 還沒聽到這一輪問題

查到 Brief 給得太少,我下一個念頭是:

那就多塞一點 Project MOC。

至少 Agent 一啟動,就能多看到幾則 Knowledge。

但再看 Hook 的觸發時機,問題又多一層。

Session Start 發生時,使用者這一輪的 Prompt 還沒進來。

系統只知道 Agent 位於 serialwrap、testpilot 或其他 Project。

但下一句可能是:

查 UART Completion
修 Packaging
搬 Service
改 CI

四個 Task 需要的 Knowledge 完全不同。

到這裡才看清楚兩個責任:

  • Orientation:先讓 Agent 知道自己在哪個 Project、Memory 入口在哪裡。

  • Recall:等真正的 Task 出現後,再找這次可能相關的 Knowledge。

PR #80 做的是 Orientation。

錯的是我把一張 Project 導覽,直接當成這一輪的書單。

館員可以先告訴讀者樓層配置。

不能在讀者還沒開口前,就替他決定今天要借哪一本。


Prompt 到了再找,Agent 真的開過檔案才算 Read

PR #156 把下一步接到 UserPromptSubmit

這條 Hook 在使用者真的送出 Prompt 時觸發;此時系統終於看得到當前 Task。

它再依這一輪問題搜尋 Knowledge,產生一份 Task-conditioned Shortlist

少量相關標題
一行摘要
Knowledge 的絕對路徑

Shortlist 就是根據這次 Task 選出的少量候選入口。

它由 Prompt-time Retrieval Hook 產生,交給當前 Agent;保存的是這次可能相關的 Knowledge Path。

它不是答案,也不是把整個 Knowledge Tree 塞進 System Prompt。

Review 同時要求這條新路徑接上 policy.check_boundary

Memory 能跨 Session、跨 Tool 保存,不代表搜尋到的內容可以不經 Redaction,就直接送進目前 Agent 的 Context。

有了可開啟的 Path,Usage 才能從猜測改成觀察實際動作。

Agent 使用 Read Tool 開啟 Knowledge File 後,PostToolUse(Read) Hook 才留下一筆 Read Attribution:哪個 Session,真的開過哪一則 Knowledge。

第一輪 Review 還抓到 Symlink Path 對不回原始 Knowledge 的問題;修正後,真實 Read 才不會因為路徑形狀不同又被漏掉。

但 Read 的 Claim 仍然很窄:

Brief 出現
≠ Read

Agent 開啟 Knowledge File
= Read

Read
≠ 採用
Read
≠ 做對

Target


我原本想養 Agent,查完才發現先要補的是 Consumption Loop

PR #80/#156 能支持:

  • Claude、Codex、Copilot 在 Session Start 可以收到 Project Orientation。

  • User Prompt 到達後,可以依真正 Task 重新搜尋 Knowledge。

  • Shortlist 提供可直接 Read 的 Path,不只是一串 MOC 標題。

  • Agent 實際開啟 Knowledge File 時,能留下可歸因的 Read Event。

  • Memory 注入仍受 Policy Boundary 保護。

它們不能支持:

Agent 看過就代表採用,更不能證明工程結果因此變好。

第一天我以為 Memory 只是還沒養熟。

一個星期後才查到,原本接通的只是 Project 導覽,不是完整的 Memory Consumption Loop。

走到這裡,paulshaclaw/memory 已經會 Capture、Atomize、Dream、Search、Recall,還要跨 Claude、Codex、Copilot 保存與提供工程經驗。

下一篇,三家 Agent 都靠它記東西,怎麼還掛在 Operator Shell 底下?

Have a nice day.


上一篇
Day 25 - 記憶切成幾百片後,萬軍之中找不到上將:_Map_ of Content
下一篇
Day 27 - Memory 終於開始回本,裝到第二台電腦卻連管理系統都得一起搬:又要拆分了 - Hippo
系列文
一天一個 PR,讓我告訴你嵌入式開發的殘酷:如何為 AI Agent 建立可信的工程閉環28
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言