Skip to content

HappyThis/NoMemory

Repository files navigation

NoMemory

NoMemory 是一个“记忆基础设施”:只存原始事件(evidence),不持久化“现成的记忆结论”;在需要时通过“回忆(recall)”按场景合成可用的记忆视图(memory view)。

核心理念

  • Evidence-first:事件是唯一权威来源;一切“记忆结论”都可重建、可失效、可追溯。
  • Synthesize on demand:记忆在读取时由回忆 Agent 合成,而不是写入时抽取固化。
  • Pluggable by Skills:场景差异通过 Skills(策略/提示词/工具编排/校验器)完成“微调”。

三层架构

  1. 事件层(Event Log)

    • 只负责可靠地写入/存储/检索“发生过的原始事件”
    • 中事件以对话消息为核心:一个 user_id 对应一条按时间排序的消息序列
  2. 查询层(Query Layer / Recall API)

    • 在事件之上提供多维检索能力(可组合)
    • 典型维度:时间窗、关键词检索、语义检索、邻域上下文等
  3. 适配层(回忆 Agent + Skills)

    • 回忆 Agent = Agent + 可加载的回忆 skill(标准 Agent Skill)
    • 回忆 Agent 使用查询层工具进行多轮检索与重写查询
    • 将召回的事件“合成”为一次性记忆视图(memory view),供调用方选择是否采纳
    • 不固化“裁决结果”:回忆时可通过继续检索尽力裁决,但不把结论写回为长期事实(除非调用方另行存储)

关键术语

  • Message(消息):chat 场景的一条对话消息(用户/助手/system)。
  • Query(查询):对消息集合的检索请求(时间/关键词/语义/过滤/分页;顺序通常由接口固定定义)。
  • Recall(回忆):基于查询结果,由回忆 Agent 合成“记忆视图”的过程。
  • Memory View(记忆视图):一次性生成的“当前可用记忆”(例如:用户偏好/背景),应携带可追溯引用(message_id)。
  • Skill(技能):一组可配置策略与工具编排,用于约束/提升回忆效果(召回范围、查询改写、输出格式、引用要求、覆盖范围声明等)。
    • 在本文档体系里,Skill 以“标准 Agent Skill”的形式存在(Skill 目录 + SKILL.md)。

文档(Docs)

  • docs/README.md:文档目录与阅读顺序
  • docs/query-api.md:查询接口(范围读取 / lexical_search / semantic_search / neighbors 等)
  • docs/recall-service.md:检索服务(绑定 user_id 并向 Agent 暴露不含 user_id 的工具)
  • docs/recall-agent-playbook.md:回忆 Agent 技术方案(如何检索与合成)
  • docs/retrieval-skill-creator.md:creator skill 设计(生成回忆 skill)

Skills 能做什么

Skills 的目标是“同一份事件数据,用不同策略生成不同的记忆视图”。常见能力:

  • 召回范围:默认时间窗、是否只看 role=user
  • 检索编排:多轮查询、查询重写(更好的 query_text)、必要时补 neighbors
  • 输出约束:固定结构、必须给出 message_id 引用、声明覆盖范围(limits)

非目标(Non-goals)

  • 不把“总结后的记忆”作为系统内的事实来源长期保存
  • 不在存储层固化“真值”(回忆时可通过继续检索尽力裁决,但不把裁决结果写回为长期事实)
  • 不强制规定调用方如何缓存/是否回忆(NoMemory 提供原语与契约)

LoCoMo Bench

20260211T034355Z(GLM-4.7)

产物目录:experiments/locomo/20260211T034355Z/

run_id samples qa_total f1_mean judge_mean summary
20260211T034355Z 10 1540 0.5394 0.7922 experiments/locomo/20260211T034355Z/summary.json

judge_mean:LLM-as-judge(LLM 评分正确/错误的均值,范围 0~1)。

