Hindsight × Cursor:用 hindsight-cursor 插件为 Cursor 构建跨会话长期记忆
2026/9/14 19:36:16 网站建设 项目流程

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 installhindsight-cursor init的每一步操作、init究竟在磁盘上写入了哪些文件、sessionStart/stop/sessionEnd钩子的底层调用链、MCP 工具的接入方式,以及 bank 隔离、配置分层、状态文件验证等实战细节。读完本文,你可以独立完成"新会话自动召回项目记忆、任务结束后自动留存对话"的端到端配置,并能从源码层面解释每一次记忆注入与留存是如何发生的。

如果你想要给 Cursor 加上长期记忆,最干净的做法就是hindsight-cursor插件。一条hindsight-cursor init命令即可安装插件钩子:会话开始时自动召回相关项目记忆,每个任务结束后自动留存对话,同时写入 MCP 配置,让 Agent 在会话中拥有显式的recallretainreflect三个工具。这样 Cursor 就具备了跨编码会话的长期记忆,而不是每个新会话都重新摸索一遍同样的项目上下文。

这个方案天然契合 Cursor,因为 Cursor 同时暴露了钩子系统(hooks)原生 MCP 支持,插件两者都用上了:sessionStart钩子自动注入召回的记忆作为上下文,stop钩子在任务完成时留存对话转录,MCP 工具则负责按需的定向检索。环境式记忆(ambient memory)无需任何用户干预,而工具始终待命,供 Agent 显式使用。

快速答案(TL;DR)

  1. 在你的项目目录内执行pip install hindsight-cursor
  2. 运行hindsight-cursor init --api-url ... --api-token ...(Hindsight Cloud)或--api-url http://localhost:8888(自托管)。
  3. 完全退出并重新打开 Cursor——插件在启动时加载。
  4. 会话召回会自动注入项目记忆;自动留存会在每个任务结束后保存对话。
  5. 验证方式:让后一个会话记得前一个会话存下的内容。

前置条件

开始之前,请确认:

  • 已安装并可正常使用 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:latest

init会一次性配好两套机制。只想用钩子、跳过 MCP 配置时加--no-mcp;需要覆盖已有安装时加--force

init的完整命令行参数(以 cli.py 中argparse定义为准):

参数默认值说明
project(位置参数).Cursor 项目路径,缺省为当前目录
--api-urlNoneHindsight API 地址,如https://api.hindsight.vectorize.io
--api-tokenNoneHindsight API token
--bank-idcursor记忆 bank ID
--no-mcp关闭跳过 MCP 集成配置
--force关闭覆盖已存在的安装

Step 3: 完全退出并重新打开 Cursor

插件在启动时加载,因此安装后必须完全退出 Cursor 再重新打开,仅仅重新加载窗口是不够的。如果你给一个已经打开的工作区添加了插件却跳过这一步,插件不会激活。

init到底做了什么

