关于 live-memory
live-memory 是面向 Claude Code 的代码库记忆 MCP 服务,通过读取和编辑钩子持续积累各工作区知识,让 Agent 可查询代码理解信息。它只读且可跨会话保留记忆。
主要功能
- 01跨会话保存工作区记忆
- 02通过钩子被动学习文件内容
- 03提供只读代码问答工具
- 04支持预加载参考文档
- 05可配置模型与服务提供方
适用场景
- 01询问代码位置与调用关系
- 02了解代码如何实现某项功能
- 03让 Agent 开始编辑前获取代码背景
MCP 相关
它作为 HTTP MCP 服务提供 ask_live_memory 只读工具,供 Claude Code 查询累积的代码库记忆。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
██╗ ██╗██╗ ██╗███████╗
██║ ██║██║ ██║██╔════╝
██║ ██║██║ ██║█████╗
██║ ██║╚██╗ ██╔╝██╔══╝
███████╗██║ ╚████╔╝ ███████╗
╚══════╝╚═╝ ╚═══╝ ╚══════╝
███╗ ███╗███████╗███╗ ███╗ ██████╗ ██████╗ ██╗ ██╗
████╗ ████║██╔════╝████╗ ████║██╔═══██╗██╔══██╗╚██╗ ██╔╝
██╔████╔██║█████╗ ██╔████╔██║██║ ██║██████╔╝ ╚████╔╝
██║╚██╔╝██║██╔══╝ ██║╚██╔╝██║██║ ██║██╔══██╗ ╚██╔╝
██║ ╚═╝ ██║███████╗██║ ╚═╝ ██║╚██████╔╝██║ ██║ ██║
╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝
always-up-to-date codebase memory for Claude Code · ask, don't re-read
Live Memory — Claude Code 插件
一个廉价、始终运行的模型,能够学习你的代码仓库,让你的 Agent 不必再反复读取代码。
Live Memory 将一个独立、价格低廉、上下文窗口大的模型作为长期运行的 MCP 服务,在多个会话中不断积累对代码库的了解。你的 Agent 不必每个会话都重新读取相同的文件,而是可以通过一个只读工具 ask_live_memory 提出需要整体理解的问题——“X 在哪里,Y 如何工作,什么会调用 Z”——Live Memory 会回答这些问题,为主 Agent 做好启动高效工作的准备(例如编辑代码)。它会通过钩子被动地从 Agent 自己的读取和编辑操作中学习(内容会被转发,无需额外读取),并随着代码仓库的变化(修改和删除)保持更新。只读且受路径限制(绝不会编辑、创建或运行任何内容);使用 Claude 订阅即可零配置(Haiku,无需 API 密钥);记忆模型可插拔——可接入本地模型或任何兼容 OpenAI 的端点。

