Hindsight × Cline:用生命周期 Hooks 为 Cline 装上确定性长期记忆(免 MCP 方案)
Hindsight × Cline用生命周期 Hooks 为 Cline 装上确定性长期记忆免 MCP 方案【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsightHindsight 的 Cline 集成hindsight-cline通过 Cline 的生命周期 Hooks 实现任务前自动召回、任务结束自动沉淀的长期记忆闭环全程不依赖 MCP、不需要模型主动调用任何工具。本文基于仓库中 hindsight-integrations/cline/README.md 及其配套源码完整讲解这套集成的工作机制、安装流程、全部配置项与底层实现细节读完你可以直接在 macOS/Linux 环境下为自己的 Cline 工作流接入跨会话记忆。一、为什么选择 Hooks 而不是 MCP传统方式为编码智能体接入记忆的做法通常是注册一个 MCP Server让模型在对话中决定是否调用记忆工具。这种方式有一个根本弱点记忆行为依赖模型的临场判断——模型忘了调用记忆就丢了。hindsight-cline换了条路线Cline 提供了一套lifecycle hooks 机制允许用户在关键时点执行外部脚本。本集成注册了四个 hook 脚本把记忆读写变成确定性的旁路逻辑Hook 事件触发时机行为TaskStart任务开始时以任务描述为 query 执行 recall注入相关记忆UserPromptSubmit每次用户发消息以 prompt 为 query 执行 recall 注入记忆同时把 prompt 追加到任务 transcriptTaskComplete任务完成时retain 累积的完整 transcript 最终摘要TaskCancel任务被取消时retain 部分 transcript标记为 cancelled由于运行在 hooks 上记忆注入与沉淀是自动发生的与模型是否愿意调用工具无关。这是该集成 README 中反复强调的核心设计动机。二、工作机制从 stdin JSON 到hindsight_memories注入2.1 Cline Hooks 的 I/O 契约Cline 以子进程方式运行每个 hook把一段 JSON 写入 hook 的stdin再从stdout读回一段固定形状的 JSON。这个契约在 cline_io.py 中有精确实现入参stdin包含hookName、taskId、promptUserPromptSubmit、taskTaskStart/TaskComplete/TaskCancel、workspaceRoots、model等字段被解析为强类型的HookInputdataclass出参stdout固定为三个字段{cancel: false, contextModification: hindsight_memories…, errorMessage: }其中contextModification就是 hook 向模型上下文注入文本的通道——召回到的记忆会被渲染成hindsight_memories块通过该字段注入。值得注意的两个防御性设计见 hooks_impl.py绝不抛异常所有 entrypoint 用try/except包裹任何记忆侧故障都降级为空输出no-op记忆服务的抖动永远不会阻塞 Cline 本身最小长度门槛prompt 或任务描述少于RECALL_MIN_CHARS 5个字符时直接跳过 recallcline_io.py避免为 hi 这类寒暄发起无意义的检索。2.2 转录累积Cline 不给 transcript就自己攒一个关键约束是Cline 不会把会话 transcript 传给 hooks。因此集成自己维护了每任务一份的转录文件逻辑在 state.py 与 content.py每个UserPromptSubmit把用户 prompt 以{role: user, content: ...}追加到~/.hindsight/cline/state/transcript_taskId.jsonTaskStart把任务描述作为首轮写入hooks_impl.pyTaskComplete/TaskCancel时把完成摘要hook 的task字段作为assistant轮追加再将整段 transcript 格式化为纯文本后提交 retain成功后清空状态文件状态文件采用tmp os.replace原子写且任务轮次上限 500 条防止文件无限膨胀文件名经过路径穿越净化_safe_filename替换危险字符并做 realpath 前缀校验。retain提交时的元数据也做了精心设计document_id使用taskId便于按任务追溯、context默认为cline帮助 Hindsight 按来源聚类、metadata携带task_id/project/statuscompleted 或 cancelled、tags默认为[{task_id}]且支持模板变量{task_id}、{project}、{status}、{timestamp}。另一个容易被忽略的细节是反馈环防护retain 前会用正则剥掉内容中的hindsight_memories/relevant_memories块content.py 的strip_memory_tags。因为这些块是 recall 阶段注入到上下文里的若不剥离就会被当成用户说的话再次存储形成记忆自我复制。三、服务端与客户端零第三方依赖的 REST 集成集成支持两类 Hindsight 后端Hindsight Cloud注册获取 API key使用https://api.hindsight.vectorize.io自托管pip install hindsight-all export HINDSIGHT_API_LLM_API_KEYyour-openai-key hindsight-api # starts on http://localhost:8888客户端实现在 client.py刻意只用Python 标准库urllib发 HTTP 请求保证 hook 脚本零第三方依赖。三个核心 API方法端点说明recall()POST /v1/default/banks/{bank_id}/memories/recall携带query、max_tokens、budgetlow/mid/high、typesretain()POST /v1/default/banks/{bank_id}/memories以itemsasync: true提交服务端后台异步处理set_bank_mission()PATCH /v1/default/banks/{bank_id}/config写入reflect_mission与retain_mission两个工程细节值得记录User-Agent 伪装每个请求都带上hindsight-cline/version的 UA原因是自托管部署如果架在 Cloudflare 等按 UA 过滤机器人的反代后面标准库默认的Python-urllib/X.Y会触发 Cloudflare 1010 错误client.py 有明确注释API URL 解析策略cline_io.py 的resolve_api_url优先用配置的外部 URL若为空则探测http://localhost:{apiPort}默认 9077的/health。探不通就静默降级为 no-op——它永远不自动拉起 daemon找不到服务就不做记忆操作绝不让 Cline 卡住。四、安装与卸载4.1 平台前提Cline hooks 仅在macOS 和 Linux上运行不支持 Windowshooks 需要 Python 3。4.2 安装pip install hindsight-cline然后在项目目录下hindsight-cline install --api-url https://api.hindsight.vectorize.io --api-token YOUR_KEY全局安装对所有项目生效hindsight-cline install --global --api-url https://api.hindsight.vectorize.io --api-token YOUR_KEY卸载hindsight-cline uninstall全局安装则加--global。CLI 的完整参数在 cli.py 中定义install/uninstall子命令均支持--project-dir默认当前目录与--global--api-url与--api-token可省略而改用环境变量HINDSIGHT_API_URL/HINDSIGHT_API_TOKEN提供。安装动作install.py具体做了三件事从 wheel 包内的hindsight_cline/hooks/数据目录经importlib.resources解析拷贝四个 hook 脚本TaskStart、UserPromptSubmit、TaskComplete、TaskCancel到目标目录并逐个chmod 0o755Cline 只执行有可执行位 hook 文件拷贝共享库lib/与 settings.json 到同一目录hook 脚本通过sys.path.insert加载本目录下的lib/把连接信息写入~/.hindsight/cline.json该文件在重装/升级时保留不动配置因此是稳定的。目标目录二选一项目安装 →.clinerules/hooks/建议提交进版本库与团队共享全局安装 →~/Documents/Cline/Rules/Hooks/。每个 hook 脚本本体极薄例如 TaskStart 只是把脚本所在目录加入sys.path后调用lib.hooks_impl.main_task_start()。最后一步——在 Cline 中启用 hooksSettings → Features → Hooks。五、配置系统四层合并、typed dataclass5.1 常用配置项默认值写在随包安装的settings.json中个人覆盖写在~/.hindsight/cline.json跨重装稳定。README 列出的常用键Setting默认值说明hindsightApiUrl(空)Hindsight 服务 URL。留空则探测apiPort上的本地服务hindsightApiTokennullHindsight Cloud 的 API keybankIdcline该集成使用的记忆库autoRecalltrue任务/消息前注入记忆autoRetaintrue任务结束时沉淀 transcriptrecallBudgetmid召回深度low/mid/highrecallTypes[world,experience]要召回的记忆类型dynamicBankIdfalse按项目/会话拆库见dynamicBankGranularitydebugfalse向日志输出stderr而完整键集合可以从 settings.json 和配置数据类 HindsightClineConfig 交叉确认还包括若干 README 未逐一列出但同样可调的项Setting默认值说明来自源码recallMaxTokens1024recall 结果的最大 token 预算recallTimeout/retainTimeout10/15秒recall / retain 请求超时recallContextTurns1recall query 携带的上下文轮数≤1 时仅用最新消息recallMaxQueryChars800组合 query 的字符上限超限时优先保最新消息recallPromptPreambleRelevant memories from past conversations…注入块中的引导语retainContextclineretain 的来源标记帮助服务端按来源聚类retainTags[{task_id}]支持{task_id}/{project}/{status}/{timestamp}模板变量retainMetadata{}自由键值元数据字符串值同样支持模板变量apiPort9077未配置hindsightApiUrl时探测的本地端口bankIdPrefixbank id 前缀多集成共用一个 Hindsight 实例时隔离用dynamicBankGranularity[agent,project]动态 bank 的粒度维度可选agent/project/session/useragentNamecline动态 bank 中 agent 维度的取值bankMission/retainMission面向编码场景的英文 mission 文本bank 首用时自动 PATCH 到服务端见下文5.2 加载顺序与类型转换config.py 中load_config()的合并顺序后者覆盖前者内置默认值dataclass 字段默认插件settings.json经find_settings_path()向上逐级查找兼容仓库布局与安装布局用户配置~/.hindsight/cline.json环境变量覆盖。落盘格式统一为camelCase加载时经camel_to_snake()转换为 snake_case 字段。环境变量映射表ENV_OVERRIDES目前覆盖 15 个键例如HINDSIGHT_BANK_ID、HINDSIGHT_AUTO_RECALLfalse、HINDSIGHT_API_URL、HINDSIGHT_RECALL_BUDGET等bool 类型接受true/1/yes解析失败静默忽略。未知键不在 dataclass 字段集内的在文件合并阶段直接跳过因此 schema 演进时旧配置不会报错。5.3 动态 Bank按 agent / 项目 / 会话 / 用户拆库默认所有记忆汇入单一 bankcline。开启dynamicBankId: true后bank.py 的derive_bank_id()按dynamicBankGranularity指定的维度用::拼接出 bank id四个合法维度及其取值来源agent→agentName配置默认clineproject→ 第一个workspaceRoots的 basenamesession→ hook 输入的taskIduser→ 环境变量HINDSIGHT_USER_ID缺省anonymous。例如粒度[agent,project]下工作区/home/me/myapp的记忆落在 bankcline::myapp。非法维度名会在 stderr 打印告警但不中断。配套的bank mission 机制ensure_bank_mission()在 bank 首次使用时把bankMissionreflect 侧人格设定与retainMissionretain 侧提取指令PATCH 到服务端并用状态文件bank_missions.json记录已设置避免重复请求记录超过 10000 条时裁剪一半防止膨胀。默认 mission 把 bank 定位为Cline AI 编码助手聚焦技术决策、代码变更、调试会话、架构选择等并在 retain 侧明确忽略寒暄与临时性操作细节——这直接决定了记忆提取的信噪比。六、验证安装启动 Hindsighthindsight-api或 Hindsight Cloud运行hindsight-cline install并带上 URL/key在 Cline 中开启 hooksSettings → Features → Hooks发起一个任务——召回的记忆会以hindsight_memories块出现在上下文中完成任务后检查clinebank通过 API 或 dashboard应能看到新记忆。不启动 Cline 也能冒烟测试单个 hook——stdin 喂入 payloadstdout 即返回契约 JSONecho {hookName:UserPromptSubmit,prompt:how do we authenticate?,taskId:t1,workspaceRoots:[/tmp/x]} \ | .clinerules/hooks/UserPromptSubmit # → {cancel: false, contextModification: hindsight_memories…, errorMessage: }七、开发与测试仓库内该集成的开发流程README 原文uv sync uv run pytest tests/ -v测试集位于 hindsight-integrations/cline/tests/覆盖四个层面test_hooks.pyrecall 注入/转录累积/禁用开关/短 prompt 跳过、retain 提交内容与元数据、tags 模板渲染、stdin→stdout 契约以及服务端整体宕机时优雅降级为空输出且不抛异常test_main_degrades_gracefully_when_server_downtest_bank.py动态 bank 派生与粒度字段校验test_content.py多轮 query 组合、超长按先丢最旧上下文行策略截断、hindsight_memories标签剥离等test_install.py安装/卸载的文件落位与可执行位。这套测试也侧面印证了前述源码结论recall 与 retain 完全解耦、故障隔离是显式验收项。八、总结hindsight-cline用四个生命周期 hook 脚本 一个零依赖的 REST 客户端把 Hindsight 的 recall/retain 能力确定性地织入 Cline 的任务生命周期任务开始时按任务描述召回、每条消息按 prompt 召回并累积转录、任务结束无论完成还是取消异步 retain 整段 transcript 并打上 task_id/project/status 元数据。配置采用内置默认 → settings.json → 用户 json → 环境变量四层合并支持静态单 bank 与按 agent/project/session/user 维度的动态 bank且所有故障路径都设计为静默降级——记忆层出问题Cline 永远照常工作。对于希望在编码智能体中积累跨会话项目记忆、又不想引入 MCP 运行时开销的开发者这是当前 Hindsight 仓库中最轻量的接入路径之一完整源码可参考 hindsight-integrations/cline/ 目录。【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考