Mem0 Platform v3 REST API 深度解析:端点、记忆对象模型、过滤系统与异步处理模型
本文以 Mem0 插件技能包中的 API 参考文档 为核心,系统梳理 Mem0 Platform v3 REST API 的全部端点、记忆对象字段结构、四级作用域标识、嵌套过滤系统与异步事件处理模型,并结合本仓库中 Python/TypeScript 客户端的源码实现(mem0/client/main.py、mem0-ts/src/client/mem0.ts)验证文档描述与实际调用行为的一致性,帮助你在直连 https://api.mem0.ai 或使用官方 SDK 时,准确构造请求、正确编写过滤器并理解响应格式。
一、API 总览:Base URL、鉴权与端点清单
Mem0 Platform 对外提供 REST API,Base URL 为 https://api.mem0.ai。所有端点都要求携带同一鉴权头:
Authorization: Token <MEM0_API_KEY>
API Key 以 m0- 前缀开头,通常在客户端 SDK 中通过 MEM0_API_KEY 环境变量注入。Python 客户端构造函数 MemoryClient 的默认 host 正是 https://api.mem0.ai,并在 httpx 请求头 中注入 Authorization: Token <key> 与 Mem0-User-ID 两个头——后者是 API Key 的 MD5 哈希,用于平台侧的用户识别。
文档给出的核心端点清单如下:
| 操作 | 方法 | URL |
|---|---|---|
| Add Memories | POST |
/v3/memories/add/ |
| Search Memories | POST |
/v3/memories/search/ |
| Get All Memories | POST |
/v3/memories/ |
| Get Single Memory | GET |
/v1/memories/{memory_id}/ |
| Update Memory | PUT |
/v1/memories/{memory_id}/ |
| Delete Memory | DELETE |
/v1/memories/{memory_id}/ |
| Delete All Memories | DELETE |
/v1/memories/?user_id=X&app_id=Y |
| Get Event Status | GET |
/v1/event/{event_id}/ |
注意版本混用的设计:写入(add/search/get-all)走 v3 端点,而单条记忆的增删改查与事件轮询仍保留在 v1 路径下。这与仓库源码完全对应——MemoryClient.add() 向 /v3/memories/add/ 发 POST,search() 与 get_all() 分别 POST 到 /v3/memories/search/ 和 /v3/memories/,而 get()/update()/delete() 均作用于 /v1/memories/{memory_id}/。TypeScript 客户端 mem0.ts 同样在三个 v3 端点上发起请求,并有 单元测试 逐条断言 POST /v3/memories/add/ 等 URL 与方法,可作为端点行为的独立佐证。
不依赖 SDK 时也可以直接用 cURL 调用(取自 quickstart.md):
export MEM0_API_KEY="m0-your-api-key"
# Add memory
curl -X POST https://api.mem0.ai/v3/memories/add/ \
-H "Authorization: Token $MEM0_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"messages": [
{"role": "user", "content": "I am a vegetarian and allergic to nuts."},
{"role": "assistant", "content": "Got it! I will remember your dietary preferences."}
],
"user_id": "user123"
}'
# Search memories
curl -X POST https://api.mem0.ai/v3/memories/search/ \
-H "Authorization: Token $MEM0_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "What are my dietary restrictions?",
"filters": {"user_id": "user123"}
}'
二、Memory 对象结构
每条记忆在服务端表现为一个统一结构的对象:
| 字段 | 类型 | 说明 |
|---|---|---|
id |
string (UUID) | 唯一记忆标识 |
memory |
string | 记忆的文本内容 |
user_id |
string | 关联用户 |
agent_id |
string (nullable) | Agent 标识 |
app_id |
string (nullable) | 应用标识 |
run_id |
string (nullable) | 运行/会话标识 |
metadata |
object | 自定义键值对 |
categories |
array of strings | 自动分配的分类标签 |
hash |
string | 内容哈希 |
created_at |
datetime | 创建时间戳 |
updated_at |
datetime | 最后修改时间戳 |
搜索(Search)结果在此结构之外额外附带 score 字段,作为相关性度量值;在 v3 中,score 是一个综合多信号的相关性得分(combined multi-signal relevance score),而非单一的向量相似度。
一个真实的搜索响应形如:
{
"results": [
{
"id": "ea925981-...",
"memory": "Is a vegetarian and allergic to nuts.",
"user_id": "user123",
"categories": ["food", "health"],
"score": 0.89,
"created_at": "2024-07-26T10:29:36.630547-07:00"
}
]
}
三、作用域标识符(Scoping Identifiers)与实体分区规则
记忆可以在四个粒度上作用域隔离:
| 作用域 | 参数 | 使用场景 |
|---|---|---|
| User | user_id |
按用户隔离记忆 |
| Agent | agent_id |
按 Agent 划分记忆分区 |
| Application | app_id |
跨 Agent 的应用级记忆 |
| Run/Session | run_id |
会话级的临时记忆 |
文档特别标注了一条关键(Critical)约束:将 user_id 与 agent_id 放在同一个 AND 过滤块中会得到空结果,因为实体是分开存储(stored separately)的——应改用 OR 逻辑或分别查询。
这一约束在 SDK 层面有直接体现。mem0/client/main.py 定义了实体参数集合:
ENTITY_PARAMS = frozenset({"user_id", "agent_id", "app_id", "run_id"})
并且 search() 与 get_all() 会在入口处主动拒绝这些顶层实体参数,抛出 ValueError 提示改用 filters={'user_id': '...'}。也就是说,身份字段必须放进 filters 字典传递,v3 API 不接受顶层实体参数——mem0/client/types.py 的模块 docstring 对此有明确声明,AddMemoryOptions、SearchMemoryOptions 等 Pydantic 模型也都把 filters 设计为承载 user_id 等身份字段的首选字段。
[SKILL.md](https://gitcode.com/GitHub_Trending/em/embedchain/blob/0070e08e01d70f5517bca303f4a91199cd18be46/integrations/mem0-plugin/skills/mem0/SKILL.md?utm_source=gitcode_repo_files) 还补充了一条容易踩坑的"隐式 null 作用域"规则:filters={"user_id": "alice"} 只返回 agent_id、app_id、run_id 全部为 null 的记忆;若想包含带其他作用域字段的记忆,需要包一层 {"OR": [...]}。
四、异步处理模型(v3 默认)
文档的 Processing Model 一节说明了三条事实:
- 记忆的写入在 v3 默认情况下是异步处理的;
- Add 响应只返回已排队的
ADD事件——v3 是 ADD-only 的,不再有 UPDATE/DELETE 事件; - 需通过
GET /v1/event/{event_id}/轮询处理状态。
对应到 SKILL.md 中关于 v3 相对 v2 的变更说明:v3 采用单趟(single-pass)ADD-only 抽取,记忆是累积式的(accumulate)而非归并式的(consolidate);实体链接(entity linking)取代了 v2 的图记忆(graph memory),在 add() 时自动抽取、无需配置;org_id、project_id、enable_graph 参数已从 SDK 移除。
由此推出一个实用的工程事实:add 之后立即 search 可能查不到刚写入的记忆,[SKILL.md](https://gitcode.com/GitHub_Trending/em/embedchain/blob/0070e08e01d70f5517bca303f4a91199cd18be46/integrations/mem0-plugin/skills/mem0/SKILL.md?utm_source=gitcode_repo_files) 建议等待 2-3 秒后再检索,同时检查 user_id 是否大小写完全一致。v3 的检索默认值为 top_k=20、threshold=0.1、rerank=False。
五、过滤系统:嵌套 JSON、操作符与可过滤字段
5.1 过滤器结构
过滤条件使用嵌套 JSON,根节点必须是一个逻辑操作符:
{
"AND": [
{"user_id": "alice"},
{"categories": {"contains": "finance"}},
{"created_at": {"gte": "2024-01-01"}}
]
}
根节点只允许 AND、OR、NOT 三者之一;同时也支持简写形式 {"user_id": "alice"},等价于单条件 AND。
5.2 支持的操作符
| 操作符 | 说明 |
|---|---|
eq |
相等(默认) |
ne |
不相等 |
in |
匹配数组中任一值 |
gt, gte |
大于 / 大于等于 |
lt, lte |
小于 / 小于等于 |
contains |
大小写敏感的包含 |
icontains |
大小写不敏感的包含 |
* |
通配——匹配任意非 null 值 |
5.3 可过滤字段与各自合法操作符
| 字段 | 合法操作符 |
|---|---|
user_id, agent_id, app_id, run_id |
eq, ne, in, * |
created_at, updated_at, timestamp |
gt, gte, lt, lte, eq, ne |
categories |
eq, ne, in, contains |
metadata |
eq, ne, contains(仅顶层键) |
keywords |
contains, icontains |
memory_ids |
in |
5.4 六条过滤约束
- 实体作用域分区:
user_id与agent_id同处一个AND块会得到空结果; - metadata 限制:只能过滤顶层键,且仅支持
eq、contains、ne,不支持in和gt; - 操作符语法:必须使用
gte、lt、ne这类词法操作符,SQL 风格写法(>=、!=)会被拒绝; - get-all 必须携带实体过滤:
user_id、agent_id、app_id、run_id至少要提供一个; - 通配符排除 null:
*只匹配非 null 值; - 日期格式:ISO 8601(
YYYY-MM-DDTHH:MM:SSZ),不带时区的时间默认按 UTC 处理。
六、响应格式详解
6.1 Add 响应(v3)
{
"message": "Memory processing has been queued for background execution",
"status": "PENDING",
"event_id": "evt-uuid"
}
响应体印证了第四节的异步模型:status 为 PENDING,event_id 用于后续经 GET /v1/event/{event_id}/ 轮询。v3 下该事件流中只有 ADD 事件,没有 UPDATE 或 DELETE。
6.2 Get All 响应(v3 分页信封)
{
"count": 123,
"next": "https://api.mem0.ai/v3/memories/?page=2&page_size=50",
"previous": null,
"results": [...]
}
v3 的列表接口返回标准分页信封,通过 page 与 page_size 查询参数翻页。这一点在 Python SDK 中同样成立:get_all() 会把 page、page_size 从 body 参数中剥离出来,改作为 POST /v3/memories/ 的 query parameters 发送,docstring 也承诺返回 {"count", "next", "previous", "results"} 结构;GetAllMemoryOptions 进一步暴露了 start_date、end_date、categories、show_expired、latest_only 等选项。
6.3 Search 响应
如第二节示例所示,搜索返回 {"results": [...]},每条结果携带 score。Python SDK 的 SearchMemoryOptions 提供了完整的检索调优面:top_k(返回条数)、rerank(是否重排)、threshold(最低相似度阈值)、fields(裁剪响应字段)、categories、show_expired、reference_date(相对时间查询的基准日期)、latest_only、keyword_search,与文档"v3 默认 top_k=20、threshold=0.1、rerank=False"的说明互为表里。
七、源码级验证:Python 与 TypeScript 客户端如何映射这些端点
以 mem0/client/main.py 中的同步客户端为样本,可以逐条确认 API 参考与实现的对应关系:
- add:L217
self.client.post("/v3/memories/add/", json=payload)。入参messages支持字符串、单条 dict 或消息列表三种形态,字符串会被自动包装为[{"role": "user", "content": ...}](L208-L213); - search:L329
self.client.post("/v3/memories/search/", json=payload),且 query 会先经过 非空校验与 trim; - get / update / delete:均对
/v1/memories/{memory_id}/发起 GET / PUT / DELETE,其中delete额外支持delete_linked参数——为True时会沿 v3 的linked_memory_ids链传递性删除被当前记忆取代的旧版本; - get_all / search 的实体参数护栏:两者都在方法开头用
ENTITY_PARAMS & set(kwargs.keys())拦截顶层实体参数并抛出ValueError,这是"身份字段必须走 filters"这条 API 约束在客户端侧的防御性实现; - 错误处理:所有公开方法都挂
@api_error_handler装饰器(来自 mem0/client/utils.py),将 HTTP 错误归一化为AuthenticationError、RateLimitError、MemoryQuotaExceededError、MemoryNotFoundError等异常类型。
TypeScript 侧,mem0-ts/src/client/mem0.ts 在 add、getAll、search 三个方法中分别拼接 ${this.host}/v3/memories/add/、${this.host}/v3/memories/、${this.host}/v3/memories/search/,并用 query string 承载分页参数。[SKILL.md](https://gitcode.com/GitHub_Trending/em/embedchain/blob/0070e08e01d70f5517bca303f4a91199cd18be46/integrations/mem0-plugin/skills/mem0/SKILL.md?utm_source=gitcode_repo_files) 还特别指出 TypeScript 客户端只接受 camelCase 参数名(userId、agentId、appId、topK),与 Python 的 snake_case 形成对照——跨语言迁移代码时这是最容易出错的一点。测试目录 mem0-ts/src/client/tests/ 中的 memoryClient.crud.test.ts、memoryClient.search.test.ts、memoryClient.identity.test.ts 对三个 v3 端点的 URL、HTTP 方法与参数传递逐一做了断言,可视为端点契约的活文档。
八、常见问题与工程建议
结合 SKILL.md 的"Common edge cases"清单,与本文 API 参考逐条对照后,可沉淀出五条实用建议:
- 搜索返回空:先确认 add 的异步处理已完成(等 2-3 秒或轮询
GET /v1/event/{event_id}/);再确认user_id大小写精确匹配;同时警惕"隐式 null 作用域"——若目标记忆带有agent_id/app_id/run_id,纯user_id过滤会命中不到,需用{"OR": [...]}组合条件; - AND 组合 user_id + agent_id 得空结果:实体分区存储所致,改用
OR或拆成两次独立查询(即第五节约束 1 的复现); - 重复记忆:
infer=True(默认)会通过 LLM 抽取事实并去重,infer=False原样存储、同一文本可能存两次;两者不要对同一批数据混用; - SDK 选择:Platform 场景用
from mem0 import MemoryClient(打向api.mem0.ai),自托管 OSS 场景用from mem0 import Memory(本地运行),两者不要混用; - v3 检索调参:默认
top_k=20、threshold=0.1、rerank=False,对召回精度有更高要求时通过SearchMemoryOptions显式上调threshold或开启rerank。
总结
Mem0 Platform v3 REST API 的核心特征可以概括为三点:写入异步化(add 返回 PENDING 事件并走事件轮询,ADD-only 抽取模型)、查询过滤体系化(AND/OR/NOT 嵌套过滤器 + 词法操作符 + 严格的实体分区规则)、版本路径分层(v3 负责 add/search/get-all,v1 保留单条记忆 CRUD 与事件查询)。本仓库的 Python 客户端、类型化选项模型 与 TypeScript 客户端及其测试 与 API 参考文档 在端点、参数约束和响应结构上高度一致,可以作为编写、调试或审计 Mem0 API 集成时的双份权威依据。
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