Supermemory 怎么设计 containerTag 实现多租户记忆隔离 Supermemory 怎么设计 containerTag 实现多租户记忆隔离【免费下载链接】supermemoryMemory and context engine app that is extremely fast, scalable, and can be run fully locally. The Memory API for the AI era.项目地址: https://gitcode.com/GitHub_Trending/su/supermemory当你的应用用同一个 Supermemory 组织服务多个用户、客户或租户时必须保证租户 A 的记忆永远不会出现在租户 B 的检索结果里。Supermemory 用 containerTag 解决这件事一个由你自己定义的字符串标识符写记忆时附上它之后搜索、列表、更新、删除时再传回去数据就被限制在对应容器内。本文给出一条完整操作路径设计命名规则、把数据写入正确的容器、验证隔离效果并用 scoped API key 把边界锁死在数据层。前置条件是一个 Supermemory 账号和 API key登录 Developer Platform在 API Keys 页面点Create API Key选择名称和过期时间后复制以及supermemorySDK 或 cURL。containerTag 的隔离机制containerTag 是一个不透明标识符——Supermemory 不会解析它的含义user_123、project_mobile、org:acme:team:growth都是合法的。你的应用里有什么访问边界tag 就该怎么取。隔离的关键在于两点自动建容器第一次带某个 tag 写入时Supermemory 自动为该 tag 创建 space限定在你的组织内无需提前配置后续写入复用同一容器。独立的向量命名空间每个 tag 被哈希进专属的 vector namespace该 tag 的 embeddings、chunks 和 memory 条目与其他 tag 完全独立存储和检索——不存在一个需要过滤的共享索引所以隔离是严格的strict而不是 best-effort。同一个 tag 贯穿记忆整个生命周期官方文档给出的各操作行为如下操作行为Add把记忆写入该 tag 的容器自动创建 spaceSearch检索被限制在该 tag 的 namespace 内List只返回属于该 tag 的记忆Update / Delete作用于指定 tag 容器内的记忆字段注意当前 API 用单数containerTag字符串。复数containerTags数组字段已弃用只在旧的/v3端点上为向后兼容保留/v4API 只接受containerTag。唯一的例外是 documents 列表接口按文档的字段差异表它使用数组形式// 搜索单数字符串 await client.search({ q: planning, containerTag: project_q1 }); // 列表文档数组形式 await client.documents.list({ containerTags: [project_q1] });选择命名规范并遵守命名规则先决定一个隔离空间在你的应用里对应什么层级再定 tag 格式。文档给出的四种模式模式示例适用场景按用户user_{userId}消费级应用每用户独立记忆按项目project_{projectId}工作区或项目级内容按 Agentagent_{agentId}每个 AI agent 一份长期记忆层级式org:{orgId}:user:{userId}多级多租户 SaaS冒号被刻意允许就是为了支持层级式 tag。文档同时给出一条重要建议保持 tag确定性——直接由你已有的 ID用户 ID、租户 ID推导这样查询时总能重建出正确的 tag而不需要额外查找。另外边界之内的分类、状态、日期等属性应该用 metadata 表达不要为每个想过滤的属性新建 tag那是 metadata 的职责见 Organizing Filtering。tag 在每次请求时都会校验规则是长度100 个字符以内只允许字母、数字、连字符-、下划线_、冒号:匹配正则^[a-zA-Z0-9_:-]$// ✅ Valid user_123 project-mobile-app org:acme:user:john tenant_42_workspace_7 // ❌ Invalid — 空格、斜杠和其他符号会被拒绝 user 123 project/mobile teamacme把记忆写入指定租户容器选定规范后写入时同时带上containerTag隔离用和可选的metadata容器内细分查询用。以多租户支持平台为例每个客户一个 tag工单状态、优先级走 metadataawait client.add({ content: Customer reports checkout button unresponsive on Safari, containerTag: org_customer_442, metadata: { status: open, priority: high, channel: chat }, });不用 SDK 时可以直接调 API$SUPERMEMORY_API_KEY替换为你的组织 key 或 scoped keycurl -X POST https://api.supermemory.ai/v3/documents \ -H Authorization: Bearer $SUPERMEMORY_API_KEY \ -H Content-Type: application/json \ -d { content: Customer reports checkout button unresponsive on Safari, containerTag: org_customer_442, metadata: {status: open, priority: high, channel: chat} }请求成功后的响应文档示例{ id: abc123, status: queued }处理是异步的用返回的id跟踪状态const doc await client.documents.get(abc123); console.log(doc.status); // queued | processing | done状态变为done即表示该文档已分块、嵌入并索引进该容器。注意文档中的一个警告如果发生不可恢复的处理错误文档会在 2 分钟后被自动删除。验证隔离检索只返回本租户数据隔离的验证方式是文档明确给出的行为一次搜索只限定在一个 container tag 内containerTag: user_123会把结果限制在该容器的记忆中一个 tag 里的记忆永远不会被限定在另一个 tag 的搜索返回。检索时可以叠加 metadata filters 缩小范围filter 结构必须包在AND/OR数组里const results await client.search({ q: checkout issue, containerTag: org_customer_442, searchMode: documents, filters: { AND: [ { key: status, value: open }, { key: priority, value: high }, ], }, });判断标准对租户 A 的 tag 检索只应返回写入 A 容器的记忆用租户 B 的 tag 做同样的查询拿不到 A 的任何内容。metadata filter 永远不跨越 containerTag 边界——你无法用 filter 去看另一个租户的容器。用 scoped API key 在数据层锁定边界组织层面还有两种机制把 containerTag 变成授权边界而不只是组织手段API key 可以被限制到特定的 tag 集合每个 tag 分别授予读/写权限组织成员也可以被授权只访问某些 tag。受限请求的校验行为请求超出允许集合的 tag → 返回403 Forbidden而不是静默过滤对只读 tag 执行写操作add/update/delete→403 Forbidden受限调用方未提供 tag 时 → 请求自动限定在其允许的 tag 内这意味着你可以签发一把在数据层就物理上无法读写其他租户数据的 key不依赖你的应用代码。创建 scoped keycurl https://api.supermemory.ai/v3/auth/scoped-key \ --request POST \ --header Content-Type: application/json \ --header Authorization: Bearer $SUPERMEMORY_API_KEY \ -d { containerTag: my-project, name: my-key-name, expiresInDays: 30 }参数说明参数必填默认值说明containerTag是—限定该 key 可访问的容器name否scoped_{containerTag}key 的显示名expiresInDays否—有效期1–365 天rateLimitMax否500每窗口最大请求数1–10,000rateLimitTimeWindow否60000窗口毫秒数1–3,600,000创建响应文档示例{ key: sm_orgId_..., id: key-id, name: scoped_my-project, containerTag: my-project, expiresAt: 2026-03-08T00:00:00.000Z, allowedEndpoints: [/v3/documents, /v3/memories, /v4/memories, /v3/search, /v4/search, /v4/profile] }返回的 key 用法与普通 key 完全相同只是出了它的容器范围就不生效。两个边界要知道scoped key 只能访问上面列出的文档/记忆/搜索/profile 端点不能读账单、管理组织设置或再签发 key回收时用创建响应里的id发DELETE https://api.supermemory.ai/v3/auth/scoped-key/KEY_ID之后该 key 的请求返回401但记忆和 container tag 本身不会被删除。容器级配置与生命周期管理每个 tag 可以带独立于其他 tag 的配置name容器的显示名entityContext处理该容器内文档时应用的自定义上下文提示用于按租户/项目引导抽取与摘要按 add API 文档最长 1500 字符await client.containerTags.update(project_research, { entityContext: This project contains research papers about machine learning., });容器还有完整的管理端点{containerTag}替换为实际 tag端点用途GET /v3/container-tags/{containerTag}读取 tag 配置PATCH /v3/container-tags/{containerTag}更新 tag 配置DELETE /v3/container-tags/{containerTag}删除容器及其数据POST /v3/container-tags/merge把一个 tag 合并进另一个GET /v3/container-tags/merge/{mergeId}轮询合并状态两个破坏性操作必须在执行前明确其影响DELETE /v3/container-tags/{containerTag}会删除该容器及其全部数据client.documents.deleteBulk({ containerTags: [user_123] })按 tag 批量删除内容删除是永久性的、不可恢复。只在确认要清退某个租户数据时使用。常见约束与错误判断一次搜索只能限定一个 container tag。需要跨容器检索时例如公司级共享容器 员工个人容器由你的应用在每次请求中分别查询、再在客户端合并结果——containerTag 边界是 per-request 而不是 per-user 的。错误码来自 add API 文档的错误处理表400缺字段或参数非法401key 无效或缺失403权限不足包括上面两类 tag 越权429触发限流或配额超限500处理失败。一处文档差异authentication.mdx 中 scoped key 的containerTag参数说明允许字母数字、连字符、下划线、冒号、点比 Container Tags 概念页的校验规则^[a-zA-Z0-9_:-]$不含点更宽。保守做法是按概念页的严格规则命名 tag。完成上述步骤后你的验证路径是同一查询分别打到两个租户的 tag各自只返回自己的数据换一把 scoped key 去请求其范围外的 tag收到403 Forbidden。隔离与授权边界都由数据层强制执行。深入阅读可参考 Multi-tenancy Overview、Multi-tenancy Examples个人 agent、公司 agent、邮件助手、支持平台四种形态和 Container Tags API。【免费下载链接】supermemoryMemory and context engine app that is extremely fast, scalable, and can be run fully locally. The Memory API for the AI era.项目地址: https://gitcode.com/GitHub_Trending/su/supermemory创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考