Skip to main content

mem8

mem8 0.2: structured messages and dual update APIs

String message content remains backwards compatible. Rich transcripts can use vendor-neutral text, thinking, tool_call, tool_result, and attachment_text parts:

from mem8 import (
    AttachmentTextPart,
    Memory,
    Message,
    TextPart,
    ThinkingPart,
    ToolCallPart,
    ToolResultPart,
)

messages = [Message(role="assistant", content=[
    ThinkingPart(text="private reasoning"),
    ToolCallPart(call_id="call-1", name="python_version"),
    ToolResultPart(call_id="call-1", content="Python 3.12"),
    AttachmentTextPart(text="project requires Python 3.12", filename="README.txt"),
    TextPart(text="The project uses Python 3.12."),
])]

with Memory.open() as memory:
    memory.update(messages)  # extracts Knowledge, then builds memory

During extraction, thinking, tool_call, and failed tool_result parts are excluded by default. Text, successful textual tool results, and extracted attachment text can be used as evidence. Binary attachments are not accepted.

When an external LLM has already summarized the knowledge, skip compression and directly reuse mem8's deduplication, decision, and write-back pipeline:

from mem8 import Knowledge, Memory

knowledges = [Knowledge(
    claim="The user prefers concise answers.",
    scope="communication preferences",
    evidence=["Please keep answers concise."],
    confidence=1.0,
    suggested_tags=["preference", "style"],
)]

with Memory.open() as memory:
    report = memory.update_from_knowledge(
        knowledges,
        operation_key="memory-intent:example-1",
        expected_generation=memory.generation,
    )
  • Memory.update(messages) remains the transcript-driven API for future dream workflows.
  • Memory.update_from_knowledge(knowledges) is the preferred API for knowledge already summarized by an external LLM; it accepts 1 to 10 items per call.
  • Both modes share write logic, locking, operation receipts, and optimistic generation checks. Read-only workspaces reject both modes.
  • mem8 has no MCP, agent_runner, admgraiindustry, or vendor transcript SDK dependency. Hosts map SDK events into mem8's generic message parts.

CLI equivalents:

uv run mem8 update --messages messages.jsonl
uv run mem8 update-knowledge --knowledge-file knowledges.json

Installation from PyPI

pip install mem8-fs

The distribution name is mem8-fs; the Python import package remains mem8:

from mem8.api import Memory

mem8 是一个面向 AI Agent 的本地优先长期记忆 Python 包。Markdown 是记忆正文的事实来源;SQLite 保存元数据、链接和评估记录,并通过 FTS5 BM25、sqlite-vec 向量检索及 RRF 融合提供混合检索。LLM 负责从对话中提炼、判断和更新记忆,也用于检查并修复断链。

当前版本为 0.2.0,支持本地 Markdown 记忆、核心记忆注入、按 ID 或路径查询、BM25 与向量混合检索、对话驱动或结构化知识驱动的记忆更新、断链检查修复,以及 retrieval、update、check 评估。默认记忆根目录是当前工作目录下的 .mem8。

环境要求

  • Python 3.11 或更高版本。
  • 使用 uv 管理依赖、虚拟环境和命令。
  • 默认 LLM 为 Anthropic,需要配置 ANTHROPIC_API_KEY。
  • 至少安装一种 Embedding Provider:Local、OpenAI 或 Voyage。
  • Local Embedding 首次加载模型时可能需要联网下载模型文件。

当前内置 LLM 实现仅支持 Anthropic。openai extra 目前只提供 OpenAI Embedding,不提供 OpenAI LLM。

安装与初始化

安装项目

安装开发、评估和默认 Local Embedding 依赖:

uv sync --extra dev --extra evals --extra local

也可以按需选择 Embedding Provider:

uv sync --extra local   # 本地 sentence-transformers,默认配置
uv sync --extra openai  # OpenAI Embedding
uv sync --extra voyage  # Voyage Embedding

初始化记忆目录

uv run mem8 init

初始化后,mem8 使用以下目录结构:

.mem8/
├── core/       # 用户注入的只读核心记忆,首次注入时创建
├── notes/      # Agent 创建和维护的普通记忆,首次写入时创建
├── mem8.db     # SQLite 数据库及索引
└── mem8.toml   # Provider 与存储配置

所有卡片路径都相对于记忆根目录,例如 notes/context.md。所有 CLI 命令均可通过 --memory-root PATH 指定其他完整记忆根目录;Python API 则通过 Memory.open(memory_root=...) 指定。mem8 不会在自定义根目录中再创建第二层 .mem8。

打开旧工作区时,如果存在 <memory_root>/.mem8/mem8.toml 或 <memory_root>/.mem8/mem8.db,且根目录不存在同名文件,mem8 会自动将其迁移到根目录。新旧位置同时存在同名文件时会停止迁移,要求人工处理冲突。

journal/ 属于后续恢复机制设计,当前版本不会创建或使用该目录。

CLI 使用

初始化、迁移与配置

# 初始化工作区;重复执行是安全的
uv run mem8 init

# 单独执行幂等数据库迁移
uv run mem8 migrate

# 修改配置
uv run mem8 config set llm.model claude-sonnet-4-6
uv run mem8 config set llm.max_tokens 4096
uv run mem8 config set embedding.provider local
uv run mem8 config set embedding.model all-MiniLM-L6-v2
uv run mem8 config set embedding.dim 384
uv run mem8 config set storage.db_filename mem8.db

