Skip to content

feat(reindex): support tag updates - #3964

Open
zhoujh01 wants to merge 3 commits into
mainfrom
feat/reindex-tags
Open

feat(reindex): support tag updates#3964
zhoujh01 wants to merge 3 commits into
mainfrom
feat/reindex-tags

Conversation

@zhoujh01

@zhoujh01 zhoujh01 commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

变更概述

为 reindex 增加显式设置 tags 的能力,并让 tags 随每条重建向量记录的首次 upsert 一起写入。

  • 在 reindex HTTP API 中新增 tagstag_mode
  • 支持 replaceappend 两种写入模式。
  • 覆盖 resource、memory、skill 及 namespace 级 reindex。
  • 未传 tags 时保留已有 tags。
  • 支持通过 tags: []tag_mode: "replace" 清空 tags。
  • 同步支持 wait=truewait=false 后台任务。
  • 对齐 Python、TypeScript、Go SDK 和 Rust CLI。
  • 修复单文件 reindex 和 prune 错误使用 tree lock 的问题。

行为说明

覆盖 tags

{
  "uri": "viking://resources/docs",
  "mode": "vectors_only",
  "tags": ["team=search", "env=prod"],
  "tag_mode": "replace"
}

本次 reindex 成功重建的所有向量记录都会使用传入的 tags。

对于目录或 namespace reindex,tags 会作用于成功重建的目录 L0/L1 和叶子 L2 记录。

追加 tags

{
"uri": "viking://resources/docs",
"mode": "vectors_only",
"tags": ["region=cn"],
"tag_mode": "append"
}

已有的其他 tag key 会被保留;如果传入 tags 中包含相同 key,则使用新的值覆盖旧值。

省略与空数组

  • 省略 tags:保留已有 tags。
  • tags: [] + append:不修改已有 tags。
  • tags: [] + replace:清空 tags。
  • mode="prune_orphans":忽略 tags 和 tag_mode。

tags 继续复用已有的严格 k=v 校验和标准化逻辑,包括转小写和重复 key 处理。

tags 会在 EmbeddingMsg 入队前写入,不会在 reindex 完成后额外调用一次 set_tags。

接口示例

Python SDK

client.reindex(
"viking://resources/docs",
tags=["team=search"],
tag_mode="append",
)

TypeScript SDK

await client.reindex("viking://resources/docs", {
tags: ["team=search"],
tagMode: "append",
});

Go SDK

client.Reindex(ctx, "viking://resources/docs", &openviking.ReindexOptions{
Wait: true,
Tags: []string{"team=search"},
TagMode: "append",
})

Go 调用方传入非 nil 的 ReindexOptions 时,需要显式设置 Wait。Go 的布尔零值为 false,只有 opts=nil 时才会使用 SDK 默认的 wait=true。

CLI

ov reindex viking://resources/docs
--tag team=search
--tag env=prod
--tag-mode append

--tag 可以重复传入。

CLI 只有在至少传入一个 --tag 时才会发送 tags 字段。通过空数组清空 tags 的能力目前只在 HTTP API 和 SDK 中提供。

文件锁修复

此前 reindex 会对单文件目标使用 tree lock,导致 AGFS 把文件当作目录扫描,并返回 not a directory。

本次调整后:

  • 已存在的文件目标使用 exact lock。
  • 目录目标继续使用 tree lock。
  • prune_orphans 遇到已存在的文件目标时使用 exact lock。
  • prune_orphans 遇到已经不存在的目标时继续使用 tree lock,以便扫描和清理该路径下残留的历史向量记录。

兼容性

  • 未传 tags 的现有调用保持原有行为。
  • 不修改向量库 schema。
  • 不修改持久化数据格式,无需数据迁移。
  • 继续依赖 partial_update=True 保留 reindex 未显式提供的字段。
  • 不重新引入 main 分支已经删除的 Python embedded client。

测试

  • 服务端 reindex 与 IngestOptions 测试:63 passed
  • Python SDK reindex 测试
  • TypeScript reindex 测试及 tsc --noEmit
  • Go SDK reindex 测试
  • Rust CLI 参数解析和编译测试
  • 本地持久化 AGFS + VectorDB 端到端测试:22 个断言
  • 目录 tags 递归传播
  • replace 覆盖
  • append 合并及同 key 替换
  • 大小写与重复 key 标准化
  • 空数组清空和空数组 append
  • 省略 tags 时保留已有值
  • wait=false 后台任务 tags 传播
  • 非法 tag 和非法 tag_mode 校验
  • 单文件 reindex 与 prune 锁行为
  • 服务重启后 tags 持久化

zhoujh01 and others added 3 commits August 12, 2026 19:33
Add replace and append tag modes to reindex vector rebuilds, preserve omission-aware behavior, and propagate options through background tasks and namespace rebuilds. Align Python, TypeScript, Go, and CLI interfaces with tests and documentation.

Co-authored-by: TRAE CLI <noreply@bytedance.com>
Use an exact path lock for existing file targets while retaining tree locks for directories and prune-orphans scopes. Add a regression test for single-file reindex.

Co-authored-by: TRAE CLI <noreply@bytedance.com>
Use exact locks for existing file targets in prune-orphans mode while retaining tree scope for missing targets. Document the existing Go ReindexOptions wait semantics and add lock regression coverage.

Co-authored-by: TRAE CLI <noreply@bytedance.com>
@zhoujh01
zhoujh01 marked this pull request as ready for review August 12, 2026 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

1 participant