iT邦幫忙

2026 iThome 鐵人賽

DAY 18
0
AI Engineering

30天拆Agent:從Repo看設計系列 第 18 篇

Day 18|OpenClaw 怎麼記住人?從 Memory Promotion 到多人記憶隔離

  • 分享至 

  • xImage
  •  

如果 Agent 學到的不是「做事方法」,而是一個人、一個事實或一個長期決策,它到底怎麼變成 Memory?

例如:

「以後 code example 都用 Python。」

這不是新的 SOP。

又例如:

「這個航空客服專案決定:
customer_id 一律由 LINE userId mapping。」

這也不是新的 Tool。

它們比較像是:

Preference
Fact
Decision
Context

所以這篇只看四件事:

1. OpenClaw 怎麼區分不同種類的 Memory?
2. 一句對話怎麼真的被寫進 Memory?
3. 沒有人說「記住」時,Dreaming 怎麼形成 Long-term Memory?
4. 多人共用 Agent 時,這份 Memory 到底屬於誰?

1. OpenClaw 先把 Memory 分層,再讓 Agent 決定寫什麼

OpenClaw 的 Memory 主要有三層:

workspace/
├── USER.md
├── MEMORY.md
└── memory/
    └── YYYY-MM-DD.md
檔案 放什麼
USER.md 穩定的 User preference、communication style、profile
MEMORY.md Durable fact、decision、短摘要
memory/YYYY-MM-DD.md Daily observation、running context、比較原始的紀錄

例如:

User:
以後所有 code example 都用 Python。

這比較像:

USER.md

而:

航空客服專案已經決定:
LINE userId mapping 到 customer_id。

比較像:

MEMORY.md

今天測試時:

LINE webhook 第三次測試發生 timeout。

則可以先放:

memory/2026-10-01.md

OpenClaw 官方 Memory 文件也是這樣區分:USER.md 是 compact user model、MEMORY.md 是 curated long-term layer、daily notes 則是 working layer。


1-1. 但誰決定「這句話要放哪裡」?

docs/reference/templates/AGENTS.md

已經先告訴 Model:

Daily notes
→ raw logs / running context

USER.md
→ stable preferences / profile facts

MEMORY.md
→ durable non-profile facts / decisions

流程:

User:
「以後 example 都用 Python」
        ↓
Model 同時看到 AGENTS.md
        ↓
判斷這是 Stable Preference
        ↓
使用 File Tool
        ↓
修改 USER.md

也就是:

  • Memory 的種類 → OpenClaw 預先定義
  • 這一句屬於哪一種 → LLM + AGENTS.md 判斷
  • 真的寫入檔案 → Tool 執行

這部分本質上仍然是:

Prompt-driven Memory Write。


1-2. 所以 Memory Policy 可以自己改

因為判斷規則主要在 AGENTS.md,User 可以直接調整。

例如我不希望 Agent 因為一次 request 就自行推論長期喜好,可以加:


Memory Policy

Only update USER.md when the user explicitly states
a long-term preference or asks you to remember something.

Do not infer a permanent preference
from a one-time request.

這樣:

User:
這次請用 Python。

不應直接變成:

Prefer Python.

但:

User:
記住,以後 code example 都用 Python。

才符合長期 Preference。

所以 OpenClaw 這一層可以整理成:

  • Runtime → 提供 Memory architecture
  • AGENTS.md → 定義 Memory policy
  • LLM → 做 semantic judgement

這比另外開發一個固定 classification function 更有彈性。


1-3. SQLite 不是另一套 Memory

如果 daily notes 累積成:

memory/
├── 2026-09-01.md
├── 2026-09-02.md
├── ...
└── 2026-10-01.md

當然不能每次全部塞進 Context。

OpenClaw 預設的 built-in Memory engine 會把:

