首页
/ Mem0 Pi Agent 插件的 context-loader 技能:如何在任务开始前把相关记忆预注入 Agent 上下文

Mem0 Pi Agent 插件的 context-loader 技能:如何在任务开始前把相关记忆预注入 Agent 上下文

2026-09-04 09:19:06作者:宗隆裙

本篇以 @mem0/pi-agent-plugin 插件中的 context-loader 技能定义文件 为主体,完整解析该"任务前记忆预加载"技能的工作流程:如何从当前消息中提取主题、如何发起 2–4 次并行语义搜索、如何按记忆 ID 去重、如何输出紧凑的上下文块,以及四条硬性约束(只读、最多 10 条、空结果静默、跳过已在上下文的记忆)。同时结合插件源码,说明该技能依赖的 mem0_memory 搜索工具、作用域(scope)过滤规则与记忆格式化输出的底层实现,读完即可掌握在 Pi Agent 中构建"先召回、再工作"记忆流水线的完整方案。

技能定位:context-loader 是什么

在 Mem0 的 Pi Agent 插件 中,skills/ 目录包含 8 个 SKILL.md 文件,每个文件定义一种指导 Agent 如何正确使用记忆能力的"技能"。context-loader 是其中负责**预取(pre-fetch)**的技能:

Pre-fetches relevant memories to prime context before working on a task or topic.(在工作于某个任务或主题之前,预取相关记忆以预热上下文。)

它解决的核心问题是:Agent 开始处理一个新任务时,往往不知道用户过去已经表达过哪些决策、偏好和背景知识。如果不先召回记忆,Agent 要么向用户重复提问,要么基于过时的假设工作。context-loader 的作用就是在动手之前,把与当前任务相关的记忆批量拉进上下文。

该技能的 YAML frontmatter 明确了触发描述:

name: context-loader
description: Searches and injects relevant memories into context before starting work
  on a task or topic. Use when beginning a new task, switching context, or when
  past decisions, preferences, or knowledge need to be loaded.

触发时机:何时启用 context-loader

技能文档给出了三类明确的触发场景:

  • 会话启动——由扩展的 before_agent_start 事件自动触发;
  • 用户开始处理某个特定主题或领域时;
  • 用户显式询问——例如说 "what do we know about X" 或 "context for X"。

第一个触发点在插件源码中有对应实现。入口文件 中注册了 before_agent_start 事件处理器,每轮对话开始前它会做两件事:

  1. MEMORY_POLICY(记忆使用策略)追加到系统提示词;
  2. 调用 buildRecallContext 做一次自动预取:用用户的 prompt 直接搜索 project 作用域下的记忆,把命中的记忆格式化成 <mem0-relevant-memories> 块注入系统提示词。

源码注释点明了设计意图:这是"shallow first pass"(浅层第一遍),且声明"This is a shallow first pass — search mem0_memory for more if you need it"——即自动预取只保证基础召回,深入的多角度检索正是交给 context-loader 技能来完成的。两者是互补关系:前者单次搜索、结果直接注入;后者是 Agent 按技能指引主动发起的 2–4 次并行搜索。自动预取由配置项 contextInjection 控制开关(默认 true,见 配置默认值)。

工作流:五步完成上下文预热

context-loader 技能文档定义了完整五步流程,以下是逐条继承与展开:

第 1 步:从当前消息/任务中提取主题

从当前消息或任务描述中识别四类要素:

  • subject areas(主题领域)
  • people mentioned(提到的人)
  • project names(项目名)
  • goal references(目标引用)

这一步是纯推理步骤,不产生任何工具调用。其质量直接决定后续搜索的覆盖面——提取遗漏会导致该方向的历史记忆无法被召回。

第 2 步:发起 2–4 次并行搜索

使用 mem0_memory 工具的 action="search",从不同角度(query angle)分别构造查询,并行执行:

Query angle 目的
Topic/subject name(主题名) 召回相关决策和偏好
People mentioned(提到的人) 召回关系上下文
Project/goal references(项目/目标引用) 召回进展和背景
Broad context(宽泛上下文) 兜底捕获任何相关内容

