工作智能体记忆存储位置解析
工作智能体跨会话记住的内容存在哪里、以什么形态保存。
来源 docs/技术博客/工作智能体记忆存储位置解析.md
表述:本文面向开发与运维,说明 工作区「我的智能体」 的跨会话记忆 落在哪、以什么形态存、与数据库如何分工。产品侧用户说法见
docs/core-mechanisms/智能体记忆.md与help/product-features/agent-memory.md。
日期:2026-07-09 相关代码:backend/internal/agentmemory/、backend/internal/runtimews/
结论
Cadau 工作智能体的 记忆主体在文件夹,不在数据库。
产品采用 「文件优先 Workspace」 范式(见 docs/产品规格.md §3.5):跨会话记忆以 Markdown 文件 落在磁盘;数据库只存智能体元数据、开关配置和聊天消息,不存长期记忆正文。
根目录在哪
由配置项 runtime_dir(环境变量 RUNTIME_DIR)决定:
| 环境 | 路径 |
|---|---|
本地开发(backend/mindlink.json) | backend/tmp/runtime(相对后端进程工作目录) |
| Docker / 测试服 | /srv/mindlink/data/tmp/runtime |
配置示例(backend/mindlink.json):
"paths": {
"runtime_dir": "tmp/runtime"
}
每只工作智能体对应一个子目录,目录名 = 智能体 ID(user_agents.id):
{RUNTIME_DIR}/{智能体ID}/
创建智能体时,后端调用 InitAgentRuntime 初始化该目录(backend/internal/runtimews/init_runtime.go)。
目录树:记忆相关文件
{RUNTIME_DIR}/{智能体ID}/
├── USER.md ← 用户画像(「关于你」)
├── MEMORY.md ← 长期记忆索引(标题 + 类型 + 一句话)
├── memory/
│ ├── entries/
│ │ ├── preference-abc12345.md ← 长期记忆条目正文(每条一个 .md)
│ │ └── project-deadline-xyz.md
│ ├── 2026-07-09.md ← 日笔记(按日期)
│ ├── 2026-07-08.md
│ ├── legacy-conversation-log.md ← 旧版整段对话流水(迁移归档)
│ └── .session-surfaced/
│ └── {会话ID}.json ← 辅助:记录本轮已注入哪些记忆(去重)
各层对应关系
| 用户说法 | 存储位置 | 格式 |
|---|---|---|
| 用户画像 | USER.md | Markdown |
| 长期记忆 | MEMORY.md(索引)+ memory/entries/*.md(正文) | Markdown + YAML frontmatter |
| 日笔记 | memory/YYYY-MM-DD.md | Markdown |
| 旧版对话流水 | memory/legacy-conversation-log.md | Markdown(已停用自动追加) |
常量定义见 backend/internal/agentmemory/types.go:
EntriesSubdir = "memory/entries"LegacyArchiveRel = "memory/legacy-conversation-log.md"
写入与读取路径(实现)
长期记忆
- 索引:
MEMORY.md,由RebuildIndex根据memory/entries/下条目自动重建。 - 正文:
memory/entries/{filename}.md,由WriteEntry写入。 - 包:
backend/internal/agentmemory/store.go
日笔记
- 路径:
memory/{YYYY-MM-DD}.md - 写入:
AppendDailyNote(用户「记住」选日笔记、或上下文压缩前 flush) - 包:
backend/internal/agentmemory/flush.go
用户画像
- 路径:
USER.md - 包:
backend/internal/runtimews/files.go(UserFile = "USER.md")
会话注入去重(辅助状态)
- 路径:
memory/.session-surfaced/{session_id}.json - 用途:记录上一轮已注入正文的记忆文件名,避免重复塞满上下文;不是用户可见的记忆内容。
- 包:
backend/internal/agentmemory/surfaced.go
统一写入入口
工具与 REST 共用 WriteMemory(backend/internal/agentmemory/write.go):
layer = long_term→memory/entries/*.mdlayer = daily→memory/YYYY-MM-DD.md
对应 REST 路由(backend/internal/httpserver/router.go):
GET/PUT /user-agents/{id}/memory— 索引MEMORY.mdGET/POST/PUT/DELETE /user-agents/{id}/memory/entries[/{filename}]— 条目 CRUDPOST /user-agents/{id}/memory/remember— 消息「记住」GET/POST /user-agents/{id}/memory/maintain/history|run— 本助手整理历史 / 手动整理GET/POST /admin/agent-memory-maintain/*— 管理端全站状态、历史、立刻整理
闲时整理审计文件:
{RUNTIME_DIR}/.memory_maintain_status.json、.memory_maintain_history.jsonl{RUNTIME_DIR}/{智能体ID}/memory/.maintain/log.jsonl
工具:memory_write(可带 path 更新)、memory_delete、memory_search、memory_get。
数据库里有什么
PostgreSQL 不存记忆正文,只存与记忆 相关 的元数据与对话:
| 表 / 字段 | 内容 | 与记忆的关系 |
|---|---|---|
user_agents | 智能体 ID、名称、config_json 等 | config_json 含 memory_auto_append、memory_auto_extract 等开关 |
chat_sessions + chat_messages | 会话与消息 | 工作记忆(当前对话历史),不是长期记忆 |
(无 memory_* 表) | — | 记忆正文不落库 |
记忆相关开关定义于 backend/internal/runtimews/agentconfig.go:
MemoryAutoAppend *bool `json:"memory_auto_append,omitempty"`
MemoryAutoExtract *bool `json:"memory_auto_extract,omitempty"`
默认策略:memory_auto_append 关闭,memory_auto_extract 开启(见 agentconfig_test.go)。
智能体概况中的 memory_bytes 由运行时扫描 MEMORY.md + memory/entries/ 体积汇总(backend/internal/store/agent_stats.go + agentmemory.TotalByteSize),不是数据库字段。
容易混淆的其它目录
| 路径 | 用途 | 是不是「智能体记忆」 |
|---|---|---|
{RUNTIME_DIR}/{智能体ID}/knowledge/ | 智能体知识文档 | 否(知识文档,按问题检索) |
{RUNTIME_DIR}/workspace-knowledge/{工作区ID}/ | 工作区知识文档 | 否(团队共用说明材料) |
CHAT_ARCHIVE_DIR(默认 tmp/memoryforge/chat-archive) | MemoryForge 对话扫描归档 | 否(管理侧分析提案,不是用户记忆) |
帮助智能体(未选工作区时的产品帮助)没有上述个人记忆目录;它读部署侧 help/ 系统知识文档。
检索方式
当前 memory_search 工具与 REST GET .../memory/search 使用 关键词匹配(agentmemory.Search、SelectRelevant),在 memory/entries/ 与日笔记中查找;不是向量库索引。
对话每轮注入时(MemoryContextForChat / BuildContextBlock)大致包含:
MEMORY.md索引(清单)- 与当前问题相关的少量条目全文(默认最多约 5 条)
- 今、昨两日笔记节选
本机如何查看
- 在 Web 智能体 → 我的智能体 记下智能体 ID。
- 打开
{RUNTIME_DIR}/{智能体ID}/(本地一般为backend/tmp/runtime/{智能体ID}/)。 - 查看
MEMORY.md、memory/entries/、memory/YYYY-MM-DD.md等。
若目录不存在,可能原因:
- 该智能体尚未产生任何记忆写入;
- 后端进程工作目录与
runtime_dir配置不一致(路径为相对路径时依赖 CWD)。
产品边界(排查时常见)
| 场景 | 行为 |
|---|---|
| 工作区「我的智能体」 | 有个人记忆目录 |
| 帮助智能体 | 无个人记忆 |
| 同事的智能体 | 记忆 不共享 |
| 复制智能体方案 | 不带原实例记忆 |
| 团队共用口径 | 应写 工作区知识文档,不是个人记忆 |
相关文档
| 文档 | 说明 |
|---|---|
| 产品规格.md §3.2、§3.5 | Memory 体系与 Workspace 文件范式 |
| core-mechanisms/智能体记忆.md | 产品机制:分层、写入、注入规则 |
| help/product-features/agent-memory.md | 用户帮助:记住、纠正、自动整理 |
| help/admin-ops/agent-memory-maintain.md | 管理端:闲时整理与执行历史 |
| help/guides/runtime-files-map.md | 运行时文件与界面对照 |