Mem0 双语言 SDK 对照指南:Python 与 TypeScript 客户端 API 差异速查与迁移实践
本文档的正文主体基于 differences.md,并辅以 python.md / node.md 及仓库源码佐证。
Mem0 同时提供 Python(mem0ai pip 包)与 TypeScript(mem0ai npm 包)两套官方 SDK,分别服务于 Python/数据科学生态与 Node.js/前端生态的 AI Agent 与应用的记忆层接入。两套 SDK 覆盖面高度一致(Platform 托管 API 与 OSS 自托管两套产品形态均有),但在方法命名、参数风格、同步/异步模型与 HTTP 实现上存在系统性差异。
本指南以“跨语言对照表 + 实战代码”为主线,帮你快速回答下列问题:两套 SDK 的构造函数如何写?方法名如何从 snake_case 对应到 camelCase?filters 里的 key 到底用哪种命名?哪些 Platform 功能只有 Python 有、哪些只有 TypeScript 有?OSS 配置如何做键名转换?v3 API 中实体 ID 如何传?文末给出平台选型与迁移检查清单,以及仓库内对应源码入口,便于你在做双栈开发或从单语言扩展时直接检索证据。
核心结论:规则只有三条
- 方法名:Python 一律
snake_case(get_all、delete_users),TypeScript 一律camelCase(getAll、deleteUsers)。 - 顶层参数:Python 用 keyword 参数,TypeScript 用 options 对象且键为
camelCase(userId、topK)。 - filter 内的键:两边都必须用
snake_case(user_id、agent_id),这是最常见的踩坑点。
三者的适用范围见原文的 “Entity ID Passing (v3)” 与 “Common Gotcha”,下文各节展开。
构造函数差异
| Aspect | Python | TypeScript |
|---|---|---|
| Import(Platform) | from mem0 import MemoryClient |
import MemoryClient from 'mem0ai' |
| Import(OSS) | from mem0 import Memory |
import { Memory } from 'mem0ai/oss' |
| 构造函数 | MemoryClient(api_key="m0-xxx") |
new MemoryClient({ apiKey: 'm0-xxx' }) |
| 必传参数 | api_key(位置参数或 kwarg) |
apiKey(在 options 对象中) |
两者都支持在未传 key 时读取 MEM0_API_KEY 环境变量。
注意 OSS 的导入路径差异:Python 侧 Memory / AsyncMemory 与 Platform 的 MemoryClient / AsyncMemoryClient 统一从 mem0 顶层导出(见 mem0/init.py);TypeScript 侧则必须从 mem0ai/oss 子路径导入 Memory,从根导出路径(默认导出)导入 MemoryClient,两个入口在 npm 包内分属不同构建产物(见 mem0-ts/package.json 的 exports 字段)。
从源码看,两套 SDK 的构造器都在初始化时完成 Key 校验与 HTTP 客户端装配:
- Python
MemoryClient.__init__:self.api_key = api_key or os.getenv("MEM0_API_KEY"),缺少 Key 时直接raise ValueError,随后用 MD5(api_key) 生成Mem0-User-ID请求头(mem0/client/main.py)。 - TypeScript
MemoryClient构造器:this.host = options.host || "https://api.mem0.ai",校验 Key 非空字符串(mem0-ts/src/client/mem0.ts)。
方法命名对照表
| Operation | Python | TypeScript |
|---|---|---|
| Add | add() |
add() |
| Search | search() |
search() |
| Get | get() |
get() |
| Get all | get_all() |
getAll() |
| Update | update() |
update() |
| Delete | delete() |
delete() |
| Delete all | delete_all() |
deleteAll() |
| History | history() |
history() |
| Batch update | batch_update() |
batchUpdate() |
| Batch delete | batch_delete() |
batchDelete() |
| List users | users() |
users() |
| Delete users | delete_users() |
deleteUsers() |
| Get project | project.get() |
getProject() |
| Update project | project.update() |
updateProject() |
| Create webhook | create_webhook() |
createWebhook() |
| Get webhooks | get_webhooks() |
getWebhooks() |
| Update webhook | update_webhook() |
updateWebhook() |
| Delete webhook | delete_webhook() |
deleteWebhook() |
| Create export | create_memory_export() |
createMemoryExport() |
| Get export | get_memory_export() |
getMemoryExport() |
| Feedback | feedback() |
feedback() |
Rule:Python 方法名 snake_case,TypeScript 方法名 camelCase。
值得留意的是:users() 与 history() 两个方法在两侧天然同名(单字母差异较小);但 project.get() / project.update() 在 Python 中经由 client.project 子对象访问,TypeScript 中则平铺为 client.getProject() / client.updateProject()——这是因为 Python 将项目管理实现为独立的 Project 类并挂载为属性,而 TypeScript 直接把 Project 相关端点收拢进主客户端。
参数传递方式
Platform 客户端最典型的两个操作——写入与检索:
# Python: kwargs
client.add(messages, user_id="alice", metadata={"source": "chat"})
client.search("query", filters={"user_id": "alice"}, top_k=5, rerank=True)
// TypeScript: options object with camelCase for top-level params, snake_case for filter keys
await client.add(messages, { userId: 'alice', metadata: { source: 'chat' } });
await client.search('query', { filters: { user_id: 'alice' }, topK: 5, rerank: true });
v3 规范:
- Python 侧全部使用
snake_case(包括top_k、user_id这类键)。 - TypeScript 侧顶层参数用
camelCase(userId、topK、agentId),但filters内部的键用snake_case(user_id、agent_id)。
Python 侧对“实体参数必须放进 filters”做了强校验:在 mem0/client/main.py 中 search() 会拒绝任何出现在顶层 kwargs 的实体参数,并抛出带修复提示的 ValueError:
Top-level entity parameters {...} are not supported in search().
Use filters={'user_id': '...'} instead.
这说明**“filters 里用 snake_case 传实体 ID”是 v3 的强制约定,而非个人风格选择**。TypeScript 侧则由类型定义约束:SearchMemoryOptions.filters 声明为 Record<string, any>(mem0-ts/src/client/mem0.types.ts),运行时并不强制,因此跨语言移植时尤其要留意。
架构差异
| Aspect | Python | TypeScript |
|---|---|---|
| HTTP library | httpx | axios |
| Default timeout | 300s | 60s |
| Sync support | Yes(MemoryClient) |
No(全部 async) |
| Async support | Yes(AsyncMemoryClient) |
所有方法均为 async |
| Project management | client.project.*(独立类) |
client.getProject() / client.updateProject() |
| Context manager | async with AsyncMemoryClient() |
不支持 |
这些差异有明确的源码对应:
- Python 同步客户端在构造时创建
httpx.Client(..., timeout=300)(mem0/client/main.py),异步客户端(AsyncMemoryClient)实现了__aenter__/__aexit__(mem0/client/main.py 与 mem0/client/main.py),因此可以写async with AsyncMemoryClient(...) as client。 - TypeScript 使用
axios.create({ ..., timeout: 60000 })(mem0-ts/src/client/mem0.ts),所有公开方法均返回Promise。仓库里没有同步版本的MemoryClient,也没有 context-manager 约定——资源释放交给进程退出与 axios 连接池管理。 - 默认超时差异(300s vs 60s)意味着:将 Python 平台上“长耗时记忆操作”直接平移到 Node 时,若单请求超过 60s 会先超时,必要时需按 60s 粒度拆分任务或在服务端处理。
Platform 特性差异:两边的“独有能力”
Python-only(TypeScript 暂无)
| Method | Description |
|---|---|
get_summary(filters) |
获取记忆摘要(GET /v1/summary/,见 mem0/client/main.py) |
reset() |
删除全部数据(用户+记忆,见 mem0/client/main.py) |
project.create(name) |
新建项目 |
project.delete() |
删除当前项目 |
project.get_members() |
列出项目成员 |
project.add_member(email, role) |
添加成员 |
project.update_member(email, role) |
修改成员角色 |
project.remove_member(email) |
移除成员 |
Python 的项目成员管理位于独立的 Project 类中(mem0/client/project.py),add_member 默认角色为 "READER",可选 "OWNER",例如:
client.project.create(name="My Project", description="...")
client.project.add_member(email="user@example.com", role="READER")
client.project.update_member(email="user@example.com", role="OWNER")
client.project.remove_member(email="user@example.com")
members = client.project.get_members()
client.project.delete()
TypeScript-only(Python 暂无)
| Method | Description |
|---|---|
deleteUser(data) |
便捷地删除单个实体(对应 Python delete_users 的子集场景) |
ping() |
健康检查端点 |
TS 侧 deleteUser({ userId: 'alice' }) 与更灵活的 deleteUsers({ agentId: 'bot-1' }) 同时存在(mem0-ts/src/client/mem0.ts);ping() 在客户端初始化阶段也会被内部调用以解析 identity(mem0-ts/src/client/mem0.ts)。
迁移提示:若你的 Node 服务需要“项目创建/成员管理”或“全量 reset / 记忆摘要”,当前应改用 Python 侧实现,或将操作收敛到 Python 服务;反过来,Node 里常见的
ping()健康检查在 Python 客户端没有对等公开方法。
OSS 配置键名映射
OSS 自托管形态下,Memory 类的配置字典键名也遵循同样的命名风格:
| Python config key | TypeScript config key |
|---|---|
vector_store |
vectorStore |
history_db_path |
historyDbPath |
custom_instructions |
customInstructions |
这同时反映在 Python 侧 Memory.from_config(mem0/memory/main.py)与 TS 侧 Memory.fromConfig(config) / new Memory(config)(mem0-ts/src/oss/src/memory/index.ts)的入参结构上。TypeScript OSS 默认配置里同样使用 vectorStore、historyDbPath、apiKey 等键(mem0-ts/src/oss/src/config/defaults.ts),并额外支持 disableHistory 开关。
OSS 作用域参数映射
无论 Platform 还是 OSS,记忆都需要归属到一个实体(用户/Agent/会话):
| Python | TypeScript |
|---|---|
user_id="alice" |
userId: 'alice' |
agent_id="bot" |
agentId: 'bot' |
run_id="session" |
runId: 'session' |
OSS add() 要求至少提供 user_id、agent_id、run_id 三者之一作为作用域,Python 与 TS 一致:
# Python OSS
m.add("I prefer dark mode", user_id="alice")
m.add("This belongs to a bot", agent_id="bot")
m.add("Tracked by session", run_id="session")
// TypeScript OSS
await m.add('I prefer dark mode', { userId: 'alice' });
await m.add('This belongs to a bot', { agentId: 'bot' });
await m.add('Tracked by session', { runId: 'session' });
v3 实体 ID 传递规则
v3 起,实体 ID 的传递位置因方法而异——add 放顶层,search/get_all 放 filters:
| Method | Python | TypeScript |
|---|---|---|
add() |
顶层 user_id="alice" |
顶层 { userId: 'alice' } |
search() |
filters 内 filters={"user_id": "alice"} |
filters 内 { filters: { user_id: 'alice' } } |
get_all() |
filters 内 filters={"user_id": "alice"} |
filters 内 { filters: { user_id: 'alice' } } |
例如查询“alice 的所有记忆”:
memories = client.get_all(filters={"user_id": "alice"})
const memories = await client.getAll({ filters: { user_id: 'alice' } });
同时 v3 的 search() / get_all() 的 filters 支持布尔组合与操作符,例如 AND 组合与 contains 操作符(Platform 侧文档见 python.md):
memories = client.get_all(
filters={"AND": [{"user_id": "alice"}, {"categories": {"contains": "health"}}]}
)
OSS Python 在元数据过滤层支持 eq、ne、gt、gte、lt、lte、in、nin、contains、not_contains 等操作符,并会做操作符映射与合法性校验(mem0/memory/main.py)。
Common Gotcha:filters 内部始终是 snake_case
搜索/过滤时,Python 与 TypeScript 两侧 filters 里的键都必须写 snake_case;TypeScript 只在顶层方法参数使用 camelCase:
# Python - snake_case in filters
results = client.search("query", filters={"user_id": "alice"})
// TypeScript - snake_case in filters, camelCase for top-level params
const results = await client.search('query', { filters: { user_id: 'alice' }, topK: 20 });
如果你在 TS 中把 filters 键误写成 userId,服务端将收不到实体过滤条件(返回为空或结果未被隔离到该用户),因为服务端协议层对过滤键使用 snake_case 语义。这也解释了为什么不能直接把 Python 代码机械“驼峰化”后搬到 TS——只有顶层参数需要转 camelCase,filters 内部要原样保留 snake_case。
同步/异步语境对照速查
Python 侧你通常同时拿到同步与异步两个客户端(MemoryClient / AsyncMemoryClient),且异步版本可直接做上下文管理器:
from mem0 import AsyncMemoryClient
# Or use as context manager
async with AsyncMemoryClient(api_key="m0-xxx") as client:
results = await client.search("query", filters={"user_id": "alice"})
TypeScript 侧则没有“同步/异步”两种形态,全部方法都返回 Promise,因此必须 await。从 TS 视角看,Python 的 MemoryClient 用法约等于“同步化”的对应物;从 Python 视角看,Node 里无需挑选客户端,风格统一。
双栈协作的迁移清单
把下面的自查表当作文档的“落地速记版”,能覆盖 90% 的迁移错误:
- [ ] 方法名转换:
get_all→getAll、delete_all→deleteAll、batch_update→batchUpdate、delete_users→deleteUsers、create_webhook→createWebhook。 - [ ] 参数容器转换:Python keyword → TS options 对象(
user_id=→{ userId: },top_k=→{ topK })。 - [ ] filters 键保持
snake_case:filters={"user_id": "alice"}在 TS 中仍写作{ filters: { user_id: 'alice' } }。 - [ ] OSS 配置键:
vector_store→vectorStore、history_db_path→historyDbPath、custom_instructions→customInstructions。 - [ ] 平台独有 API 核对:Python 有
get_summary/reset/project.*;TS 有deleteUser/ping;跨栈前确认目标端存在对等能力。 - [ ] 运行语义核对:TS 全部 async 且默认超时 60s;Python 同步 300s 超时、异步客户端可用
async with。 - [ ] 导入入口核对:Python 统一
from mem0 import ...;TS 区分默认导出(Platform)与mem0ai/oss子路径(OSS)。
相关源码与文档入口
需要进一步核对细节时,可以直接打开以下仓库文件:
- 本文档同目录的完整参考:python.md(含 Platform/OSS 全部方法与参数表、v2 兼容说明)、node.md(含 TypeScript 类型定义与 v2 兼容说明)。
- Python Platform 客户端:mem0/client/main.py(
MemoryClient)、mem0/client/main.py(AsyncMemoryClient);项目管理与成员:mem0/client/project.py。 - Python OSS 记忆引擎:mem0/memory/main.py(
Memory)、mem0/memory/main.py(AsyncMemory);入口导出见 mem0/init.py。 - TypeScript Platform 客户端:mem0-ts/src/client/mem0.ts 及其 index.ts 导出配置与 mem0.types.ts 类型定义。
- TypeScript OSS 记忆引擎:mem0-ts/src/oss/src/memory/index.ts(
Memory)与默认配置 defaults.ts;OSS 子路径构建配置见 mem0-ts/package.json。
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 StartedRust0627
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