TencentDB Agent Memory 的资产类型枚举:源码四值、契约三值
读一个中等规模的 TypeScript 工程时,最容易踩的不是复杂算法,而是同一个概念在不同层用了不同字面量。TencentDB Agent Memory 里的「资产类型」就是这样一个字段:你要往绑定表里写一条记录、要调网关接口、要在知识服务里判断这是 Wiki 还是代码图谱,三处填的字符串并不一样。
先把前提摆清楚。以下全部基于该仓库 feat/server_team 分支(这也是它的默认分支,不是 main、不是 master)在 2026-08-16 的快照 97f9465,我们只读文件,没有部署、没有启动任何模块、没有跑过一次请求。该项目主模块 MemoryCore/package.json 的版本是 2.0.0-beta.1,另外三个模块的 package.json 版本仍是 0.1.0,处于 beta 阶段,字段与接口随版本变动,下面提到的每一处都请以仓库当前内容为准。
概念层:README 讲的是四类资产
README_CN.md 用四个小节介绍四类记忆资产。Chat Memory 那节(README_CN.md:97 起)原文写「Chat Memory 保留偏好、事实、决策和交互历史」,并写「每个 Agent 创建时自动获得独立记忆,下次对话不必从自我介绍开始」。Skill 那节(:107 起)写「Skill 不只是一段 Prompt:它有版本、资源文件、触发边界、执行步骤和验证规则」。第三节(:117 起)一次讲两个::119 写「Wiki 把产品文档、设计方案和运维手册生成结构化页面与链接图谱」,:123 写「CodeGraph 索引代码符号、文件、调用关系和影响路径」。
所以文档口径里的四个名字是 Chat Memory、Skill、Wiki、CodeGraph——注意 README 正文用的是 Wiki 与 CodeGraph 这种驼峰写法。这一层没有下划线,也没有横杠。
第一套:metadata 层的四值枚举
进到代码,MemoryCore/src/metadata/types.ts:24 一行写死了资产类型:
export type AssetType = "skill" | "llm_wiki" | "code_graph" | "chat_memory";
同样的四值在 MemoryCore/src/metadata/router/v3-meta-schemas.ts:11 有一份 Zod 枚举。往下走还能看到这四值成组出现:MemoryCore/src/metadata/types.ts:206-211 的 FixedAssetTypeCounts 接口,字段正好是 skill / code_graph / llm_wiki / chat_memory 四个计数;落到库表上,MemoryCore/src/metadata/store/sqlite-adapter.ts:252-261 的 meta_agent_fixed_assets 建表语句里有一列就叫 asset_type,同表还有 injection_mode(DEFAULT 'summary')与 priority(DEFAULT 50),并带 UNIQUE(agent_id, asset_id) 约束。
也就是说,在元数据这一层,从类型定义、请求校验、聚合统计到建表,四值是贯通的。chat_memory 在这一层不是可有可无的:MemoryCore/src/metadata/service/metadata-service.ts:1236-1250 的方法注释写着「幂等确保 (team, agent) 对应的 chat_memory 资产存在并已绑定到 agent」,创建时写死 visibility: "private"、source_type: "auto"、injection_mode: "summary"、priority: 50(:1293-1322)。
第二套:网关生成契约里只有三值
换到网关目录,MemoryCore/src/gateway/generated/ 下的文件是由 kubb 从 OpenAPI 描述生成的。MemoryCore/src/gateway/generated/types.ts:98-102 的 assetTypeEnum 只有三项:skill、llm_wiki、code_graph;MemoryCore/src/gateway/generated/schemas.ts:46 的 assetTypeSchema 同样是这三值的 z.enum。
也就是同一个仓库里,metadata/types.ts:24 是四值、gateway/generated/types.ts:98-102 是三值,差的那一个是 chat_memory。这里只陈述这个差异并标明两处位置,不推断哪一处「才是对的」,也不据此评价什么。
顺带说一句这份生成文件的来源:MemoryCore/kubb.config.ts:12 写的 OpenAPI 输入路径是 ./docs/team-api-仅memory.yaml,而 MemoryCore/docs/ 目录在这个快照里并不存在(ls MemoryCore/docs 报 No such file or directory)。快照里实际存在的 docs 目录是 MemoryCore/openclaw-plugin/docs 与 MemoryPanel/docs。所以这份契约的上游描述文件,我们在开源仓库里读不到,只能读它生成出来的结果。
第三套:知识层的横杠写法
第三个地方在知识侧。MemoryCore/src/core/store/types.ts:453:
export type KnowledgeType = "wiki" | "code-graph";
横杠,而且没有 llm_ 前缀。MemoryKnowledge/src/routes/tools.ts:191 用的也是 "wiki" | "code-graph" 这套写法。
顺着这个文件往上翻,还能看到这两类知识在工具层是分开列的:Wiki 一侧的只读工具是 get_info / search / list_pages / read_page / get_graph / list_raw / read_raw,源码注释写「Wiki tools (7)」(:48);Code-Graph 一侧是 get_info / search / explore / callers / callees / impact / node / status / files,注释写「Code-Graph tools (9)」(:90)。我们按 name: 字段数了一遍,两边分别是 7 条与 9 条,与注释自称的数量一致。该文件还明写「Management operations (create/delete/ingest/sync) are NOT exposed — only read-only query tools.」(:8-9)。
于是同一件事在这个仓库里有三种字面量:资产层 llm_wiki / code_graph(下划线),知识层 wiki / code-graph(横杠),README 正文 Wiki / CodeGraph(驼峰)。如果你在写迁移脚本、对账查询或者管理端筛选条件,把这两套下划线与横杠混着用是不会有编译提示的——它们分属两个类型定义。
还有一套:资产 ID 前缀
再往下一层,ID 前缀是第四种命名方式,且四类资产的生成规则并不统一。
- Skill:
skl-+ 12 字符 base62,见MemoryCore/src/core/skill/skill-core.ts:232-235。 - LLM-Wiki 与 Code-Graph:
WIKI_ID_PREFIX = "wiki-"、CODE_GRAPH_ID_PREFIX = "cg-",各加 8 位 base36,见MemoryKnowledge/src/store/ids.ts:17-18;该文件头注释(:4-8)写明「8-char base36 ≈ 36^8 ≈ 2.8e12 space」。 - Chat Memory:不是随机短串,而是组合出来的——
chat_memory-{team_id}-{agent_id},前缀常量CHAT_MEMORY_ASSET_PREFIX = "chat_memory-"与拼接函数buildChatMemoryAssetId都在MemoryCore/src/metadata/utils/chat-memory-asset.ts(分别在:19与:22-24)。
网关那份生成文件对前缀也有一段描述文本,MemoryCore/src/gateway/generated/schemas.ts:49 写「Skill=skl-,LLM-Wiki=wiki-,Code-Graph=cg-」——同样是三个,与它上面那个三值枚举一致。
顺着这个字段再看一眼 injection_mode
既然 meta_agent_fixed_assets 表里 asset_type 与 injection_mode 是并排的两列,把后者一起看完会更省事。它的枚举定义在 MemoryCore/src/metadata/types.ts:34,共四值:"direct" | "summary" | "tool" | "reference"。而我们在这个快照里能读到的实际写入点只有三种取值,并且是按资产类型分开的:
summary:chat_memory 走这个值(MemoryCore/src/metadata/service/metadata-service.ts:1320),另外sqlite-adapter.ts:1398与mongodb-adapter.ts:1104也把它作为缺省兜底。reference:skill 走这个值(metadata-service.ts:1431,方法注释见:1349)。tool:知识类资产走这个值,写入点在MemoryPanel/src/panel/http/routes/knowledge/allocate-routes.ts:103,该文件头注释(:8)写「injection_mode = ‘tool’(knowledge 是工具型注入,Proxy 渲染<knowledge_tools>)」。
剩下那个 direct,枚举里有,我们没有找到写入点,也没有在 MemoryProxy/ 里找到按该字段分支的实现——那里 injection_mode 只作为 DTO 字段出现一次,类型是 injection_mode?: string(MemoryProxy/src/meta/client.ts:91)。按前面提过的第三条规矩:枚举里出现不等于这条路径已经可用,核不到实现就照实记为「未核实到」。
绑定这条链路本身的入口是四条路由:/v3/meta/agent-fixed-asset/set、/list、/list-with-detail、/summary-by-agents(MemoryCore/src/metadata/router/v3-meta-router.ts:264-273,schema 映射在 v3-meta-schemas.ts:433-436),前缀常量 V3_PREFIX = "/v3/meta"。要提交 asset_type,就是在这几条上提交,用的是四值那一套。
自己动手核对的路径
这类差异不必部署、也不必运行任何模块就能确认,看四个文件就够,顺序建议是从窄到宽:
- 打开
MemoryCore/src/metadata/types.ts,找到AssetType那一行,数一下有几个字面量。 - 打开
MemoryCore/src/gateway/generated/types.ts,找到assetTypeEnum,再数一次。 - 打开
MemoryCore/src/core/store/types.ts,找到KnowledgeType,注意分隔符是横杠还是下划线。 - 在
MemoryCore/src/metadata/router/v3-meta-schemas.ts里找那份 Zod 枚举,确认请求校验走的是哪一套。
如果你手上的分支或版本与我们读到的不同,前三处数出来的结果可能会变,那说明上游改过,以你本地读到的为准——这正是为什么本文每一处都给了文件路径:结论会过期,位置不会。
最后提醒一句用法上的选择:该用哪一套,取决于你接的是哪一层的接口,不存在一个「正确的」全局写法。项目没有给出统一的映射函数,我们也没有在仓库里找到一处集中做两套拼写转换的地方;要不要在自己的代码里加一层映射,取决于你的调用面,这一点没有依据给通用建议。另外,MemoryPanel 的包名是 team-memory-control、MemoryProxy 的包名是 context-proxy,目录名与包名同样不是一回事,写安装命令时别把目录名当包名。
延伸阅读
- 从头读起:TencentDB Agent Memory 是什么:团队级 Agent 记忆中枢怎么读
- 本专题共 40 篇,完整分组目录见专题页
- TencentDB Agent Memory 的 Loadout:源码里它叫 agent-fixed-asset
- TencentDB Agent Memory 的权限:README 4 种可见性,代码有 5 种
本文依据 TencentDB Agent Memory 官方仓库(github.com/TencentCloud/TencentDB-Agent-Memory)
feat/server_team 分支上的 README、INSTALL、CHANGELOG、ROADMAP 与四个模块的源码整理,
核对日 2026-08-16,对应仓库快照 97f9465。该仓库的默认分支即为 feat/server_team。
本文内容为仓库源码与文档口径,我们没有部署、也没有运行过该项目的任何一个模块,
因此不涉及运行效果、检索质量与性能的任何描述。
该项目主模块处于 beta 阶段、其余模块版本号仍为 0.1.0,参数与接口随版本变动,请以仓库最新内容为准。
该项目会采集并存储团队的对话、文档与代码,属于敏感数据,是否使用请结合自身合规要求评估。
安全与合规相关做法请结合自身环境评估,本文不构成安全方案建议。