阅读材料: 第19部分:基于SQLite的智能体记忆

模块「第19部分:基于SQLite的智能体记忆」中第 1 / 5 节课
您正在未登录状态下查看课程。 请登录,以保存进度并参加测试。

第19部分:基于SQLite的智能体记忆

SDD将项目意图存储在仓库中:QWEN.mdAGENTS.mdspecs/CHANGELOG.md。但智能体开发还有另一个记忆层:会话中发生了什么、哪些错误反复出现、用户确认了哪些偏好、哪些命令生效了、哪些决策需要智能体从上下文中推断。

Qwen Code已内置记忆:QWEN.md、自动记忆、/remember/forget/dream。对于大多数项目,这已经足够。但如果你想自己掌控记忆、查看审计日志、在不同运行环境之间迁移记忆、并使用自己的清理规则,可以基于SQLite构建本地记忆层。

现代智能体记忆方法的核心思想很简单:

flowchart TD
  A["Qwen Code事件<br/>请求、工具、结果"] --> B["钩子<br/>log_event.py"]
  B --> C[("SQLite<br/>events表")]
  C --> D["后台归纳<br/>/dream 或 dream_sqlite.py"]
  D --> E[("SQLite<br/>memories表")]
  E --> F["添加上下文<br/>inject_memory.py"]
  F --> G["新会话<br/>或新请求"]
  E --> H{"记忆是否已成为规则?"}

H -- "是" --> I["迁移到specs/<br/>QWEN.md 或技能"]
  H -- "否" --> E

重要限制:这种记忆不能替代规范。它是对规范的补充。影响产品的决策必须进入specs/QWEN.md,而不能只存在于数据库中。

具体该记住什么

不需要把请求上下文中的所有内容都保存下来。可以存储很多,但添加到上下文中的应该很少。

有用的类别:

  • 用户持续稳定的偏好;
  • 已确认的项目命令;
  • 智能体反复出现的错误;
  • 检查后的结论;
  • 外部文档引用;
  • 关于活跃分支和进程的备注;
  • 需要迁移到规范中的决策。

无用的类别:

  • 机密信息;
  • 不必要的大量完整会话记录;
  • 随机的中间想法;
  • 没有有效期的过时变通方案;
  • 智能体可以轻松从代码中读取到的内容。

SQLite 架构

创建目录:

mkdir -p .qwen/hooks .qwen/memory

架构已提取到单独文件中:examples/sqlite-memory/schema.sql

在哪里获取示例文件。 下文假设教程仓库 sdd-qwen-code-ru/ 位于你的项目旁边,且变量 TUTORIAL_DIR 指向它。如果教程是单独克隆的,请在执行以下命令前设置 export TUTORIAL_DIR=/path/to/sdd-qwen-code-ru。如果你以其他方式获取了示例文件(下载zip、手动复制),只需替换路径前缀即可。

初始化:

cp "$TUTORIAL_DIR/examples/sqlite-memory/schema.sql" .qwen/memory/schema.sql
sqlite3 .qwen/memory/agent-memory.db < .qwen/memory/schema.sql

钩子1:事件日志记录

脚本已提取到单独文件中:examples/sqlite-memory/hooks/log_event.py

将其复制到项目中并设置为可执行:

cp "$TUTORIAL_DIR/examples/sqlite-memory/hooks/log_event.py" .qwen/hooks/log_event.py
chmod +x .qwen/hooks/log_event.py

钩子2:添加相关记忆

脚本已提取到单独文件中:examples/sqlite-memory/hooks/inject_memory.py

cp "$TUTORIAL_DIR/examples/sqlite-memory/hooks/inject_memory.py" .qwen/hooks/inject_memory.py

chmod +x .qwen/hooks/inject_memory.py

在Qwen Code中配置钩子

配置示例已提取到 examples/sqlite-memory/settings-hooks.example.json

如果项目中已有设置,请手动合并JSON。不要覆盖模型和认证设置。

记忆的后台归纳

后台归纳不应在每个钩子中运行。它读取累积的事件并创建紧凑的记忆记录。可以手动运行、通过cron运行,或在完成重要阶段后运行。

最简单的无API方案:让Qwen Code执行整合,并通过SQL写入结果。

/clear
通过sqlite3读取.qwen/memory/agent-memory.db的最后几行。
将稳定的结论压缩到以下记忆路径:
- profile/preferences.md
- project/agentclinic.md
- workflow/sdd-validation.md
- tools/qwen-code.md

不要包含机密信息和原始记录。
写入前先展示建议的记忆条目。

可以进一步自动化:dream_sqlite.py 获取最新事件,通过你的API客户端调用模型,并更新或插入 memories 中的记录。

两个现成文件:

安装:

