Hindsight 与 OMO 集成实战:为 oh-my-openagent 智能体接入跨会话长期记忆
【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight
本文围绕 Hindsight 官方发布的 OMO(oh-my-openagent)集成(changelog 记录于 skills/hindsight-docs/references/changelog/integrations/omo.md),完整讲解该集成的安装部署、五个生命周期钩子的工作机理、全部配置项与优先级规则,并结合仓库源码(hindsight-integrations/omo)深入剖析 recall / retain 的执行链路。读完本文,你将能够独立为 OMO 智能体接入 Hindsight 长期记忆:自动在每次提示前召回相关上下文、在会话结束后沉淀学习成果,并针对多项目隔离、多记忆库召回等场景完成进阶配置。
一、集成背景:OMO Changelog 0.1.0 带来了什么
在 OMO Integration Changelog 中,Hindsight 官方记录了该集成的首个版本0.1.0:
- 新增了一个面向Oh-My-OpenAgent(OMO)的 Hindsight 集成;
- 提供了一整套hooks(钩子)与 scripts(脚本),用于在会话之间保留(retain)与召回(recall)记忆;
- 该版本由 @dcbouius 贡献,对应提交为
6dc56498。
这份 changelog 本身只有一条 Feature 记录,但它在仓库中对应的实现却是完整可用的:集成目录 hindsight-integrations/omo 下包含 README、hooks 配置、5 个入口脚本、4 个公共库模块、规则文件、demo 与测试用例。本文后续内容即围绕这套真实实现展开,使 changelog 中"跨会话记忆"这一句话落地为可操作的技术细节。
二、集成架构与工作流程
OMO 集成的设计目标很明确:让 OMO 智能体在每次提示前自动召回相关历史记忆注入上下文,并在会话中/会话结束时把对话沉淀进 Hindsight 记忆库。整体数据流如下(见 README 中的架构图):
OMO (orchestrator) ├── SessionStart hook → health check(健康检查) ├── UserPromptSubmit hook → recall memories → inject as additionalContext ├── Stop hook → retain session transcript (async)(异步保留对话) ├── SubagentStop hook → retain sub-agent findings (async)(异步保留子智能体结论) └── SessionEnd hook → force final retain(强制最终保留)这一架构由 hooks/hooks.json 落地实现,五个钩子事件与行为对应关系如下:
| Hook 事件 | 触发时机 | 动作 |
|---|---|---|
SessionStart | 会话开始 | 健康检查;若缺失 API Key 则给出警告 |
UserPromptSubmit | 每次用户提示前 | 向 Hindsight 查询相关记忆,注入为上下文 |
Stop | 智能体完成 | 提取对话记录,异步发送给 Hindsight 做事实提取 |
SubagentStop | 子智能体完成 | 与 Stop 相同——捕获子智能体的学习成果 |
SessionEnd | 会话终止 | 对短会话强制执行最终 retain |
在 hooks/hooks.json 中可以看到每个钩子均通过command类型执行对应 Python 脚本,并设置了差异化的超时与异步策略:UserPromptSubmit超时 45 秒(召回需要等待远端结果注入),Stop/SubagentStop超时 15 秒且标记"async": true(异步执行避免阻塞),SessionEnd超时 10 秒。命令统一写作python3 "${PLUGIN_ROOT}/scripts/xxx.py" || python "${PLUGIN_ROOT}/scripts/xxx.py",通过||回退兼容仅安装python命令的环境。
降级设计:所有钩子都以"优雅降级"为原则——如果 Hindsight 服务不可达,OMO 继续正常工作,只是没有记忆功能。这一点在脚本实现中被反复强化(详见下文源码分析)。
三、安装与部署
1. 获取 API Key
前往 Hindsight 云服务注册并创建 API Key(形如hsk_...)。
2. 安装集成文件
从仓库的hindsight-integrations/omo/目录执行安装(详见 README):
# Hooks(全局) mkdir -p ~/.omo/hooks cp hooks/hooks.json ~/.omo/hooks/hindsight-hooks.json # Scripts + settings(全局) mkdir -p ~/.omo/plugins/hindsight/scripts cp -r scripts/ ~/.omo/plugins/hindsight/scripts/ cp settings.json ~/.omo/plugins/hindsight/settings.json # Rules(按项目安装 —— 在项目根目录执行) mkdir -p /path/to/your/project/.omo/rules cp rules/hindsight-memory.md /path/to/your/project/.omo/rules/hindsight-memory.md安装说明中体现了集成的三层结构:
- hooks(全局):注册到
~/.omo/hooks/,让 OMO 在五个生命周期事件上调用 Hindsight 脚本; - scripts + settings(全局):插件本体,
${PLUGIN_ROOT}指向~/.omo/plugins/hindsight/; - rules(按项目):项目级规则文件,指导智能体何时使用记忆工具。
3. 设置 API Key
export HINDSIGHT_API_TOKEN=hsk_your_key_here或持久化写入~/.hindsight/omo.json:
{ "hindsightApiToken": "hsk_your_key_here" }4. 在 OMO 配置中放行环境变量
在~/.config/opencode/oh-my-openagent.jsonc中:
{ "mcp_env_allowlist": [ "HINDSIGHT_API_URL", "HINDSIGHT_API_TOKEN", "HINDSIGHT_BANK_ID" ] }完成以上四步后启动 OMO,记忆功能即自动生效。
5. 自托管模式(可选)
若使用自托管的 Hindsight 实例,通过环境变量覆盖 API 地址:
export HINDSIGHT_API_URL=http://localhost:8888或写入~/.hindsight/omo.json:
{ "hindsightApiUrl": "http://localhost:8888", "hindsightApiToken": null }本地实例无需 API Token。从源码看,HindsightClient(scripts/lib/client.py)会校验 API URL 必须为http/https协议且包含主机名,否则抛出ValueError;recall.py与retain.py中还有一条兜底逻辑——当 API 地址包含api.hindsight.vectorize.io(即云模式)但未配置 Token 时,直接静默跳过,避免在未认证状态下反复报错。
四、配置体系:三级优先级与完整参数表
1. 配置加载顺序
配置按以下顺序加载,后者覆盖前者(见 scripts/lib/config.py 中load_config()的实现):
- 内置默认值(云 URL 预置,定义于
DEFAULTS字典); - 插件默认
settings.json(${PLUGIN_ROOT}/settings.json,即安装到~/.omo/plugins/hindsight/settings.json的文件); - 用户配置
~/.hindsight/omo.json(稳定、与版本无关); HINDSIGHT_*环境变量(最高优先级)。
环境变量映射表在 scripts/lib/config.py 的ENV_OVERRIDES中定义,且做了类型转换(_cast_env):布尔值接受true/1/yes,整数直接int(),转换失败则忽略该变量。配置文件中值为null的键不会覆盖既有值(_load_settings_file中if v is not None过滤)。
2. 关键配置参数
官方 README 给出的核心参数表如下:
| 配置项 | 环境变量 | 默认值 | 说明 |
|---|---|---|---|
hindsightApiUrl | HINDSIGHT_API_URL | https://api.hindsight.vectorize.io | API 端点 |
hindsightApiToken | HINDSIGHT_API_TOKEN | — | API Key(hsk_...),云模式必需 |
bankId | HINDSIGHT_BANK_ID | omo | 记忆库名称 |
autoRecall | HINDSIGHT_AUTO_RECALL | true | 提示前自动召回 |
autoRetain | HINDSIGHT_AUTO_RETAIN | true | 响应后自动保留 |
retainEveryNTurns | — | 10 | 保留频率(轮次) |
recallBudget | HINDSIGHT_RECALL_BUDGET | mid | 召回深度(low/mid/high) |
dynamicBankId | HINDSIGHT_DYNAMIC_BANK_ID | false | 按项目隔离记忆库 |
debug | HINDSIGHT_DEBUG | false | 向 stderr 输出调试日志 |
3. 完整默认配置
settings.json 提供了比 README 更完整的默认配置,可作为自定义配置的基线模板。除上表参数外,还包括:
- 召回相关:
recallMaxTokens: 1024(召回结果的最大 token 数)、recallTypes: ["world", "experience"](召回的事实类型)、recallContextTurns: 1(召回时纳入的上下文轮数)、recallMaxQueryChars: 800(查询文本截断长度)、recallRoles: ["user", "assistant"](参与构造查询的角色)、recallPromptPreamble(注入上下文时的引导语,提示模型"优先采纳近期记忆、只使用直接有用的记忆"); - 保留相关:
retainMode: "full-session"(保留模式,可选chunked分块模式)、retainOverlapTurns: 2(分块模式的重叠轮数)、retainToolCalls: false(是否保留工具调用)、retainContext: "omo"、retainTags: ["{session_id}"](支持模板变量的标签)、retainMetadata: {}; - 银行相关:
bankMission与retainMission(记忆库使命设定,用于指导事实提取,详见下文)、bankIdPrefix: ""、dynamicBankGranularity: ["agent", "project"]、resolveWorktrees: true、directoryBankMap: {}; - 连接:
requestTimeoutSeconds: null(全局请求超时覆盖)。
其中bankMission与retainMission的默认文案值得关注(settings.json):
bankMission:"You are an OMO (oh-my-openagent) orchestrator. Focus on technical discussions, decisions, architectural context, and coding patterns relevant to the user's projects."retainMission:"Extract technical decisions, architectural choices, user preferences, project context, debugging insights, and tool/library relationships. Ignore routine greetings and transient operational details."
它们通过 scripts/lib/bank.py 的ensure_bank_mission()在首次使用时调用client.set_bank_mission()(对应 APIPATCH /v1/default/banks/{bank}/config,设置reflect_mission与retain_mission)写入记忆库,且已设置的银行会记录在本地状态bank_missions.json中避免重复调用。
4. 动态记忆库 ID(多项目隔离)
启用按项目隔离:
{ "dynamicBankId": true, "dynamicBankGranularity": ["agent", "project"] }这会产生形如omo::myproject、omo::other-repo的记忆库。从 scripts/lib/bank.py 的derive_bank_id()源码看,记忆库 ID 的解析顺序为:
directoryBankMap显式映射:cwd精确匹配映射中的目录时直接返回对应银行 ID(支持bankIdPrefix前缀);- 静态模式(
dynamicBankId=false):使用单一bankId(默认omo); - 动态模式(
dynamicBankId=true):按dynamicBankGranularity字段组合生成,合法字段为agent、project、session、channel、user,用::连接;其中project通过_resolve_project_name()解析——当resolveWorktrees开启时会调用git rev-parse --path-format=absolute --git-common-dir识别 git worktree 并统一映射到主仓库名,使同一仓库的所有 worktree 共享记忆库。
5. 多记忆库召回
在召回主记忆库之外,可附加查询其他记忆库:
{ "recallAdditionalBanks": ["shared-team-knowledge"] }在 scripts/recall.py 中,主库召回结果会与每个附加库的召回结果合并(results = results + extra_results),任一附加库失败只记录 debug 日志,不影响主流程。
五、源码级解析:五个钩子脚本的执行链路
1.SessionStart:健康检查(session_start.py)
会话开始时执行一次。逻辑要点:
- 若
autoRecall与autoRetain均关闭则直接跳过; - 云模式(API URL 含
api.hindsight.vectorize.io)下未配置 Token 时,向 stderr 打印警告:"Using Hindsight Cloud but no API key set..."; - 否则构造
HindsightClient并调用health_check(timeout=3)(GET/health,返回 200 即视为可达); - 任何异常均被捕获,
main()最终sys.exit(0)——绝不因健康检查失败阻断会话启动。
2.UserPromptSubmit:自动召回(recall.py)
这是集成的核心路径,每次用户提示前执行:
autoRecall关闭则直接退出;- 从 stdin 读取 OMO 钩子输入 JSON,提取
prompt(或user_prompt),长度不足 5 个字符则跳过(避免琐碎输入触发召回); - 构造
HindsightClient,derive_bank_id()推导记忆库,ensure_bank_mission()确保使命已写入; - 查询构造:默认
recallContextTurns=1时直接用当前 prompt 作为查询;大于 1 时读取钩子输入中的transcript_path(JSONL 对话记录),通过compose_recall_query()把最近若干轮user/assistant消息与当前 prompt 组合成上下文查询,再用truncate_recall_query()截断到recallMaxQueryChars(默认 800 字符); - 发起召回:调用
client.recall(),对应 APIPOST /v1/default/banks/{bank}/memories/recall,携带query、max_tokens、budget、types参数,超时 10 秒; - 多库合并:遍历
recallAdditionalBanks执行附加召回并合并结果; - 注入上下文:把召回结果格式化为
<hindsight_memories>...</hindsight_memories>包裹的消息块,包含recallPromptPreamble引导语与当前时间,写入状态文件last_recall.json,最后以hookSpecificOutput.additionalContext的形式输出到 stdout,OMO 会将其作为额外上下文注入本次提示。
注意其异常处理策略:召回失败只打印[Hindsight] Recall failed到 stderr 并返回(不注入任何内容);脚本末尾的兜底异常处理器在debug模式下退出码为 2、否则为 0——始终不阻断 OMO 主流程。
3.Stop/SubagentStop:异步保留(retain.py)
Stop与SubagentStop共用retain.py,由 hooks.json 配置为async: true异步执行。核心流程:
autoRetain关闭则退出;读取钩子输入中的session_id与transcript_path;- 轮次控制:
retainEveryNTurns > 1且非强制(force=False)时,通过increment_turn_count(session_id)计数,仅当计数整除retainEveryNTurns才执行保留; - 保留模式:
retainMode="chunked"且轮次间隔大于 1 时,用slice_last_turns_by_user_boundary()按用户消息边界截取最近retainEveryNTurns + retainOverlapTurns轮(默认 12 轮,重叠 2 轮),实现滑动窗口式分块保留;默认full-session模式则保留全部消息; - 转录格式化:
prepare_retention_transcript()按retainRoles(默认 user/assistant)过滤消息,retainToolCalls控制是否包含工具调用; - 文档 ID 策略:分块模式生成
{session_id}-{毫秒时间戳};完整模式通过track_retention()跟踪分块序号生成{session_id}或{session_id}-c{chunk_index},并检测到 transcript 收缩(compaction)时自动推进分块序号,避免覆盖已有文档; - 标签与元数据:
retainTags支持模板变量{session_id}、{bank_id}、{timestamp}、{user_id}(_resolve_template替换),值为空的key:形式标签会被过滤;retainMetadata同样支持模板替换,并自动附加retained_at、message_count、session_id; - 发起保留:调用
client.retain(),对应 APIPOST /v1/default/banks/{bank}/memories,携带content、document_id、context(默认omo)、metadata、tags,请求体async: true(服务端异步处理事实提取)。
4.SessionEnd:强制最终保留(session_end.py)
会话终止时执行,解决短会话问题:如果会话轮次不足retainEveryNTurns,常规保留永远不会触发,导致学习成果丢失。session_end.py在autoRetain开启且存在transcript_path时,以force=True调用run_retain(),强制跳过轮次计数条件完成最终保留。retain.py中force参数直接绕过了retain_every_n的取模判断,确保短会话也能落库。
5. 公共库模块
- scripts/lib/config.py:默认值、环境变量映射与加载合并逻辑(上文已述);
- scripts/lib/client.py:纯标准库(
urllib)实现的 HTTP 客户端,无第三方依赖;包含 URL 校验、Authorization: Bearer头、User-Agent: hindsight-omo/0.1.0、health_check/recall/retain/set_bank_mission四个方法;request_timeout_override可在全局覆盖所有请求超时; - scripts/lib/bank.py:记忆库 ID 推导(目录映射 → 静态 → 动态)与使命写入;
- scripts/lib/state.py:轮次计数、保留分块跟踪、
last_recall.json/bank_missions.json等本地状态读写; - scripts/lib/content.py:召回查询组合、转录格式化、记忆格式化等文本处理。
六、项目规则文件:指导智能体何时使用记忆
安装步骤第 2 步中按项目复制了 rules/hindsight-memory.md,这是一份alwaysApply: true的规则文件,指导 OMO 智能体正确使用记忆能力:
- 何时召回:开始非平凡任务前,从用户请求提取 3–5 个关键术语,搜索既往解决方案、调试洞察或架构决策;琐碎任务(错别字修复、简单问答)不召回;
- 何时保留:完成重要工作后,存储可能复现的问题解决方案、关键架构决策及理由、用户偏好、难以发现的调试洞察;不保留琐碎修改、应用代码(已在 git 中跟踪)与敏感数据(API Key、凭据、密钥);
- 何时反思:当用户要求跨主题综合或需要对大量记忆进行模式推理时,使用
reflect工具。
七、测试与验证
集成自带完整的单元测试(目录 hindsight-integrations/omo/tests):
# 运行单元测试 cd hindsight-integrations/omo pip install pytest python -m pytest tests/ -v # 针对本地 Hindsight 服务器运行交互式 demo HINDSIGHT_API_URL=http://localhost:8888 python demo.py测试覆盖了 test_bank.py(记忆库 ID 推导与使命管理)、test_config.py(配置加载优先级与环境变量覆盖)、test_hooks.py(钩子输入处理)等关键模块,可用于验证配置合并逻辑与银行解析规则是否符合预期。
八、总结
OMO 集成(0.1.0,见 changelog)是 Hindsight 生态中"为 Agent 提供长期记忆"的又一个落地案例。它的核心价值可以概括为三点:
- 全生命周期覆盖:通过
SessionStart、UserPromptSubmit、Stop、SubagentStop、SessionEnd五个钩子,实现"会话开始检查 → 每次提示前召回 → 会话中/子代理完成后保留 → 会话结束强制落库"的闭环; - 零侵入的优雅降级:所有脚本都以"绝不阻断 OMO 主流程"为底线,Hindsight 不可用时记忆静默失效,不影响智能体正常工作;
- 灵活可配:三级配置优先级、动态记忆库隔离、多记忆库召回、分块保留与标签模板等机制,使其既能开箱即用,也能适应多项目、多用户的复杂部署场景。
对于想要为 OMO 智能体补上"跨会话连续性"的开发者,按照本文第三节的安装步骤操作即可快速接入;如需进一步定制,可对照 settings.json 与 scripts/lib/config.py 调整参数,并借助单元测试验证配置行为。
【免费下载链接】hindsightHindsight: Agent Memory That Learns项目地址: https://gitcode.com/GitHub_Trending/hindsight2/hindsight
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考