KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA

配套项目:把每个记忆概念落到代码里 — keel 龙骨

Persistent Memory 的配套项目:配套项目:把每个记忆概念落到代码里

从数据契约开始,逐步把保存、读取、检索、上下文装配和 Harness 接口连起来。不要在第一章就通读所有源码;每理解一个概念,再打开对应模块,代码为什么存在会更清楚。

1. 准备环境

建议使用 Python 3.11 或更高版本:

python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt

四个示例会自动找到 src 目录,不需要手动设置 PYTHONPATH。

需要真实模型的示例还要求本机运行 Ollama:

ollama serve
ollama pull qwen3:8b
ollama pull qwen3-embedding:8b

2. 按章节运行和阅读

完成第 03 章后:看数据契约

打开 src/persistent_memory_course/contracts.py,只看四个对象:

MemoryScope      当前数据属于哪个租户和用户
MemorySource     这条信息真正来自哪里
MemoryCandidate  模型提出、但还没有写入权限的候选
MemoryRecord     通过门禁后保存的正式记录

先尝试回答每个字段由模型、Harness、策略还是存储层提供,再继续看代码。

完成第 04 章后:看 SQLite 生命周期

python examples/01_store_and_recall.py
$env:PYTHONPATH = "src"
python -m pytest tests/test_repository.py -q

对应源码是 repository.py。按这个顺序阅读:

_create_tables()  -> 数据怎样落盘
add()             -> 主记录和审计怎样一起提交
list_active()     -> 作用域、状态和过期怎样过滤
supersede()       -> 新旧版本怎样在同一事务中切换
delete()          -> 记录怎样停止参与正常查询

完成第 05 章后:看 Harness 接口

打开 service.py。MemoryService 不是完整 Harness,而是 Harness 调用的记忆应用服务:

remember()  写路径:策略 -> embedding -> 正式记录
search()    读路径:作用域过滤 -> 相似度 -> 排序
forget()    删除入口:身份作用域 -> 状态变化

重点观察 scope 是调用参数,而不是模型输出。

完成第 06 章后:接入真实 Ollama

python examples/02_extract_candidate.py
$env:PYTHONPATH = "src"
python -m pytest tests/test_extractor_and_context.py -q

对应源码是 extractor.py。它只负责把自然语言转换成 MemoryCandidateBatch,没有 repository,也不能写数据库。

完成第 07 章后:观察检索和上下文

python examples/03_semantic_recall.py
python examples/04_build_context.py

03 使用真实 qwen3-embedding:8b;04 使用确定性的测试 provider,方便反复修改上下文预算。

对应源码:

embeddings.py       Ollama provider、测试 provider、余弦相似度
service.py          过滤后的检索和简单重排
context_builder.py  去重、预算、来源标记和数据边界

3. 一次完整调用怎样穿过这些模块

flowchart LR
    A[OllamaMemoryExtractor] --> B[MemoryCandidate]
    B --> C[MemoryWritePolicy]
    C --> D[MemoryService]
    D --> E[EmbeddingProvider]
    D --> F[SQLiteMemoryRepository]
    F --> G[MemoryService.search]
    G --> H[build_memory_context]
    H --> I[Harness 的模型调用]

图中每条箭头都传递明确对象,而不是任意字符串。这样才能分别测试抽取错误、策略拒绝、数据库失败、检索误召回和上下文超预算。

4. 测试不是附加内容

运行全部测试:

python -m pytest -q

测试覆盖:

学习时可以故意破坏一条规则,再观察哪个测试失败。你会看到生产约束究竟由哪段代码维护。

5. 这个项目没有假装解决什么

它适合学习和小规模实验,但没有假装已经完成全部生产基础设施:

这些限制被明确留下,是为了让你先学会记忆系统的稳定边界,再根据真实规模替换实现。

返回课程目录 · 查看 Harness 接口位置

进入 keel 阅读