Recall:为Claude Code添加本地项目记忆
开源项目实现AI在多会话间维持项目上下文的能力,解决Claude Code用户需要重复说明上下文的痛点。
开源项目实现AI在多会话间维持项目上下文的能力,解决Claude Code用户需要重复说明上下文的痛点。
Claude Code 每次会话都从零开始。Recall 会保留你的会话日志并将其凝聚成一份简历式的总结——完全在你的机器上。没有 API 密钥,没有外部模型,什么都不会被发送出去。它为在本地运行 Claude Code 的订阅用户而构建:循环中唯一的 AI 是 Claude Code 本身;总结工作由经典 Python 总结器完成。
免费使用你的订阅。它解决了冷启动问题——不再需要每个会话都重新解释项目——而不需要按量计费的总结器增加开支。总结是一个本地算法,不是 LLM 调用,所以持久化记忆除了你已经支付的订阅外不需要任何成本。
节省你的使用额度。两种方式:(1) 总结在本地构建,所以捕获和更新记忆不消耗零个模型令牌;(2) 从紧凑的 context.md(~1-2K 令牌)恢复,而不是每个会话都从头重新解释项目,意味着每个会话花费远少的令牌——延伸你的订阅使用额度(或在 API 上降低计费额度)。
没有任何东西离开你的机器。你的文字记录(代码、路径,有时是密钥)永远不会被发送到任何 API。大多数"记忆"工具把你的上下文通过管道传给模型端点;Recall 做出了他们做不到的隐私保证。完整政策见 PRIVACY.md。
零摩擦。无需 pip install,无需运行本地模型,无需配置密钥,离线可用。插件加载那一刻就开始工作。
两个文件,写入你的项目下的 .recall/:
history.md — 日志。仅追加。每个会话在发生时被捕获(你的提示、Claude 的回复、触碰的文件和运行的命令)。
context.md — 总结。由本地总结器覆写——凝聚的"我们现在在哪里"你可以加载到下个会话:目标、总结、后续步骤/开放线程、触碰的文件,以及你停在何处。
它有——Recall 是补充,不是替代。内置选项解决不同的问题:
CLAUDE.md(和 # 快捷方式)是手写记忆:你策划的规则和笔记,作为 Claude 遵循的指令加载。很适合"我希望你怎么工作",但需要手动维护,它不记录会话中实际发生了什么。
--continue / --resume 重放之前的对话——完整保真,但它重新加载整个文字记录(令牌重)且与一台机器上你的本地会话历史绑定,不是可移植的、可读的摘要。
上下文压缩在会话内凝聚对话;它不是你几天后重新打开的持久记录。
Recall 填补了这个空隙:一份自动、确定的记录,记录每个会话做了什么,凝聚成一个紧凑的恢复点。
简言之:CLAUDE.md 是我希望你怎么工作;Recall 是这是我们上次做的和我们停在哪里——完全离线生成,没有模型令牌消耗。
没有任何地方有 LLM 调用——总结由在本地运行的 TF-IDF + TextRank(提取式总结)生成。
scripts/summarizer.py 排名你会话中最重要的句子:
context.md 用确定性事实包装那个总结,直接从文字记录和 git 中拉出:目标(你的第一个要求)、触碰的文件、运行的命令、你停在哪里,和 git diff --stat。
无需安装。整个 TF-IDF + TextRank 实现都在 summarizer.py 中包装。如果 numpy 恰好可导入就被用来向量化数学(对大会话更快);如果不行,一个相同的纯 Python TextRank 就运行。相同的算法,相同的结果——numpy 是可选加速器,不是要求。保存输出告诉你哪个路径运行了。
/recall:save — 运行本地总结器 → (覆写) context.md。
/recall:show — 打印 context.md。
/recall:log — tail history.md。
将其放在项目根目录以覆写默认值:
暂停项目的日志记录而不编辑配置:创建 .recall/.capture-paused。删除它以恢复。
Recall 不发起网络调用,不使用 API 密钥,不加载第三方模型。总结器是本地 Python;hooks 是仅标准库(numpy 是可选加速器)。它读取你的会话文字记录并仅写入 output_dir。具体地说:
无凭证,永远。 插件零处引用 API 密钥、auth、ANTHROPIC_*,或 HTTP。如果 claude 本身显示"Invalid API key",那是 CLI 自己的 auth——通常是陈旧的 ANTHROPIC_API_KEY env 变量遮蔽你的订阅登录。unset ANTHROPIC_API_KEY(或运行 env -u ANTHROPIC_API_KEY claude …)。它与 Recall 无关。
编辑。 最优化传递去掉常见密钥形状(API 密钥、令牌、.env 赋值、PEM 密钥)在写入前,因为 context.md / history.md 可能被提交。最优化,不是保证——提交前审查。
强化 git。 git diff/log 以 core.fsmonitor、diff.external、hooks,和传呼机禁用运行,所以一个不可信克隆的仓库不能用它自己的 git 配置在 Recall 读取真相时执行代码。设置 include_git: false 来完全跳过 git。
限制写入。 output_dir 被强制留在项目内;项目发货的配置不能重定向写入到绝对路径或 ../...
范围文字记录。 Recall 只读当前项目的文字记录(由 cwd 匹配);它永不回退到另一个项目的会话。
共享记忆的信任边界。 context.md 在会话开始被注入到模型中。如果你提交 .recall/ 作为共享团队记忆,像对待任何其他共享输入一样对待它:一个队友(或一个有仓库写入权限的坏演员)可能策划一个 context.md 来尝试提示注入。SessionStart 围栏内容并标记为不可信数据,Claude 在依赖它前询问——但如果你不完全信任谁能写仓库,保持 .recall/ git 忽略(默认)。
两个都很好。提交它作为共享团队记忆,或 git 忽略它作为个人记忆(.gitignore 默认发货忽略它——翻转注释来提交)。
/plugin marketplace add raiyanyahya/recall
/plugin install recall@recall
本地开发(无需安装步骤):
claude --plugin-dir /path/to/recall
无 pip install——总结器是包装的和仅标准库(如果存在 numpy 用作可选加速器)。进行一个会话,运行 /recall:save,打开一个新会话——Recall 用你停在哪里问候你。
Claude Code 是 Recall 的一流工具——上面的插件安装是主要的、完全支持的路径,这个部分的什么都不影响它。但 Recall 写的记忆是 .recall/ 中的普通 markdown,不是工具状态,所以其他编码代理可以生成和消费完全相同的文件。工具支持总是可选的:除非你明确设置它,什么都不激活。一个好结果:记忆跨工具共享——一个 Claude Code 用户和同一仓库上的 opencode 用户写到相同的 history.md,任一方的 context.md 都恢复对方的工作。
不像 Claude Code,opencode 没有插件市场和无在 CLI 安装命令——没有 /plugin install 要在里面运行。插件从文件和配置加载:项目的 .opencode/plugins/(或全局 ~/.config/opencode/plugins/)中的任何东西在启动时自动加载,自定义命令是 .opencode/commands/ 中的 markdown 文件,会话启动上下文来自 opencode.json 中的指令列表。Recall 恰好插入那些机制——一个小安装器一次生成文件,opencode 从那以后自动从它们获取。
每个项目设置一次——不是每个会话,不是每次机器启动:
git clone https://github.com/raiyanyahya/recall ~/recall
python3 ~/recall/scripts/install.py --opencode --project /path/to/your/project
保持克隆周围——生成的插件指向它。重新运行安装器的唯一原因是如果你移动克隆(或想卸载)。
安装器写入完全三个东西,全在目标项目内:
从那以后,每个会话是自动的:
在会话开始,opencode 加载 .recall/context.md(通过指令)——你恢复你停在哪里,无需重新解释。
在每个转换后(opencode 的 session.idle 事件),shim 追加新活动到 .recall/history.md。它通过 opencode export——opencode 的公开 CLI——读取会话,不是它的内部存储。
在包装前,运行 /recall-save 来用本地总结器重新生成 context.md——或在 recall.config.json 中设置 auto_save_context: "on_end" 它在每个转换后自动重新生成。
与 Claude Code 路径相同的保证:完全本地,无网络,无 API 密钥;捕获遵尊 recall.config.json、.capture-paused 和编辑;任何失败是一个沉默无操作所以会话从不受影响。随时卸载带 --opencode --uninstall(你的 .recall/ 数据保留),安装器永不覆写或删除一个它没生成的文件。
两个差异从 Claude Code 路径意识到:
指令,不是围栏数据。 opencode 通过它的指令机制加载 context.md,没有无信任数据围栏 Claude Code SessionStart hook 应用的。如果你提交 .recall/ 作为共享团队记忆,只这样做与你信任的协作者。
跟踪 opencode 的公开 CLI(会话列表、export、插件事件 API),这是稳定的表面——但 opencode 移动快;如果一个版本改变这些,捕获退级到一个沉默无操作。文件一个问题。
python -m venv .venv && . .venv/bin/activate
pip install pytest ruff bandit numpy # numpy optional
ruff check scripts tests benchmarks # lint
bandit -c pyproject.toml -r scripts # security static analysis
pytest # run the suite (also test without numpy)
python benchmarks/bench.py # perf + quality numbers (human-readable)
python benchmarks/bench.py --check # assert quality invariants (the CI gate)
claude plugin validate . # official manifest validation
benchmarks/bench.py 是一个仅标准库工具:并排延迟/吞吐量它评分总结器的显著句子选择对反对领头/尾部/随机基线在一个标记的装置集合和检查 numpy 和纯 Python 核心选择相同的句子。--check 出入那些质量不变(它永不出入墙钟时间)。编辑质量由单元套件(tests/test_redact.py)覆盖,所以没有秘密形状装置生活在基准中。
CI(.github/workflows/)运行 lint + Bandit,在 Python 3.9–3.13 测试套件有和没有 numpy(两个总结器路径),基准质量出入(两个路径),CodeQL,秘密扫描,和在每个推送和 PR 上的清单 JSON 验证。见 CONTRIBUTING.md 和 SECURITY.md。
recall/
├── .claude-plugin/plugin.json # manifest
├── hooks/hooks.json # SessionStart (ask/resume) · Stop+SessionEnd (capture)
├── commands/ # /recall:save · show · log
├── scripts/
│ ├── summarizer.py # vendored TF-IDF + TextRank (numpy optional)
│ ├── make_context.py # build/overwrite context.md (--harness claude|opencode)
│ ├── capture.py # append session activity to history.md
│ ├── session_start.py # surface context + ask the start questions
│ ├── parse_transcript.py # transcript → events + renderers
│ ├── harness_opencode.py # opencode adapter (public CLI only) + opencode_capture.py
│ ├── install.py # flag-based installer for opt-in harnesses (--opencode)
│ └── config.py · common.py · redact.py
├── integrations/opencode/ # generated-file templates (plugin shim, /recall-save)
├── tests/ # pytest suite (summarizer, capture, security, …)
├── benchmarks/bench.py # perf + quality harness (CI quality gate)
├── .github/ # CI, CodeQL, secret scan, dependabot
├── recall.config.json # config template / defaults
├── pyproject.toml # ruff / pytest / bandit config (no runtime deps)
├── LICENSE · SECURITY.md · CONTRIBUTING.md
└── .gitignore
欢迎错误和想法——打开一个问题(提供错误报告和功能模板)或拉取请求。在提交前见 CONTRIBUTING.md,并按 SECURITY.md 而不是公开问题中的私密报告安全漏洞。