Category Count F1 Mean Judge Mean
Multi-hop 282 0.3664 0.7340
Temporal 321 0.5045 0.7321
Open-domain 96 0.2464 0.5000
Single-hop 841 0.6443 0.8680

20260213T015814Z(GLM-5)

产物目录:experiments/locomo/20260213T015814Z/

run_id samples qa_total f1_mean judge_mean summary
20260213T015814Z 10 1540 0.5837 0.7201 experiments/locomo/20260213T015814Z/summary.json
Category Count F1 Mean Judge Mean
Multi-hop 282 0.3945 0.4184
Temporal 321 0.5998 0.7383
Open-domain 96 0.2670 0.5000
Single-hop 841 0.6771 0.8395

Quickstart(本地跑起来)

  1. 一键启动(推荐)
chmod +x ./scripts/dev-up.sh
./scripts/dev-up.sh

默认端口为 8001(可用环境变量覆盖:PORT=8000 ./scripts/dev-up.sh)。

  1. 手动启动(可选)

1.1) 启动数据库(Docker)

docker compose up -d db

1.2) 配置环境变量

  • 复制 .env.example.env 并填写 BIGMODEL_API_KEY(若你要启用 embedding/LLM)

1.3) 安装依赖并迁移(示例以 uv 为例)

uv sync
uv run alembic upgrade head

1.4) 启动服务

uv run uvicorn app.main:app --reload

1.5) 写入消息(唯一写入接口)

  • POST /v1/users/{user_id}/messages:batch

调用示例:

curl -X POST "http://127.0.0.1:8001/v1/users/u_123/messages:batch" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {
        "ts": "2026-02-02T08:00:00Z",
        "role": "user",
        "content": "我不吃辣",
        "meta": { "conversation_id": "c_001" }
      },
      {
        "ts": "2026-02-02T08:01:00Z",
        "role": "assistant",
        "content": "好的,我记住了",
        "meta": { "conversation_id": "c_001" }
      }
    ]
  }'

响应会返回服务端生成的 message_ids(与请求顺序一致)。

1.6) 回忆

  • POST /v1/recall,带 X-User-Id: <user_id>

调用示例:

curl -X POST "http://127.0.0.1:8001/v1/recall" \
  -H "Content-Type: application/json" \
  -H "X-User-Id: u_123" \
  -d '{ "question": "我有哪些饮食偏好?" }'

1.7) 查询(Query API)

  • GET /v1/users/{user_id}/messages:范围读取(支持 since/until/role/page_size/cursor
  • POST /v1/messages/lexical_search:关键词检索(FTS)
  • POST /v1/messages/semantic_search:语义检索(pgvector,若用 query_text 需配置 BIGMODEL_API_KEY 以生成 query embedding)
  • GET /v1/users/{user_id}/messages/{message_id}/neighbors:邻域上下文

调用示例:

# 1) 范围读取
curl "http://127.0.0.1:8001/v1/users/u_123/messages?page_size=20"

# 2) 关键词检索(FTS)
curl -X POST "http://127.0.0.1:8001/v1/messages/lexical_search" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": "u_123",
    "query_text": "\"不吃辣\"",
    "filter": { "role": "user", "time_range": { "since": "2026-01-01T00:00:00Z" } },
    "page_size": 20
  }'

# 3) 语义检索(需要 BIGMODEL_API_KEY,服务端会用 query_text 生成 embedding)
curl -X POST "http://127.0.0.1:8001/v1/messages/semantic_search" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": "u_123",
    "query_text": "饮食偏好 忌口 不吃辣",
    "filter": { "role": "user", "time_range": { "since": "2026-01-01T00:00:00Z" } },
    "top_k": 10,
    "min_score": 0.2
  }'

# 4) 邻域上下文(message_id 可从写入接口返回的 message_ids 中取得)
curl "http://127.0.0.1:8001/v1/users/u_123/messages/<message_id>/neighbors?before=8&after=0"

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages