TencentDB-Agent-Memory TypeScript SDK 接入实战:把召回、捕获、工具与降级组装成一套长期记忆

发布时间:2026/9/11 20:17:05
TencentDB-Agent-Memory TypeScript SDK 接入实战:把召回、捕获、工具与降级组装成一套长期记忆 TencentDB-Agent-Memory 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本指南基于tencentdb-agent-memory/memory-sdk-ts的 TypeScript SDK讲解如何在一个真实 AI Agent 中落地长期记忆在用户消息发给 LLM 之前召回记忆注入 prompt、在每轮结束后捕获对话写入 L0、把记忆检索暴露成 LLM 可主动调用的工具并保证记忆服务故障时不拖垮主对话。读完本文你将掌握一套可直接复制进任意 Agent 框架如 Claude Code、OpenClaw 等的四步接入方案。SDK API 速查可参考 TypeScript SDK README本文重点讲如何把它们组装成完整闭环。接入要做的四件事无论 Agent 框架长什么样接入长期记忆的本质都是四条数据通路缺一不可用户输入 → ① 召回注入 prompt → LLM → ② 捕获写 L0 ↑ ③ 工具让 LLM 自己再查 ↑ ④ 错误降级失败不挂主流程① 召回Recall在每次构造 prompt 前把与当前问题相关的记忆片段检索出来注入上下文② 捕获Capture每轮 agent 跑完后把新增的 user/assistant 消息清洗后写回 L0原始对话层③ 工具Toolsprompt 注入容量有限注册记忆检索工具让 LLM 按需二次查询④ 错误降级Degradation记忆服务不可用时静默降级保证主对话流程继续。新接入推荐使用 v3 严格 isolation 客户端tencentdb-agent-memory/memory-sdk-ts/v3v2 兼容客户端仍从包根入口导出。SDK 同时支持 v2 兼容 API 与 v3 严格 isolation API默认导出的MemoryClient保持 v2 兼容老代码无需修改根入口也导出V3MemoryClient供不使用子路径的场景使用见 src/index.ts。0. 初始化配置 v3 严格 isolation 客户端import { MemoryClient } from tencentdb-agent-memory/memory-sdk-ts/v3; const client new MemoryClient({ endpoint: https://your-memory-gateway, apiKey: process.env.MEMORY_API_KEY!, serviceId: your-instance-id, teamId: team-xxx, agentId: agt-xxx, userId: usr-xxx, sessionId: session-xxx, // 可选L0/L1 缺省时可跨 session 聚合 });必须传 config 对象不能传裸 transportnew MemoryClient(transport, isolation)仅用于单测 mock。从源码看v3/client.ts 的构造函数会通过post in configOrTransport区分是 config 还是 transport只有显式传入 transport 且附带 isolation context 时才会走 mock 分支。各配置项的作用与源码约束配置项是否必填作用endpoint是记忆网关内核 gateway地址如http://127.0.0.1:8420构造时校验必须是合法 http/https URLapiKey是网关 Bearer 密钥对应KERNEL_AUTH_TOKEN/TDAI_GATEWAY_API_KEYserviceId是记忆实例 ID决定 memory instance 隔离请求头x-tdai-service-idteamId是v3v3 严格 isolation 三元组之一避免写入/查询串到其它团队agentId是v3v3 严格 isolation 三元组之一userId是v3v3 严格 isolation 三元组之一sessionId否传入时 L0/L1 按单会话收敛不传或置空时按(team, agent, user)跨 session 聚合L2/L3 是 teamagent 级 profile不消费 sessionIdtaskId否附加在 isolation 字段中的任务 ID用于任务级上下文标记源码层面有三个值得注意的强约束v3/client.ts三元组非空校验IsolationContext构造时对teamId/agentId/userId调用requireNonEmpty缺失直接抛ParamError从源头杜绝越权读写写路径强制 sessionresolveSessionForWrite()要求addConversation必须拿到非空session_id构造时传入或调用时传参否则抛错——目的是避免无 session 的写入被服务端静默合并进默认 bucket与其他调用方数据混在一起而query/search/count/delete等读路径允许省略 sessionId服务端按(team, agent, user)跨 session 聚合传输层校验v3/http.ts 中apiKey与serviceId均要求非空timeout必须为正数默认 30 秒。跨 session 做 agent 级召回// 跨 session 聚合查询当前 agent/user 的全部对话 const client2 client.withIsolation({ sessionId: null });withIsolation(overrides)会基于当前 client 派生一个新的 client共享同一 HTTP transport用overrides.sessionId null把 session 维度置空。V3IsolationOverrides支持teamId/agentId/userId/sessionId/taskId五个字段的部分覆盖类型定义见 v3/types.ts。1. 召回Recall三类记忆并行拉取注入 prompt在用户消息发给 LLM 前并行拉三类记忆拼到 system prompt 里async function recall(client: MemoryClient, userQuery: string) { const [l1, persona, scenes] await Promise.allSettled([ client.searchAtomic({ query: userQuery, limit: 5 }), // L1 结构化记忆 client.readCore(), // L3 用户画像 client.listScenarios({}), // L2 场景索引 ]); const l1Items l1.status fulfilled ? l1.value.items : []; const personaText persona.status fulfilled ? persona.value.content : null; const sceneList scenes.status fulfilled ? scenes.value.entries : []; return formatPrompt(l1Items, personaText, sceneList); }Promise.allSettled是这里的关键——任何一路超时/失败其它两路结果照常用不影响主对话。仓库中 openclaw-plugin/src/hooks/recall.ts 的performRecall就是这一模式的线上实现三路并行L1 搜索 L3 persona L2 场景列表逐路用status fulfilled判定取数并记录L1n, personayes/no, scenesm的耗时日志方便观测召回链路质量。拼 prompt 的两个区块prependContext动态L1 召回结果每轮都变放在用户消息前appendSystemContext稳定Persona Scene 索引 工具调用指南放在 system prompt 末尾用 KV cache 命中。待确定放到 system prompt 末尾仍可能造成 KV cache miss需要继续讨论。function formatPrompt(l1, persona, scenes) { const prepend l1.length 0 ? relevant-memories\n${l1.map(m - [${m.type}] ${m.content}).join(\n)}\n/relevant-memories : undefined; const parts: string[] []; if (persona) parts.push(user-persona\n${persona}\n/user-persona); if (scenes.length 0) { parts.push(## Scene Navigation\n*以下场景可用 tdai_read_file 读取详情*); parts.push(scenes.map(s - \${s.path}\).join(\n)); } parts.push(MEMORY_TOOLS_GUIDE); // 见下文 return { prepend, append: parts.join(\n\n) }; }这里的 prompt 格式约定与仓库实现完全一致openclaw-plugin/src/format.ts 中formatL1Memories生成relevant-memories列表带类型标签[type]formatSystemContext组装user-personaScene Navigation仅列出path不注入全文并做去重判断persona 已含 Scene Navigation 时不重复注入 工具调用指南。实现要点在before_prompt_build钩子里缓存原始用户文本清洁版未注入 recall后面 capture 阶段要用——见第 2 节。2. 捕获Capture清洗本轮消息写回 L0在 agent 一轮跑完后agent_end钩子把这一轮新增的 user/assistant 消息清洗后写回 L0async function capture(client: MemoryClient, ctx: { sessionKey: string; rawMessages: any[]; // 框架给的完整消息历史 originalUserText: string; // 召回阶段缓存的清洁版用户文本 originalUserMessageCount: number; // 召回阶段缓存的消息数 }) { // ① 位置切片只保留这一轮新增的消息 const newMessages ctx.rawMessages.slice(ctx.originalUserMessageCount); // ② 提取 user/assistant去掉 tool calls / system / 多模态噪声 const extracted extractUserAssistant(newMessages); // ③ 把被 recall 污染的用户消息换回原始版 for (const m of extracted) { if (m.role user m.timestamp newMessages[0]?.timestamp) { m.content ctx.originalUserText; break; } } // ④ 文本清洗去图片 base64、去代码块、过滤太短/纯符号 const cleaned extracted .map(m ({ ...m, content: sanitize(m.content) })) .filter(m m.content.trim().length 5); if (cleaned.length 0) return; // ⑤ 提交 await client.addConversation({ session_id: ctx.sessionKey, messages: cleaned.map(m ({ role: m.role, content: m.content, timestamp: new Date(m.timestamp).toISOString(), })), }); }仓库中 openclaw-plugin/src/hooks/capture.ts 的performCapture完整实现了这五步且细节更丰富提取时兼容content: string与content: Array{type:text, text}两种消息形态内联 base64 图片数据统一替换为[image]占位符位置切片不可用时如重启后消息数不可信提供afterTimestamp时间游标兜底maxTimestamp返回值支持调用方推进游标最终 POST 返回serverTotalCount便于核对服务端落库总数。为什么要替换被污染的用户消息召回阶段会往用户消息前 prepend 一段relevant-memories.../relevant-memories。如果不还原成原始文本就写 L0下一轮召回就会基于这段被污染的文本去 search/embedding——形成反馈环记忆会越来越乱。这也是 sanitize.ts 中第一条清洗规则就把relevant-memories、user-persona、relevant-scenes、scene-navigation、memory-tools-guide等注入标签整体剥除的原因——双保险防止污染文本回流到记忆库。为什么要位置切片agent_end给你的是完整历史不是本轮新增。直接全发会重复写历史消息。在before_prompt_build时记一下消息数 Nagent_end时messages.slice(N)就是这轮新增的。客户端清洗规则与源码对齐剥除全部记忆注入标签relevant-memories/user-persona/relevant-scenes/scene-navigation/memory-tools-guide剥除 offload 注入的任务上下文块current_task_context/history_task_context剥除框架注入的元数据块Conversation info / Sender / Thread starter 等untrusted块、旧版 session JSON 块、[[reply_to_current]]指令、¥¥[...]¥¥skill 选择包裹、行首时间戳、[media attached:...]标记、System 执行块、base64 图片数据assistant 消息额外调用stripCodeBlocks剥掉 围栏代码块保留解释性文本、去掉噪音代码shouldCaptureL0过滤空消息与框架引导噪音如(session bootstrap)、NO_REPLY、/开头的斜杠命令并归一化多余空行。3. 工具暴露让 LLM 自己再查只用 prompt 注入的记忆是有限的。再注册三个工具让 LLM 自己查工具何时用实现tdai_memory_search找结构化偏好/事实client.searchAtomic({ query, limit })tdai_conversation_search找原始对话片段client.searchConversation({ query, limit })tdai_read_file读场景全文 / 核心记忆v3 用client.readScenario({ path })/client.readCore()COS 原始产物读取继续用 v2client.readFile(path)三个工具在仓库中均有对应的真实实现MemoryCore/openclaw-plugin/src/tools/memory-search.ts、conversation-search.ts、read-cos.ts可供参考落库时的输入输出契约。在 system prompt 里说清楚什么时候该调并加上调用次数上限## 记忆工具 - tdai_memory_search搜结构化记忆用户偏好、规则、历史事件 - tdai_conversation_search搜原始对话原文 - tdai_read_file读取场景文件用 Scene Navigation 列出的路径 ⚠️ memory_search conversation_search 一轮总共最多调 3 次。不限次数 LLM 会反复瞎搜。仓库 format.ts 中的MEMORY_TOOLS_GUIDE还补充了失败策略首次搜索无结果时可换关键词或换工具重试但总调用不超过 3 次3 次仍无结果则说明信息不在记忆中直接根据已有信息回复。4. 错误降级记忆服务挂了不能挂主对话三条原则召回用Promise.allSettled单路失败不影响其它捕获包 try/catch失败只记日志try { await capture(...); } catch (e) { logger.warn(capture failed: ${e.message}); }工具返回错误信息字符串而不是抛异常让 LLM 自己看到 memory unavailable 然后继续聊。5. 错误处理非零 code 抛TDAMErrorSDK 对 HTTP 契约做了统一信封解包响应code 0时返回data非零code抛TDAMError实现见 v3/http.ts 与 http.tsimport { TDAMError } from tencentdb-agent-memory/memory-sdk-ts; try { await client.readFile(scene_blocks/x.md); } catch (e) { if (e instanceof TDAMError) { if (e.code 404) { // 文件不存在正常情况 } else { logger.warn(memory error code${e.code} request_id${e.requestId}); } } }TDAMError定义在 src/errors.ts携带三个关键字段code业务错误码非零或 HTTP 状态码requestId优先取自响应头x-qcloud-transaction-id/x-trace-id其次取信封内request_iddetails服务端在data中附带的结构化诊断信息如 skill 更新冲突时返回的current_version可用于冲突恢复。requestId在 server 端也有日志排障时把request_id和trace_id给后端即可定位。另外 SDK 还导出ParamError参数校验错误与HttpTransport/MemoryFileReader/StsCredentialManager等底层组件见 src/index.ts自定义 transport 或 STS COS 直读场景可直接复用。6. 性能建议召回总预算 200ms三路并行后取最快返回的可用结果超时的丢掉prompt 注入控制大小L1 ≤ 5 条、Scene 列表只列 path 不列内容、Persona 一份就够。让 LLM 不够用时再用工具拉详情session 粒度sessionKey是 L0 conversation 的 partition key长期对话用稳定 id用户 id 会话 id不要每轮换。各层 API 与底层接口对应速查v3 客户端方法到网关接口的映射完整列表见 README.md实现在 v3/client.ts层级方法接口L0addConversation()/queryConversation()/searchConversation()/deleteConversation()/countConversation()POST /v3/conversation/*L1updateAtomic()/queryAtomic()/searchAtomic()/deleteAtomic()/countAtomic()POST /v3/atomic/*L2listScenarios()/readScenario()/writeScenario()/rmScenario()/countScenario()POST /v3/scenario/*L3readCore()/writeCore()/countCore()POST /v3/core/*注意addConversation与deleteConversation有额外的参数守卫addConversation缺session_id抛ParamErrordeleteConversation要求message_ids非空列表或session_id至少给一个见 v3/client.ts。请求体统一经过stripUndefined过滤undefined字段不会上送。此外v2 兼容客户端还保留 Offload 三件套offloadIngest()/offloadCompact()/offloadQueryMmd()POST /v2/offload/*。7. 管理面Knowledge / 元数据上面讲的都是MemoryClient数据面读写记忆。如果你还需要管理Knowledge 知识源wiki / code-graph的元数据、或管理 user/team/agent/task/asset用MetadataClientimport { MetadataClient } from tencentdb-agent-memory/memory-sdk-ts; const meta new MetadataClient({ endpoint: http://127.0.0.1:8420, apiKey: process.env.MEMORY_API_KEY, serviceId: your-instance-id, }); // 登记 / 列出 / 改名 / 删除 Knowledge 实体管理面 CRUD详见 README.md await meta.createKnowledge({ knowledge_id: wiki-1, type: wiki, service_url: http://ks:8421/v3, name: Wiki, team_id: team-1 }); await meta.listKnowledge({ team_id: team-1, type: wiki });MetadataClient封装内核网关的 v3 元数据管理面接口/v3/meta/*54 条含user-key/*以及/v3/knowledge/*Knowledge CRUD5 条鉴权用 Bearer x-tdai-service-id可选x-tdai-user-keyuser/create、user/delete 等 system_admin 接口需要。Knowledge 管理面方法一览方法接口说明createKnowledge()POST /v3/knowledge/createupsert 元数据幂等重复 post 即覆盖getKnowledge(id, teamId?)POST /v3/knowledge/get单条查询updateKnowledge()POST /v3/knowledge/update部分更新name/summary/service_url/repo_url/branchdeleteKnowledge(ids, teamId?)POST /v3/knowledge/delete批量删除≤100listKnowledge()POST /v3/knowledge/list按 team_id 列出可选 type 过滤 / 按 id 批查明细注意MetadataClient只管元数据 CRUD真正搜 wiki 内容、读页面、同步仓库要调 Knowledge Service 数据面service_url指向的:8421那是另一组接口不在本 SDK 范围内。安装与构建# 从 npm 安装发布后 npm install tencentdb-agent-memory/memory-sdk-ts # 从本地 .tgz 安装 npm install ./tencentdb-agent-memory-memory-sdk-1.0.0.tgz本地构建与测试npm run build、npm test、npm pack详见 sdk/memory-core/typescript/package.json。小结把四个环节串起来就是一个不依赖具体 Agent 框架的长期记忆闭环before_prompt_build缓存清洁用户文本并执行三路并行召回 → 组装prependContextL1 动态与appendSystemContextPersona Scene 索引 工具指南注入 prompt → 注册三个记忆检索工具兜底 →agent_end用位置切片 污染还原 清洗过滤后写回 L0 → 全程Promise.allSettled/ try-catch / 工具错误字符串化保证记忆服务故障不影响主对话。配合MetadataClient治理 Knowledge 知识源元数据即可把对话、文档与代码沉淀为团队可共享、可治理的记忆资产。【免费下载链接】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),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询