cp "$TUTORIAL_DIR/examples/sqlite-memory/dream_sqlite_qwen_example.py" .qwen/memory/dream_sqlite.py

运行:

python .qwen/memory/dream_sqlite.py --since 24h --dry-run
python .qwen/memory/dream_sqlite.py --since 24h

这与Anthropic的后台归纳有何关联

VentureBeat的文章描述了一个原则:智能体不修改模型权重,而是定期回顾过往会话,提取重复出现的模式、错误和有效的工作方法,然后让这些笔记可供未来会话使用。对于SDD,这在检查之后特别有用:

  • 智能体两次忘记更新roadmap.md
  • 用户每次都要求先展示差异;
  • 项目中的测试命令与标准不同;
  • 某种特定类型的迁移经常出问题;
  • 有效的检查清单值得转化为技能。

在SQLite版本中,这成为一个完全本地化和可审计的流程:原始事件保留在 events 中,压缩后的笔记保留在 memories 中,而人可以打开两个表查看。

记忆应让位于规范的地方

如果后台归纳发现了一条新的稳定规则:

workflow/sdd-validation.md

始终在合并功能分支前更新CHANGELOG.md。

需要将其迁移到 QWEN.md 或变更日志技能中。

如果后台归纳发现了一项产品约定:

project/agentclinic.md

AgentClinic中的反馈记录必须是公开且讽刺性的,
而不是私密的客服投诉。

需要将其迁移到功能规范或 mission.md 中。

记忆帮助发现规则。规范使规则成为强制性的。

为什么更少的上下文往往效果更好

智能体记忆很容易变成「曾经讨论过的一切」的仓库。这是个坏主意。近年来的研究和实践记录了一种称为「上下文退化」(context rot)的现象:在大量输入中,模型更难选择相关片段。300个token的简短、精确的上下文,往往比数万个token的大量不相关内容效果更好。

由此得出连接记忆的简单规则:

  • QWEN.md 中混入的不是「想起的一切」,而是仅与当前任务相关的记录(例如按标签/类别);
  • 限制注入长度——几个简短的项目优于长列表;
  • 如果条目失去相关性,删除它,而不是「细化」它;
  • 如果同一条记录每次都需要——这已经不是「记忆」,而是规则,它应该放在 QWEN.md 或章程中。

同样的原理解释了为什么角色之间使用 /clear 有效:你有意识地将会话缩小到对下一个角色重要的内容,而不是在一个会话中累积所有内容。关于技能和会话中的上下文卫生,参见第14部分

检查和查看

事件列表:

sqlite3 .qwen/memory/agent-memory.db \

"select event_name, tool_name, substr(prompt,1,80), timestamp from events order by id desc limit 20;"

记忆条目列表:

sqlite3 .qwen/memory/agent-memory.db \
  "select path, updated_at from memories order by path;"

搜索:

sqlite3 .qwen/memory/agent-memory.db \
  "select path, snippet(memory_fts, 1, '[', ']', '...', 12) from memory_fts where memory_fts match 'validation OR changelog';"

手动记录:

sqlite3 .qwen/memory/agent-memory.db < "$TUTORIAL_DIR/examples/sqlite-memory/manual-memory-example.sql"

隐私和安全

智能体记忆很容易变成多余物品的仓库。设定规则:

  • 不记录环境变量;
  • 截断工具响应;
  • 不保存机密和个人数据;
  • 不向上下文添加超过3-5个记忆块;
  • 定期删除过时记录;
  • 只提交架构和脚本,不提交 .qwen/memory/agent-memory.db

.gitignore 的规则示例已提取到 examples/sqlite-memory/gitignore.example

实践

  1. 创建SQLite架构。
  2. log_event.py 连接到 UserPromptSubmitPostToolUseStop
  1. inject_memory.py 连接到 SessionStartUserPromptSubmit
  2. 完成一个SDD功能。
  3. 查看 events
  4. 创建2-3条手动记忆条目。
  5. 启动新的Qwen Code会话,检查相关记忆是否被添加到上下文中。
  6. 检查后,手动或通过脚本对记忆进行简要归纳。
  7. 将记忆中的强制性规则迁移到 QWEN.md、规范或技能中。

思考题

  1. 为什么原始事件和稳定记忆条目应该是不同的表?
  2. 哪些信息不能保存在智能体记忆中?
  3. 为什么记忆的后台归纳最好离线运行,而不是在每个钩子中运行?
  4. 什么时候需要将记忆迁移到 specs/
  5. 如何限制添加的上下文,避免记忆污染请求?
我的笔记
0 / 10000

笔记保存在当前浏览器中。在其他设备上将不会显示。

课程菜单

课程

基于 Qwen Code CLI 的规范驱动开发
进度 0 / 135