这是本文最关键的源码级环节。对照 cmd_init 的实现,init实际完成四件事:

  1. 复制插件文件到.cursor-plugin/hindsight-memory/。拷贝清单由_PLUGIN_FILES硬编码,包括:plugin.json、hooks/hooks.json、always-on 规则 rules/hindsight-memory.mdc、两个钩子脚本scripts/session_start.pyscripts/retain.pyscripts/lib/全部七个库模块(bank、client、config、content、daemon、llm、rules_file、state)、settings.json 默认值文件,以及按需技能 skills/hindsight-recall/SKILL.md。拷贝是"全有或全无"的:任何文件缺失都会直接报错退出,因为session_start.py会导入全部lib/模块,缺一个文件每次钩子调用都会变成静默 ImportError。

  2. 写入/合并项目级.cursor/hooks.json。注意 CLI 源码注释 特别说明:只往.cursor-plugin/下放文件是不够的——Cursor 只加载工作区(或用户级).cursor/hooks.json。合并逻辑以.cursor-plugin/hindsight-memory路径为标记识别本插件条目,重跑init只会替换 Hindsight 自己的条目,已有的其他钩子原样保留。注册结果为:

    钩子事件目的
    session_start.pysessionStart会话召回——查询记忆,写入规则文件,并输出additionalContextJSON
    retain.pystop自动留存——提取转录并 POST 到 Hindsight
    retain.pysessionEnd最终冲刷——把回合窗口没来得及留存的部分兜底保存

    每个命令超时 15 秒(见_project_hooks_block);Windows 下解释器自动选python(因为 Windows 的 PATH 上通常没有python3)。

  3. 创建~/.hindsight/cursor.json(若不存在)。_scaffold_config只写入bankId以及你传入的hindsightApiUrl/hindsightApiToken;文件已存在则跳过,不覆盖你的自定义配置。

  4. 写入.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_rootsconversation_id等)→ 解析 API 地址(外部、已有本地服务,或自动拉起守护进程)→ 推导 bank ID(静态或动态)→ 首次使用时设置 bank mission → 用工作区上下文构造一个宽泛的项目级查询 → 调用 Hindsight recall API(默认max_tokens=1024budget=midtypes=["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_atmessage_countsession_idretainContext默认为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

连接与守护进程

设置环境变量默认值说明
hindsightApiUrlHINDSIGHT_API_URL""外部 Hindsight API 服务器地址
hindsightApiTokenHINDSIGHT_API_TOKENnull外部 API 认证 token
apiPortHINDSIGHT_API_PORT9077本地hindsight-embed守护进程端口
useLocalDaemonHINDSIGHT_USE_LOCAL_DAEMONfalsefalse时空 URL 回落到托管后端;自托管者想自动拉起本地守护进程可设为true
embedVersionHINDSIGHT_EMBED_VERSION"latest"安装的hindsight-embed版本
embedPackagePathHINDSIGHT_EMBED_PACKAGE_PATHnull本地hindsight-embed包路径(开发覆盖)

记忆 Bank

设置环境变量默认值说明
bankIdHINDSIGHT_BANK_ID"cursor"dynamicBankId为 false 时使用的 bank ID
dynamicBankIdHINDSIGHT_DYNAMIC_BANK_IDfalse是否从上下文字段推导 bank ID
dynamicBankGranularity["agent", "project"]推导动态 bank ID 的字段(agent / project / session)
bankIdPrefix""附加到所有 bank ID 的前缀
agentNameHINDSIGHT_AGENT_NAME"cursor"动态 bank ID 使用的 Agent 名
bankMissionHINDSIGHT_BANK_MISSION""首次使用时设置到 bank 的 mission
retainMissionnullbank 的自定义留存 mission

会话召回

设置环境变量默认值说明
autoRecallHINDSIGHT_AUTO_RECALLtrue开启/关闭会话开始召回
recallBudgetHINDSIGHT_RECALL_BUDGET"mid"检索彻底程度:low / mid / high
recallMaxTokensHINDSIGHT_RECALL_MAX_TOKENS1024召回记忆块的最大 token 数
recallTypes["world", "experience"]召回的记忆类型
recallMaxQueryCharsHINDSIGHT_RECALL_MAX_QUERY_CHARS800召回查询的最大字符数
recallPromptPreamble见 settings.json拼接在召回记忆前的引导文案
useRulesFileFallbackHINDSIGHT_USE_RULES_FILE_FALLBACKtrue将召回记忆写入.cursor/rules/hindsight-session.mdc(绕过 Cursor 3.x 的 additionalContext 缺陷)
appendToGitignoreHINDSIGHT_APPEND_TO_GITIGNOREtrue写规则文件时幂等地把其路径加入工作区.gitignore(非 git 工作区无操作)

自动留存

设置环境变量默认值说明
autoRetainHINDSIGHT_AUTO_RETAINtrue开启/关闭自动留存
retainModeHINDSIGHT_RETAIN_MODE"full-session"留存策略:full-sessionchunked
retainEveryNTurnsHINDSIGHT_RETAIN_EVERY_N_TURNS10每 N 轮留存一次(1 = 每轮都存)
retainOverlapTurns2chunked 模式下的窗口重叠轮数
retainToolCallsfalse留存转录是否包含工具调用消息
retainContextHINDSIGHT_RETAIN_CONTEXT"cursor"留存记忆的来源标签
retainTags[]应用于留存文档的标签(支持{session_id}模板)
retainMetadata{}留存文档的附加元数据

LLM(仅守护进程模式)与调试

设置环境变量默认值说明
llmProviderHINDSIGHT_LLM_PROVIDERnull守护进程模式的 LLM 提供方覆盖
llmModelHINDSIGHT_LLM_MODELnull守护进程模式的 LLM 模型覆盖
llmApiKeyEnvnull存放 LLM API key 的环境变量名
debugHINDSIGHT_DEBUGfalse向 stderr 输出详细日志(异常时退出码变为 2 以便排查)

三种连接模式(见 README):

  1. 外部 API(生产推荐):{"hindsightApiUrl": "https://your-hindsight-server.com", "hindsightApiToken": "your-token"}
  2. 本地守护进程(自动管理):hindsightApiUrl留空并设useLocalDaemon: true后,插件通过uvx自动启动/停止hindsight-embed,需要一个 LLM 提供方 API key,apiPort默认 9077;
  3. 已有本地服务hindsightApiUrl留空,把apiPort指向你已运行的hindsight-embed端口。

验证记忆是否真的在工作

插件在每次钩子调用时都会写状态文件——即使没有找到记忆、或留存被跳过也要写。查看它们可以确认钩子确实在触发:

cat ~/.hindsight/cursor-state/state/last_recall.json cat ~/.hindsight/cursor-state/state/last_retain.json

每个文件记录:saved_at时间戳、statussuccess/empty/skipped/error)、使用的bank_id,以及result_count(recall)或message_count(retain)。对照 session_start.py 的状态写入 和 retain.py 的状态写入 可知,skipped还会附带reason字段(disabledempty_transcriptno_new_messagesturn_window等),error会附带截断到 200 字符的reason——排障时先看saved_at是否随使用在更新(说明钩子在触发),再看statusreason理解发生了什么。

一个不错的端到端测试序列:

  1. 在某个项目里使用 Cursor,让 Agent 记录一个决策或约定;
  2. 结束任务,让转录被留存;
  3. 在同一项目开启一个新会话;
  4. 询问之前那个决策。

如果新会话能说出之前的决策,配置就是成功的。

常见错误

没有完全重启 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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询