Show HN: Capn-hook —— 编码代理的持久记忆工具 —— 不再重复grep同一谜题

Hacker News Top 工具

摘要

Capn-hook 是一个 CLI 工具,它为编码代理提供持久记忆,保存回答代码库问题的文件,使得代理不再跨会话重复探索同一谜题,将重复问题的 Token 使用量减少 77%。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/07/15 19:45

cyrusNuevoDia/capn-hook 来源:https://github.com/cyrusNuevoDia/capn-hook

🧢🪝 cap’n hook

无需重复排查同一神秘问题。

为编程智能体提供持久化记忆。当你的智能体花费十分钟在某处搞清楚代码结构时,capn 会保存回答该问题的文件。下一次会话中,一条命令即可获取这些文件,无需重新探索——一旦底层文件发生变化,已保存的回答会自动删除。

重复提问时减少 77% 的 token

在 5 个生产代码库(Dub、Polar、PostHog、Twenty、Documenso)上对 60 个真实开发者问题进行测试,使用 capn 回忆的智能体比从头探索的智能体节省了 77% 的 token——两组回答全部正确,60 个问题中右图全部正确,大约 1.6 次回忆即可收回图表会话的成本。 评估运行方式、完整数字及原始证据 → · 谁适合使用 capn → · 使用场景 →

问题

编程智能体会忘记会话之间的所有信息。从“支付 webhook 在哪里处理?”到“src/api/webhooks.ts, handlers in src/billing/handlers/”的路径需要花费真实的时间和 token——并且在会话结束后消失。明天的会话将再次为同样的发现买单。

工作原理

capn init 为 Claude Code 和 Codex 安装一个会话启动钩子。每个新会话中,智能体会看到一条简短提示:在搜索代码库之前,先询问 capn;在辛苦发现之后,将其保存。 该提示(capn context)是完整的集成——没有封装器、没有中间件、没有强制行为。模型读取它并自行决定。从此循环分为三步:

1. 搜索前先询问。

capn ask "where are payment webhooks handled?"

命中则返回 JSONL,包含回答该问题的确切文件,跳过整个搜索过程。未命中则返回退出码 1 并在 stderr 上提示探索并记录发现——未命中仅需数秒;重新探索需要数分钟。

2. 保存代价高昂的发现。 当智能体费尽周折找出答案时,它会记录一个简洁可答的问题以及回答该问题所需的文件,可选地添加行号或陷阱等额外细节:

capn chart "where are payment webhooks handled?" \
  --files src/api/webhooks.ts,src/billing/handlers/stripe.ts \
  --details "Router starts near line 40; Stripe handler owns signature checks."

每个支持文件在保存时都会进行指纹标记(sha256)。好的图表是原子的,而不是巨大的上下文转储。将独立的事实拆分为不同的图表,但当多个文件共同回答一个聚焦的问题时,可以包含多个文件。

3. 过期答案自动删除。 如果任何支持文件发生变化或消失,该条目在可能再次回答之前即被移除。已保存的答案从不编辑——一个答案要么仍然正确(其文件未变),要么毫无价值。这就是为什么命令是 chartunchart,而不是 addupdate:capn 将你的代码库视为海岸线。智能体记录它已经探索过的内容;当海岸线变化时,旧图表被丢弃,智能体在下一次遇到时重新记录。最坏情况下,条目被删除,智能体会重新探索——这正好是 capn 不存在时的状态。

安装

npm install -g capn-hook
# 或 bun install -g capn-hook
cd /path/to/your/project
capn init  # 创建 .capn/, capn 的 QMD 索引, Claude Code 钩子, 和 Codex 钩子
capn init --git  # 同时安装一个提交后钩子以进行清理

