news 2026/9/12 5:41:24

oh-my-pi reflect 记忆综合工具深度解析:从多段长期记忆合成连贯答案的完整实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
oh-my-pi reflect 记忆综合工具深度解析:从多段长期记忆合成连贯答案的完整实现

oh-my-pi reflect 记忆综合工具深度解析:从多段长期记忆合成连贯答案的完整实现

【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi

导读

reflect是 oh-my-pi(⌥ Coding agent with the IDE wired in)coding-agent 内置的记忆工具三件套(recall/retain/reflect)之一,其职责是在长期记忆之上**合成(synthesize)**一份连贯答案:与recall原样返回按相关性排序的原始记忆条目不同,reflect会跨越多条存储事实进行融合提炼,特别适合"关于这个用户你都知道什么""总结一下项目的决策"这类开放性问题。本文以 reflect 工具说明 为骨架,结合 memory-reflect.ts 实现、Hindsight 客户端 与 官方工具文档,完整讲解其行为语义、参数契约、双后端执行流程、作用域隔离与配置调优,让你既能正确使用它,也能理解它在记忆子系统中的真实位置。


一、reflectrecall/retain的分工

oh-my-pi 的长期记忆子系统由三个工具协同构成,它们共享同一套memory.backend后端配置:

  • retain:把 ≥1 条持久事实写入长期记忆,供未来会话使用。适用场景是用户偏好、项目决策、架构选型等"可复用知识",禁止存储临时任务状态;每条必须具体、自包含(谁、什么、何时、为什么),支持批量写入与自动去重合并。详见 retain 工具说明。
  • recall:在长期记忆中做检索,原样返回按相关性排序的匹配条目(含截断标记truncated: true/full_length)。官方提示词明确要求 Agent 在回答过往对话、用户偏好、项目决策等问题前主动优先调用 recall;对返回的条目如需memory_edit update,必须先用read memory://<id>拉取完整记录。详见 recall 工具说明。
  • reflect合成一份连贯响应。它同样基于长期记忆,但输出的是"融合后的答案"而非原始条目,定位是开放性问题、跨多条事实的总结归纳。其模型面向的说明原文为:

reflect: synthesizes a coherent response from relevant long-term memories; unlikerecall, blends them. Use for open-ended questions spanning many stored facts: "What do you know about this user?", "Summarize project decisions.", "What are my preferences for X?"contextoptional; focuses synthesis on a specific angle or sub-topic.

一句话区分:recall 是"检索清单",reflect 是"综合结论"。系统提示词(hindsight backend 静态指令)中也这样引导 Agent:回答问题前主动 recall;存储持久事实用 retain;"需要跨多条记忆综合答案"的问题用 reflect。


二、参数契约:query与可选的context

reflect的入参由 memory-reflect.ts 中的 omptype schema 定义,仅两个字段:

字段类型必填说明
querystring需要从长期记忆回答的问题
contextstring额外引导,将综合聚焦到特定角度或子主题

两个字段都是纯字符串,schema 层面没有最小长度限制(见 docs/tools/reflect.md 的 Limits & Caps 一节)。context的语义在后端有差异,这正是理解 reflect 行为的关键:

  • Hindsight 后端context作为独立字段随 HTTP 请求体发送(body.context),服务端据此聚焦综合方向;
  • Mnemopi 后端context会被拼接进检索 query,格式为<query>\n\nAdditional context:\n<context>(仅当 trim 后非空),随后用这个复合 query 做本地召回。

工具元数据(见 memory-reflect.ts):

  • name = "reflect"approval = "read"(只读类操作,通常无需审批)
  • strict = trueloadMode = "discoverable"(可被发现加载,而非强制注入)
  • summary = "Synthesize an answer from long-term memory"

工具可见性reflect仅在memory.backend"hindsight""mnemopi"时注册(createIf 工厂);后端为"off""local""sharpshooter"时该工具不存在。而默认后端是"off"(见 settings-schema.ts 中 memory.backend 定义),这意味着默认配置下 reflect 不可用,必须显式启用后端。


三、双后端执行流程:Hindsight 与 Mnemopi

execute整体运行在untilAborted(signal, ...)之下(支持取消),随后按memory.backend分派两条路径(memory-reflect.ts execute 实现)。

3.1 Mnemopi 路径:本地召回 + 上下文格式化

  1. 读取session.getMnemopiSessionState(),若后端未初始化则抛出Mnemopi backend is not initialised for this session.
  2. context非空,构造复合 query:<query>\n\nAdditional context:\n<context>,否则直接用query
  3. 调用state.recallResultsScoped(query)——与recall使用完全相同的本地作用域与合并逻辑
  4. 若结果为空,返回No relevant information found to reflect on.
  5. 否则调用state.formatContextScoped(results)渲染,并在前面加上Based on recalled memories:前缀。