USER.md
MEMORY.md
memory/*.md

切成 chunk,再建立每個 Agent 自己的 SQLite index。

目前預設 chunk 約:

400 tokens
80-token overlap

搜尋則包含:

BM25
+
Vector Search
+
Hybrid ranking

最後透過:

memory_search

把少量 relevant memory 找回來。


2. User 沒有說「記住」時,Memory 怎麼自己長出來?

前面這條路仍然需要:

Agent 當下判斷
↓
主動寫檔

但還有另一種情況。

假設過去幾天 repeatedly 發生:

Day 1
航空客服工作時用了 customer_id mapping

Day 2
查訂單時又 recall 這個 mapping

Day 3
處理退款時再次使用

User 從來沒有說:

請把這件事情永久寫進 MEMORY.md。

但它已經是一個反覆被使用的 project fact。

這就是 OpenClawDreaming處理的問題。


2-1. Dreaming 不是「再問一次 LLM 這個重要嗎?」

OpenClaw 的 Dreaming 分:

Light
↓
REM
↓
Deep

三個 phase。

這篇不需要逐一介紹三種睡眠名稱。

真正值得看的只有:

只有 Deep 可以把 candidate promotion 到 MEMORY.md。

而且 Deep 在交給 Model consolidation 以前,先有 deterministic gate。

目前 source:

src/memory-host-sdk/dreaming.ts

定義預設 threshold:

minScore         = 0.75
minRecallCount   = 3
minUniqueQueries = 3

recencyHalfLifeDays = 14
maxAgeDays           = 30

也就是一段資訊至少要有:

足夠的 score
+
真的被 recall 多次
+
不是只被同一種 query 一直撞到

才進下一步。

所以概念可以縮成:

Short-term Evidence
        ↓
score / recall / query diversity
        ↓
Deterministic Gate
        ↓
LLM Consolidation
        ↓
MEMORY.md

官方 Dreaming 文件也明確說明:

Light
→ 不寫 MEMORY.md

REM
→ 不寫 MEMORY.md

Deep
→ 通過 ranking / threshold gate
→ 再進 tool-free completion
→ additions / merge / supersession
→ MEMORY.md

2-2. Dreaming 可以設定什麼?

Dreaming 預設開啟。

主要設定在:

plugins.entries.memory-core.config.dreaming

例如:

{
  "plugins": {
    "entries": {
      "memory-core": {
        "config": {
          "dreaming": {
            "enabled": true,
            "frequency": "0 3 * * *"
          }
        }
      }
    }
  }
}

可以改:

enabled
frequency
model
部分 output / consolidation 設定

但要特別注意:

minScore
minRecallCount
minUniqueQueries

雖然 OpenClaw source 有明確 default,目前官方 Memory Config 仍把這些 phase thresholds 視為internal implementation behavior,不是一般 user-facing config。

如果只是人工測試 promotion,CLI:

openclaw memory promote

則可以用 command flags 做單次 override。

所以不能把它寫成:

{
  "dreaming": {
    "minScore": 0.8
  }
}

3. 多人使用時,這份 Memory 到底是誰的?

最後才是 OpenClaw 比較特殊的地方。

因為它本來就是 Gateway。

同一個 Agent 可能同時遇到:

Alice
Bob
Carol

這時只分 Session 還不夠。

Session 解決的是:

Alice 的 Conversation
≠
Bob 的 Conversation

但 Memory 還要回答:

Alice 的 Preference 是誰的?

哪些 Memory 是所有人共用?

哪些 Memory 不應該進 Group Context?

3-1. Shared USER.md 跟 Personal USER.md 是兩層

單人 Gateway 預設只使用:

workspace/USER.md

例如:

- 使用繁體中文。
- destructive operation 前先說明。

但 Shared Gateway 如果存在至少兩個 distinct、unmerged person profiles,可以再有:

workspace/
├── USER.md
└── users/
    ├── <alice-profile-id>/
    │   └── USER.md
    └── <bob-profile-id>/
        └── USER.md

例如:

Shared USER.md
→ 所有客服都使用繁體中文

Alice USER.md
→ Prefer concise answers

Bob USER.md
→ Prefer detailed technical explanation

OpenClaw 在符合條件的 Session 中會:

Shared USER.md
↓
Personal USER.md

依序載入。

Personal preference 因此可以覆蓋 conflicting shared defaults。

而且 Personal file 不是 Model 自己傳:

profileId = alice

決定。

Runtime 會根據 authenticated person / session owner 選擇 target,personal_instructions Tool 也只會修改實際 requester 自己的檔案。

這一層才是真正的:

同一個 Agent
+
不同 Human Memory

3-2. 但同一個 Workspace,不代表所有 Memory 都會給 Group

這是一個很容易誤會的地方。

假設:

Alice
Bob
Carol

都在使用同一個:

flight Agent

而且共用:

workspace-flight

並不代表:

Group Conversation

每次都會直接拿到 root:

MEMORY.md

OpenClaw 對 Long-term Memory 有額外限制。

官方 Agent Workspace 文件明確指出:

MEMORY.md
→ main private session

shared / group context
→ 不直接載入 root MEMORY.md

目的就是避免 Personal / Private long-term memory 無意間流進共享對話。

所以如果是:

所有航空客服都一定要知道:
未取得乘客確認不得改票。

這種 Team rule,比較適合放:

AGENTS.md
Skill
Tool / Backend Gate

而不是:

某個人的 MEMORY.md

這也讓 OpenClaw 的 Memory scope 更清楚:

USER.md
→ Person / shared preference

MEMORY.md
→ Agent 的 curated private long-term memory

daily memory
→ Episodic evidence

AGENTS.md / Skill
→ Team procedure / operating rule

3-3. Personal USER.md 也不是 Security Boundary

最後還有一個多人環境一定要注意的地方。

官方 User Model 文件直接提醒:

Personal USER selection 是 Prompt Selection,不是 Filesystem Secrecy。

也就是:

Alice USER.md
≠
真正 OS-level tenant isolation

如果 Agent 本身還有:

filesystem Tool
Session Tool
Plugin

仍然可能有其他資料存取路徑。

例如 Session tools 還受:

tools.sessions.visibility

控制。

目前 Gateway-wide Session visibility 預設可以是:

all

若想縮小範圍,可以考慮:

{
  "tools": {
    "sessions": {
      "visibility": "tree"
    }
  }
}

或依需求使用:

self
tree
agent
all

所以多人架構最後要區分三件完全不同的事:

Session isolation
→ Conversation 是否分開

Memory scope
→ 哪一份知識屬於誰

Tool authorization
→ Agent 最後到底讀得到什麼

不能只設定 Personal USER.md,就當成完整 Multi-tenant Security。

官方 Security 文件對 intentional shared-user setup 也建議再搭配 sandbox、workspace-scoped filesystem 等隔離。


References


上一篇
Day 17|OpenClaw 的 Tool、Skill、MCP:真正不同的是誰能用、何時觸發,以及怎麼學
系列文
30天拆Agent:從Repo看設計 共 18 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言