TencentDB Agent Memory TypeScript SDK 演进实录:从 15 个 Skill 端点全覆盖到对话强制归档

📅 发布时间:2026/9/12 4:02:45
TencentDB Agent Memory TypeScript SDK 演进实录:从 15 个 Skill 端点全覆盖到对话强制归档
TencentDB Agent Memory TypeScript SDK 演进实录从 15 个 Skill 端点全覆盖到对话强制归档【免费下载链接】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导读本文以 sdk/memory-core/typescript/CHANGELOG.md 为核心脉络完整梳理tencentdb-agent-memory/memory-sdk-ts从1.1.0到 Unreleased 各版本的能力演进V3SkillClient如何 1:1 覆盖全部 15 个/v3/skill/*端点、conversationAdd与conversationForceArchive两个对话增量/强制归档入口的正确用法、以及技能抽取从同步轮询到异步 fire-and-forget的架构转变。读完你将掌握该 SDK 的完整 API 表面、参数约束与响应结构差异并能直接写出可运行的技能管理与对话归档代码。文中所有结论均可在 MemoryCore/src/gateway/skill-handlers.ts 与 MemoryCore/src/gateway/skill-schemas.ts 等源码中找到对应实现。一、为什么关注这份 ChangelogSDK 的 CHANGELOG 往往只记录增删改但这三页条目实际浓缩了该 TypeScript SDK 在 2026-07 短短三周内的三次重要架构演进每一处都与 MemoryCore 服务端行为严格对齐1.1.02026-07-08V3SkillClient上线一次性补齐 14 个/v3/skill/*端点标志 SDK 技能能力从部分可用走向全量覆盖2026-07-18服务端删除POST /v3/skill/extract/result技能抽取从入队 轮询结果改为异步 fire-and-forgetSDK 同步删除extractResult()属于破坏性变更2026-07-20 / 2026-07-31先后补齐conversationAdd第 14 个端点与conversationForceArchive第 15 个端点即最后一个SDK 达到与服务端路由表完全一致的全量覆盖。从源码看这份15 个端点的承诺是真实可验证的makeSkillRouteTable()在 skill-handlers.ts 中注册了create / update / patch / delete / get / list / search / versions / files/write / files/remove / files/read / listing / extract / conversation/add / conversation/force-archive共 15 条路由而 src/v3/skill-client.ts 的类注释同样列出了这 15 个方法。两条路径一一对应这是 Changelog 中full 15 endpoints论断的直接证据。二、1.1.0V3SkillClient 全量覆盖与配套类型面2.1 客户端构造与端点清单V3SkillClient从包根导出即 src/v3/index.ts 中的export { SkillClient }CHANGELOG 写作V3SkillClient与类名SkillClient是同一对象构造参数继承自MemoryClientConfig并叠加SkillClientDefaultsteamId / agentId / userId / taskId支持两种构造方式import { SkillClient } from tencentdb-agent-memory/memory-sdk-ts; // 方式一直接传配置 const skills new SkillClient({ endpoint: https://memory.example.com, apiKey: sk-mem-..., serviceId: mem-abc, teamId: team-1, agentId: agent-coder, userId: usr-1, }); // 方式二共享 transport 覆盖默认隔离 idwithDefaults 语义 const skills2 skills.withDefaults({ teamId: team-2 });1.1.0覆盖的 14 个端点及其 SDK 方法如下对应 skill-client.ts 中的 CRUD 段类别端点SDK 方法CRUDcreate / update / patch / delete / get / list / search / versionscreate() / update() / patch() / delete() / get() / list() / search() / versions()资源文件files/write / files/remove / files/readwriteFiles() / removeFiles() / readFile()Prompt 注入listinglisting()抽取extractextract()2.2 关键设计默认隔离 id 的合并策略与 v3 数据面MemoryClient的构造时必须传 team/agent/user不同Skill 系列的隔离字段在 schema 层全部可选见 skill-schemas.ts 的idFieldsShape仅约束agent_id 依赖 team_id这一跨字段规则。因此 SDK 采用构造时记默认值、每次调用可覆盖的策略// skill-client.ts 中的合并逻辑 private ids(overrides: SkillIdFields): SkillIdFields { return { user_id: overrides.user_id ?? this.defaults.userId, team_id: overrides.team_id ?? this.defaults.teamId, agent_id: overrides.agent_id ?? this.defaults.agentId, task_id: overrides.task_id ?? this.defaults.taskId, }; }这意味着调用create / update / search等 CRUD 方法时可以省略隔离字段交由构造时的 defaults 补齐而缺失 id 不会在客户端抛异常而是由服务端返回40001bad request/40301not owner/40302team mismatch错误码。这也是 skill-types.ts 中SkillErrorCode常量存在的意义——调用方需要自己处理冲突恢复。2.3 类型面与辅助工具完整类型导出SkillSummary / SkillDetail / SkillSearchHit / SkillListingData / SkillFileContent / SkillExtractData等全部从包根 re-export见 src/v3/index.ts数值错误码常量SkillErrorCodeVERSION_STALE 40901、VERSION_EXPIRED 41002、RESOURCE_TOO_LARGE 41301、FRONTMATTER_INVALID 42203等供冲突恢复与重试判断静态资源编码助手SkillClient.encodeUtf8(path, content, opts)与SkillClient.encodeBase64(path, bytes, opts)分别生成encoding: utf-8与encoding: base64的SkillResourcePayload。encodeBase64接受Buffer / Uint8Array / ArrayBuffer / 预编码 base64 字符串四种输入见 skill-client.tswithDefaults(overrides)克隆一个共享同一 transport、但默认隔离 id 不同的新客户端避免为不同 agent 重复建立连接。2.4 TDAMError.details错误信封中的诊断数据1.1.0的另一处非破坏性增强HTTP transport 在code ! 0时会把信封中的data透传到 TDAMError.details 字段。典型场景/v3/skill/update返回40901版本冲突时details.current_version携带服务端当前版本号/v3/skill/files/read返回41002版本已过期时details.latest_version携带最新版本号。配合SkillErrorCode调用方可以实现读冲突详情 → 拉最新版本 → 重试的闭环恢复。TDAMError保留code / message / requestId三个基础字段不依赖details的既有调用方不受影响。2.5 变更SkillExtractMessage.timestamp 收窄为 string从number | string收窄为纯string是有服务端依据的extractMessageSchema.timestamp在 skill-schemas.ts 中使用z.string().datetime()校验只接受 ISO-8601 时间字符串。传数字必然在服务端被40001拒绝SDK 收窄类型只是提前在编译期暴露错误避免运行时 400。三、破坏性变更2026-07-18抽取结果从轮询改为 fire-and-forget3.1 为什么删除 extractResultChangelog 明确服务端已删除POST /v3/skill/extract/result端点。在新架构中技能抽取是异步、无需轮询的extract在归档写入完成后立即返回{ ok, task_id, archived_at_ms, archive_key }真正的技能挖掘由 Core 侧的 extractor worker 异步执行SkillConversationExtractWorker结果通过/v3/skill/list或/v3/skill/search观察不提供独立的轮询端点——这是刻意设计见 skill-handlers.ts 中改造前是入 Redis job 队列 轮询 /result改造后走跟 conversation/add 完全同一套下游的注释。3.2 对调用方的影响删除的 SDK 类型SkillExtractResultRequest / SkillExtractResultData / SkillExtractStatus / SkillExtractSyncData / SkillExtractAsyncData / SkillExtractCandidateSkillExtractData从sync | async联合类型简化为单一扁平接口{ ok: true, task_id, archived_at_ms, archive_key }与 skill-handlers.ts 中successEnvelope的实际返回结构一致。3.3 触发一次抽取的完整请求以 skill-types.ts 的SkillExtractRequest为准const res await skills.extract({ team_id: team-1, agent_id: agent-coder, user_id: usr-1, session_id: sess-9, // 可选缺省时服务端生成 sx- 前缀一次性 id space_id: mem-abc, // 可选缺省回落到 transport 的 x-tdai-service-id reason: user asked to save a skill, options: { max_iterations: 16 }, // 1–64默认 16 messages: [ { role: assistant, content: ..., timestamp: 2026-07-20T10:00:00Z }, ], }); // res { ok: true, task_id, archived_at_ms, archive_key }注意extract走的是构造默认值合并 本地校验策略SkillClient会在本地校验user_id / team_id / agent_id非空、messages非空未通过抛ParamError。session_id缺省时服务端生成一次性sx-前缀 id见 skill-handlers.ts因为 direct-trigger 没有跨轮 buffer每次调用独立归档即可。3.4 服务端的处理管线源码佐证从 skill-handlers.ts 可以还原extract的服务端处理链prepareArchivePayload以forceCompress: true压缩消息direct-trigger 恒压缩space_id优先取 body缺省回落auth.serviceId两者不一致时记录告警但仍以 body 为准trigger.archive()一次性写入一个独立 archive 一条SkillTaskEntry不写data-current / meta缓冲返回{ ok, task_id, archived_at_ms, archive_key }并通过trace.report(skill.extract, ...)上报观测数据。这与 Changelogfire-and-forget、无独立轮询端点的描述完全吻合。四、conversationAdd每轮对话增量入口2026-07-20 补齐4.1 端点语义POST /v3/skill/conversation/add是per-turn 增量写入接口代理proxy每轮对话结束后同步调用一次由 Core 侧完成buffer 拼接 阈值判定 归档一次调用可能只追加、也可能顺带触发归档。设计依据见docs/design/2026-07-15-skill-trigger-in-core-design.md§11.1服务端 handler 为 handleConversationAdd。4.2 参数约束与服务端 schema 严格一致CHANGELOG 强调conversationAdd不合并构造默认值调用方必须显式传 id。对照 conversationAddRequestSchema字段必填约束session_id✅非空不得含\|Redis 队列元素分隔符保留user_id✅同上team_id✅同上agent_id✅同上space_id可选缺省回落x-tdai-service-idheader即auth.serviceIdtask_id可选业务 task 引用透传到archive.task.task_ref_id最长 128 字符messages✅1–500 条tool_call/tool_result必须携带tool_call_idmessages的每一条使用 conversationMessageSchema 校验支持user / assistant / tool_call / tool_result / system五种角色与extract不同conversation/add的timestamp同时接受number | stringz.union([z.number(), z.string()])见 skill-types.ts。4.3 自动归档阈值为什么说buffer 达到阈值即归档conversation/add的自动归档由 add-handler.ts 的HandlerThresholds决定默认值在 L95-L99export const DEFAULT_HANDLER_THRESHOLDS: HandlerThresholds { toolCallThreshold: 10, // tool_call 累计 ≥ 10 次 bytesThreshold: 40 * 1024, // 累计字节 ≥ 40 KB requestCompressThresholdBytes: 40 * 1024, // 单次请求 ≥ 40 KB 走压缩路径 };判定逻辑L196-L203const addedToolCalls countRoles(input.messages, TOOL_CALL_ROLES); const nextTool meta.tool_call_count addedToolCalls; const nextBytes meta.byte_count rawBytes; const hitTool nextTool this.thresholds.toolCallThreshold; const hitBytes nextBytes this.thresholds.bytesThreshold; const shouldArchive useCompress || hitTool || hitBytes;两点容易被忽略的细节只数tool_call不数tool_result。源码注释解释得很清楚二者天然 1:1 配对若都计数会把阈值 10 变成实际 5 次工具调用即归档违背配置语义add-handler.ts归档 reason 有四种tool_calls累计 tool_call 达标、bytes累计字节达标、compressed单请求超大强制压缩路径、oversize压缩后仍超chunkMaxBytes 80 KB的兜底截断对应 skill-types.ts 中SkillConversationArchivedInfo.reason的联合类型。4.4 响应结构// status: ok —— 仅追加未触发归档 { status: ok } // status: archived —— 本次调用触发归档archived 为嵌套对象 { status: archived, archived: { task_id: ..., archived_at_ms: 1753000000000, archive_key: ..., reason: tool_calls | bytes | compressed | oversize, } }对应SkillConversationAddData/SkillConversationArchivedInfo类型skill-types.ts与服务端AddConversationResult一一对应。4.5 典型调用const res await skills.conversationAdd({ session_id: sess-9, user_id: usr-1, team_id: team-1, agent_id: agent-coder, task_id: task-ref-42, messages: [ { role: user, content: 请把刚才的 SQL 优化技巧记下来 }, { role: assistant, content: 好的已记录避免 SELECT * ..., timestamp: Date.now() }, ], }); if (res.status archived) { console.log(归档触发reason , res.archived!.reason, task_id , res.archived!.task_id); }注意Changelog 提到conversationAdd的space_id覆盖约定与extract相同——body 优先、缺省回落 transport 的x-tdai-service-idheader服务端在两者不一致时记录 mismatch 告警skill-handlers.ts。4.6 SDK 本地校验与 CRUD 端点缺失 id 交给服务端报错不同conversationAdd在 SDK 层就做严格校验skill-client.tssession_id / user_id / team_id / agent_id必须为非空字符串、messages必须非空否则抛出ParamError。这是因为该端点 schema 层就是必填约束SDK 提前拦截比等服务端 40001 更友好。五、conversationForceArchive手动强制归档2026-07-31 收官5.1 定位第三个触发条件conversation/add的自动归档受阈值驱动tool_call ≥ 10 或 bytes ≥ 40 KBconversationForceArchive则是绕过阈值、手动强制归档的入口语义与自动触发互补自动触发tool_call累计 ≥ 10 或字节累计 ≥ 40 KB或单请求超大压缩手动触发调用方在任意时刻主动归档当前 session buffer无论 buffer 大小。CHANGELOG 指出它引入于MemoryCore7ed542922026-07-28SDK 补齐后V3SkillClient达到与服务端路由表完全一致的 15 个端点。5.2 参数与响应最容易踩坑的差异点对照 forceArchiveRequestSchema 与 SkillConversationForceArchiveData字段必填约束session_id / user_id / team_id / agent_id✅与 conversationAdd 相同必填、非空space_id可选缺省回落auth.serviceIdreason可选最长 2000 字符task_id可选归档时透传到archive.task.task_ref_id响应结构是 Changelog 反复强调的坑——归档坐标位于顶层而不是像conversationAdd那样嵌套在archived下// buffer 为空无内容可归档 { status: empty, message: No messages in buffer to archive } // 归档成功task_id / archived_at_ms / archive_key 全部在顶层 { status: archived, task_id: ..., archived_at_ms: 1753000000000, archive_key: ..., }5.3 服务端处理链源码佐证从 handleForceArchive 可以还原完整流程路由与依赖检查resolveConversationAdd未接线时返回50301force-archive 与 conversation/add 复用同一套 wiringschema 校验forceArchiveRequestSchema.safeParse失败返回40001读取当前 buffer并行执行buffer.readCurrent(sess)与buffer.readMeta(sess)空 buffer 短路无消息直接返回{ status: empty, message }不产生归档任务无条件归档直接调trigger.archive({ bufferAtTrigger, taskRefId, reason })跳过阈值判定写回清理归档后清空data-current并重置tool_call_count / byte_count等 meta 计数与 add-handler 归档后行为一致见 L952-L967。5.4 典型调用const res await skills.conversationForceArchive({ session_id: sess-9, user_id: usr-1, team_id: team-1, agent_id: agent-coder, reason: session ended, archive before teardown, task_id: task-ref-42, }); if (res.status archived) { console.log(res.task_id, res.archived_at_ms, res.archive_key); // 顶层取值 } else { console.log(res.message); // buffer 为空 }与conversationAdd相同该方法不合并构造默认值session_id / user_id / team_id / agent_id必须显式传入SDK 本地校验失败抛ParamErrorskill-client.ts。5.5 实践建议何时使用强制归档会话收尾agent 会话即将销毁或切换空间前主动归档残留 buffer避免数据滞留关键节点落盘长对话中里程碑式转折点方案定稿、需求确认主动归档让技能挖掘 worker 及时消费不必等工具调用次数凑满阈值与自动阈值互补自动触发保证不遗漏强制触发保证不拖延两者共用同一套 buffer 计数归档后归零可安全混用。六、SDK 使用全景从安装到错误处理6.1 安装与版本npm install tencentdb-agent-memory/memory-sdk-ts包名在 package.json 中为tencentdb-agent-memory/memory-sdk-ts-v2Changelog 标题中的memory-sdk-ts为其包根名。engines.node 18仅运行时依赖undici。构建与发布脚本npm run buildtsc、npm testvitest、npm pack。6.2 错误处理模式所有非零code响应都会抛出TDAMErrorerrors.tsimport { TDAMError, SkillErrorCode } from tencentdb-agent-memory/memory-sdk-ts; try { await skills.update({ skill_id: sk-1, expected_version: 3, content: ... }); } catch (e) { if (e instanceof TDAMError) { console.error(code${e.code} message${e.message} request_id${e.requestId}); if (e.code SkillErrorCode.VERSION_STALE) { // e.details.current_version 携带服务端当前版本重新拉取后重试 } } }完整错误码对照skill-handlers.ts 的错误码映射注释 skill-types.ts 常量错误码常量含义40001BAD_REQUESTschema/参数校验失败40301NOT_OWNER非技能所有者40302TEAM_MISMATCHteam 不匹配40401NOT_FOUND技能不存在40901VERSION_STALE乐观锁版本冲突41002VERSION_EXPIRED读取的版本已过期41301RESOURCE_TOO_LARGE资源超限42201NAME_DUPLICATE技能名重复42202PATCH_NOT_UNIQUEpatch 目标不唯一42203FRONTMATTER_INVALIDfrontmatter 非法50301QUEUE_UNAVAILABLE/STORAGE_NOT_FOUND队列/存储不可用50302LLM_UNAVAILABLELLM 不可用50303COS_REQUIRED需要 COS 存储七、版本时间线总结版本/日期类型核心变更1.1.02026-07-08新增V3SkillClient覆盖 14 个端点完整类型面SkillErrorCodeencodeUtf8/encodeBase64withDefaultsTDAMError.details1.1.02026-07-08变更SkillExtractMessage.timestamp收窄为 stringUnreleased2026-07-18破坏性删除extractResult()SkillExtractData扁平化抽取改为 fire-and-forgetUnreleased2026-07-20新增conversationAdd()第 14 个端点SkillExtractRequest.space_id覆盖能力Unreleased2026-07-31新增conversationForceArchive()第 15 个端点收官结语这份 Changelog 记录的不只是方法增删而是该 TypeScript SDK 与服务端技能链路同步演进的完整缩影从 CRUD 全覆盖到抽取架构从同步轮询转向异步 fire-and-forget再到以conversationAddconversationForceArchive收官的自动阈值 手动强制双通道对话归档体系。对于使用者本文梳理出的三个核心记忆点是15 个端点已 1:1 对齐服务端路由表、conversationAdd / conversationForceArchive 不合并构造默认值且必须显式传四个隔离 id、force-archive 的归档坐标在响应顶层而 add 在archived嵌套层。结合 skill-handlers.ts、skill-schemas.ts 与 skill-client.ts 交叉阅读即可在真实项目中安全、正确地接入这套技能管理与对话归档能力。【免费下载链接】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),仅供参考