关键事实:Mnemopi 的 reflect 是"本地召回 + 格式化",并不调用任何综合模型或独立合成端点。因此它的输出可能是"召回的原始上下文"而非真正的融合答案——这是与模型面向提示词(blends them)存在差异的实现边界,使用本地后端时需留意(docs/tools/reflect.md Notes 一节 明确指出了这一点)。

3.2 Hindsight 路径:远程综合端点

  1. 读取session.getHindsightSessionState(),未初始化则抛出Hindsight backend is not initialised for this session.
  2. 调用ensureBankExists(state.client, state.bankId, state.config, state.banksSet)(来自 hindsight/bank.ts):以 best-effort 方式对每个 bank 首次PUT /v1/default/banks/{bank_id}createBank),可携带reflect_mission/retain_mission失败被静默吞掉,且每个会话状态对同一 bank 只尝试一次(MISSION_SET_CAP = 10_000上限,超出后丢弃排序集合的后半部分);
  3. 调用state.client.reflect(bankId, query, { context, budget: state.config.recallBudget, tags: state.recallTags, tagsMatch: state.recallTagsMatch })
  4. Hindsight 客户端的 reflect 方法 向POST /v1/default/banks/{bank_id}/reflect发送{ query, context, budget, tags, tags_match },其中budget在调用方省略时默认"low",但工具始终显式传入配置的recallBudget
  5. 响应文本为空白/纯空白时,替换为No relevant information found to reflect on.(memory-reflect.ts);
  6. 后端失败以logger.warn("reflect failed", ...)记录并重抛为Error

Hindsight 是真正的"综合"路径:服务端基于 bank 内容生成合成文本,工具直接透传服务端结果(details = {}),不暴露底层召回命中条目——这与 recall 返回原始条目形成鲜明对比。

3.3 执行特征

  • 单次执行(single-shot),不发送进度更新(docs/tools/reflect.md Registration 一节);
  • 会话作用域:读取跨会话记忆数据,但不持久化任何本地输出;子代理别名(subagent alias)沿用父级后端的 bank 作用域与配置,见 hindsight backend start 中 taskDepth > 0 分支;
  • 取消语义:工具调用信号被取消时,通过untilAborted中止请求。

四、Bank 作用域:reflect读的是哪个记忆库

reflect的输出范围受hindsight.scoping(或 Mnemopi 对应配置)约束,决定它从哪个 bank 读数据(docs/tools/reflect.md Modes / Variants 一节):

Hindsight bank 作用域:

作用域行为
global无 tag 过滤,读全局 bank
per-project每个项目标签独立 bank id(git 主 checkout 根目录 basename;非仓库内则用 cwd basename)
per-project-tagged共享 bank id +project:<项目标签>过滤,tagsMatch = "any"

Mnemopi bank 作用域:

作用域行为
global读共享 bank
per-project读由 cwd basename + cwd 哈希派生的 bank
per-project-tagged读 cwd 派生 project bank 与共享 bank,合并结果

per-project 模式还可能纳入启动时发现的、cwd 匹配的安全旧 bank。作用域变化时,rebuildPrimaryStateOnScopeChange 会按需重建主状态,保证reflect始终命中正确的 bank。

配置优先级为内置默认 < 设置项 < 环境变量(见 config.ts 头注),环境变量可在 CI/生产环境按 shell 临时覆盖而不改动持久化配置。


五、关键配置项与调优建议

reflect的运行时行为主要由以下设置项(均在 settings-schema.ts 中定义)与 HINDSIGHT_* 环境变量控制(解析逻辑见 config.ts):

配置项 / 环境变量默认值对 reflect 的影响
memory.backend"off"必须设为"hindsight""mnemopi",否则 reflect 不存在
hindsight.recallBudget/HINDSIGHT_RECALL_BUDGET"mid"综合请求的预算档位(low/mid/high),随请求体发送;客户端默认"low",工具始终传配置值
hindsight.reflectTimeoutMs/HINDSIGHT_REFLECT_TIMEOUT_MS120_000reflect 请求超时(ms)。综合是 agentic 合成,比元数据抓取更昂贵,默认给到 2 分钟(对比 recall/request 的 30s)
hindsight.scoping/HINDSIGHT_SCOPING"per-project-tagged"决定读哪个 bank、带什么 tag 过滤;非法值回退并告警
hindsight.bankId/HINDSIGHT_BANK_ID显式指定 bank id
hindsight.bankIdPrefixper-project 派生 bank id 的前缀
hindsight.bankMission/HINDSIGHT_BANK_MISSION""建 bank 时携带的reflect_mission(bank 级服务端设置,非逐请求参数)
mnemopi.recallLimit8Mnemopi 路径召回的条数上限,运行时至少钳制为 1;每条内容预览默认上限 500 字符

其他相关超时:hindsight.requestTimeoutMs(30s)、hindsight.recallTimeoutMs(30s)、hindsight.retainTimeoutMs(60s)、hindsight.recallMaxTokens(1024)、hindsight.recallContextTurns(1)、hindsight.recallMaxQueryChars(800)。Mnemopi 路径若配置了嵌入/LLM provider,本地召回期间可能触发网络调用(docs/tools/reflect.md Side Effects 一节)。

