Hindsight Codex 记忆银行策略:按仓库隔离分库,把跨仓库召回噪声降为零
2026/9/16 14:44:01 网站建设 项目流程

Hindsight Codex 记忆银行策略:按仓库隔离分库,把跨仓库召回噪声降为零

【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight

用 Hindsight 给 Codex 配记忆时,默认所有仓库的会话都写进同一个名为codex的银行。代价是:修 API 仓库的 bug 时,recall 会把前端仓库的 lint 约定一起端上来——记忆都是真的,但来自错误的地方。本文的方案:用 Hindsight 的dynamicBankId机制按工作目录自动派生记忆银行 ID,一仓库一库,再配一个固定命名的团队共享库。效果是同一仓库内的召回不受影响,其他仓库的记忆完全不进入召回预算。

安装与环境准备一句话带过:按 Codex 安装指南 装好钩子并连接后端(Hindsight Cloud、自托管服务器或本地 embed daemon 均可),下文只讲银行布局。

方案速览

  1. ~/.hindsight/codex.json里开启dynamicBankId: truedynamicBankGranularity: ["agent", "project"],每个仓库工作目录自动对应一个银行;
  2. 银行 ID 由字段用::拼接,例如codex::api,无需手工命名;
  3. 跨仓库的团队规范放固定命名的共享银行(dynamicBankId: false+ 固定bankId),不要混进按仓库的库;
  4. 默认retainModefull-session,会话结束时整份 transcript 被保留,正常干活即可沉淀记忆;
  5. 用双仓库测试序列验证:同仓库要能召回,跨仓库必须保持干净。

银行 ID 是怎么拼出来的

派生规则

派生逻辑在 bank.py#L24-L65:静态模式(dynamicBankId: false)直接返回bankId配置值,缺省为"codex",配置了bankIdPrefix则拼为前缀-bankId;动态模式按dynamicBankGranularity取值、用::连接。Codex 支持的字段有四个:agentagentName配置,默认"codex")、project(工作目录基名,空则"unknown")、session(会话 ID)、user(环境变量HINDSIGHT_USER_ID,缺省"anonymous")。channel维度被刻意不提供——CLI 没有 Telegram/Discord 那样的多通道路由。

test_bank.py 固化了两个关键行为:agentName="mybot"且 cwd 为/home/user/hindsight时派生出mybot::hindsight;含空格或 UTF-8 的目录名原样保留、不做 URL 编码——这是关键,因为 retain 与 recall 两次钩子调用只要编码规则一致,就必然命中同一个银行,隔离才不会在传输层悄悄失效。

配置加载顺序

config.py#L110-L140 定义了四层加载顺序,后者覆盖前者:内置默认值DEFAULTS→ 插件安装时写入的settings.json→ 用户配置~/.hindsight/codex.json(推荐改这里,升级不丢)→ 环境变量覆盖。因此一次运行即可用HINDSIGHT_DYNAMIC_BANK_ID=trueHINDSIGHT_BANK_ID=team-standards这类变量切换分库策略,不必改任何文件;HINDSIGHT_DEBUG=true则用于排查派生结果。

三个钩子挂起读写

hooks.json 显示记忆读写挂在 Codex 的三个生命周期事件上:

钩子脚本动作
SessionStartsession_start.py预热 Hindsight 服务器,后台预启动 daemon
UserPromptSubmitrecall.py从当前银行召回记忆,注入 prompt 上下文
Stopretain.py把会话 transcript 写入当前银行

recall.py读取钩子输入后派生银行 ID,按recallContextTurns组装多轮查询、按recallMaxQueryChars(默认 800 字符)截断,调用 recall API 后用<hindsight_memories>包裹结果,经hookSpecificOutput.additionalContext注入。退出码恒为 0,任何错误都不打断对话——召回失败时 Codex 只是少了上下文,而不是挂掉,这是优雅降级设计。

retain.pyretainMode处理 transcript:full-session保留整份会话,document_idsession_id保证同一会话反复 upsert;chunked模式按retainEveryNTurnsretainOverlapTurns取重叠窗口并在文档 ID 后追加时间戳。注意即使full-session模式,retainEveryNTurns(默认 10)仍然生效:turn 数到倍数才触发写入,测试召回前这点容易踩坑。

分库与共享库的配置写法

按仓库分库

最小配置写两个字段,存到~/.hindsight/codex.json

{ "dynamicBankId": true, "dynamicBankGranularity": ["agent", "project"] }

改什么:开启动态派生。效果:在~/projects/api~/projects/frontend分别运行 Codex,银行 ID 为codex::apicodex::frontend,retain 与 recall 各走各库。若两个仓库目录基名撞名(比如有同名子模块目录),在粒度数组里加sessionuser进一步区分;用bankIdPrefix可区分测试/生产两套库。

什么内容值得沉淀

银行价值取决于你放进去的信息密度。四类回报最高的内容:

内容类型示例为什么值得留
约定"本项目用 FastAPI + asyncpg,不用 SQLAlchemy"每次新会话都要重新解释一遍
已知脆弱区"部署前必须先跑迁移,否则 500"阻止 Codex 用踩坑方式重新学会
历史排障"401 是时钟偏移导致,用 X 修好"复发 bug 一次召回即定位
工程决策"为什么重试逻辑改成这样"决策从 diff 反推很贵,召回很便宜

默认full-session模式下无需刻意操作,让会话自然结束即可。要做的是在会话里把约定或决策明确说出来——被说出来的规则才值得被抽取成事实,含糊带过的不会留下。

跨仓库共享库

团队级 commit 约定、共享 CI 流水线、安全评审要求这类知识跨仓库边界,放进任何按仓库的库都会丢失。用静态配置开一个固定银行:

{ "dynamicBankId": false, "bankId": "team-standards" }

指向同一bankId的银行在各集成与队友之间共享,一人 retain 的规范人人可 recall。实用布局:日常开发走按仓库银行,跨切规范走这一个共享银行。

反模式

反模式一:所有仓库留在默认codex银行。默认值见 settings.json,不开dynamicBankId就共享codex。后果是写入的仓库越多,每次召回与无关上下文的竞争越激烈,召回预算被错误仓库的记忆挤占——召回结果冒出别的项目内容就是该拆分的信号。

反模式二:期望跨库召回。银行隔离是严格的,数据不跨库流动,API 仓库永远召回不到前端仓库的决策。这是特性而非缺陷:确实要共享的知识,走共享库。

召回效果验证步骤

retainEveryNTurns默认 10,测试前临时设为1让每次 turn 都触发 retain。按序执行:

  1. 仓库 A 里让 Codex 明确说出一个决策(比如为什么加重试),结束会话等 transcript 被 retain;
  2. 仓库 A 开新会话问该决策——通过判据:答案被召回且与首次会话一致;
  3. 仓库 B 开会话问同样问题——通过判据:不出现仓库 A 的决策;
  4. 第 2 步失败时,确认两次运行派生出相同银行 ID(开debug: true后 stderr 可见 bank ID 日志);第 3 步失败时,检查dynamicBankId是否真为true,以及有没有被HINDSIGHT_BANK_ID环境变量覆盖。

进一步阅读

完整配置表与默认值见 Codex 集成 README;想核对派生行为,读 bank.py 及其对应 test_bank.py;还没有后端的话,按快速开始 自建一个 Hindsight 服务器配合本文布局使用。

【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

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

立即咨询