DeerFlow Memory Settings 增删改流程本地评审指南:从 Fixture 加载到 API 逐层验证
【免费下载链接】deer-flowAn open-source long-horizon SuperAgent harness that researches, codes, and creates. With the help of sandboxes, memories, tools, skill, subagents and message gateway, it handles different levels of tasks that could take minutes to hours.项目地址: https://gitcode.com/GitHub_Trending/de/deer-flow
本文基于 DeerFlow 仓库中的 Memory Settings 评审文档,完整介绍如何以最少手动步骤本地评审“记忆设置”页面的事实(fact)新增与编辑流程:包括启动服务、加载样本 Fixture、执行最小手动测试与可选健全性检查,并结合 Gateway 的 Memory API 路由、前端 Memory Settings 页面组件与 DeerMem 存储层源码,说明每一步操作背后的接口与实现细节,帮助读者既能照做验证、又能读懂其底层机制。
评审目标与适用场景
DeerFlow 的Settings > Memory页面提供对全局记忆数据(用户上下文摘要、历史摘要、记忆事实 facts)的本地搜索、过滤、清空与单条增删改能力。backend/docs/MEMORY_SETTINGS_REVIEW.md就是为这套功能的评审者准备的操作手册:它假设你已经有一个可用的本地开发环境,通过预置一份“内容可预测”的样本数据,把“新增事实立即生效、编辑立即生效、刷新后持久化”这三条核心验收标准压缩成 6 步以内的手动操作。
适用前提:
- 本地已按任意可用方式运行 DeerFlow(
make dev、make docker-start或已有环境); - 使用 Python 3 执行 Fixture 加载脚本(脚本自身无第三方依赖,仅用标准库
argparse/json/shutil)。
第一步:启动本地服务
文档给出的两种启动方式都定义在仓库根目录的 Makefile 中:
make dev对应 Makefile 中的dev目标:先执行./scripts/check.py做前置检查,再通过./scripts/serve.sh --dev以开发模式启动前后端。
make docker-start对应 Makefile 中的docker-start目标,实际调用./scripts/docker.sh start走 Docker Compose 环境。如果本地已有运行中的 DeerFlow 实例,文档明确允许直接复用,无需重启。
启动后文档给出了两个默认本地地址:
| 地址 | 说明 |
|---|---|
http://localhost:2026 | 完整应用(前端 + Gateway)入口 |
http://localhost:3000 | 仅前端的本地降级入口(frontend-only fallback) |
第二步:加载样本记忆 Fixture
进入评审状态的关键一步是把预置的样本记忆写入本地运行时文件:
python scripts/load_memory_sample.py该脚本 scripts/load_memory_sample.py 的默认行为是:把 backend/docs/memory-settings-sample.json 拷贝到backend/.deer-flow/memory.json(即默认本地运行时目标,见脚本中的default_source/default_target,scripts/load_memory_sample.py)。
脚本支持三个可选参数(--help可见):
| 参数 | 默认值 | 作用 |
|---|---|---|
--source | backend/docs/memory-settings-sample.json(相对仓库根) | 指定样本 JSON 路径 |
--target | backend/.deer-flow/memory.json | 指定运行时memory.json目标路径 |
--no-backup | 未启用 | 跳过备份,直接覆盖目标文件 |
备份机制值得单独说明:若目标文件已存在且未传--no-backup,脚本会先用当前时间戳(%Y%m%d-%H%M%S格式)把旧文件复制为memory.json.bak-<timestamp>,再执行覆盖拷贝,并打印备份路径;这是文档中“loader 脚本在覆盖已有运行时记忆文件前会自动创建带时间戳的备份”一句的源码依据(scripts/load_memory_sample.py)。脚本还会先对源文件做json.load校验,避免把坏 JSON 写进运行时(scripts/load_memory_sample.py)。
样本 Fixture 的结构
backend/docs/memory-settings-sample.json 是一个完整的记忆文档,顶层包含version("1.0")、lastUpdated、user、history、facts五部分:
user:三个上下文小节workContext/personalContext/topOfMind,每项为{summary, updatedAt};history:三个历史小节recentMonths/earlierContext/longTermBackground;facts:10 条fact_review_001到fact_review_010的示例事实,覆盖preference、workflow、project、testing等 category,confidence在 0.78–0.95 之间,source多为thread_*形式的会话来源标识,其中fact_review_010的source为"manual"——这正是“编辑测试”步骤要用的那条样例事实This sample fact is intended for edit testing.,而fact_review_009(Delete fact testing can target this disposable sample entry.)则是专门留给“单条删除”检查的一次性条目。
这份 Fixture 与后端 API 的响应模型一一对应:Gateway 路由中的MemoryResponse/UserContext/HistoryContext/FactPydantic 模型(backend/app/gateway/routers/memory.py)字段名与 Fixture 的 JSON 键完全一致,因此同一份文件既可被脚本写入磁盘,也可直接通过POST /api/memory/import导入。
第三步:打开 Settings > Memory 页面
服务就绪、Fixture 加载后,在http://localhost:2026(或前端的http://localhost:3000)进入Settings > Memory。页面组件为 frontend/src/components/workspace/settings/memory-settings-page.tsx,它会通过 frontend/src/core/memory/api.ts 请求GET /api/memory拉取当前用户的全部记忆并渲染两个区块:
- 摘要区块(Summaries):把
user与history的 6 个小节渲染为 Markdown(buildMemorySectionGroups+summariesToMarkdown,memory-settings-page.tsx); - 事实列表(Facts):渲染
facts数组,每条显示内容、category、置信度与来源(source)。
最小手动测试(Minimal Manual Test)
文档的核心验收流程共 6 步,以下是完整步骤及对应的后端接口:
- 点击
Add fact。 - 创建一条新事实:
- Content:
Reviewer-added memory fact - Category:
testing - Confidence:
0.88
- Content:
- 确认新事实立即出现在列表中,且来源显示为
Manual。 - 编辑样本事实
This sample fact is intended for edit testing.(即fact_review_010),改为:- Content:
This sample fact was edited during manual review. - Category:
testing - Confidence:
0.91
- Content:
- 确认被编辑的事实立即更新。
- 刷新页面,确认新增事实与被编辑事实仍然持久存在。
前端到后端的调用链
- 步骤 2 触发
useCreateMemoryFact,最终POST {backend}/api/memory/facts,请求体为FactCreateRequest(content必填、category默认context、confidence限定 0–1,默认 0.5),见 frontend/src/core/memory/api.ts 与后端模型 backend/app/gateway/routers/memory.py; - 步骤 4 触发
useUpdateMemoryFact,走PATCH {backend}/api/memory/facts/{factId},请求体是“保留缺省字段”的FactPatchRequest(三个字段均为可空),对应后端update_fact调用(backend/app/gateway/routers/memory.py); - 两个接口的响应均为完整
MemoryResponse,前端据此立即刷新列表——这就是“立即出现/立即更新”验收点的机制来源:每次写操作返回全量文档,而非让前端局部推断。
“Manual” 来源标记的实现依据
新增事实后来源显示Manual,这一点在存储层有明确定义:DeerMem 的写入路径会把人工新增事实的source标记为"manual"(见update_fact/create_fact实现中的"source": "manual",backend/packages/harness/deerflow/agents/memory/backends/deermem/deermem/core/updater.py),且存储层将manual/consolidation/import/unknown识别为一组“非会话来源”的合法取值(backend/packages/harness/deerflow/agents/memory/backends/deermem/deermem/core/storage.py)。DeerMem 更新器还会对source.type == "manual"的高置信度用户手写事实打上[MANUAL]标记,避免其被后续自动更新逻辑改写(updater.py)。因此“来源显示Manual”不仅是 UI 文案,而是贯穿存储与更新策略的数据语义。
写接口的错误语义(评审时可能遇到)
从 backend/app/gateway/routers/memory.py 的路由实现看,写操作返回的错误码是有约定的:
| 状态码 | 触发条件 |
|---|---|
| 400 | confidence越界、内容为空等校验错误(_map_memory_fact_value_error,memory.py) |
| 409 | 内容重复(Duplicate fact),或事实数达到memory.max_facts容量策略上限后新事实被驱逐(memory.py) |
| 404 | PATCH/DELETE时 fact id 不存在(memory.py) |
| 501 | 当前配置的 memory backend 不支持该操作(最小化 backend 只实现add/get_context,memory.py) |
| 500 | 并发冲突之外的存储损坏(MemoryCorruptionError)或文件 IO 失败 |
本地评审默认使用 DeerMem 后端,正常走完上述 6 步不应遇到这些错误码;它们主要用于解释“如果手动测试失败,页面报错该如何解读”。
可选健全性检查(Optional Sanity Checks)
文档在最小测试之外列出了 5 项可选检查,逐项对应源码行为:
- 搜索
Reviewer-added,确认新事实被命中。前端搜索为纯本地过滤:输入经useDeferredValue归一化后,对每条事实做${fact.content} ${fact.category}的小写包含匹配(memory-settings-page.tsx),不走服务端。 - 搜索
workflow,确认 category 文本也参与搜索。上式把category拼进匹配串,正是“category 文本可被检索”的实现;Fixture 中fact_review_002的 category 恰为workflow,因此该关键词必然命中。 - 在
All/Facts/Summaries三种视图间切换。视图切换由MemoryViewFilter = "all" | "facts" | "summaries"控制,showSummaries = filter !== "facts"、showFacts = filter !== "summaries"决定两个区块的显隐(memory-settings-page.tsx)。 - 删除一次性样本事实
Delete fact testing can target this disposable sample entry.(fact_review_009),确认列表立即更新。删除走DELETE /api/memory/facts/{factId}(memory.py),同样返回全量MemoryResponse驱动即时刷新。 - 清空全部记忆,确认页面进入空态。清空走
DELETE /api/memory(memory.py);前端空态由isMemorySummaryEmpty(6 个摘要小节全空)与 facts 列表为空共同决定(memory-settings-page.tsx)。
补充说明:用户归属与运行时文件位置
- 记忆按用户隔离。Gateway 通过
_resolve_memory_user_id解析本次请求的记忆属主:内部通道调用可携带受信 owner 头(经AuthMiddleware校验后生效),浏览器/API 调用则回退到 contextvar 中的有效用户;原始 id 会经make_safe_user_id归一化,保证记忆桶与文件/上传桶对齐(backend/app/gateway/routers/memory.py、backend/packages/harness/deerflow/config/paths.py)。本地单用户评审场景下这一层无感,但它解释了为什么运行时文件默认落在backend/.deer-flow/这一项目级目录。 - 除评审文档点名的两个文件外,页面还提供
GET /api/memory/export与POST /api/memory/import(前端 Export/Import 按钮)、GET /api/memory/config(返回enabled/mode/injection_enabled/shutdown_flush_timeout_seconds/manager_class/backend_config等后端无关配置)、GET /api/memory/status(配置+数据一体)以及POST /api/memory/reload(外部改动文件后强制从存储重载)等端点,均可在 backend/app/gateway/routers/memory.py 中逐一核对;评审“手动改memory.json后点 reload 是否生效”这类场景时可直接使用。
评审检查单(速查)
| # | 操作 | 预期结果 | 对应接口/实现 |
|---|---|---|---|
| 1 | python scripts/load_memory_sample.py | 打印目标路径与备份路径 | scripts/load_memory_sample.py |
| 2 | Add fact(0.88 / testing) | 立即出现,来源Manual | POST /api/memory/facts |
| 3 | 编辑fact_review_010(0.91) | 立即更新 | PATCH /api/memory/facts/{id} |
| 4 | 刷新页面 | 两条事实仍在 | GET /api/memory+ 磁盘memory.json |
| 5 | 搜索Reviewer-added/workflow | 分别命中新事实 / category 匹配 | 前端本地过滤 |
| 6 | 删除fact_review_009、清空全部 | 列表即时更新 / 进入空态 | DELETE /api/memory/facts/{id}、DELETE /api/memory |
按此清单完成最小测试后,即覆盖了 Memory Settings 增/改/删/查四条主链路与搜索、过滤、持久化三个验收点;若需继续深入,可分别阅读 backend/docs/MEMORY_IMPROVEMENTS.md 与 backend/docs/MEMORY_IMPROVEMENTS_SUMMARY.md 了解记忆机制的改进脉络,以及 backend/app/gateway/routers/memory.py 中各端点的完整错误处理约定。
【免费下载链接】deer-flowAn open-source long-horizon SuperAgent harness that researches, codes, and creates. With the help of sandboxes, memories, tools, skill, subagents and message gateway, it handles different levels of tasks that could take minutes to hours.项目地址: https://gitcode.com/GitHub_Trending/de/deer-flow
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考