Hindsight × Cursor:用 hindsight-cursor 插件为 Cursor 构建跨会话长期记忆
【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight
本文基于 Hindsight 仓库中的官方指南 Guide: Add Cursor Memory with Hindsight,完整讲解如何把 hindsight-cursor 记忆插件安装到 Cursor 项目中:从pip install到hindsight-cursor init的每一步操作、init究竟在磁盘上写入了哪些文件、sessionStart/stop/sessionEnd钩子的底层调用链、MCP 工具的接入方式,以及 bank 隔离、配置分层、状态文件验证等实战细节。读完本文,你可以独立完成"新会话自动召回项目记忆、任务结束后自动留存对话"的端到端配置,并能从源码层面解释每一次记忆注入与留存是如何发生的。
如果你想要给 Cursor 加上长期记忆,最干净的做法就是hindsight-cursor插件。一条hindsight-cursor init命令即可安装插件钩子:会话开始时自动召回相关项目记忆,每个任务结束后自动留存对话,同时写入 MCP 配置,让 Agent 在会话中拥有显式的recall、retain、reflect三个工具。这样 Cursor 就具备了跨编码会话的长期记忆,而不是每个新会话都重新摸索一遍同样的项目上下文。
这个方案天然契合 Cursor,因为 Cursor 同时暴露了钩子系统(hooks)和原生 MCP 支持,插件两者都用上了:sessionStart钩子自动注入召回的记忆作为上下文,stop钩子在任务完成时留存对话转录,MCP 工具则负责按需的定向检索。环境式记忆(ambient memory)无需任何用户干预,而工具始终待命,供 Agent 显式使用。
快速答案(TL;DR)
- 在你的项目目录内执行
pip install hindsight-cursor。 - 运行
hindsight-cursor init --api-url ... --api-token ...(Hindsight Cloud)或--api-url http://localhost:8888(自托管)。 - 完全退出并重新打开 Cursor——插件在启动时加载。
- 会话召回会自动注入项目记忆;自动留存会在每个任务结束后保存对话。
- 验证方式:让后一个会话记得前一个会话存下的内容。
前置条件
开始之前,请确认:
- 已安装并可正常使用 Cursor;
- 一个可达的 Hindsight 后端——Hindsight Cloud 或自托管服务器均可(自托管可用仓库根目录
docker/下的多种 compose 方案,指南给出的最简方式是单个 Docker 容器,见下文 Step 2); - 一个项目目录,因为
init会把插件文件安装到项目里。
另外注意:插件包 hindsight-cursor 要求 Python ≥ 3.10,且零运行时依赖(所有插件脚本只用 Python 标准库),这是它在任意 Cursor 工作区里都能被钩子安全调用的前提。
Step 1: 安装插件
在你想为其添加记忆的项目目录内执行安装:
cd /path/to/your-project pip install hindsight-cursor如果不想永久安装这个包,可以直接用uvx hindsight-cursor init代替"pip install + hindsight-cursor init"的组合。
Step 2: 把插件指向 Hindsight 后端
Hindsight Cloud:向init传入 API 地址和 token:
hindsight-cursor init --api-url https://api.hindsight.vectorize.io --api-token YOUR_HINDSIGHT_API_TOKEN自托管 Hindsight 服务器:
hindsight-cursor init --api-url http://localhost:8888如果还没有 Cloud token,可以注册 Hindsight Cloud 并创建 API key;或者用 Docker 在本地启动 Hindsight:
export OPENAI_API_KEY=your-key docker run --rm -it --pull always -p 8888:8888 \ -e HINDSIGHT_API_LLM_API_KEY=$OPENAI_API_KEY \ -e HINDSIGHT_API_LLM_MODEL=gpt-4o-mini \ -v $HOME/.hindsight-docker:/home/hindsight/.pg0 \ ghcr.io/vectorize-io/hindsight:latestinit会一次性配好两套机制。只想用钩子、跳过 MCP 配置时加--no-mcp;需要覆盖已有安装时加--force。
init的完整命令行参数(以 cli.py 中argparse定义为准):
| 参数 | 默认值 | 说明 |
|---|---|---|
project(位置参数) | . | Cursor 项目路径,缺省为当前目录 |
--api-url | None | Hindsight API 地址,如https://api.hindsight.vectorize.io |
--api-token | None | Hindsight API token |
--bank-id | cursor | 记忆 bank ID |
--no-mcp | 关闭 | 跳过 MCP 集成配置 |
--force | 关闭 | 覆盖已存在的安装 |
Step 3: 完全退出并重新打开 Cursor
插件在启动时加载,因此安装后必须完全退出 Cursor 再重新打开,仅仅重新加载窗口是不够的。如果你给一个已经打开的工作区添加了插件却跳过这一步,插件不会激活。
init到底做了什么
这是本文最关键的源码级环节。对照 cmd_init 的实现,init实际完成四件事:
复制插件文件到
.cursor-plugin/hindsight-memory/。拷贝清单由_PLUGIN_FILES硬编码,包括:plugin.json、hooks/hooks.json、always-on 规则 rules/hindsight-memory.mdc、两个钩子脚本scripts/session_start.py与scripts/retain.py及scripts/lib/全部七个库模块(bank、client、config、content、daemon、llm、rules_file、state)、settings.json 默认值文件,以及按需技能 skills/hindsight-recall/SKILL.md。拷贝是"全有或全无"的:任何文件缺失都会直接报错退出,因为session_start.py会导入全部lib/模块,缺一个文件每次钩子调用都会变成静默 ImportError。写入/合并项目级
.cursor/hooks.json。注意 CLI 源码注释 特别说明:只往.cursor-plugin/下放文件是不够的——Cursor 只加载工作区(或用户级).cursor/hooks.json。合并逻辑以.cursor-plugin/hindsight-memory路径为标记识别本插件条目,重跑init只会替换 Hindsight 自己的条目,已有的其他钩子原样保留。注册结果为:钩子 事件 目的 session_start.pysessionStart会话召回——查询记忆,写入规则文件,并输出 additionalContextJSONretain.pystop自动留存——提取转录并 POST 到 Hindsight retain.pysessionEnd最终冲刷——把回合窗口没来得及留存的部分兜底保存 每个命令超时 15 秒(见
_project_hooks_block);Windows 下解释器自动选python(因为 Windows 的 PATH 上通常没有python3)。创建
~/.hindsight/cursor.json(若不存在)。_scaffold_config只写入bankId以及你传入的hindsightApiUrl/hindsightApiToken;文件已存在则跳过,不覆盖你的自定义配置。写入
.cursor/mcp.json。_setup_mcp使用单 bank MCP 端点{api_url}/mcp/{bank_id}/,这样recall/retain/reflect工具天然限定在配置的 bank 内,无需再传 bank 参数;有 token 时附加Authorization: Bearer <token>请求头,并与已有mcpServers合并写入。
此外,插件自带一个按需技能hindsight-recall(见 SKILL.md),其工作流是:先检查上下文里<hindsight_memories>块是否已覆盖问题,不够深入时才调用 MCPrecall,涉及架构决策时用reflect对累积记忆做推理;以及一个 always-on 规则文件 hindsight-memory.mdc,指示 Agent 优先使用当前上下文、不向用户暴露原始记忆元数据、并优先调用 MCP 工具处理"自动会话记忆未覆盖"的查询。
想卸载时,hindsight-cursor uninstall会逆操作以上全部:删除插件目录、.cursor/hooks.json中 Hindsight 的条目、MCP server 条目、生成的会话规则文件及其.gitignore行(见 cmd_uninstall)。
插件如何使用记忆:两套互补机制
机制一:插件钩子(自动)
sessionStart钩子——会话召回。session_start.py 的流程是:从 stdin 读取钩子输入(workspace_roots、conversation_id等)→ 解析 API 地址(外部、已有本地服务,或自动拉起守护进程)→ 推导 bank ID(静态或动态)→ 首次使用时设置 bank mission → 用工作区上下文构造一个宽泛的项目级查询 → 调用 Hindsight recall API(默认max_tokens=1024、budget=mid、types=["world","experience"]、超时 10 秒)→ 格式化记忆并输出。
会话开始时并没有具体用户提示词,因此_build_session_query会拼出类似Project: <项目名>加上 bank mission 文本的查询,超过recallMaxQueryChars(默认 800)则截断。召回结果被包进<hindsight_memories>标签,前面拼接recallPromptPreamble(内置默认文案要求"冲突时优先采用较新的记忆,只用与当前对话直接相关的记忆")和当前时间。
一个必须了解的关键细节:Cursor 3.x 的原生注入通道有 bug。Cursor 对 sessionStart 钩子原生的注入通道是additionalContextJSON 字段——钩子把记忆文本打到 stdout,Cursor 应把它放进 Agent 系统提示。但插件 README(Architecture 一节)记录了该通道在 Cursor 3.x 中失效的问题(官方论坛已有确认、且截至 3.6.31 仍未修复)。插件的应对是双通道投递:除了照旧向 stdout 输出additionalContext(保持前向兼容,Cursor 修复后无需改代码),同时把召回记忆写入<workspace>/.cursor/rules/hindsight-session.mdc,frontmatter 标记alwaysApply: true——工作区规则文件会被 Cursor 的规则引擎可靠注入,Agent 在每个新对话的第一条提示词就能"看到"这些记忆。配套行为包括:
- 每次
sessionStart都重新生成该规则文件,上一会话的过期记忆不会残留(rotate_session_rules在召回前就先把旧文件轮转掉——即使本次召回为空,也不会带着陈旧记忆继续跑); - 该文件在 git 工作区中被自动、幂等地加入
.gitignore(可由appendToGitignore关闭); - 可用
useRulesFileFallback: false完全禁用规则文件写入,此时插件退化为只依赖additionalContext。
从源码结构看,Cursor 会阻塞提示词提交直到sessionStart钩子返回,因此每次新对话的第一条提示词都带有记忆,代价只是召回本身的延迟(通常小于 1 秒)。
stop+sessionEnd钩子——自动留存。retain.py 同时注册在这两个事件上,原因写在 CLI 源码注释 里:stop在每次 Agent 循环结束时触发,粒度适合周期性留存,但每次触发都受回合窗口约束;sessionEnd在会话结束时触发一次,作为最终冲刷。没有这个冲刷,任何短于retainEveryNTurns的对话都会整体丢失——默认值为 10 时,一个只有 7 轮的对话会触发 7 次stop,全部被回合门控拒掉,会话永远不被存储;sessionEnd绕过回合窗口,保证会话尾部总能被留存。两个事件在会话末尾会重叠,插件按会话记录已留存的消息数水位(retained.json),没有新消息的运行就是 no-op,因此重叠不会造成重复存储。
retain.py 主流程 的几个实现要点:
- 转录解析兼容三种格式:扁平
{role, content}、type 嵌套{type, message},以及 Cursor 3.x 的角色嵌套格式{role, message: {content: [blocks]}}(见read_transcript)。content 为分块列表时,text块保留、tool_use/tool_result块被压缩为[tool_use:名称]/[tool_result]标记; - 回合门控:
retainEveryNTurns > 1且非sessionEnd时,每 N 轮才真正留存一次,状态文件记录"下一轮第几轮触发"; - 两种留存模式(
retainMode):默认的full-session每次留存整个会话;chunked模式取"最近retainEveryNTurns + retainOverlapTurns轮"的滑动窗口切片,sessionEnd冲刷则精确存储水位之后的尾部,避免与已有窗口重叠; - 文档 ID 设计:
document_id = "{session_id}-{毫秒时间戳}",同一会话的多次留存累积为不同文档而不是覆盖同一条(注释里说明了旧设计用 session_id 做 document_id 会在多轮会话重复留存时静默丢弃早期轮次); - 标签模板:
retainTags支持{session_id}、{bank_id}、{timestamp}占位符;默认 settings.json 中为["{session_id}"]。元数据自动附带retained_at、message_count、session_id,retainContext默认为cursor。
机制二:MCP 工具(按需)
init写入的.cursor/mcp.json把 Cursor 的原生 MCP 支持接到 Hindsight 的 MCP 端点,Agent 因此获得三个显式工具:
- recall— 按查询检索特定记忆;
- retain— 把特定内容存入记忆;
- reflect— 对累积的记忆做推理。
Agent 在会话中途需要超出"会话开始时注入内容"的记忆时会使用这些工具。
一个实用的区分:插件钩子触发的召回是静默的——它把记忆注入 Agent 上下文,而不会显示可见的工具调用。如果你在 Agent 窗口里看到显式的 "Ran Recall in hindsight" 消息,那是 MCP 路径在工作,不是插件钩子。两者可以同时工作、互不冲突。想更深入了解底层行为,可以查阅仓库内的 Hindsight 文档 中 recall / retain API 的说明。
记忆银行(Memory Banks)
默认 bank 是cursor,由~/.hindsight/cursor.json里的bankId设置决定。Bank 是一个相互隔离的记忆存储——相当于独立的"大脑"——一个 bank 里的记忆绝不会泄漏到另一个 bank。
如果希望按 Agent、按项目或按会话隔离,把dynamicBankId设为true。此时 bank ID 由dynamicBankGranularity(默认["agent", "project"],可选session)列出的字段推导,Agent 名由agentName(默认cursor)提供。
内置的 bank mission 与留存 mission 默认值来自 settings.json:mission 引导 Hindsight 把 Cursor 场景当作"Cursor AI 编码助手",聚焦技术讨论、架构决策、代码模式、用户偏好与项目上下文;retainMission则指示留存时提取技术决策、架构选择、用户偏好、项目上下文与工具/库关系,忽略日常寒暄与瞬态操作细节。
完整配置参考
所有设置都在~/.hindsight/cursor.json,每一项都可用环境变量覆盖。加载顺序(后者胜):内置默认值(硬编码)→ 插件settings.json→ 用户配置~/.hindsight/cursor.json→ 环境变量。这一分层在 lib/config.py 中实现,环境变量映射表见ENV_OVERRIDES。
连接与守护进程
| 设置 | 环境变量 | 默认值 | 说明 |
|---|---|---|---|
hindsightApiUrl | HINDSIGHT_API_URL | "" | 外部 Hindsight API 服务器地址 |
hindsightApiToken | HINDSIGHT_API_TOKEN | null | 外部 API 认证 token |
apiPort | HINDSIGHT_API_PORT | 9077 | 本地hindsight-embed守护进程端口 |
useLocalDaemon | HINDSIGHT_USE_LOCAL_DAEMON | false | false时空 URL 回落到托管后端;自托管者想自动拉起本地守护进程可设为true |
embedVersion | HINDSIGHT_EMBED_VERSION | "latest" | 安装的hindsight-embed版本 |
embedPackagePath | HINDSIGHT_EMBED_PACKAGE_PATH | null | 本地hindsight-embed包路径(开发覆盖) |
记忆 Bank
| 设置 | 环境变量 | 默认值 | 说明 |
|---|---|---|---|
bankId | HINDSIGHT_BANK_ID | "cursor" | dynamicBankId为 false 时使用的 bank ID |
dynamicBankId | HINDSIGHT_DYNAMIC_BANK_ID | false | 是否从上下文字段推导 bank ID |
dynamicBankGranularity | — | ["agent", "project"] | 推导动态 bank ID 的字段(agent / project / session) |
bankIdPrefix | — | "" | 附加到所有 bank ID 的前缀 |
agentName | HINDSIGHT_AGENT_NAME | "cursor" | 动态 bank ID 使用的 Agent 名 |
bankMission | HINDSIGHT_BANK_MISSION | "" | 首次使用时设置到 bank 的 mission |
retainMission | — | null | bank 的自定义留存 mission |
会话召回
| 设置 | 环境变量 | 默认值 | 说明 |
|---|---|---|---|
autoRecall | HINDSIGHT_AUTO_RECALL | true | 开启/关闭会话开始召回 |
recallBudget | HINDSIGHT_RECALL_BUDGET | "mid" | 检索彻底程度:low / mid / high |
recallMaxTokens | HINDSIGHT_RECALL_MAX_TOKENS | 1024 | 召回记忆块的最大 token 数 |
recallTypes | — | ["world", "experience"] | 召回的记忆类型 |
recallMaxQueryChars | HINDSIGHT_RECALL_MAX_QUERY_CHARS | 800 | 召回查询的最大字符数 |
recallPromptPreamble | — | 见 settings.json | 拼接在召回记忆前的引导文案 |
useRulesFileFallback | HINDSIGHT_USE_RULES_FILE_FALLBACK | true | 将召回记忆写入.cursor/rules/hindsight-session.mdc(绕过 Cursor 3.x 的 additionalContext 缺陷) |
appendToGitignore | HINDSIGHT_APPEND_TO_GITIGNORE | true | 写规则文件时幂等地把其路径加入工作区.gitignore(非 git 工作区无操作) |
自动留存
| 设置 | 环境变量 | 默认值 | 说明 |
|---|---|---|---|
autoRetain | HINDSIGHT_AUTO_RETAIN | true | 开启/关闭自动留存 |
retainMode | HINDSIGHT_RETAIN_MODE | "full-session" | 留存策略:full-session或chunked |
retainEveryNTurns | HINDSIGHT_RETAIN_EVERY_N_TURNS | 10 | 每 N 轮留存一次(1 = 每轮都存) |
retainOverlapTurns | — | 2 | chunked 模式下的窗口重叠轮数 |
retainToolCalls | — | false | 留存转录是否包含工具调用消息 |
retainContext | HINDSIGHT_RETAIN_CONTEXT | "cursor" | 留存记忆的来源标签 |
retainTags | — | [] | 应用于留存文档的标签(支持{session_id}模板) |
retainMetadata | — | {} | 留存文档的附加元数据 |
LLM(仅守护进程模式)与调试
| 设置 | 环境变量 | 默认值 | 说明 |
|---|---|---|---|
llmProvider | HINDSIGHT_LLM_PROVIDER | null | 守护进程模式的 LLM 提供方覆盖 |
llmModel | HINDSIGHT_LLM_MODEL | null | 守护进程模式的 LLM 模型覆盖 |
llmApiKeyEnv | — | null | 存放 LLM API key 的环境变量名 |
debug | HINDSIGHT_DEBUG | false | 向 stderr 输出详细日志(异常时退出码变为 2 以便排查) |
三种连接模式(见 README):
- 外部 API(生产推荐):
{"hindsightApiUrl": "https://your-hindsight-server.com", "hindsightApiToken": "your-token"}; - 本地守护进程(自动管理):
hindsightApiUrl留空并设useLocalDaemon: true后,插件通过uvx自动启动/停止hindsight-embed,需要一个 LLM 提供方 API key,apiPort默认 9077; - 已有本地服务:
hindsightApiUrl留空,把apiPort指向你已运行的hindsight-embed端口。
验证记忆是否真的在工作
插件在每次钩子调用时都会写状态文件——即使没有找到记忆、或留存被跳过也要写。查看它们可以确认钩子确实在触发:
cat ~/.hindsight/cursor-state/state/last_recall.json cat ~/.hindsight/cursor-state/state/last_retain.json每个文件记录:saved_at时间戳、status(success/empty/skipped/error)、使用的bank_id,以及result_count(recall)或message_count(retain)。对照 session_start.py 的状态写入 和 retain.py 的状态写入 可知,skipped还会附带reason字段(disabled、empty_transcript、no_new_messages、turn_window等),error会附带截断到 200 字符的reason——排障时先看saved_at是否随使用在更新(说明钩子在触发),再看status和reason理解发生了什么。
一个不错的端到端测试序列:
- 在某个项目里使用 Cursor,让 Agent 记录一个决策或约定;
- 结束任务,让转录被留存;
- 在同一项目开启一个新会话;
- 询问之前那个决策。
如果新会话能说出之前的决策,配置就是成功的。
常见错误
没有完全重启 Cursor
插件在启动时加载,重载窗口不够——安装后必须完全退出并重新打开 Cursor。
把 MCP 召回与插件召回混淆
插件路径的召回是静默的。看到可见的 "Ran Recall in hindsight" 消息说明是 MCP 在做,不是钩子。两者可以共存。
测试留存测得太早
自动留存发生在任务完成时。如果任务还没停你就去查,对话可能尚未入库。
空 bank 时期待有记忆
召回只能呈现已被留存的东西。全新的 bank 至少需要一次留存循环之后,召回才会有结果。
FAQ
必须用 Hindsight Cloud 吗?不必。自托管 Hindsight 服务器同样可用——--api-url http://localhost:8888传入其地址,或用上文 Docker 命令本地运行。
必须用 MCP 吗?不必。MCP 工具是可选的,只想用自动插件钩子时给init传--no-mcp。
记忆的作用域如何划分?默认所有会话共享cursorbank;需要按 Agent / 项目 / 会话隔离时把dynamicBankId设为true。
与其他编码 Agent 集成类似吗?精神上相同。Cursor 用的是插件钩子 + MCP,而不是包装命令,但"先召回、后留存"的模式与其他 Hindsight 编辑器集成一致——仓库中 hindsight-integrations/ 下还有 claude-code、codex、cline 等大量同类集成可对照阅读。
延伸阅读
- 插件完整文档(含架构与配置全表):hindsight-integrations/cursor/README.md
- 安装/卸载 CLI 实现:hindsight-integrations/cursor/hindsight_cursor/cli.py
- 会话召回钩子:hindsight-integrations/cursor/scripts/session_start.py
- 自动留存钩子:hindsight-integrations/cursor/scripts/retain.py
- 配置分层与默认值:hindsight-integrations/cursor/scripts/lib/config.py、hindsight-integrations/cursor/settings.json
- 测试用例(含端到端钩子测试):hindsight-integrations/cursor/tests/
- 原始指南:hindsight-docs/guides/2026-07-17-guide-cursor-memory-with-hindsight.md
【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考