资讯动态

OpenHuman 记忆检索 Agent 深度解析:Memory Agent 域架构、六大检索策略与性能基准

发布时间:2026/9/10 1:07:18 来源:尧图企业网站定制
OpenHuman 记忆检索 Agent 深度解析Memory Agent 域架构、六大检索策略与性能基准【免费下载链接】openhumanOpenHuman is an open source personal AI for Mac, Windows and Linux — local-first memory, agent orchestration, and deep research.项目地址: https://gitcode.com/GitHub_Trending/op/openhuman导读本文聚焦 OpenHuman 开源项目中负责从用户记忆中检索答案的核心子系统——Memory Agent 域代码位于src/openhuman/memory/agent/。它以专用子 Agent 的形式组合向量检索、关键词匹配、实体查找、时间摘要树浏览等多种策略在用户的 memory tree 中完成从查询到带引用的答案的完整闭环。读完本文你将掌握该域的模块划分、内存树目录规范、agent.toml配置语义、系统提示词中的性能契约与 fail-fast 机制、call_memory_agent工具的参数与同步/异步行为以及如何使用bench-memory-walk.sh对检索性能做基准测量。Memory Agent 域的定位与模块布局Memory Agent 域src/openhuman/memory/agent/是一个面向检索的专用领域domain其职责集中为三件事记忆检索 Agent 的定义与注册、系统提示词的动态构建以及记忆树遍历与分块检索的性能埋点。根据src/openhuman/memory/agent/mod.rs的模块声明该域由五个模块组成文件职责mod.rs模块声明与重导出含agent、memory_loader、ops、tools、types五个子模块types.rs基准测试与性能追踪类型RetrievalStep、WalkBenchmark、BenchmarkSummaryops.rs内存树遍历性能的基准测试 harnesstools.rscall_memory_agent工具实现记忆 Agent 的外部调用入口memory_loader.rs会话记忆加载与引用citation收集逻辑域内还嵌套了一个agent/子模块src/openhuman/memory/agent/agent/它是内置记忆 Agent 的完整定义agent.toml工具白名单、模型提示、迭代上限、prompt.rs动态提示词构建器、prompt.md系统提示词原型。从源码结构看该域是定义 执行 度量三位一体的设计定义侧提供 Agent 的声明式配置与提示词执行侧通过tools.rs把整个子 Agent 作为工具暴露给上层 Agent度量侧则由ops.rstypes.rs支撑基准测试。六大检索策略一个 Agent 的组合拳根据README.md对 Purpose 的描述记忆 Agent 是一个专精子 Agentspecialist sub-agent它遍历用户的 memory tree 来回答问题核心能力是组合多种检索策略向量检索Vector search——对全部已存储 embedding 做语义相似度匹配关键词检索Keyword search——对磁盘上的原始内容文件做模式匹配实体检索Entity search——规范实体canonical entity查找与关系跟随树浏览Tree browse——基于时间的摘要树的分层导航内容读取Content read——直接读取 raw/wiki/episodic/document 存储中的文件来源列举Source listing——发现可用的来源与内容类型。这六种策略并非各自孤立。从agent/tools.rs中call_memory_agent工具的描述可以印证memory_tree工具中的walk/smart_walk模式现在运行的是确定性 E2GraphRAG 检索器其余模式search_entities、query_source、cover_window、drill_down、fetch_leaves是独立的检索原语而call_memory_agent则是把整个agent_memory子 Agent 派生出来由子 Agent 自主决定组合哪些检索策略最终返回一份经过综合、带引用的答案。因此可以理解为上层宽而全的检索交给子 Agent底层单策略的精确查询交给memory_tree工具。Memory Tree 存储结构{workspace}/memory_tree/content/记忆 Agent 的检索对象是位于{workspace}/memory_tree/content/的目录树README 给出了标准布局content/ ├── chat/ # 会话分块按来源 │ └── conversations-agent/ │ └── {hash}.md ├── episodic/ # 会话/潜意识情节分块 │ └── {session_id}/ │ └── {hash}.md ├── raw/ # 原始摄取文档GitHub、Gmail 等 │ └── {source-slug}/ │ └── {hash}.md └── wiki/ # 摘要树层级化 └── summaries/ └── {namespace}/ └── {level}/{node_id}.md四类内容的语义分别为chat/按来源组织的会话分块例如chat/conversations-agent/{hash}.md存放对话 Agent 的会话片段episodic/会话或潜意识subconscious情节的分块按{session_id}再按{hash}.md组织raw/从 GitHub、Gmail 等渠道摄取进来的原始文档按来源 slug 分类wiki/层级化摘要树wiki/summaries/{namespace}/{level}/{node_id}.md构成按时间/主题收敛的多层摘要结构——这正是walk/smart_walk与drill_down等模式得以工作的数据基础。基准脚本scripts/bench-memory-walk.sh在启动时会统计该目录下的 Markdown 文件数、目录数与总大小并以{level}/{node_id}.md这种多层结构作为摘要树导航的依据。Agent 定义与配置agent.toml逐字段解读内置记忆 Agent 的声明式定义位于 src/openhuman/memory/agent/agent/agent.toml关键字段如下id agent_memory display_name Memory Agent delegate_name retrieve_memory when_to_use Deep memory-retrieval specialist: walks the memory tree with vector, keyword and entity search. Use when the user asks to find, recall or look something up from their memory, conversations or documents. temperature 0.2 max_iterations 6 sandbox_mode read_only agent_tier worker omit_identity true omit_memory_context false omit_safety_preamble true omit_profile false omit_memory_md false [model] hint chat [tools] named [ memory_recall, memory_tree, query_memory, memory_doctor, memory_flavour, ask_user_clarification, ]逐项解读id/display_name/delegate_nameAgent 的内部 ID、展示名与委派名。delegate_name retrieve_memory表示上层 Agent 可以以检索记忆的语义委派给它id agent_memory同时是tools.rs中call_memory_agent工具按AGENT_ID常量在注册表中查找的定义标识。when_to_use面向编排器的路由描述——当用户请求从记忆/会话/文档中查找、回忆或检索某内容时启用。temperature 0.2偏低的采样温度强调检索结果的确定性与忠实性。max_iterations 6工具调用预算的硬上限。配置注释引用了 issue #4655一次合法的回答通常只需要几次调用walk → 可选的 drill_down/fetch_leaves → 作答预算过大时Agent 可能在约 80 秒内暴力执行约 10 次空搜索后以[SUBAGENT_INCOMPLETE]结束而非给出未找到数据的结论。保持 6 次的小预算可以让退化的空记忆树快速失败同时给深度检索留出余量。sandbox_mode read_only只读沙箱与检索类 Agent 的身份匹配——它不应产生任何写操作。agent_tier workerworker 层级属于后台执行型子 Agent。omit_identity true/omit_safety_preamble true跳过身份与安全前导段omit_memory_context false/omit_profile false/omit_memory_md false保留记忆上下文、用户画像与 memory 说明——这与该 Agent 专门处理记忆的定位一致。[model] hint chat向模型路由层提示优先使用对话类模型。[tools] named [...]工具白名单六个工具中除ask_user_clarification澄清提问与memory_doctor健康诊断外其余四个均为检索工具。memory_flavour的特殊性在于它读取的是用户编译后的人格画像刻面communication、coding_style、stack、workflow、environment、directives、anti_preferences 之一属于只读的风格/偏好画像与上述事实/情节检索路径相互独立。系统提示词与性能契约prompt.md与prompt.rs提示词构建agent/prompt.rs中的build()函数以include_str!(prompt.md)将提示词原型编译进二进制随后按顺序拼接用户文件上下文render_user_files、工具说明render_tools、安全说明render_safety、工作区上下文render_workspace。即最终系统提示词 原型 运行时注入的用户文件/工具清单/安全/工作区段这保证了提示词既能保持记忆检索专家的核心人格又能适应不同工作区的实际情况。检索策略指引prompt.md 核心prompt.md中首先定义工具选型策略memory_tree主工具——统一分发器含多种模式walk/smart_walk确定性 E2GraphRAG 检索提取查询实体后在实体图局部与密集摘要全局之间路由全程无 LLM返回排序后的证据命中。适合开放式问题我对 X 知道什么找找关于 Y 的会话search_entities先找规范实体 ID按实体过滤前应调用query_source按来源类型chat、email、document 时间窗口过滤drill_down把某个摘要节点向下展开一层fetch_leaves拉取原始分块用于引用citation。memory_recall——遗留的键值记忆检索适合精确的偏好/事实查询。query_memory——对已存记忆做简单文本搜索。memory_doctor——诊断记忆树健康问题。memory_flavour——读取用户在某一刻面的蒸馏风格画像当问题涉及用户偏好如何工作而非某个具体事实/事件时使用。性能契约Performance contract提示词向 Agent 强约束了检索行为模式先宽后窄先用walk或search_entities开头再用drill_down/fetch_leaves取细节walk/smart_walk是确定且廉价的单次调用即返回排序后的证据综合由 Agent 自己做禁止多轮漫游式 walk必须引用来源答案中的每个事实都应追溯到具体分块或摘要节点如实报告缺失记忆树存在缺口时明确说明而不是猜测。Fail fast小预算下的求生策略提示词专门用一节强调不要耗尽工具预算。其背景与agent.toml的max_iterations 6一脉相承在一个空记忆树上反复搜索不是彻底而是失败——浪费约 80 秒后以[SUBAGENT_INCOMPLETE]结束用户的问题仍得不到回答。因此规则明确两击规则Two-strike rule如果第一次检索memory_tree的walk/smart_walk没有相关命中最多再尝试一个替代角度如search_entitieswalk或单次memory_recall/query_memory若仍为空立即停止并返回负结果禁止把所有工具和模式轮一遍。退化记忆是 fail-fast 条件不是绕过的目标若召回出错或异常为空调用一次memory_doctor当它报告healthy: false例如 embeddings 提供方未配置embeddings_unconfigured、语义召回不可用、或存在失败/排队任务时不要用关键词变体暴力补偿——语义搜索在该状态下不可能成功更多调用只会增加延迟应立即返回带memory degraded标注的答案。绝不耗尽预算后以[SUBAGENT_INCOMPLETE]收场对没有数据的查询回答未找到相关记忆并停止。负结果输出与引用格式当记忆无相关内容时要求直说并停止、绝不编造No relevant memory found for this query. Nothing in the users memory tree, conversations, or documents matches it.当memory_doctor显示子系统退化时需附带原因以便编排器呈现给用户No relevant memory found — and memory is currently degraded: semantic recall is unavailable (embeddings provider not configured). Results may be incomplete until embeddings are configured.正常作答的格式约定为答案正文带内联引用[1]、[2]…随后列出证据来源[Answer text with citations like [1], [2]...] Sources: 1. chat/conversations-agent/abc123.md — relevant snippet 2. raw/github-repo/def456.md — relevant snippetcall_memory_agent工具如何把整个 Agent 变成一次调用tools.rs 实现了call_memory_agent工具。它与底层memory_tree工具的本质区别正如其模块注释所述memory_tree的walk/smart_walk现在运行确定性 E2GraphRAG 检索器、其余模式是检索原语而call_memory_agent派生完整的agent_memory子 Agent由它自主决定组合哪些检索策略并返回综合、带引用的答案。工具元数据定义如下namecall_memory_agentdescription调用记忆检索 Agent 遍历记忆树、返回与查询相关的上下文Agent 自主组合向量搜索、关键词匹配、实体查找与树浏览然后返回带引用的答案适用于需要全面记忆搜索、而非单一策略查询的场景categorySystempermission_levelReadOnlyscopeAgentOnly仅 Agent 可调用工具白名单拦截is_concurrency_safetrue。参数 Schema{ type: object, required: [query], properties: { query: { type: string, description: Natural-language query to search the users memory for. }, context: { type: string, description: Optional context to help the memory agent understand what youre looking for and why. }, max_turns: { type: integer, description: Max retrieval turns the memory agent can take. Default: 15, hard cap: 20., minimum: 1, maximum: 20 }, async: { type: boolean, description: If true, fire-and-forget — the agent runs in the background and results are not returned inline. Default: false (synchronous). } } }其中max_turns在execute_with_context中被clamp(1, 20)收敛到合法区间并作为约束行写入子 Agent 的提示词async默认false。执行链路与安全门执行流程execute_with_context值得逐段展开参数校验query为必填context、max_turns、async均可选。父上下文检查调用current_parent()获取当前父 Agent 上下文若不存在非 Agent 回合内调用直接返回错误。注册表查找从AgentDefinitionRegistry::global()中按AGENT_ID agent_memory查找定义找不到则报错。白名单门禁校验parent.allowed_subagent_ids是否包含agent_memory不包含则记录 warning 并返回不在父 Agent 子 Agent 白名单的错误——这是安全上的关键一环防止任何 Agent 绕过编排器的子 Agent 许可直接拉起记忆 Agent。提示词组装以Search the users memory tree and return relevant context for this query:\n\n{query} 开头可选追加max_turns约束与额外上下文然后以随机mem-{uuid}作为task_id。执行模式异步fire-and-forgettokio::spawn后台运行立即返回Memory agent dispatched asynchronously (task_id: ...)完成/失败仅记录日志同步默认阻塞等待run_subagent完成随后根据SubagentRunStatus追加说明Completed直接返回、AwaitingUser附加澄清问题、Incomplete附加停止原因最后统一追加\n\n---\n_Memory agent: {iterations} iterations, {elapsed:.1}s_的性能注脚并把迭代数与耗时一并回传给调用方。这一实现同时说明从上层 Agent 视角一次全面记忆搜索就是一次call_memory_agent工具调用复杂策略组合被封装在子 Agent 内部。检索性能基准ops.rs、types.rs与bench-memory-walk.sh数据模型types.rstypes.rs 定义了三个串行化数据结构RetrievalStep单次检索操作——turn回合序号、action动作名、args_summary参数摘要、result_preview结果预览、elapsed耗时、chunks_returned返回分块数、bytes_scanned扫描字节数WalkBenchmark一次被基准的检索的完整结果——query、namespace、content_root、total_elapsed、steps、total_turns、total_chunks_retrieved、total_bytes_scanned、answer、stop_reasonBenchmarkSummary一批基准运行的汇总统计——runs、avg_elapsed_ms、p50_elapsed_ms/p95_elapsed_ms、avg_turns、avg_chunks、total_bytes_scanned。from_benchmarks()对耗时排序后取中位数与 95 分位用于衡量延迟分布而非仅平均值。基准实现ops.rsops.rs 的bench_walk()直接调用fast_retrieveE2GraphRAG 确定性检索器因此循环中没有 LLM追踪被建模为单个检索步骤total_turns恒为 0基准聚焦墙钟延迟 命中数。实现要点通过config.memory_tree_content_root()解析内容根可被content_root参数覆盖经绑定驱动的MemoryRetrieval调用fast_retrieve(query, opts, scope)其中 scope 来自as_bus_scope()用于把当前主机的来源白名单渲染进契约词汇充当权限门禁若驱动不提供 Retrieval 能力如无摘要树可排序如实返回空结果而非报错bench_batch()顺序执行一批查询容忍单条失败记 warning 继续全部失败才bail!最后汇总BenchmarkSummary。命令行基准脚本bench-memory-walk.shscripts/bench-memory-walk.sh 是官方推荐的使用方式# 默认基准查询针对 staging 记忆树 ./scripts/bench-memory-walk.sh # 自定义查询 ./scripts/bench-memory-walk.sh --query what did I discuss about OpenHuman? --max-turns 15 # 自定义内容根 ./scripts/bench-memory-walk.sh --content-root /path/to/memory_tree/content完整命令行选项选项说明默认值--content-root PATH记忆树内容根目录$OPENHUMAN_MEMORY_CONTENT_ROOT或 staging 路径~/.openhuman-staging/users/{uid}/workspace/memory_tree/content--max-turns N每条查询的最大 LLM 回合数12--namespace NS记忆命名空间default--model MODELprovider:model覆盖空跟随配置--query TEXT运行单条自定义查询替代默认 5 条空--verbose显示完整工具输出关闭脚本行为的几个要点默认查询集覆盖不同检索模式共 5 条What projects am I working on?、What did I discuss in my most recent conversations?、What are my preferences and settings?、Find any mentions of GitHub or pull requests、What people have I interacted with recently?启动前会校验内容根存在性并统计 Markdown 文件数、目录数与总大小若target/debug/openhuman-core不存在会自动cargo build每条查询通过 JSON-RPC 方法openhuman.memory_smart_walk参数query、namespace、max_turns经openhuman-core rpc --stdin调用用 python3 构造 JSON 载荷以避免查询注入结果按{query, elapsed_ms, status, timestamp}逐条追加写入target/bench-memory/bench-{时间戳}.jsonl最后输出通过/失败数与总耗时有失败查询时以非零码退出并提示加--verbose排查。会话记忆加载与引用memory_loader.rs的辅助角色除检索主链路外memory_loader.rs 承担会话记忆注入与引用收集PRIOR_CONVERSATION_LIMIT 3限制了新会话开头注入的[Prior conversations]行数上限收紧只为恢复高重要性事实的连续性issue #1399PRIOR_CONVERSATION_KEY_PREFIX high.意味着只有high.前缀的重要条目进入提示词块中低优先级条目保持按需查询CROSS_CHAT_HEADER常量是[Cross-chat context — historical; capabilities may have changed since]的唯一事实来源被主 JSONL 路径、harness/memory_context.rs回退召回路径与编排器Capability questions提示词段三处共用测试对它有断言MemoryCitation结构id/key/namespace/score/timestamp/snippet为 UI 展示记忆来源提供轻量出处collect_recall_citations()走 tinyagents 检索门面使记忆上下文影响回复时 UI 能展示可信来源。这些机制与记忆 Agent 的引用来源契约形成呼应从加载、检索到展示出处贯穿始终。小结一条从查询到带引用答案的完整链路回顾 Memory Agent 域可以勾勒出它在 OpenHuman 中的完整协作链路注入与加载memory_loader.rs在新会话注入高重要性历史记忆并收集引用入口上层 Agent 调用call_memory_agent或直接使用memory_tree等原语定义与路由agent.toml声明工具白名单、模型提示与 6 次迭代上限prompt.rs把prompt.md原型与运行时上下文拼成系统提示词执行子 Agent 依据性能契约先宽后窄组合向量/关键词/实体/树浏览策略调用memory_tree的确定性 E2GraphRAGwalk/smart_walk及配套模式质量护栏两击规则与memory_doctor健康检查确保空树/退化记忆快速失败绝不编造答案强制带来源引用度量ops.rstypes.rsbench-memory-walk.sh提供基于openhuman.memory_smart_walkRPC 的延迟与命中率基准p50/p95 分位统计服务于性能回归观察。这套设计的关键价值在于把用户记忆里到底有什么这件复杂检索问题收敛为一个声明式定义、行为可约束、性能可度量的专精子 Agent既保持了上层编排的简洁又让检索质量与系统健康embedding 配置、摘要树完整性变得可观测、可诊断。【免费下载链接】openhumanOpenHuman is an open source personal AI for Mac, Windows and Linux — local-first memory, agent orchestration, and deep research.项目地址: https://gitcode.com/GitHub_Trending/op/openhuman创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价