配置保存在 <memory-root>/mem8.toml,也可以使用环境变量覆盖:

  • MEM8_LLM__MODEL
  • MEM8_LLM__MAX_TOKENS
  • MEM8_EMBEDDING__PROVIDER
  • MEM8_EMBEDDING__MODEL
  • MEM8_EMBEDDING__DIM
  • MEM8_STORAGE__DB_FILENAME

核心记忆、检索与查询

# 注入核心记忆,仅接受 Markdown 文件
uv run mem8 core inject ./seed.md

# BM25 + Vector + RRF 混合检索
uv run mem8 retrieve "context overflow" --topk 5 --similarity 0.55

# 按 ID 或相对路径查询,二者必须且只能提供一个
uv run mem8 query --card-id 1
uv run mem8 query --path notes/context.md

更新与检查

更新命令接收 JSONL 历史对话:

uv run mem8 update --messages messages.jsonl
uv run mem8 check

messages.jsonl 的每个非空行必须包含 role 和 content:

{"role":"user","content":"I prefer concise answers."}
{"role":"assistant","content":"Understood."}

update 执行“压缩 → 决策 → 写回”流程;check 扫描并尝试修复断链。

评估

uv run mem8 eval --suite retrieval
uv run mem8 eval --suite update --record
uv run mem8 eval --suite check --baseline
uv run mem8 eval --suite all --record

--record 只持久化普通评估运行,不会自动将其设为基线。--baseline 仅在数据库已有 is_baseline=True 的显式基线时计算相对差值;门禁指标下降超过 5% 时命令返回非零状态。当前 CLI 尚未提供设置基线的命令,可以通过 Python API 写入基线。

Python API

打开与使用记忆

from mem8 import Memory
from mem8.domain.message import Message

with Memory.open() as memory:
    results = memory.retrieve(
        "how should context overflow be handled?",
        topk=5,
        similarity=0.55,
    )

    if results:
        card = memory.query(card_id=results[0].card_id)

    update_report = memory.update([
        Message(role="user", content="I prefer concise answers."),
        Message(role="assistant", content="Understood."),
    ])

    check_report = memory.check()
    core_card_id = memory.inject_core_card("seed.md")

Memory.open 支持注入自定义组件,便于测试或替换 Provider:

memory = Memory.open(
    memory_root="/path/to/memory",
    llm=my_llm,
    embedding=my_embedding,
    tokenizer=my_tokenizer,
    settings=my_settings,
)

公开方法

Memory.retrieve(prompt, topk, similarity) -> list[RetrievalResult]
Memory.query(card_id=..., path=...) -> RetrievalResult
Memory.update(messages) -> UpdateReport
Memory.check() -> CheckReport
Memory.inject_core_card(source_md_path) -> int
Memory.record_eval_run(run) -> int
Memory.list_eval_runs(eval_name) -> list[EvalRun]
Memory.get_baseline_eval_run(eval_name) -> EvalRun | None

retrieve 要求 prompt 非空、topk > 0,且 similarity 位于 [0, 1]。query 必须且只能提供 card_id 或 path 之一。

如需创建评估基线,可构造 is_baseline=True 的 EvalRun:

from mem8.domain.eval_run import EvalRun

memory.record_eval_run(EvalRun(..., is_baseline=True))

写入约束

  • Agent 新卡只能写入 notes/。
  • 核心记忆只能通过 inject_core_card 或 core inject 注入,更新流程不得修改核心卡。
  • 路径必须是安全的根目录相对 Markdown 路径;绝对路径、反斜杠和目录穿越会被拒绝。
  • 创建卡片时禁止覆盖已有路径。
  • 每张卡片最多 4096 token、最多 8 个 Markdown 出链;链接按 1 token 计数。
  • 修改链接前会重新检查来源卡和目标卡的 token 与出链限制。
  • 混合检索中任一路结果足够强即可进入 RRF 候选,避免单路弱分误杀结果。

开发指南

质量检查

uv run pytest
uv run ruff check mem8 evals tests
uv run mypy mem8 evals

测试覆盖单元、集成和端到端场景。提交代码前应确保 pytest、Ruff 和 mypy 全部通过。

项目文档

prd.md 是产品要求基线;dev.md 包含当前实现梳理与后续演进设计。README 以当前仓库中实际可运行的公开能力为准。

当前边界

dev.md 中的 audit/repair 分离、sync、reindex、recover、journal 恢复和 OpenAI LLM 等属于后续设计目标,当前公开 API 与 CLI 尚未提供这些入口。

Metadata

Release files for mem8-fs 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mem8-fs 0.2.0
File Size Uploaded
mem8_fs-0.2.0.tar.gz 56.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mem8-fs 0.2.0
File Interpreter ABI Platform
mem8_fs-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 129.2 kB

Release files / mem8_fs-0.2.0.tar.gz

Download URL mem8_fs-0.2.0.tar.gz
Size 56.1 kB
Tags Source
SHA-256 checksum
How to use checksums
bd99291f40662495f51b41b085c84b569ce5f57c6610dcb0dd8f2d3efa703bfb
BLAKE2b-256 checksum
How to use checksums
6e682e2afa4e7605a9de239036b62be833bd01f2f8c1986f197c1893930a36ae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

Release files / mem8_fs-0.2.0-py3-none-any.whl

Download URL mem8_fs-0.2.0-py3-none-any.whl
Size 73.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
81a272344f467789c96e7275bc50267435e1d709adb441f845851e0018239714
BLAKE2b-256 checksum
How to use checksums
a18b279aad862e3208f7a2b87734198533abe03fa1f83983290b507e38785226
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

Release history Release notifications | RSS feed

0.3.9

2 release files

0.3.8

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

This release

0.2.0 This release

2 release files

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page