这种"多角度查询"策略与工具注册时的 prompt 指引一致:在 工具注册代码promptGuidelines 中明确写道:

'For multi-part or comparative questions, run several searches with different phrasings and combine the results before answering -- one search is rarely enough'(单次搜索往往不够,应运行多次不同措辞的搜索再合并结果。)

也就是说,context-loader 技能把这条通用指引具体化为"主题/人物/项目/宽泛"四个标准角度。

第 3 步:跨搜索结果按记忆 ID 去重

多个查询角度的结果集必然存在重叠(同一条记忆可能同时命中主题查询和宽泛查询)。技能要求在所有搜索响应之间按 memory ID 去重,保证输出的上下文块中每条记忆只出现一次,也保证最终数量统计准确。

第 4 步:输出紧凑上下文块(最多 10 条)

去重后,按相关性只保留最重要的记忆,以紧凑格式输出(上限 10 条):

context-loader: loaded <N> memories for "<task summary>"
  - [decisions] <content> [mem0:<short_id>]
  - [preferences] <content> [mem0:<short_id>]
  - [lessons] <content> [mem0:<short_id>]

这个输出格式与插件的记忆格式化实现一脉相承。格式化模块formatMemoryCompact 生成的每条记忆形如:

[<category>] <memory content> (<age>) [mem0:<id>]

即"[分类] 内容 (距今时间) [mem0:ID]"。技能输出中的 [decisions][preferences][lessons] 等前缀,正是来自 Mem0 的自动分类。分类体系由 types.ts 中的 DEFAULT_CUSTOM_CATEGORIES 定义,共 10 个通用类目:identitypreferencesgoalsprojectsdecisionstechnicalrelationshipsroutineslessonsworkmem0:<id> 后缀的作用是在 Agent 后续需要对该记忆执行 update/delete 时,可以直接引用该 ID。

第 5 步:零结果时静默

如果所有搜索都返回空结果,什么都不输出——不要宣布"没有找到上下文"。这条规则避免了在无记忆可加载时污染上下文、干扰 Agent 正常工作节奏。

搜索的底层实现:mem0_memory 工具与 scope 过滤

context-loader 技能的全部检索都通过 mem0_memory 工具完成,其底层实现在 tools.ts 中可以完整验证:

搜索分支的实际调用链