工作原理
flowchart LR
repo[("Your repo")]
subgraph sessions["Claude Code sessions — premium model (many, over time)"]
agent["Agent"]
end
agent -->|"reads / edits files"| repo
agent -. "PostToolUse / FileChanged hooks<br/>tee file content — passive learning (free)" .-> lm
agent ==>|"ask_live_memory(question, cwd)<br/>one read-only MCP tool"| lm
lm ==>|"grounded answer — no file re-reading"| agent
subgraph server["Live Memory — one MCP server per workspace (singleton)"]
lm["Cheap / local large-context model<br/>+ accumulating context window<br/>append-only · neutral compaction to a ledger"]
lm --> snap[("Local JSON snapshot<br/>persists across sessions")]
end
你的 Agent 照常读取或编辑文件;钩子会悄悄将这些内容转发给服务,让它免费学习。当 Agent 需要了解某些内容时,它会询问 ask_live_memory,而不是重新读取——服务会从按工作区积累的记忆中回答(如果尚未见过相关内容,则会自行只读代码)。一个服务可供所有会话使用,并且会在会话之间持续运行。
基准测试
在真实代码仓库上进行 A/B 测试,统计每项任务从开始到完成的成本。成本从三个方面展示:高级模型(负责构建)的费用——即昂贵模型的开销,因为配套模型使用的是低成本或本地模型;以及总成本,其中还计入配套模型使用 DeepSeek-v4-flash 或 Haiku 时自身的成本:
| 每项任务 | 高级模型费用 | 总成本 · DeepSeek-flash† | 总成本 · Haiku | 速度提升 |
|---|---|---|---|---|
| 理解密集型(追踪 / 理解) | −61% | −57% | −25% | ~22% |
| 混合型(先理解再编辑:修复漏洞 + 实现功能) | −28% | −26% | −11% | ~11% |
| 纯编辑 / 执行 | ~持平 | ~持平 | ~持平 | ~0 |
理解密集型任务还会将高级模型读取代码库的 token 减少约 93%(成本波动也更小),而且混合型任务的正确性从未下降(使用和不使用它时,12/12 项都通过)。DeepSeek-v4-flash 的回答准确率与 Haiku 相当(3 次重复测试中为 98% 对 91%),token 价格却低约 8 倍;使用本地配套模型的成本几乎为零,因此总成本约等于高级模型费用。结果可完全复现并经过审计(人工 + Fable)。完整数据和方法: benchmark/results/RESULTS.md。
† 配套模型按 DeepSeek-v4-flash 费率重新计价(比 Haiku 便宜约 8 倍);理解型任务的数据为精确值,混合型任务的数据则根据实测成本比推算。
项目渊源: Live Memory 最初是 shofer.dev(Arkware 的并行多 Agent 编码平台)的一项功能,多个会话共享一份同步的代码库记忆。现在,这一理念以独立的 Claude Code 插件形式呈现——全新实现、独立完整,不依赖 shofer。它属于 shofer Claude Code 插件系列(另有 slang-workflows)。设计:DESIGN.md · 与 Copilot/Cursor 的对比:COMPARISON.md · 测试:TESTING.md · 隐私:PRIVACY.md。
快速开始
live-memory 是一个只需启动一次的 HTTP MCP 服务(单例,为每个 Claude Code 会话提供服务),
外加一个用于注册 ask_live_memory、钩子和斜杠命令的插件。先启动服务——Claude Code 只会连接到它(不会启动它),因此如果服务未运行,就会出现连接错误。
1 — 启动服务(使用 Claude 订阅即可零配置 → Haiku;无需 API 密钥):
git clone https://github.com/shofer-dev/claude-code-live-memory
cd claude-code-live-memory/deploy && ./install-service.sh # venv + user systemd service, auto-starts on boot
# …or just run it in a terminal:
# cd claude-code-live-memory/server && pip install -e . && python -m live_memory
2 — 安装插件(在 Claude Code 会话中):
/plugin marketplace add shofer-dev/claude-code-live-memory
/plugin install live-memory@shofer-live-memory
向你的 Agent 提出一个关于整个代码库的问题——它会调用 ask_live_memory,而不是读取文件。
/live-memory-stats 显示积累的知识和费用 · /live-memory-config 切换模型/提供商 · /live-memory-empty 清空记忆 · /live-memory-reset 重新开始工作区,并重新加载已配置的预加载文档。提供商、systemd、工作区和并发的详细信息见下文。
结构
live-memory/
├── .claude-plugin/plugin.json # plugin manifest
├── .mcp.json # registers the server (type:http, explicit timeout)
├── hooks/ # PostToolUse(Read|Write|Edit|…) + FileChanged → TEE file content (passive learning)
│ ├── hooks.json
│ └── notify.py
├── skills/live-memory/SKILL.md # tells the agent when/why to call ask_live_memory
├── commands/ # USER-facing slash commands (not agent tools)
│ ├── live-memory-stats.md # /live-memory-stats → GET /stats
│ ├── live-memory-config.md # /live-memory-config → set model/provider, hot-reload
│ ├── live-memory-empty.md # /live-memory-empty → wipe memory (this workspace or `all`)
│ ├── live-memory-reset.md # /live-memory-reset → drop history + re-preload configured docs
│ ├── stats.py · config.py · empty.py · reset.py
├── settings.json
├── deploy/ # systemd unit + env example + install-service.sh
└── server/ # the long-running MCP server (Python, asyncio)
├── pyproject.toml # deps + mypy(strict) + pytest config
├── tests/ # pytest unit suite (mocked; no network)
└── live_memory/
├── __main__.py # entrypoint: python -m live_memory
├── server.py # MCP (HTTP) ask_live_memory + /health + /stats + /notify + /clear + /reset + /reload
├── workspace.py # per-cwd state registry (window + queue + store); fork/commit
├── manager.py # the agent loop (process one question); compaction
├── context_window.py # budget; file-context evict, Q&A summarize; fork/clone
├── summarizer.py # NEUTRAL, query-agnostic knowledge-ledger summarization
├── question_queue.py # per-workspace admission (serial/parallel) + per-entry timeout
├── async_jobs.py # opt-in fire-and-forget job registry (submit/poll)
├── keep_warm.py # background KV/prompt-cache keep-warm loop
├── conversation_store.py # versioned JSON snapshot (SHA-256 file validation)
├── llm_client.py # provider-pluggable: Anthropic Messages | OpenAI-compatible
├── oauth.py # subscription OAuth credential + auto-refresh (zero-config)
├── config.py # layered config (env > config.json > defaults) + provider knowledge
├── constants.py # ALL tunable magic numbers + defaults, centralized (config sources its defaults here)
├── models.py # core dataclasses (ChatMessage, FileContext, QuestionResult, …)
├── tool_executor.py # read-only tools (Read/Grep/Glob/find_paths/git/…), path-jailed
├── preload.py # configured preload globs → verbatim docs on workspace load
├── directory_tree.py # workspace scan, ~10% context cap
├── pricing.py # per-model USD cost (+ env overrides)
├── logging_setup.py # stderr→journald + optional rotating file
└── prompts.py # system prompt + neutral-summary prompt
架构(完整设计依据请参阅 DESIGN.md)
- 由外部监督、具备幂等性的 HTTP MCP 服务(单例)为所有
Claude Code 会话提供服务;状态按工作区(
cwd)区分。 - 模型独立且可切换提供商:服务运行自己的廉价模型(而非会话使用的模型)。两种适配器涵盖了几乎所有情况——Anthropic Messages
(带有
cache_control)和兼容 OpenAI 的接口(DeepSeek/OpenAI/网关)。 零配置:没有密钥但拥有 Claude 订阅时,会在 Haiku 上使用订阅 OAuth 令牌(自动刷新)。 - 被动(自然)学习:PostToolUse/FileChanged 钩子会将 Agent 读取或编辑的文件内容同步写入
记忆,因此记忆会从实际工作中免费积累;对于尚未见过的内容,则由
ask_live_memory主动补充。 - 预加载 glob(可选):
preload_globs(例如docs/*.md)指定参考 文档;每当工作区加载或重新加载时,这些文档都会原样载入系统提示词,让记忆一开始就了解它们。它们的处理方式与观察到的内容相同: 后续压缩时,会在需要时将其提炼到知识账本中。/live-memory-reset会清除工作区的历史记录,并重新预加载这些文档。 - 压缩之间采用仅追加窗口;压缩 = 批量中性摘要 并配合高/低水位线(不频繁、批量处理)——将观察到的文件和问答提炼成与查询无关的知识账本——绝不从前端截断。
- 冻结的易变区块 + 观察增量(保留 KV 缓存):易变系统区块(账本 + 预加载/观察到的内容 + 清单) 在压缩之间保持冻结,并以逐字节相同的内容重新发送;期间到达的变更(同步写入的文件、过期通知)会作为增量消息追加到历史记录 中,而不是修改该区块——这样提供商的前缀缓存就能持续匹配,而不会在首个变更字节处截断。
- 双层超时:
ask_live_memory(question, cwd, max_answer_tokens?)最多等待由服务配置的软超时预算(default_timeout_s, 默认 60s——不再是工具参数),并在硬性.mcp.jsonMCP 超时之前返回尽力而为的答案。 - 明确告知的答案长度预算:答案设有硬性上限(默认为
LIVE_MEMORY_MAX_ANSWER_TOKENS),并且模型也会获知该上限,因此会自行控制长度,而不是在句子中途被截断;可选参数max_answer_tokens可针对单个问题覆盖该上限。 - 通过
/live-memory-stats斜杠命令查看人工可读状态(→/stats),并从 Agent 的工具界面中隐藏。
安装
前置条件: Python ≥ 3.10;建议安装 ripgrep(rg)(支持 Grep);git 可选(支持 git_search / get_changed_files)。
1. 安装服务:
cd server
pip install -e . # runtime deps (mcp, anthropic, starlette, uvicorn, watchdog, httpx)
# for development/tests: pip install -e ".[dev]" # adds mypy, pytest, pytest-asyncio
2. 将插件安装到 Claude Code 中,以便它读取 .mcp.json、钩子、技能和斜杠命令。仓库根目录同时也是一个单插件市场(.claude-plugin/marketplace.json);/plugin install 只能从市场安装,不能从普通目录安装——所以请先添加市场,再从中安装。在 Claude Code 会话中:
/plugin marketplace add https://github.com/shofer-dev/claude-code-live-memory
/plugin install live-memory@shofer-live-memory
shofer 是市场名称;live-memory 是插件名称。若要从本地克隆安装,请将 add 指向检出目录:
/plugin marketplace add /ABSOLUTE/PATH/TO/claude-code-live-memory
/plugin install live-memory@shofer-live-memory
之后编辑插件文件时,运行 /plugin marketplace update shofer,然后运行 /reload-plugins(已安装的插件会缓存在 ~/.claude/plugins/ 下,因此源文件的编辑不会实时生效)。
本地开发时,可完全跳过市场,直接加载插件并启动 Claude Code——这样通过 /reload-plugins 就能加载编辑内容:
claude --plugin-dir /ABSOLUTE/PATH/TO/claude-code-live-memory
(Claude Code 连接前,步骤 3 中的服务必须正在运行——.mcp.json 指向一个 type:http 端点,Claude Code 只会连接它,不会启动它;如果服务未运行,你会在 /plugin 的 Errors 标签页中看到连接错误。)
3. 运行服务(见下一节)。4. 开发检查: mypy live_memory/ && pytest。
运行服务
HTTP 传输要求 Claude Code 连接前服务已经运行(Claude Code 不会启动 type:http 服务)——请在外部监管程序(systemd/容器等)下运行它。
零配置(无需 API 密钥):如果你已登录 Claude 订阅账户,就能直接使用——服务会在 Haiku 上复用该凭据(并自动刷新)。
cd server && pip install -e .
python -m live_memory
# serves MCP at http://127.0.0.1:7711/mcp (+ /health, /stats, /notify, /reload)
订阅方案使用的是订阅的速率限制额度(不按 $ 计费)——这是服务条款中有记载的灰色地带。若要运行始终在线的服务,建议使用密钥。
选择任意模型/提供商——使用环境变量,或 /live-memory-config 斜杠命令(会写入 config.json、热重载且无需重启):
# DeepSeek (cheap, recommended), via env:
LIVE_MEMORY_PROVIDER=openai LIVE_MEMORY_BASE_URL=https://api.deepseek.com \
LIVE_MEMORY_API_KEY=sk-... LIVE_MEMORY_MODEL=deepseek-chat python -m live_memory
# …or at runtime, from inside Claude Code:
/live-memory-config set provider=openai base_url=https://api.deepseek.com model=deepseek-chat api_key=sk-...
/live-memory-config show
支持的提供商:anthropic(Messages API 以及 Bedrock/Vertex/网关,支持 API 密钥或订阅 OAuth)和 openai(任何兼容 OpenAI 的端点:OpenAI、DeepSeek、本地模型、网关)。然后启用插件,让 Claude Code 读取 .mcp.json 并进行连接。
作为 systemd 服务运行
deploy/ 中提供了基础配置。只需一条命令即可注册并启动:
cd deploy
./install-service.sh # user service (recommended — see below)
./install-service.sh --system # system-wide (best for API-key setups)
它会创建 venv 并安装服务,在 ~/.config/live-memory/live-memory.env 中写入配置(基于 live-memory.env.example——请编辑该文件以设置提供商/模型/密钥),安装 live-memory.service,启用 lingering,并启动服务。systemd 会通过 EnvironmentFile= 将配置提供给进程。
- 重启后会自动保留数据:每个工作区的快照都保存在
LIVE_MEMORY_DATA_DIR中(默认为~/.claude/plugins/data/live-memory),因此重启后,每个工作区的记忆会在下次查询时重新加载。 - 订阅(零配置)身份验证需要使用用户服务(默认设置):它以你的身份运行,因此可以读取
~/.claude/.credentials.json并复用你的 Claude 登录凭据(并自动刷新)。--system服务也可以实现这一点,但单元配置必须设置User=和Environment=HOME=…(安装程序会为你完成设置)。
systemctl --user status live-memory
journalctl --user -u live-memory -f
systemctl --user restart live-memory # after editing the env file
日志
默认情况下,服务会将日志写入 stderr,systemd 会将其捕获到 journal 中——这是惯用的日志存储位置,并提供日志轮转以及单元/PID 元数据:
journalctl --user -u live-memory -f # user service
sudo journalctl -u live-memory -f # system service
有两点需要注意,以及一种替代方案:
- 只有当 journald 使用持久化存储(
/var/log/journal存在)时,用户服务的 journal 才会在重启后保留。如果你的存储是易失的,这些日志会在重启后消失。 - 无论如何,如果需要持久、便于搜索的纯文本日志,可设置
LIVE_MEMORY_LOG_FILE(例如,系统服务可设为/var/log/live-memory/live-memory.log,用户服务可设为~/.local/state/live-memory/下的绝对路径)。这是一个轮转处理器(LIVE_MEMORY_LOG_MAX_BYTES×LIVE_MEMORY_LOG_BACKUPS),除了写入 journald 外,也会写入该文件。LIVE_MEMORY_LOG_LEVEL(默认值为INFO)用于调整详细程度。
工作区与 cwd
记忆按工作区隔离,依据是传递给 ask_live_memory 的 cwd。
cwd 必须是绝对路径(相对路径会被拒绝——共享服务无法根据你的会话解析该路径)。默认情况下,服务会将每个 cwd 归一到其所属的 git 仓库根目录,因此子目录和仓库根目录共享同一份记忆:
| 环境变量 | 默认值 | 作用 |
|---|---|---|
LIVE_MEMORY_CANONICALIZE_WORKSPACE | true | 将 cwd 归一到其 git 仓库根目录。设为 false 可让每个确切目录拥有独立记忆。 |
LIVE_MEMORY_REPO_ROOT_MODE | nearest | 位于子模块/工作树中时:nearest = 子模块自身的根目录(git 默认行为);outermost = 超级项目根目录(将子模块的问题合并到父项目的记忆中)。 |
预加载 glob——一开始就了解你的文档
preload_globs 用于指定 glob 模式(相对于每个工作区根目录),匹配的文件会从磁盘读取,并在每次工作区加载或重新加载时原样载入系统提示词——这些参考资料会在提出第一个问题之前就为记忆所知。预加载内容会被视为一条观察记录:在知识账本将其提炼并因预算压力舍弃原始字节之前,内容会以内嵌形式显示在自己的标题下。
/live-memory-config set preload_globs=docs/*.md,README.md # or:
LIVE_MEMORY_PRELOAD_GLOBS="docs/*.md,README.md"
| 环境变量 | 默认值 | 作用 |
|---|---|---|
LIVE_MEMORY_PRELOAD_GLOBS | (空) | 以逗号分隔的 glob 模式(相对于工作区根目录,支持 **),在工作区加载时原样预加载。绝对路径模式、匹配结果超出工作区范围的路径(符号链接)以及二进制文件都会被跳过。 |
LIVE_MEMORY_PRELOAD_MAX_TOTAL_BYTES | 2097152 | 每个工作区所有预加载文件的总上限(单个文件的上限为 LIVE_MEMORY_PASSIVE_MAX_FILE_BYTES)。实际有效上限还会受窗口预算限制(compaction_floor × LIVE_MEMORY_MAX_CONTEXT_TOKENS)——超过下限的预加载内容只会让第一个问题立即触发提炼并舍弃文档。若要预加载大于约 300 KB 的语料,也请提高 LIVE_MEMORY_MAX_CONTEXT_TOKENS。 |
注意:
- 预加载会在工作区加载时运行——即服务启动后、执行
/live-memory-empty后或配置变更后的首次查询。通过/live-memory-config更改 glob,只会在已加载工作区下次重置或重启时生效,不会追溯应用。 /live-memory-reset可一步重新启动工作区:丢弃当前历史记录(问答历史、知识账本、文件清单——记忆和磁盘快照),并立即从磁盘重新预加载配置的 glob。若累积的记录已过时,但你想恢复详细参考文档,请使用此命令。(/live-memory-empty会执行相同的清除操作,但不会主动重新预加载——文档仍会在下一个问题到来时延迟加载。)
监控范围(file_globs)和提问超时
| 环境变量 / 配置键 | 默认值 | 作用 |
|---|---|---|
LIVE_MEMORY_FILE_GLOBS / file_globs | (空 — 监控所有内容) | 以逗号分隔的 fnmatch 模式(相对于工作区;* 也会匹配 /)。设置后,文件变更流——被动摄取、过期 / 删除跟踪、修改提示——仅适用于匹配的路径;其他内容都会在工作区边界处被丢弃。将它与 preload_globs 配合使用,创建仅包含文档的记忆:/live-memory-config set preload_globs=docs/*.md file_globs=docs/*.md。 |
LIVE_MEMORY_DEFAULT_TIMEOUT_S / default_timeout_s | 60 | 每个问题的软时间预算。ask_live_memory 不再接受 timeout 参数——调用方将使用此处配置的预算;模型会获知该预算,并在截止时间返回尽力而为的答案。请将其设为低于 .mcp.json 中 MCP 硬超时的值。 |
范围设置也会影响缓存稳定性:不设范围的变更流会收集 Agent 接触的每个文件,而每条新观察结果都是下一次提问必须携带的增量。仅包含文档的范围能让记忆保持聚焦,并缩小提示词。
并发
针对同一工作区的问题采用以下两种模式之一:
| 环境变量 | 默认值 | 作用 |
|---|---|---|
LIVE_MEMORY_CONCURRENCY | parallel | parallel(默认)= 无排队延迟——每个问题都会派生一个窗口,最多同时运行 MAX_PARALLEL_QUERIES 个问题,并由探索代码库最多的派生窗口提交结果(其他窗口仍会返回答案,但不会更新共享记忆)。serial = 每个工作区一次只处理一个问题(共享窗口原地增长;缓存局部性最佳,并发调用方需等待)。 |
LIVE_MEMORY_MAX_PARALLEL_QUERIES | 4 | parallel 模式下每个工作区可并发处理的问题数上限。 |
(无论此设置如何,针对不同工作区的问题始终会并发运行。)
异步(即发即忘)工具 — 选择启用
MCP 工具调用会阻塞调用方当前轮次,直到调用返回。如果希望 Agent 提交耗时较长的查询后继续工作,并稍后收集答案,请设置 LIVE_MEMORY_ASYNC_TOOLS=true,以额外启用:
ask_live_memory_submit(question, cwd)→ 立即返回job_id。ask_live_memory_result(job_id)→ 就绪时返回答案,否则返回[running],以便再次轮询。
Agent 负责轮询(Claude Code 无法将完成结果推送到正在运行的轮次中)。此功能默认关闭;ask_live_memory(同步)始终可用。
保持缓存温热
默认关闭——可通过设置 LIVE_MEMORY_KEEP_WARM=true 启用,或使用斜杠命令:/live-memory-config set keep_warm=true。后台循环会向每个近期活跃工作区的前缀发送 ping(max_tokens=1,丢弃输出),以避免提供商的 KV / 提示词缓存变冷——让下一次实际查询享受缓存命中计价,而非完整冷读。心跳间隔根据提供商而定:Anthropic / OpenAI 为 4 分钟(240s),略短于其以分钟计的缓存 TTL;DeepSeek 则会自动设为很长的间隔(其磁盘缓存可持续数小时 / 数天,因此即使启用,此功能也会在该提供商上自动禁用)。可通过 LIVE_MEMORY_KEEP_WARM_INTERVAL_S / /live-memory-config set keep_warm_interval_s=… 覆盖间隔,也可通过 LIVE_MEMORY_KEEP_WARM_MAX_IDLE_S 让空闲工作区更早停止预热。/live-memory-stats 会显示上次刷新缓存的时间。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。