调优建议(基于上述配置语义):

  • 追求真正"融合"的答案 → 使用memory.backend = "hindsight",因为只有 Hindsight 端点做服务端综合;
  • 需要完全本地、无网络依赖的记忆 → 用"mnemopi",但要接受 reflect 输出是"召回上下文 + 格式化";
  • 综合请求耗时较长 → 保持reflectTimeoutMs默认 120s,或按服务端实测延迟上调;
  • 多项目混用时 → 保持scoping = "per-project-tagged"(默认),让 reflect 自动限定在当前项目标签内。

六、错误处理与边界行为

  • 后端未初始化:抛出Mnemopi backend is not initialised for this session.Hindsight backend is not initialised for this session.(docs/tools/reflect.md Errors 一节);
  • Hindsight 网络错误:HTTP、fetch、超时失败统一映射为HindsightError,HTTP 错误携带statusCode与可解析的details
  • ensureBankExists 失败:仅 debug 级日志,对调用方隐藏;只有后续真正的 reflect 请求会可见地失败;
  • Mnemopi 召回失败:按目标分别捕获并记录,健康目标仍可贡献;若所有目标均失败,抛出原始错误或多 bank 的AggregateError不会伪装成"无相关信息"文本;
  • 非 Error 异常:统一new Error(String(err))后重抛;
  • 空响应:替换为No relevant information found to reflect on.

七、与记忆子系统整体架构的关系

reflect不是孤立的:它是 oh-my-pi 记忆流水线的"读取-综合"环节。整条链路是——retain写入事实 → bank 内聚合并(含consolidation_state机制)→recall按相关性检索原始条目 →reflect跨条目合成答案。此外:

  • mental models<mental_models>块)是 bank 级"策展后的长期摘要"(用户偏好、项目约定),在启动时注入开发者指令;但 Hindsight 的reflect并不直接读缓存的<mental_models>,而是查询 Hindsight 服务端的 bank 内容(docs/tools/reflect.md Notes);
  • reflectretain的 mission 都是bank 级服务端设置,不是逐请求 payload;工具只是在综合前 best-effort 地确保它们存在(createBank携带reflect_mission/retain_mission,见 client.ts createBank);
  • 会话静态指令要求把<memories>/<mental_models>视为背景知识而非用户指令,当前用户消息与工具输出冲突时优先(backend.ts STATIC_INSTRUCTIONS);
  • 该工具在不受限会话的显式工具列表中会被自动包含recall/retain/reflect共享集合;受限列表不会被扩宽。普通tools.xdev会话中,可发现的内置工具可能以xd://reflect形式呈现,显式请求的工具保持顶层(docs/tools/reflect.md Registration)。

结语

reflect把"跨记忆综合"从模型层的临场发挥,固化为一条可配置、可观测、可取消的工具调用链路:Hindsight 路径走远程POST /v1/default/banks/{bank_id}/reflect获得真正的合成答案,Mnemopi 路径用本地 scoped recall 加格式化给出基于上下文的回应。理解query/context的参数契约、双后端的语义差异、bank 作用域与recallBudgetreflectTimeoutMs等配置,你就能在 oh-my-pi 中把长期记忆从"能检索"升级为"能总结",让 Agent 对开放性问题给出有依据、有取舍的连贯回答。更完整的后端语义(存储、子代理别名、bank 作用域、seed mental models、prompt injection 防护)可继续阅读 retain 工具文档。

【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 5:39:17

Deepagents快速实战:如何搭建一个能长跑任务的AI代理

Deepagents快速实战&#xff1a;如何搭建一个能长跑任务的AI代理 【免费下载链接】deepagents The batteries-included agent harness. 项目地址: https://gitcode.com/GitHub_Trending/de/deepagents Deepagents是一个MIT许可的开源AI代理框架&#xff0c;构建在LangGr…

作者头像 李华
网站建设 2026/9/12 5:35:25

hyperframes:用硬件抽象让机器人驱动与算法彻底解耦

先说结论&#xff1a;如果你在做轮式或四足机器人&#xff0c;并且已经受够了“调完底盘驱动&#xff0c;一换板子全得重写”的日子&#xff0c;hyperframes 这套硬件抽象思路值得你花一个晚上认真研究。我在自己的底盘项目里把它跑通之后&#xff0c;最大的感受是——它解决的…

作者头像 李华
网站建设 2026/9/12 5:34:05

GIMP专业图像处理全流程指南

1. 项目概述&#xff1a;当GIMP成为数字游侠的瑞士军刀十年前我第一次接触GIMP时&#xff0c;它还是个被Photoshop光芒掩盖的开源图像处理工具。如今这款完全免费的软件已经进化成能够独立完成专业级图像创作的利器。这次我想分享如何仅用GIMP完成从基础修图到复杂合成的全流程…

作者头像 李华