buildToolExecute 中的 search 分支(tools.ts#L56-L66)逻辑为:

  1. 校验 query 必填(否则抛出 query is required for search);
  2. 调用 resolveSearchFilters(scope, scopeCtx) 生成 Mem0 搜索过滤器;
  3. 执行 mem0.search(params.query, { filters })
  4. formatMemoryList 格式化结果,并经过 truncateOutput 截断后返回。

两个值得注意的工程细节:

  • 输出截断MAX_OUTPUT_LINES = 200MAX_OUTPUT_BYTES = 50_000tools.ts#L17-L37)。防止单次搜索撑爆上下文窗口——这也是 context-loader 需要自己做"最多 10 条"精选的原因之一:工具层的截断是硬防线,技能层的 10 条上限是质量防线。
  • 工具描述强调主动召回工具描述 写明 'Use action "search" proactively -- before answering anything that may depend on what the user told you earlier',这与 context-loader"任务开始前先检索"的定位完全呼应。

scope 如何决定"搜到哪些记忆"

context-loader 技能未显式指定 scope 时,会使用插件的 defaultScope(默认 project)。作用域解析模块 为不同 scope 生成不同的 Mem0 过滤器:

Scope 搜索过滤器 适用场景
project(默认) user_id + app_id 项目专属知识:决策、架构、配置
session user_id + app_id + run_id 仅当前会话的临时上下文
global user_id + app_id: "*" 跨所有项目

其中 app_id 的确定方式由 detectAppId 实现:执行 git rev-parse --show-toplevel 取 git 仓库根目录名(3 秒超时),非 git 目录则回退到当前工作目录名。这使得 monorepo 的所有子目录共享同一个记忆池。对 context-loader 而言这意味着:在仓库中执行任务时预取的记忆天然限定在本项目内,不会把其他项目的决策错误地注入当前任务上下文。

相关参数在 配置文件解析逻辑 中合并:配置文件 ~/.pi/agent/mem0-config.json 与环境变量(MEM0_API_KEYMEM0_USER_ID 优先)共同决定 defaultScopecontextInjection 等取值。完整配置项说明可参考 Pi Agent 集成文档

四条硬性约束及其设计动机

技能文档的 Constraints 一节列出了四条不可违反的约束,逐条分析其动机:

约束 内容 设计动机
Read-only(只读) 绝不修改或删除记忆 context-loader 只负责"加载";写入由 remember 技能和自动捕获(auto-capture)负责,删除由 forget 技能(含确认对话框)负责。职责分离避免预取流程产生副作用
Max 10 memories 最多返回 10 条,只保留最相关的 控制上下文注入量。10 条是"信息密度"与"上下文预算"的折中,且远低于工具层 200 行/50KB 的截断上限
Silent on empty 仅在存在相关上下文时才呈现结果 空召回不是异常,不应打扰用户或改变 Agent 行为
跳过已可见记忆 当前会话上下文中已可见的记忆不再重复加载 避免同一事实在系统提示词的自动召回块和本技能输出中重复出现

前三条约束共同保证该技能是一个低噪声、零副作用的上下文增强器:有相关记忆就安静地注入,没有就保持沉默,任何时候都不会改动记忆存储本身。

与自动召回的分工:两条互补的召回路径

从源码结构看,插件实际提供两条记忆注入路径,context-loader 属于第二条:

  1. 被动自动召回(guaranteed recall)before_agent_start 事件用当前 prompt 做一次 project 作用域搜索,命中结果直接包在 <mem0-relevant-memories> 标签里追加到系统提示词(entry.ts#L113-L120)。它是"保证有"但"只有一遍"的浅层召回,且失败时静默降级(best-effort,绝不阻塞对话轮次)。
  2. 主动技能召回(context-loader):Agent 在开始任务/切换主题时,按技能定义的"提取主题 → 多角度并行搜索 → 去重 → 精选 10 条 → 紧凑输出"流程自行执行。它覆盖面更广(多个查询角度),但依赖 Agent 正确遵循技能指引。

两条路径的分工清晰:自动召回保证"每次回答前至少有一遍记忆检索",context-loader 保证"新任务开始时上下文被系统性预热"。自动召回注释中的提示语("search mem0_memory for more if you need it")正是把 Agent 引向 context-loader 这类深度检索的衔接点。

使用与验证方式

  • 技能文件:查看 skills/context-loader/SKILL.md,其余 7 个技能(remember、search、forget、dream、tour、pin、status)位于同目录的 skills/ 下,可在 README 的 Skills 表中对照各自职责。
  • 插件安装pi install npm:@mem0/pi-agent-plugin,并设置 MEM0_API_KEYm0- 前缀的密钥),详见 插件 README官方集成文档
  • 验证连接:启动新会话后执行 /mem0-status 查看用户 ID、检测到的项目(app_id)与记忆数量。
  • 典型效果场景:Session 1 中用户说"I prefer dark mode and concise answers",自动捕获存入偏好类目;Session 2 开始新任务时,context-loader 以"主题/偏好"角度搜索命中该记忆,Agent 无需用户重新解释即可按既有偏好工作。

小结

context-loader 是 Mem0 Pi Agent 插件中"记忆预加载"的标准作业流程:它以 mem0_memorysearch 动作为检索底座,以 project/session/global 三级作用域过滤器保证召回范围正确,以 10 类自动分类和 [category] content [mem0:id] 的紧凑格式控制输出规模,并以"只读、限量、空则静默、去冗余"四条约束把预取过程变成一个零副作用的上下文增强步骤。结合源码可见,它与 before_agent_start 的自动浅层召回互补,共同构成该插件"保证记忆可用 + 按需深度预热"的双层召回架构。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
982
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384