mem0 pi-agent-plugin 的 remember 技能:逐字存储记忆与十类分类的完整实现解析
本文基于 @mem0/pi-agent-plugin 中的 remember 技能 展开,完整还原该技能的“提取内容—分类—存储—确认”四步执行流程,并结合 命令处理器、mem0_memory 工具 与 作用域解析 的源码,说明“逐字存储(no inference)”与 10 类记忆分类在 Mem0 API 层面是如何落地的。读完本文,你可以掌握该技能的触发条件、分类判定表、确认输出格式,以及它背后的存储参数(infer: false、customCategories)与 project/session/global 三级作用域机制。
一、remember 技能在 pi-agent-plugin 中的定位
@mem0/pi-agent-plugin 是为 Pi Agent 提供持久化语义记忆的扩展,由 Mem0 驱动,记忆可跨会话、跨项目、跨设备保留。插件包含 8 个斜杠命令与 8 个技能(SKILL.md),其中 remember 技能负责回答一个明确的问题:当用户明确要求“记住这句话”时,Agent 应如何把内容原样存入 Mem0,而不是经过 LLM 推理改写。
技能清单与职责对照(来自 README):
| 技能 | 用途 |
|---|---|
context-loader |
会话开始时预取相关记忆 |
remember |
带分类地存储事实(本文主题) |
search |
快速语义搜索,紧凑结果 |
forget |
带确认地删除记忆 |
forget/dream/tour/pin/status |
删除/整合/浏览/保护/诊断 |
技能的元数据定义在 SKILL.md 的 frontmatter 中:
name: remember
description: Stores a memory verbatim from user input with appropriate category classification. Use when the user says remember this, save this, store this, note that, or explicitly asks to record a preference, decision, goal, or lesson.
这段描述同时定义了技能的触发词(“remember this / save this / store this / note that”)与适用对象(偏好、决策、目标、经验教训)。Pi Agent 依据这段 description 判断何时激活该技能。
二、四步执行流程:原文档的完整继承
以下四步严格对应 SKILL.md 的 Execution 章节,是该技能的核心骨架。
Step 1:提取内容
用户以参数形式提供内容:
/mem0-remember <text>
若未提供文本,Agent 应主动询问:“What should I remember?”。这一点与源码一致——commands.ts 的 mem0-remember 处理器 在参数为空时直接提示用法:Usage: /mem0-remember <text>,不做任何猜测式补全。
Step 2:分类记忆(完整判定表)
根据内容信号选择最佳类别。下表完整继承原文档的判定规则,最后一行是兜底规则(无明确信号时归入 lessons):
| 内容信号 | 分类 |
|---|---|
| "I prefer...", "I like...", "use X instead of Y" | preferences |
| "we decided...", "always use...", "never..." | decisions |
| "I learned...", "figured out...", "don't try..." | lessons |
| "my goal is...", "I want to...", "working toward..." | goals |
| "I work at...", "my role is...", "my team..." | work |
| "every day I...", "my workflow is..." | routines |
| "I'm working on...", "the project involves..." | projects |
| "John is...", "my manager...", "the team..." | relationships |
| "my name is...", "I'm from...", "I studied..." | identity |
| setup、tools、config、environment | technical |
| 其他任何情况 | lessons(兜底) |
这 10 个类别并非技能自创,而是插件在 types.ts 中定义的 DEFAULT_CUSTOM_CATEGORIES:
export const DEFAULT_CUSTOM_CATEGORIES: CustomCategory[] = [
{ identity: "Personal details, background, and self-descriptions" },
{ preferences: "Likes, dislikes, habits, and preferred ways of doing things" },
{ goals: "Objectives, aspirations, and targets the user is working toward" },
{ projects: "Ongoing work, initiatives, and areas of focus" },
{ decisions: "Choices made, rationale, and trade-offs considered" },
{ technical: "Technical knowledge, tools, configurations, and environment details" },
{ relationships: "People, teams, organizations, and their roles" },
{ routines: "Recurring patterns, workflows, schedules, and processes" },
{ lessons: "Insights learned, mistakes to avoid, and best practices discovered" },
{ work: "Professional context, role, responsibilities, and work environment" },
];
即技能的分类判定表与 Mem0 侧的分类体系是一一对应的:技能负责在客户端把用户的自然语言信号映射到这 10 个类别,而 Mem0 在存储时同样接收这份 customCategories 定义。
Step 3:存储
使用 mem0_memory 工具完成写入,关键参数只有两个:
action="add"content="<the user's text>"
文档特别强调:/mem0-remember 命令是逐字存储——不做推理(no inference),这一点已由命令本身保证。
Step 4:确认输出
存储成功后按固定格式回执:
Remembered as <category>: "<content, first 80 chars>"
且仅在内容确实被截断(原文超过 80 字符)时才追加 ...,避免对短文本误加省略号。这是一种克制的 UI 约定:类别在前、内容截断在后,让用户一眼确认“存了什么、存到了哪类”。
三、源码印证:“逐字存储”到底如何实现
技能文档声称“verbatim — no inference”,这在插件源码中有两条相互印证的证据链。
3.1 斜杠命令路径:infer: false
commands.ts 中 mem0-remember 的处理器调用 Mem0 SDK 时显式关闭了推理开关:
const addParams = resolveAddParams(config.defaultScope, getScopeCtx());
const result = await mem0.add(
[{ role: "user", content: text }],
{ ...addParams, customCategories: DEFAULT_CUSTOM_CATEGORIES, infer: false },
);
infer: false 意味着 Mem0 不会用 LLM 从这段文本中“抽取/改写”记忆,而是把用户原文直接落库——这正是文档中 “This is already handled by the command” 的技术含义。此外,处理器会把返回结果中的 memory 字段回显给用户(**Stored to ${config.defaultScope} memory** 加逐条列表),实现文档 Step 4 的确认语义。
3.2 Agent 工具路径:mem0_memory 的 add 动作
当 Agent 不是走斜杠命令、而是自主调用 mem0_memory 工具 时,add 分支的实现为:
case "add": {
if (!params.content) throw new Error("content is required for add");
const addParams = resolveAddParams(scope, scopeCtx);
const result = await mem0.add(
[{ role: "user", content: params.content }],
{ ...addParams, customCategories: DEFAULT_CUSTOM_CATEGORIES },
);
...
}
两条路径的共同点:都以 [{ role: "user", content }] 的单条消息形式提交内容,都附带同一份 10 类 customCategories。差别在于斜杠命令路径显式加了 infer: false,而工具路径把“要不要逐字”交给上层(技能指导 Agent 传入用户原文)。tools.ts 中该工具的 description 与 promptGuidelines 还规定:Agent 应在回答任何可能依赖用户既往信息的请求前主动执行 search,而 add 用于保存用户分享的重要事实、偏好、目标、决策或教训——这与 remember 技能的触发条件完全同构。
该行为有单元测试佐证:tests/tools.test.ts 断言 mem0.add 的第二参数中 customCategories 已定义且长度为 10,确保分类体系不会在工具调用链中被丢弃。
3.3 写入时的作用域参数:resolveAddParams
存储位置由 scoping.ts 的 resolveAddParams 决定,三级作用域映射为不同参数组合:
| 作用域 | 写入参数 | 语义 |
|---|---|---|
project(默认) |
{ userId, appId } |
当前项目记忆池 |
session |
{ userId, appId, runId } |
仅当前会话 |
global |
{ userId } |
跨所有项目 |
其中 appId 的取值很关键:detectAppId 通过 git rev-parse --show-toplevel 取仓库根的目录名作为项目标识(失败时退化为当前目录名),因此 monorepo 的所有子目录共享同一个记忆池。/mem0-remember 命令固定使用 config.defaultScope(默认 project,见 config/index.ts),用户可用 /mem0-scope 在会话内切换。
四、配置与实操:让 remember 真正可用
4.1 安装与密钥
按 README 的说明:
# 安装
pi install npm:@mem0/pi-agent-plugin
# 方式一:环境变量
export MEM0_API_KEY="m0-your-key-here"
4.2 配置文件
也可创建 ~/.pi/agent/mem0-config.json(路径由 config/index.ts 中的 AGENT_ROOT = ~/.pi/agent 决定):
{
"apiKey": "m0-your-key-here",
"userId": "your-username",
"autoCapture": true,
"defaultScope": "project",
"searchThreshold": 0.2,
"dream": {
"enabled": true,
"auto": true,
"minHours": 24,
"minSessions": 5,
"minMemories": 20
}
}
配置项的默认值与加载逻辑(源码 config/index.ts):
| 字段 | 默认值 | 说明 |
|---|---|---|
apiKey |
空 | Mem0 API 密钥;环境变量 MEM0_API_KEY 优先级更高 |
userId |
空 | 用户标识;环境变量 MEM0_USER_ID 可覆盖 |
autoCapture |
true |
是否自动从对话捕获记忆(remember 之外另一条写入路径) |
defaultScope |
project |
默认记忆作用域,remember 命令写入此处 |
searchThreshold |
0.3 |
搜索相似度阈值(0–1),影响 search/forget/pin 的匹配精度 |
dream |
见上 | 记忆整合(consolidation)的开关与自动触发门槛 |
注意加载逻辑:配置文件损坏时静默回退到默认值;MEM0_API_KEY / MEM0_USER_ID 两个环境变量总是覆盖配置文件——调试时这一点最容易踩坑。
4.3 一次典型的 remember 调用链
以 /mem0-remember I prefer pnpm over npm in this repo 为例,完整链路为:
- Pi Agent 触发
mem0-remember命令处理器,args = "I prefer pnpm over npm in this repo"; resolveAddParams("project", scopeCtx)得到{ userId, appId },appId来自 git 仓库根名;mem0.add([{ role: "user", content: text }], { ...addParams, customCategories, infer: false })将原文(非改写文本)提交至 Mem0,由 Mem0 按 10 类体系归类——该句信号命中preferences;- 处理器回显 “Stored to project memory - I prefer pnpm over npm in this repo”;若由 Agent 技能路径执行,则按 Step 4 格式回执
Remembered as preferences: "I prefer pnpm over npm in this repo"(未超 80 字符,不加...)。
五、设计要点小结
- 逐字是承诺,也是参数:技能文档的 “no inference” 不是修辞,而是命令路径上
infer: false的直接体现(commands.ts)。用户明确要求记住的内容以原文落库,避免 LLM 抽取引入失真。 - 分类表 = 客户端路由表 + Mem0 分类体系:技能中的 11 行判定表把自然语言信号映射到
DEFAULT_CUSTOM_CATEGORIES的 10 个类别(types.ts),两端共享同一份类别定义,保证后续/mem0-tour按类别分组浏览时语义一致。 - 80 字符确认 + 条件省略号:回执格式短、可扫读,且只在真实截断时加
...,是技能层对输出长度的精细约束;工具层的对应约束则是 truncateOutput 的 200 行 / 50KB 截断,防止大结果撑爆上下文。 - 作用域即安全边界:remember 固定写入
defaultScope(默认 project),跨项目写入需要显式使用global作用域——工具 description 中也反复强调“除非用户明确要求跨项目,否则不要传 scope”(tools.ts)。
如需进一步阅读:技能原文见 skills/remember/SKILL.md,兄弟技能(如 context-loader、search)展示了同一 mem0_memory 工具在读侧的用法;开发验证可在该插件目录执行 pnpm install && pnpm run test(配置见 vitest.config.ts)。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00