代理「记得」的,不一定是事实
用 Claude Code 做长项目时,很多人会开代理记忆:上周讨论过的架构猜测、某次排查时随口说的「可能是缓存」、还没验证的接口假设,都会被写进记忆文件。几天后再开会话,助手把这些内容当已确认事实召回,接着就按假前提改代码、改配置。
社区里也有人干脆把 recall 迁到自建 MCP:默认只返回带证据的笔记,猜测单独标档,召回时不混进「事实」通道。本文讲怎么在一台常开的新加坡 Mac mini 上落地这套分工——Claude 账号仍由你自己开通;机器提供稳定合规的使用环境。
问题拆开:三类内容别放一个桶
| 类型 | 例子 | 召回时应怎样 | |------|------|--------------| | 有证据的事实 | 已合并的 PR 说明、跑通的测试日志路径、官方文档摘录 + URL | 默认可返回给助手 | | 工作中假设 | 「大概是限流」「怀疑是时钟漂移」 | 单独标签;召回时标明 hypothesis,或默认不返回 | | 过期草稿 | 上周已推翻的方案、临时端口号 | 归档或删除;禁止进入默认 recall |
混在一个「MEMORY.md / 自动笔记」里时,模型很难区分。你事后看文件能看出语气;工具返回的短摘要往往已经把「可能」洗成「就是」。
在新加坡 Mac mini 上建证据库目录
把权威记忆固定在一台整机独享的常开机器上,避免笔记本 A 写了一堆猜测、笔记本 B 又当成事实加载。
mkdir -p ~/work/agent-memory/{facts,hypotheses,archive,evidence}
cd ~/work/agent-memory
git init
约定:
facts/:每条一条 Markdown 或 JSON;文首必须有status: verified和至少一条evidence:(本地路径或可核对的提交哈希)。hypotheses/:同样结构化,但status: hypothesis;默认 recall 不读这个目录。evidence/:原始材料副本或链接清单(测试输出、issue 编号、commit)。archive/:已否决条目,只供人工翻阅。
示例事实条目:
---
id: rate-limit-on-upload-api
status: verified
evidence:
- commits/abc1234
- evidence/upload-429-log-2026-10-20.txt
updated: 2026-10-20
---
上传接口在连续 30 次请求后返回 429;退避后恢复。结论来自上述日志与提交,不是猜测。
假设条目把 status 改成 hypothesis,并写明「待验证问题」,不要写成像结论。
自建一个「只返回 verified」的本地 MCP
目标:Claude Code 通过 MCP 调 memory_recall 时,默认只扫 facts/;需要假设时显式传 include_hypotheses=true。
下面是一个最小可跑的示意(Node;也可用你熟悉的语言)。字段名以你当前 MCP SDK 为准,重点在过滤逻辑:
// ~/work/agent-memory/mcp-server/index.js(示意)
import fs from "fs";
import path from "path";
import matter from "gray-matter";
const ROOT = process.env.AGENT_MEMORY_ROOT || `${process.env.HOME}/work/agent-memory`;
function listNotes(dir) {
const base = path.join(ROOT, dir);
if (!fs.existsSync(base)) return [];
return fs.readdirSync(base).filter((f) => f.endsWith(".md")).map((f) => {
const raw = fs.readFileSync(path.join(base, f), "utf8");
const { data, content } = matter(raw);
return { file: f, ...data, body: content.trim() };
});
}
export async function memory_recall({ query, include_hypotheses = false }) {
const pool = listNotes("facts").filter((n) => n.status === "verified");
if (include_hypotheses) {
pool.push(...listNotes("hypotheses").map((n) => ({ ...n, _tag: "hypothesis" })));
}
const q = (query || "").toLowerCase();
const hits = pool.filter((n) =>
`${n.id || ""} ${n.body}`.toLowerCase().includes(q)
);
// 强制带上 status / evidence,避免助手当成「裸事实」
return hits.map((n) => ({
id: n.id,
status: n.status,
evidence: n.evidence || [],
tag: n._tag || "fact",
excerpt: n.body.slice(0, 500),
}));
}
在 Claude Code 的 MCP 配置里指向这台 Mac mini 上的本地进程(stdio),例如项目或用户级 .mcp.json(密钥仍走钥匙串 / 环境变量,不要明文进仓库):
{
"mcpServers": {
"agent-memory": {
"command": "node",
"args": ["/Users/user/work/agent-memory/mcp-server/index.js"],
"env": {
"AGENT_MEMORY_ROOT": "/Users/user/work/agent-memory"
}
}
}
}
路径按你机器上的实际用户与目录改。用 SSH 或 UU 远程连接维护同一份配置,不要在多台笔记本各装一份互相漂移的记忆库。
写入规则:先证据,后升格
给项目 CLAUDE.md 留一段软约定(风格层即可;真正过滤靠 MCP):
- 讨论中的猜测 → 只许写入
hypotheses/,标题带「待验证」。 - 有日志 / 提交 / 复现步骤后 → 人工或脚本把条目移到
facts/,并填写evidence。 - 召回时默认调用
memory_recall不带include_hypotheses。 - 若助手把假设写成了肯定句,先改记忆文件,再改代码——别只在对话里嘴硬纠正一次。
可选:用 PreToolUse hook 拦「直接改 facts/ 却没有 evidence 字段」的写入(字段解析以你版本工具 JSON 为准)。硬拦截放 hooks;分层说明放 CLAUDE.md。这与「软提示 vs 硬门」那篇一致,这里不重复脚本细节。
十分钟验收
在 Mac mini 仓库旁开 Claude Code:
- 放一条无
evidence的假设到hypotheses/,默认memory_recall不应返回它。 - 同一主题加一条
status: verified且带 evidence 的事实 → 应返回,且响应里能看到evidence列表。 - 显式
include_hypotheses=true时,假设条目应带hypothesis标记,而不是伪装成事实。 tmux挂着 MCP 进程或由 Claude Code 按需拉起;SSH 断开再连,记忆根目录仍在磁盘同一路径。git status:确认没有把.env、API Key 写进evidence/;敏感材料用路径引用或脱敏副本。
为什么固定在新加坡常开 Mac mini
- 一份权威库:facts / hypotheses 只维护一份,远程用 SSH 或 UU 远程连接进入同一台整机。
- MCP 常驻:笔记本合盖会断本地 MCP;常开机器上 recall 与长会话同一环境。
- 整机独享:记忆目录与本地密钥路径不与其他客户混用;退租抹机时一并结束。
- 真 macOS 工具链:Node / git / jq 与你日常开发一致,便于把「升格脚本」写进同一仓库。
Zumac.Ai 提供位于新加坡的实体 Mac mini M6,整机独享,支持 SSH 与 UU 远程连接,FileVault 全盘加密,退租时抹机重装。新客户整机租用 ¥999/月起,季付 ¥2,697.30,半年付 6 送 1 为 ¥5,994,年付 12 送 2 为 ¥11,988;已购买客户续费保持原价。新客户首单自审核开通当天起租,续费及老客户新订单自付款当天起租。建议先租一个月,把「证据门控记忆 MCP」在同一台机器上跑通。实际延迟取决于你本地的网络线路。
小结
- 代理记忆容易把上周的猜测当成事实召回;要把 verified 与 hypothesis 分目录。
- 自建本地 MCP,默认只返回带
evidence的事实;假设需显式打开。 - 写入先落假设区,有证据再升格;软约定写
CLAUDE.md,硬过滤靠 MCP(必要时加 hooks)。 - 把记忆根目录与 MCP 固定在新加坡常开 Mac mini,用 git 管理,SSH 或 UU 远程连接日常接入。