发布的 CLI 是 JavaScript,在 Bun 可用时在 Bun 下运行,否则回退到 Node.js。更喜欢委托?告诉你的编程智能体获取并执行 INSTALL.md (https://github.com/CyrusNuevoDia/capn-hook/blob/main/INSTALL.md)——它是为智能体执行的,而不是让你手动复制。

智能体文件钩子命令效果
Claude Code.claude/settings.jsonSessionStart/usr/bin/env capn context注入先询问再记录的图表契约
Codex.codex/hooks.jsonSessionStart/usr/bin/env capn context注入先询问再记录的图表契约

回忆基于 QMD (https://github.com/tobi/qmd) 运行:默认使用语义(混合)搜索,使用 capn init --no-embedding 则使用纯关键词(BM25)搜索。默认路径在首次使用时下载嵌入模型(约 300MB 起,完整混合流水线最高约 2GB),模型下载后首次 capn ask 可能需要几秒钟;BM25 路径不下载任何内容,且完全确定。你自己已经在使用 qmd?capn 的索引是 .capn/ 下的独立 sqlite——你的集合不会看到它,它也看不到你的集合。

命令

命令描述
capn init [--git] [--embedding|--no-embedding]设置 .capn/、capn 的 QMD 索引、钩子以及 .capn/ 的 gitignore 行
capn context打印先询问再记录的图表契约(由 SessionStart 钩子使用)
capn ask ""在首先清理过期条目后,打印相关图表命中的 JSONL 结果
capn chart "" --files [--details ""]记录一次发现,对每个支持文件进行哈希处理
capn unchart 手动删除一个图表条目
capn bust 删除某个文件支持的所有图表条目
capn prune删除所有文件已更改或已消失的图表条目
capn list以人类可读格式打印图表条目

图表

.capn/entries/.md——每个问题对应一个本地 markdown 文件。条目是纯文本,可以打开阅读;图表不仅可供工具浏览,也可被人类浏览。capn init 会忽略 .capn/,因此该记忆仅保留在工作副本中。

---
capn: 1
id: 9f3a1c2e
at: 2026-07-03T18:00:00.000Z
files:
  src/api/webhooks.ts: 2f4c0b9c3e0a0c7b5d5d7f8f0a6e2d1c4b8a6f1e2d3c4b5a6978877665544332
---

# Where are payment webhooks handled?

Router starts near line 40; Stripe handler owns signature checks.

.capn/map.json——一个反向索引,从文件路径映射到当前哈希和条目 ID。如果丢失或损坏,capn 会从条目前言中重建。

{
  "src/api/webhooks.ts": {
    "hash": "2f4c0b9c3e0a0c7b5d5d7f8f0a6e2d1c4b8a6f1e2d3c4b5a6978877665544332",
    "entries": ["9f3a1c2e"]
  }
}

.capn/config.json 存储本地项目选项,例如 {"embedding": true}

.capn/qmd/index.sqlite 由 QMD SDK 生成,其旁边有正常的 sqlite -wal/-shm 文件;.capn/entries/ 下的 markdown 仍然是持久性的真实来源,capn init 可以重建索引。

整个 .capn/ 目录是本地的智能体记忆,由 capn init 忽略(gitignore)。图表条目是关于代码库的情景记忆:本地、可丢弃,并且可以通过重新探索安全重建。

设计原则

  • 只记录或取消记录,从不更新。 过时性由内容哈希决定,而不是人的判断。
  • 答案永远不会过时。 capn ask 在返回任何内容之前先移除无效条目。
  • 图表是可丢弃的。 任何条目都可以随时删除;最坏情况是智能体重新探索,这正是现状。
  • 与智能体无关的核心。 CLI 和图表格式不了解 Claude Code;钩子只是一个薄适配器。其他智能体通过调用相同的 CLI 进行集成。
  • 本地优先回忆。 QMD 通过 SDK 在进程内针对 .capn/qmd/index.sqlite 运行,与任何宿主 qmd 安装隔离。没有守护进程,没有服务器——无需持续运行。

许可

MIT

相似文章