TencentDB Agent Memory TypeScript SDK 实战指南:v3 严格隔离数据面与元数据管理面详解
【免费下载链接】TencentDB-Agent-MemoryTencentDB Agent Memory is a team-level memory hub for AI Agents — turning conversations, docs, and code into four reusable memory assets (Chat Memory, Skill, LLM-Wiki, Code-Graph) that are governed, shared, and equipped across agents and frameworks.项目地址: https://gitcode.com/GitHub_Trending/te/TencentDB-Agent-Memory
本篇技术指南围绕开源仓库 TencentDB Agent Memory 的官方 TypeScript SDK(包名@tencentdb-agent-memory/memory-sdk-ts-v2)展开,系统讲解 v3 严格隔离数据面MemoryClient与/v3/meta/*、/v3/knowledge/*管理面MetadataClient的完整用法,并深入剖析 SDK 底层实现(隔离上下文解析、HTTP 传输、错误模型)。读完本文,你将掌握如何在一个 TS/Node 项目中接入团队级 Agent 记忆中心,完成对话写入、原子记忆检索、场景与核心记忆读写、团队/用户/资产元数据治理及知识源注册等全流程操作。
一、SDK 定位与安装
@tencentdb-agent-memory/memory-sdk-ts-v2是 TencentDB Agent Memory 的 TypeScript 客户端,覆盖三组能力:
- v3 数据面 API(
/v3/*):对话(L0)、原子记忆(L1)、场景记忆(L2)、核心记忆(L3)的读写与检索; - v3 元数据管理面 API(
/v3/meta/*,共 54 条路由):与面板 Control 的META_ACTIONS对齐,涵盖 user / user-key / team / team-member / agent / task / asset / ACL / config 等治理能力; - Knowledge 实体管理面 CRUD(
/v3/knowledge/*,5 条路由):注册与管理 wiki、code-graph 两类知识源的元数据。
从包的导出结构看,src/index.ts 的顶级导出直接export * from "./v3/index.js",即默认MemoryClient就是 v3 严格 isolation 版本;老代码如果之前从.../v2/v3子路径导入,package.json 中的exports保留了./v3子路径作为向后兼容别名,指向同一个实现,可无缝迁移。
安装命令:
npm install @tencentdb-agent-memory/memory-sdk-ts-v2运行环境要求:根据 package.json 中engines字段,需要 Node.js >= 18.0.0;包采用 ESM("type": "module"),HTTP 层基于undici实现(见 package.json)。
二、MemoryClient 快速开始:五分钟接入 v3 数据面
v3 数据面要求构造客户端时必须传入完整的隔离身份。以下代码完整取自官方 README 的 Quick Start 并加以注释:
import { MemoryClient } from "@tencentdb-agent-memory/memory-sdk-ts-v2"; const client = new MemoryClient({ endpoint: "http://127.0.0.1:8420", // MemoryCore 网关地址 apiKey: "your-user-key", // 从面板拿的 sk-mem-… 用户密钥 serviceId: "your-memory-instance-id", // 记忆实例 ID(x-tdai-service-id) teamId: "team-xxx", // 团队 ID(v3 必填) agentId: "agt-xxx", // Agent ID(v3 必填) userId: "usr-xxx", // 用户 ID(v3 必填) sessionId: "sess-1", // 可选:省略/清空后 L0/L1 跨 session 聚合 }); // L0:写对话 await client.addConversation({ messages: [ { role: "user", content: "Hello" }, { role: "assistant", content: "Hi!" }, ], }); // L0:查(限定在当前 session) const l0 = await client.queryConversation({ limit: 20, offset: 0 }); // L0:跨 session 聚合查询(显式清空 sessionId) const allSessions = await client.withIsolation({ sessionId: null }).queryConversation({ limit: 20 }); // L1 / L2 / L3 const l1 = await client.searchAtomic({ query: "user preferences", limit: 5 }); const scene = await client.readScenario({ path: "work.md" }); const core = await client.readCore();v3 数据面差异要点(官方明示)
- 所有请求路径统一走
/v3/*前缀(源码中const V3 = "/v3",见 v3/client.ts); - 构造时
teamId/agentId/userId均必填(严格 isolation); sessionId可选,语义分三种情况:- 传入:L0/L1 限定在单个 session 内读写;
- 不传,或通过
withIsolation({ sessionId: null })显式清空:L0/L1 跨 session 聚合到 team + agent + user 维度; - L2/L3是 team + agent 维度的 profile 数据,不消费
sessionId。
三、隔离模型源码级解析:teamId / agentId / userId / sessionId / taskId
v3 的“严格隔离”不是简单的参数校验,而是贯穿客户端构造、请求体组装、写入保护三个环节的完整机制,可以从 v3/client.ts 逐层验证。
3.1 IsolationContext:身份快照与逐请求覆盖
SDK 内部用IsolationContext类(v3/client.ts)保存一份不可变身份快照。构造时requireNonEmpty强制校验teamId/agentId/userId非空,缺任一字段都会抛出ParamError:
// v3/client.ts 中 IsolationContext 构造逻辑 requireNonEmpty("teamId", teamId); requireNonEmpty("agentId", agentId); requireNonEmpty("userId", userId);baseBody()将身份字段序列化为请求体中的team_id/agent_id/user_id/task_id(值为undefined的字段会被stripUndefined过滤掉)。这对应基础类型 types.ts 中IdFields的四个可选隔离字段设计——在 v2 时代它们全部可选,而 v3 在客户端层强制要求前三个。
3.2 写入保护:addConversation 必须携带 session_id
这是 v3 一个容易被忽略但很关键的设计:写路径必须解析出非空 session_id。resolveSessionForWrite()(v3/client.ts)在构造参数和单次调用参数都没有提供sessionId时会直接抛ParamError,源码注释解释了原因:防止无 session 的写入在服务端被静默合并到默认 bucket,从而与其他调用方的数据混在一起。而读路径(query / search / count / delete)允许省略 session,服务端会按 team + agent + user 聚合。
3.3 withIsolation:函数式隔离切换
withIsolation(overrides)(v3/client.ts)基于当前快照创建一个新MemoryClient实例,并复用同一个 HTTP transport。注意sessionId: null和taskId: null表示显式清除该字段,而undefined表示沿用默认值。类型定义见 v3/types.ts 的V3IsolationOverrides。这种不可变快照 + 覆盖合并的模式,让你可以在一个 endpoint 上安全地复用连接、按调用粒度切换隔离维度,而不会污染其他调用。
四、v3 数据面 API 全览:L0~L3 四层记忆
官方 README 给出了完整的 API 方法表,这里完整继承并补充请求参数说明:
| 层 | 方法 | Endpoint | 核心入参 |
|---|---|---|---|
| L0 | addConversation() | POST /v3/conversation/add | messages[](必填)、session_id(必填) |
| L0 | queryConversation() | POST /v3/conversation/query | limit、offset、time_start、time_end、session_id |
| L0 | searchConversation() | POST /v3/conversation/search | query(必填)、limit、time_start、time_end、session_id |
| L0 | deleteConversation() | POST /v3/conversation/delete | message_ids[]或session_id(二选一) |
| L0 | countConversation() | POST /v3/conversation/count | session_id、time_start、time_end |
| L1 | updateAtomic() | POST /v3/atomic/update | id、content(必填)、background |
| L1 | queryAtomic() | POST /v3/atomic/query | type、limit、offset、time_start、time_end |
| L1 | searchAtomic() | POST /v3/atomic/search | query(必填)、limit、type、time_start、time_end |
| L1 | deleteAtomic() | POST /v3/atomic/delete | ids[](必填) |
| L1 | countAtomic() | POST /v3/atomic/count | type、time_start、time_end |
| L2 | listScenarios() | POST /v3/scenario/ls | path_prefix |
| L2 | readScenario() | POST /v3/scenario/read | path(必填) |
| L2 | writeScenario() | POST /v3/scenario/write | path、content(必填)、summary |
| L2 | rmScenario() | POST /v3/scenario/rm | path(必填) |
| L2 | countScenario() | POST /v3/scenario/count | path_prefix |
| L3 | readCore() | POST /v3/core/read | 无(纯身份上下文) |
| L3 | writeCore() | POST /v3/core/write | content(必填) |
| L3 | countCore() | POST /v3/core/count | 无(纯身份上下文) |
4.1 L0 对话记忆:最原始的记录层
对话是记忆的原材料。ConversationItem的结构定义在 types.ts:role取值"user" | "assistant" | "system",content为消息文本,id与timestamp可选。写入成功返回{ accepted_ids, total_count };查询返回{ messages, total };搜索命中项额外携带score相似度分数(见 types.ts)。
值得注意的两个边界行为(源码可见):
deleteConversation在既没有message_ids也没有session_id时抛ParamError,且message_ids必须是「非空字符串的非空列表」(v3/client.ts);- 所有 L0 请求都会通过
resolveSession合并构造期默认值与调用期覆盖值(v3/client.ts)。
4.2 L1 原子记忆:可检索的事实碎片
L1 是经抽取后的原子化记忆条目,AtomicDetail(types.ts)包含id、type、content、background以及创建/更新时间。type字段用于记忆分类,可结合业务自行定义(如preference、fact等),searchAtomic和queryAtomic都支持按type过滤,搜索命中同样带score。
4.3 L2 场景记忆:按路径组织的文档文件
L2 将记忆组织为带路径的“文件”,适合存放工作场景、项目背景等结构化工件。ScenarioFile(types.ts)的content/created_at/updated_at在文件不存在时为null,方便做存在性判断。listScenarios支持path_prefix前缀过滤,writeScenario可附带summary摘要。由于 L2 是 team + agent 维度,调用时无需也不消费session_id。
4.4 L3 核心记忆:Agent 的长期画像
L3 是最高层级的核心记忆,相当于 team + agent 维度一份可覆盖写入的 profile 文件。readCore()/writeCore()/countCore()三个方法请求体只携带隔离上下文(见 v3/client.ts),无其他业务参数。
五、MetadataClient:v3 管理面(/v3/meta/*)
数据面之外,SDK 提供MetadataClient封装网关的 v3 元数据管理端点。它覆盖 54 条META_ACTIONS路由(含user-key/*),并额外包含/v3/knowledge/*。鉴权方式为Bearertoken +x-tdai-service-id请求头,可选携带x-tdai-user-key。这些头部在 v3/http.ts 中统一设置:
this.headers = { Authorization: `Bearer ${opts.apiKey}`, "x-tdai-service-id": opts.serviceId, "Content-Type": "application/json", }; if (opts.userKey) this.headers["x-tdai-user-key"] = opts.userKey;构造示例(完整继承自官方 README):
import { MetadataClient } from "@tencentdb-agent-memory/memory-sdk-ts-v2"; const meta = new MetadataClient({ endpoint: "http://127.0.0.1:8420", apiKey: "verify-token", // gateway Bearer (KERNEL_AUTH_TOKEN) serviceId: "knowledge-debug", // x-tdai-service-id // userKey: "...", // 可选;system_admin 端点(user/create、user/delete)需要 });注意:
MetadataClient与MemoryClient的apiKey语义不同——前者是网关 Bearer 密钥(KERNEL_AUTH_TOKEN),后者是用户的sk-mem-…用户密钥。
5.1 管理面能力矩阵
从 v3/metadata-client.ts 的实现可以梳理出完整能力分组(端点统一挂载在const V3 = "/v3/meta"前缀下,见该文件 L72):
| 分组 | 代表方法 | 端点 | 说明 |
|---|---|---|---|
| User | createUser/getUser/deleteUsers/listUsers | /v3/meta/user/* | 用户治理;user/create、user/delete需要 system_admin 级 userKey |
| UserKey | createUserKey/listUserKeys/getUserKey/revokeUserKey/updateUserKey | /v3/meta/user-key/* | 用户 API 密钥生命周期管理 |
| Team | createTeam/getTeam/updateTeam/deleteTeams/listTeams | /v3/meta/team/* | 团队治理 |
| TeamMember | addTeamMember/removeTeamMember/listTeamMembers/getTeamMember | /v3/meta/team-member/* | 团队成员管理 |
| Agent | createAgent/getAgent/updateAgent/deleteAgents/listAgents/archiveAgent | /v3/meta/agent/* | Agent 治理与归档 |
| Task | createTask/getTask/updateTask/deleteTasks/listTasks/archiveTask | /v3/meta/task/* | 任务治理与归档 |
| TaskAgent | linkTaskAgent/unlinkTaskAgent/listTaskAgents | /v3/meta/task-agent/* | Agent-任务关联 |
| ParticipationLog | appendParticipationLog/listParticipationLogs | /v3/meta/participation-log/* | 参与日志 |
| Asset | createAsset/getAsset/updateAsset/deleteAssets/listAssets/listAccessibleAssets/touchAssetUsage | /v3/meta/asset/* | 资产治理与使用统计 |
| AgentFixedAsset | setAgentFixedAssets/listAgentFixedAssets/listAgentFixedAssetsWithDetail/summarizeAgentFixedAssetsByAgents | /v3/meta/agent-fixed-asset/* | Agent 固定资产绑定 |
| ACL | grantAcl/revokeAcl/listAcl/checkAcl | /v3/meta/acl/* | 资产访问控制 |
| Auth | verifyAuth | /v3/meta/auth/verify | 用户密钥校验(body 传user_key) |
| ConfigParam (v3.2) | getInstanceQuota/getUserConfig/setUserConfig | /v3/meta/instance-quota/get、/v3/meta/config/user/* | 实例配额与用户配置 |
实现细节:部分list*方法做了重载设计——如listTeams既接受(userId, pagination)二元参数,也接受完整ListTeamsRequest对象;同时通过requireAnyString在客户端前置校验关键字段(如listTeams要求user_id或user_key至少一个),把参数错误尽早拦截在本地(v3/metadata-client.ts)。
六、Knowledge 知识源管理(/v3/knowledge/*)
MetadataClient还封装了 Knowledge 实体的管理面 CRUD。重要边界:这些是管理面的元数据操作——实际搜索 wiki 内容、阅读页面、同步代码仓库属于 Knowledge Service 数据面(service_url指向的服务)的职责,本客户端不做。
官方 README 的完整方法表:
| 方法 | Endpoint | Notes |
|---|---|---|
createKnowledge() | POST /v3/knowledge/create | upsert 元数据(幂等;重复提交覆盖) |
getKnowledge(id, teamId?) | POST /v3/knowledge/get | 按 id 查询 |
updateKnowledge() | POST /v3/knowledge/update | 部分更新(name/summary/service_url/repo_url/branch) |
deleteKnowledge(ids, teamId?) | POST /v3/knowledge/delete | 批量删除(≤100) |
listKnowledge() | POST /v3/knowledge/list | 按 team_id 列出,可选 type 过滤 / 批量 id 查询 |
类型上,Knowledge 实体分为wiki与code-graph两种(KnowledgeType)。代码示例(完整继承自官方 README):
// 注册一个 wiki 知识源 const k = await meta.createKnowledge({ knowledge_id: "wiki-docs", type: "wiki", service_url: "http://127.0.0.1:8421/v3", // Knowledge Service 数据面 URL name: "Team Docs Wiki", summary: "Internal tech docs", team_id: "team-1", user_id: "usr-1", }); console.log(k.knowledge_id, k.type, k.created_at); // 列出某个团队下所有 code-graph const list = await meta.listKnowledge({ team_id: "team-1", type: "code-graph" }); console.log(list.items, list.total); // 重命名 / 更换 service_url await meta.updateKnowledge({ knowledge_id: "wiki-docs", name: "Renamed Wiki" }); // 批量删除 await meta.deleteKnowledge(["wiki-docs", "cg-repo-1"], "team-1");返回类型:KnowledgeEntity/KnowledgeListResult { items, total }/BatchDeleteResult { deleted_ids, failed }。
源码层面,Knowledge 端点挂在/v3/knowledge前缀(V3_KNOWLEDGE常量,见 v3/metadata-client.ts),不属于/v3/meta前缀;其 handler 不读 user-key,team_id直接放在请求 body 中。
七、SkillClient:技能记忆(/v3/skill/*)
README 主文档之外,SDK 还附带SkillClient,封装 src/gateway/skill-handlers.ts 定义的 15 个/v3/skill/*端点:create / update / patch / delete / get / list / search / versions / files-write / files-remove / files-read / listing / extract / conversation-add / conversation-force-archive。
SkillClient与MemoryClient的隔离语义不同(v3/skill-client.ts):CRUD / file / listing / search 端点在 schema 层全部可选隔离字段,因此 SDK 把它们作为构造期 defaults 接受、每次调用可覆盖,且缺失 id 时不会在客户端抛错,交由服务端按需返回 40001/40301/40302。而/extract、/conversation/add、/conversation/force-archive有更严格的字段要求:
/extract:SDK 合并构造期 defaults 后本地校验user_id / team_id / agent_id非空、messages至少一条,随后发起异步抽取任务,立即返回{ task_id, archive_key, archived_at_ms };真正的技能挖掘在 core worker 异步完成,可通过/v3/skill/list或/v3/skill/search(按task_ref_id过滤)观察结果(v3/skill-client.ts);/conversation/add、/conversation/force-archive:session_id / user_id / team_id / agent_id均为必填,且 SDK不合并构造期 defaults,调用方必须显式传参。
八、错误处理:TDAMError 统一模型
所有非零code响应都会抛出TDAMError。官方 README 的错误处理示例:
import { TDAMError } from "@tencentdb-agent-memory/memory-sdk-ts-v2"; try { await client.readCore(); } catch (e) { if (e instanceof TDAMError) { console.error(`code=${e.code} message=${e.message} request_id=${e.requestId}`); } }从 errors.ts 看,SDK 定义了两类错误:
ParamError extends TypeError:客户端参数校验失败(如 v3 必填 id 缺失、endpoint 非法 URL、timeout 非正数);TDAMError extends Error:服务端业务/传输错误,携带code、requestId、可选details三个字段。
TDAMError.details有明确的实战用途:部分端点在code !== 0时会把诊断字段放进data,例如/v3/skill/update在40901 SKILL_VERSION_STALE时返回{ current_version },/v3/skill/files/read在41002 SKILL_VERSION_EXPIRED时返回{ latest_version },这些信息被保留在details中供调用方做冲突恢复(见 errors.ts 注释)。
底层判定逻辑位于 v3/http.ts:!response.ok || businessCode !== 0时抛错;code优先取业务码、否则回退 HTTP status;requestId的解析顺序为响应头x-qcloud-transaction-id→x-trace-id→ 响应体request_id。此外,每次成功响应还会把响应头x-trace-id注入返回对象(若为对象),方便全链路追踪(v3/http.ts)。
九、构建、测试与打包
官方 README 给出了标准的三步流程:
npm run build # tsc 编译到 dist/ npm test # vitest 运行测试 npm pack # 打 npm 包package.json 中的脚本细节:build为tsc;prepack/prepublishOnly都会先执行clean(清空 dist)再构建,保证发布产物干净;test使用vitest run,支持test:watch开发模式。包发布内容为dist/、src/、README.md(见files字段)。
十、进阶:传输层与自定义 Transport
V3HttpTransport(v3/http.ts)是 v3 客户端的唯一 HTTP 实现,值得注意的配置项:
endpoint必须为合法的http:/https:URL,否则抛ParamError;末尾多余的/会被去掉;timeout默认30000 ms,必须是正数;超时通过AbortController中止请求;rejectUnauthorized: false可关闭 TLS 证书校验(通过 undiciAgent的connect.rejectUnauthorized实现),仅建议在自签名证书的内网环境使用;- 所有请求统一
POST+Content-Type: application/json。
同时,index.ts 还从./cos.js导出了MemoryFileReader、StsCredentialManager、cosV5Sign、createMemoryFileReader等能力,供需要以 STS 临时凭证直读 COS 文件的调用方使用;Transport接口(见 v3/client.ts 的构造重载)允许传入自定义 Transport,实现 mock 或特殊网络策略。
十一、小结
@tencentdb-agent-memory/memory-sdk-ts-v2用一个包覆盖了 TencentDB Agent Memory 的完整客户端能力:MemoryClient负责 L0~L3 四层记忆数据面的严格隔离读写,MetadataClient负责团队级元数据治理与知识源管理,SkillClient承接技能记忆的抽取与文件管理。理解隔离模型(必填的 team/agent/user 三元组 + 可选 session 的读写差异)与统一的TDAMError错误模型,是在生产环境中正确使用该 SDK 的关键。更多示例与详细类型可继续阅读仓库中的 TypeScript SDK 目录 及其源码注释。
【免费下载链接】TencentDB-Agent-MemoryTencentDB Agent Memory is a team-level memory hub for AI Agents — turning conversations, docs, and code into four reusable memory assets (Chat Memory, Skill, LLM-Wiki, Code-Graph) that are governed, shared, and equipped across agents and frameworks.项目地址: https://gitcode.com/GitHub_Trending/te/TencentDB-Agent-Memory
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考