资讯动态

TencentDB-Agent-Memory Opik 历史数据导入:将 Opik Trace 一键迁移至 Memory Core L0

发布时间:2026/9/11 11:52:47 来源:尧图企业网站定制
TencentDB-Agent-Memory Opik 历史数据导入将 Opik Trace 一键迁移至 Memory Core L0【免费下载链接】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 仓库中MemoryCore/scripts/import-opik-to-memory-core工具完整讲解如何把 Opik 平台上已有的 Project Trace 批量转换为对话消息并通过 Memory Core Gateway 的POST /v3/conversation/add写入 L0 层。读完本文你将掌握从环境变量安全配置 Opik 与 Memory Core 地址、Dry Run 预演、断点续传、Pipeline 节流到回查校验的一整套可落地的历史数据迁移方案同时了解工具底层如何解析常见 Trace 结构、合并 input/output 消息并稳定生成 session_id。工具定位把可观测平台沉淀的对话搬进记忆系统OpikComet 开源的 LLM 可观测平台会以 Trace 形式记录每次 LLM 调用的input/output其中往往完整保存了用户与模型的对话。当团队从其他框架或自建链路迁移到 TencentDB-Agent-Memory 时这些历史对话正是最有价值的记忆资产——它们对应 Memory Core 四层记忆体系中的 L0 原始对话流水Raw Conversation。本工具index.ts扮演“数据搬运工”角色从 Opik 私有 API/api/v1/private分页读取全部 Project 与指定 Project 的全部 Trace从 Trace 的input/output中自动识别并抽取对话消息规范化为{ role, content, timestamp }结构通过 Memory Core Gateway 的POST /v3/conversation/add写入 L0并带上team_id/agent_id/user_id/service_idx-tdai-service-id等隔离字段使历史对话进入与线上链路一致的租户隔离与后续 L1 抽取流程。从工具入口看命令注册在 package.json 的import:opikscript实际执行体是tsx scripts/import-opik-to-memory-core/index.ts要求 Node.js 22.16.0。前置条件与快速查看帮助开始前需要满足以下前提Node.js 22.16.0且已安装当前项目依赖在 MemoryCore/package.json 中声明Opik REST API 可访问远端 Memory Core Gateway 可访问/health、/v3/conversation/add和/v3/conversation/query已确定目标service_id、team_id、agent_id和user_id如需要还可指定task_id。进入 Memory Core 目录后即可查看全部参数cd MemoryCore npm run import:opik -- --help从源码的usage()index.ts可以看到参数分为四组数据源Opik、目标Memory Core、执行控制、密钥环境变量。命令使用 Node 内置node:util的parseArgs解析strict: true模式下未知参数会直接报错index.ts。配置 Opik 地址与分页读取推荐只配置 Opik 根地址和 workspaceexport OPIK_URLhttp://opik.example.com:5173 export OPIK_WORKSPACEdefault也兼容直接粘贴 UI 地址http://opik.example.com:5173/default/projects?size25关于 UI URL 有两个关键点源码parseOpikBase实现index.tsUI URL 中的size25不会限制导入范围——工具会把 URL 规范化并转换成/api/v1/privateAPI 地址size参数被清除分页读取与页面展示无关URL 首段若既不是api也不是v1会被识别为 workspace例如上面的default显式传入--workspace或设置OPIK_WORKSPACE优先级更高。分页策略在OpikClientindex.ts中实现projects()与traces()均从page1起循环拉取直到已读数量 total或某页为空才停止--page-size默认100。Trace 读取时还会带上truncatefalse与strip_attachmentstrue前者保证拿到完整 input/output后者剥离附件减少无效数据最终 Trace 按start_time回退到created_at升序排序保证导入顺序与对话发生顺序一致。另外注意OPIK_URL中不允许携带用户名/密码parseOpikBase会直接抛错凭据必须通过环境变量传递。配置远端 Memory Core 与鉴权以下地址仅为示例请替换成实际 Gateway 地址export MEMORY_CORE_URLhttp://memory-core.example.com:8423 export MEMORY_CORE_SERVICE_IDdefault export MEMORY_CORE_TEAM_IDteam-001 export MEMORY_CORE_AGENT_IDagent-001 export MEMORY_CORE_USER_IDuser-001可选 Task 隔离export MEMORY_CORE_TASK_IDtask-001不需要 Task 时unset MEMORY_CORE_TASK_ID安全输入 API Key避免写入代码或配置文件read -s MEMORY_CORE_API_KEY?Memory Core API Key: echo export MEMORY_CORE_API_KEY检查 Gateway 连通性curl --fail --silent --show-error ${MEMORY_CORE_URL}/health源码层面MemoryCoreClientindex.ts对每次写请求固定携带以下 HeaderAuthorization: Bearer ${MEMORY_CORE_API_KEY}x-tdai-service-id来自MEMORY_CORE_SERVICE_ID标识服务实例Content-Type: application/json。MEMORY_CORE_API_KEY在非 Dry Run 模式下为必填缺少会直接报错退出index.ts。响应采用统一信封{ code, message, request_id, data }结构code ! 0视为失败并携带request_id便于排查成功时以data.accepted_ids.length回退data.total_count作为该批实际接收数并与本批消息数比对不一致即中止防止静默丢数据index.ts。先执行 Dry Run 验证Dry Run 会读取真实 Opik 并转换 Trace但不会写入 Memory Core 或断点文件npm run import:opik -- \ --project 5d0fd72d \ --max-traces 5 \ --dry-run--project同时接受 Project 名称和 UUID可以重复传入或使用逗号分隔npm run import:opik -- \ --project project-a \ --project 019fb2e2-16a9-717d-98a8-0cd2e1bef87e \ --dry-run不传--project会处理 workspace 下全部项目。项目数量较多时应先指定项目和--max-traces做小批验证。Dry Run 时每条 Trace 会打印一行[dry-run] project... trace... session... batch... messages...可以直观看到“一个 Trace 被拆成几个批次、每批几条消息”并且--dry-run模式不要求MEMORY_CORE_API_KEYindex.ts适合在目标环境未就绪时先行验证解析效果。Trace 消息解析原理工具的核心竞争力在于兼容多种常见的 Trace 结构。入口函数extractMessagesindex.ts的实现分两条路径路径一识别消息数组。findMessageArraysindex.ts在input/output中深度优先最多 5 层寻找“看起来像消息数组”的结构——数组内任一元素包含role字段或元素.message 内含 role。命中后优先按messages、conversation、history这三个键名查找找不到再遍历对象所有值兜底。随后bestMessageArray对所有候选数组统一规范化后选取消息数量最多的一组避免误命中子对象里的零散消息。**路径二prompt/response 兜底。**若找不到消息数组则分别从 input 的userPrompt、user_prompt、prompt、query、input、content、text等键提取 prompt从 output 的responseContent、answer、response、completion、output、content、text等键提取 answer各生成一条 user/assistant 消息index.ts。角色归一化normalizeRoleuser/human→ userassistant/ai/model/bot→ assistant仅在开启--include-system时system/developer才会以带前缀如[system]的 user 消息导入index.ts。内容提取contentToText兼容字符串、{ type: text, text }结构块、OpenAIchoices[].message等多态形式index.ts。input/output 合并mergeMessages通过检测 input 消息尾部与 output 消息头部的最大重叠相同 role 相同 content来消除重复——很多 Agent 框架的 output 会回显完整上下文这一步保证最终会话不出现重复轮次index.ts。大小限制单条消息超过MAX_MESSAGE_CHARS 8192字符会被splitContent按字符边界并避开 UTF-16 代理对截断拆分单次请求最多MAX_MESSAGES_PER_REQUEST 100条消息超出部分自动chunk成多个批次index.ts。正式导入与 session_id 生成Dry Run 确认解析无误后执行正式导入npm run import:opik -- \ --project 5d0fd72d \ --max-traces 5 \ --state-file ./opik-import-remote-state.json成功时会输出[import] project... trace... accepted... [done] seen_traces5 imported_traces5 ... imported_messages...工具实际调用POST MEMORY_CORE_URL/v3/conversation/add写入范围由以下字段共同决定x-tdai-service-id:MEMORY_CORE_SERVICE_IDteam_id:MEMORY_CORE_TEAM_IDagent_id:MEMORY_CORE_AGENT_IDuser_id:MEMORY_CORE_USER_IDtask_id:MEMORY_CORE_TASK_ID可选session_id: 根据 Opik Project ID 和thread_id/Trace ID 稳定生成session_id的生成规则在buildSessionIdindex.ts中优先使用 Trace 的thread_idOpik 中同一条会话线程会共享 thread_id缺失时回退到 Trace ID随后做「可读化 哈希稳定化」——可读部分取前 48 字符并替换非法字符再拼上 source 的 SHA-256 前 12 位最终形如opik:project_id:readable:hash12。这样的设计保证同一线程的 Trace 落在同一 session_id重复执行不产生新会话且不会与其他来源的 session 冲突。Gateway 侧/v3/conversation/add是强隔离覆盖路径之一见 v2-router.ts 的V3_ALLOWED_SUBPATHS请求体与响应契约见 v2-schemas.tssession_id缺省时自动落到默认兼容桶DEFAULT_ISOLATION_IDmessages数组 1100 条。写入 L0 后Gateway 会通过notifyPipeline触发异步 L1 抽取v2-router.ts历史对话随即进入与实时链路一致的记忆提取流程。断点续传重复执行自动跳过已完成批次默认启用断点续传。每个成功批次会立即写入--state-file重新执行相同命令时自动跳过已完成批次npm run import:opik -- \ --project 5d0fd72d \ --state-file ./opik-import-remote-state.json忽略已有断点npm run import:opik -- \ --project 5d0fd72d \ --no-resume--no-resume可能造成重复导入只应在明确需要重新导入时使用。实现细节index.ts断点文件默认.opik-memory-import-state.json格式为{ version: 1, completed: { checkpointKey: { imported_at, accepted } } }version不匹配会拒绝加载断点键为project_id:trace_id:batch 内容哈希:批次序号index.ts批次内容哈希由 SHA-256 截取 20 位生成因此消息内容变化会形成新断点键天然避免内容漂移导致的重复或漏导每个批次成功写入后立即原子落盘先写state-file.tmp-pid再 rename文件权限0600即使中途中断也不丢进度断点文件不保存 API Key可安全纳入版本控制或归档失败场景下Memory Core 接收数量与批次不符会直接抛错中止而非标记断点保证断点只记录“真实成功”的批次。Pipeline 节流等待 L1/L2/L3 空闲默认每写入 20 个批次等待 L1 空闲并在结束时等待 L1/L2/L3 全部空闲npm run import:opik -- \ --project 5d0fd72d \ --wait-every 20 \ --state-file ./opik-import-remote-state.json如果目标环境关闭了记忆提取、只需要写 L0npm run import:opik -- \ --project 5d0fd72d \ --wait-every 0 \ --no-final-wait \ --state-file ./opik-import-remote-state.json节流由MemoryCoreClient.waitForIdleindex.ts实现轮询POST /v2/pipeline/status读取各层{ idle, queued, running }状态l1模式只看 L1all模式要求 L1/L2/L3 全空闲。轮询间隔--poll-ms默认1000与单次等待上限--max-wait-ms默认600000即 10 分钟均可调。等待超时不会失败只是告警“导入数据已落 L0后台将继续处理”——因为 L0 是持久化流水后台抽取异步完成超时不影响数据完整性。需要注意/v2/pipeline/status是standalone 单机模式才开放的端点v2-router.ts 注释明确 service 模式返回 404因此在多租户 service 部署下应使用--wait-every 0 --no-final-wait。回查导入结果写入完成后用/v3/conversation/query按隔离维度回查curl --fail --silent --show-error \ -X POST ${MEMORY_CORE_URL}/v3/conversation/query \ -H Content-Type: application/json \ -H Authorization: Bearer ${MEMORY_CORE_API_KEY} \ -H x-tdai-service-id: ${MEMORY_CORE_SERVICE_ID} \ --data $(cat JSON { team_id: ${MEMORY_CORE_TEAM_ID}, agent_id: ${MEMORY_CORE_AGENT_ID}, user_id: ${MEMORY_CORE_USER_ID}, limit: 100, offset: 0 } JSON )team_id/agent_id/user_id三者为查询隔离维度也可传入session_id精确限定某条会话session_id可选缺省时按 (team, agent, user) 聚合查询见 v2-router.ts 注释。对比返回条数与导入的imported_messages即可确认全量落库。Opik 鉴权配置自托管 Opik 默认可能不需要鉴权。启用鉴权时read -s OPIK_API_KEY?Opik API Key: echo export OPIK_API_KEY export OPIK_AUTH_SCHEMEBearerOPIK_AUTH_SCHEME为空时OPIK_API_KEY会原样作为AuthorizationHeader。源码在OpikClient.headers()index.ts中实现请求始终携带Comet-Workspace-Name即 workspaceComet/Opik 服务端用它识别租户鉴权存在时拼接scheme key或裸 key。注意 OPIK 与 MEMORY_CORE 是两套独立的密钥体系切勿混用。常用参数一览参数默认值说明--project全部项目Project 名称或 UUID可重复或逗号分隔--page-size100Opik API 每页数量--max-traces0本次最多处理的 Trace 数0表示不限--state-file.opik-memory-import-state.json断点文件--dry-run关闭只拉取和转换不写入--no-resume关闭忽略断点可能重复导入--include-system关闭将 system/developer 转成带前缀的 user 消息--wait-every20每 N 个写请求等待 L10禁用--no-final-wait关闭不等待最终 L1/L2/L3 空闲--timeout-ms30000单次 HTTP 请求超时--retries4网络错误、429 和 5xx 重试次数表格之外从usage()与parseCli还可以看到两个未在 README 表格中列出的节流参数--poll-msPipeline 轮询间隔默认1000与--max-wait-ms单次等待上限默认600000以及对应的命令行等价物--opik-url、--memory-url、--workspace、--team-id、--agent-id、--user-id、--task-id、--service-id它们与同名环境变量二选一即可命令行优先。重试与网络容错HttpClient.jsonindex.ts实现了指数退避重试对网络错误、HTTP 429限流和 5xx服务端错误最多重试--retries默认 4次退避间隔为min(1000 * 2^attempt, 10000) 随机 0~250ms抖动而 4xx 除 429 外如 401/403/400属于NonRetryableHttpError直接抛出不浪费重试。每个请求通过AbortController在--timeout-ms默认 30000ms后中止。该重试策略同时作用于 Opik 读取与 Memory Core 写入配合断点机制能在网络抖动场景下安全完成大规模导入。已验证链路与最佳实践官方文档记录该工具已使用真实 Opik API 和隔离的本地 Memory Core 完成端到端验证分页读取 Opik Project 和 Trace将 5 个 Trace 转换为 15 条 L0 消息写入/v3/conversation/add通过/v3/conversation/query回查 15 条消息重复执行时断点命中、写入数为 0SQLite 与 JSONL 镜像落盘数量一致综合上述机制生产环境推荐的导入流程是小批预演--project name --max-traces 5 --dry-run确认消息抽取符合预期查看[dry-run]行数与 session 分布首次全量指定--state-file建议放在单独目录不传--max-traces或按需设置配合默认节流参数中断恢复直接重跑同一条命令断点自动跳过已完成批次校验/v3/conversation/query分页回查数量与imported_messages一致特殊数据需要保留 system 提示词时加--include-systemservice 多租户部署下使用--wait-every 0 --no-final-wait。在整个过程中所有密钥OPIK_API_KEY、MEMORY_CORE_API_KEY均只从环境变量读取工具的parseOpikBase甚至禁止在 URL 中携带凭据从源头规避了密钥落入命令历史或配置文件的泄露风险。【免费下载链接】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),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价