Mem0 Python 与 TypeScript SDK 差异详解:方法命名、参数传递与架构行为对照指南
本文基于 Mem0 仓库中维护的 Python/TypeScript SDK 对照速查文档(differences.md),系统梳理两套 Mem0 Platform SDK 在导入方式、构造参数、方法命名、参数传递约定、底层 HTTP 行为与独占功能上的全部差异,并结合仓库源码验证这些差异的真实实现。读完后,你可以在 Python 与 TypeScript 之间无损迁移 Mem0 代码,避免"方法找不到、参数传错位置、过滤器不生效"这类跨语言迁移时的典型错误。
导入与构造:两套 SDK 的入口差异
Mem0 提供两条产品线:Platform SDK(托管 API,MemoryClient)与 OSS SDK(本地运行,Memory)。两条产品线在两种语言中的导入方式与构造约定如下:
| 方面 | Python | TypeScript |
|---|---|---|
| 导入(Platform) | from mem0 import MemoryClient |
import MemoryClient from 'mem0ai' |
| 导入(OSS) | from mem0 import Memory |
import { Memory } from 'mem0ai/oss' |
| 构造 | MemoryClient(api_key="m0-xxx") |
new MemoryClient({ apiKey: 'm0-xxx' }) |
| 必选参数 | api_key(位置参数或关键字参数均可) |
apiKey(放在 options 对象中) |
两种 SDK 在未显式传入 key 时都会回退读取 MEM0_API_KEY 环境变量。这一点在 Python 侧源码中可以确认:MemoryClient 构造函数 中 self.api_key = api_key or os.getenv("MEM0_API_KEY"),取不到时直接抛出 ValueError("Mem0 API Key not provided...")。
构造行为上的几个源码细节值得注意:
- 默认 host:Python 的
MemoryClient默认host为https://api.mem0.ai(main.py),TypeScript 侧同样在构造函数中回退到https://api.mem0.ai。 - 初始化即鉴权:Python 客户端在构造时同步调用
_validate_api_key()向/v1/ping/发起验证请求(main.py),并从中解析出org_id与project_id;TypeScript 客户端则采用非阻塞策略——构造函数中this.initialized = this._resolveIdentity()异步解析身份信息,记忆读写请求不会等待 ping 完成,且同一组 (host, apiKey) 凭据在同一进程内共享一次 ping 结果(mem0.ts)。这是两套实现中"同步急切初始化"与"异步惰性初始化"的显著架构差异。 - Project 子对象的注入:Python 客户端在构造末尾直接挂载
self.project = Project(...)(main.py),这正是后文client.project.*用法的来源;TypeScript 没有这个子对象,项目管理是平铺的实例方法。
方法命名:snake_case 对 camelCase 的完整对照
下表完整继承自仓库速查文档,覆盖了 Platform SDK 的全部记忆操作、项目管理、Webhook 与导出接口:
| 操作 | Python | TypeScript |
|---|---|---|
| 添加记忆 | add() |
add() |
| 搜索 | search() |
search() |
| 获取单条 | get() |
get() |
| 获取全部 | get_all() |
getAll() |
| 更新 | update() |
update() |
| 删除 | delete() |
delete() |
| 删除全部 | delete_all() |
deleteAll() |
| 历史记录 | history() |
history() |
| 批量更新 | batch_update() |
batchUpdate() |
| 批量删除 | batch_delete() |
batchDelete() |
| 用户列表 | users() |
users() |
| 删除用户 | delete_users() |
deleteUsers() |
| 获取项目 | project.get() |
getProject() |
| 更新项目 | project.update() |
updateProject() |
| 创建 Webhook | create_webhook() |
createWebhook() |
| 获取 Webhooks | get_webhooks() |
getWebhooks() |
| 更新 Webhook | update_webhook() |
updateWebhook() |
| 删除 Webhook | delete_webhook() |
deleteWebhook() |
| 创建导出 | create_memory_export() |
createMemoryExport() |
| 获取导出 | get_memory_export() |
getMemoryExport() |
| 反馈 | feedback() |
feedback() |
规则:Python 一律使用 snake_case,TypeScript 一律使用 camelCase。 上表每一行都能在两侧源码中找到对应实现,例如 Python 侧的 batch_update/batch_delete、create_webhook、create_memory_export/get_memory_export;TypeScript 侧的 batchUpdate/batchDelete、createWebhook/updateWebhook/deleteWebhook、createMemoryExport/getMemoryExport 以及 getProject/updateProject。
参数传递:kwargs 与 options 对象的约定差异
两套 SDK 传参风格不同,这是迁移时最易踩坑的地方:
# 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;TypeScript 的顶层方法参数使用 camelCase(userId、topK),而过滤器键保留 snake_case(user_id、agent_id)。
从源码结构看,Python 侧的方法签名同时接受类型化 options 与 **kwargs(如 add、get_all 的 options: Optional[...] = None, **kwargs),类型定义位于 mem0/client/types.py(AddMemoryOptions、SearchMemoryOptions 等),因此在 Python 中 user_id、top_k 这类参数统一走 snake_case 关键字。TypeScript 侧则通过类型化的 options 对象收敛参数,例如 GetAllMemoryOptions、SearchMemoryOptions(mem0.types.ts),方法签名如 getAll(options?: GetAllMemoryOptions)。
v3 实体 ID 传递:顶层参数与 filters 的边界
Mem0 v3 对实体标识(user_id / agent_id / app_id / run_id)在不同方法上的传递位置有严格约定:
| 方法 | 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' } } |
这条规则在两套 SDK 中都有强制校验,而非仅靠文档约定:
- Python 在 main.py 定义了
ENTITY_PARAMS = frozenset({"user_id", "agent_id", "app_id", "run_id"}),用于在search/get_all等接口中拒绝以顶层参数形式传入实体 ID; - TypeScript 在 mem0.ts 定义了同样的实体参数清单(同时包含 snake_case 与 camelCase 两种写法),
rejectTopLevelEntityParams()一旦在search()/getAll()的 options 顶层发现这些键,会抛出明确错误:Top-level entity parameters [...] are not supported in xxx(). Use filters: { user_id: "..." } instead.。
也就是说,即便你在 TypeScript 中"顺手"写成 client.search(q, { userId: 'alice' }),客户端也会立刻报错而不是静默失效——这是跨 SDK 迁移时行为可预期的重要保障。
架构差异:HTTP 库、超时与同步/异步模型
| 方面 | Python | TypeScript |
|---|---|---|
| HTTP 库 | httpx | axios |
| 默认超时 | 300 秒 | 60 秒 |
| 同步支持 | 是(MemoryClient) |
否(全部异步) |
| 异步支持 | 是(AsyncMemoryClient) |
所有方法均为 async |
| 项目管理 | client.project.*(独立类) |
client.getProject() / client.updateProject() |
| 上下文管理器 | 支持 async with AsyncMemoryClient() |
不支持 |
以上各项均与源码一致:
- 超时:Python 默认 httpx 客户端
timeout=300(main.py);TypeScript 的 axios 实例timeout: 60000(mem0.ts)。如果你的批量写入在 Python 侧能跑通而迁移到 TS 后偶发超时,应首先怀疑这个 60s/300s 的差异。 - 异步双客户端:Python 同时提供同步
MemoryClient(main.py)与AsyncMemoryClient(main.py),后者实现了__aenter__/__aexit__(main.py),因此可以async with AsyncMemoryClient(api_key=...) as client:自动管理连接生命周期;TypeScript 的MemoryClient所有公开方法均为async,无同步版本,也无上下文管理器等价物,连接由 axios 实例自身管理。 - 项目管理的类结构差异:Python 将项目/成员操作封装为独立类,Project 基类与子类 定义在
mem0/client/project.py中,并在MemoryClient.__init__中注入为client.project;TypeScript 则把项目操作平铺为实例方法getProject()与updateProject()(mem0.ts),没有project子对象这一层。
Python 独占的 Platform 功能
以下方法只存在于 Python SDK(均已在 mem0/client/main.py 与 mem0/client/project.py 中确认):
| 方法 | 说明 | 源码位置 |
|---|---|---|
get_summary(filters) |
获取记忆摘要 | main.py |
reset() |
删除全部数据(用户 + 记忆) | main.py |
project.create(name) |
创建新项目 | project.py |
project.delete() |
删除当前项目 | project.py |
project.get_members() |
列出项目成员 | project.py |
project.add_member(email, role) |
添加项目成员(role 默认 READER) |
project.py |
project.update_member(email, role) |
变更成员角色 | project.py |
project.remove_member(email) |
移除成员 | project.py |
需要注意:reset() 是删除所有用户与记忆的破坏性操作,且它只是 Python 客户端方法,TypeScript 侧没有对应封装;同理,项目成员的增删改查在 TS 侧没有客户端方法,需要走 REST API(可参考 docs/api-reference/ 下的组织与项目管理接口文档)。
TypeScript 独占的 Platform 功能
| 方法 | 说明 | 源码位置 |
|---|---|---|
deleteUser(data) |
单实体删除的便捷方法 | mem0.ts |
ping() |
健康检查端点 | mem0.ts |
补充一个容易被忽略的实现细节:TypeScript 的 ping() 不仅是对外暴露的健康检查方法,还承担客户端初始化职责——构造函数 通过它解析 telemetryId、organizationId、projectId,并在进程内按凭据缓存(默认上限 50 组,identityCacheMax 可调)。Python 侧的等价逻辑是构造时的同步 _validate_api_key(),对使用者透明。
OSS 配置与范围参数的命名差异
使用 OSS SDK(本地向量库 + 本地/自托管 LLM)时,配置键与范围参数同样遵循同一套命名规则:
配置键对照:
| Python 配置键 | TypeScript 配置键 |
|---|---|
vector_store |
vectorStore |
history_db_path |
historyDbPath |
custom_instructions |
customInstructions |
TypeScript 侧的 OSS 示例(basic.ts)中可以直接看到实际写法,例如 historyDbPath: "memory.db",对应本地记忆历史 SQLite 文件的落盘路径。
范围参数(scope)对照:
| Python | TypeScript |
|---|---|
user_id="alice" |
userId: 'alice' |
agent_id="bot" |
agentId: 'bot' |
run_id="session" |
runId: 'session' |
这里再次强调边界:OSS 顶层方法参数用 camelCase,Platform filters 内部的键用 snake_case。两个语境不要混用。
常见坑:filter 键永远是 snake_case
跨语言迁移中最频繁的错误是把 camelCase 习惯带入过滤器。速查文档给出的正确姿势是:无论 Python 还是 TypeScript,搜索与过滤条件中的键一律 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 });
如果你在 TypeScript 中误写 filters: { userId: 'alice' },过滤器不会报"键名错误",但按用户过滤的语义会失效(查不到该用户的记忆);而若在 search() 顶层误放 userId,则会触发前文提到的 rejectTopLevelEntityParams 显式报错。迁移自查清单可以概括为三条:
- 顶层方法参数:Python
snake_case→ TypeScriptcamelCase(user_id→userId,top_k→topK); filters内部键:两种语言都保持snake_case;- 实体 ID 在
search()/get_all()中只能进filters,在add()中只能放顶层。
以上约定与 differences.md 速查表、mem0/client/main.py、mem0-ts/src/client/mem0.ts 的当前实现一致,可直接作为两套 SDK 并行维护或相互迁移时的对照基准。
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 StartedRust0624
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