Skip to content

内容

内容 API 负责读取 L0/L1/L2 内容、写入文本,以及维护内容对应的语义和向量索引。

API 参考

abstract()

读取 L0 摘要(约 100 token 的概要)。

参数

参数类型必填默认值说明
uristr-Viking URI(必须是目录)

Python SDK

python
abstract = client.abstract("viking://resources/docs/")
print(f"Abstract: {abstract}")
# Output: "Documentation for the project API, covering authentication, endpoints..."

TypeScript SDK

typescript
const abstract = await client.abstract("viking://resources/docs/");
console.log(abstract);

Go SDK

go
abstract, err := client.Abstract(ctx, "viking://resources/docs/")
if err != nil {
    return err
}
fmt.Println(abstract)

HTTP API

GET /api/v1/content/abstract?uri={uri}
bash
curl -X GET "http://localhost:1933/api/v1/content/abstract?uri=viking://resources/docs/" \
  -H "X-API-Key: your-key"

CLI

bash
openviking abstract viking://resources/docs/

响应

json
{
  "status": "ok",
  "result": "Documentation for the project API, covering authentication, endpoints...",
  "time": 0.1
}

overview()

读取 L1 概览,适用于目录。

参数

参数类型必填默认值说明
uristr-Viking URI(必须是目录)

Python SDK

python
overview = client.overview("viking://resources/docs/")
print(f"Overview:\n{overview}")

TypeScript SDK

typescript
const overview = await client.overview("viking://resources/docs/");
console.log(overview);

Go SDK

go
overview, err := client.Overview(ctx, "viking://resources/docs/")
if err != nil {
    return err
}
fmt.Println(overview)

HTTP API

GET /api/v1/content/overview?uri={uri}
bash
curl -X GET "http://localhost:1933/api/v1/content/overview?uri=viking://resources/docs/" \
  -H "X-API-Key: your-key"

CLI

bash
openviking overview viking://resources/docs/

响应

json
{
  "status": "ok",
  "result": "## docs/\n\nContains API documentation and guides...",
  "time": 0.1
}

read()

读取 L2 完整内容。

参数

参数类型必填默认值说明
uristr-Viking URI
offsetint0起始行号(0 开始)
limitint-1读取的行数,-1 表示读到结尾
rawboolfalse返回未过滤 MEMORY_FIELDS 的原始存储内容(仅 HTTP API,Python SDK 暂未暴露)。

说明

  • read() 只接受文件 URI。传入已存在的目录 URI 时返回 INVALID_ARGUMENT400),而不是 NOT_FOUND。该错误会携带结构化的 details 字段——details.expected"file"details.actual"directory"details.resource 为出错的 URI(HTTP 路径上会带上)——客户端据此即可以编程方式判断"文件 vs 目录"不匹配(例如回退到 list),而无需对错误消息做字符串匹配。
  • 公开 URI 参数接受 resourcesuser 作用域。访问 session 文件时,使用 viking://user/{user_id}/sessions/{session_id},也可以使用向后兼容的 viking://session/{session_id} 别名。tempqueue 等内部作用域会返回 INVALID_URI

Python SDK

python
content = client.read("viking://resources/docs/api.md")
print(f"Content:\n{content}")

TypeScript SDK

typescript
const content = await client.read("viking://resources/docs/api.md", 0, -1);
console.log(content);

Go SDK

go
content, err := client.Read(ctx, "viking://resources/docs/api.md", 0, -1)
if err != nil {
    return err
}
fmt.Println(content)

HTTP API

GET /api/v1/content/read?uri={uri}
bash
curl -X GET "http://localhost:1933/api/v1/content/read?uri=viking://resources/docs/api.md" \
  -H "X-API-Key: your-key"

CLI

bash
openviking read viking://resources/docs/api.md

响应

json
{
  "status": "ok",
  "result": "# API Documentation\n\nFull content of the file...",
  "time": 0.1
}

write()

修改一个已存在的文件,或在 mode="create" 时创建新文件,并自动刷新相关语义与向量。

参数

参数类型必填默认值说明
uristr-要写入的文件 URI。mode="create" 时目标文件必须不存在
contentstr-要写入的新内容
modestrreplacereplaceappendcreate
waitboolfalse是否等待后台语义/向量刷新完成
timeoutfloatnullwait=true 时的超时时间(秒)

说明

  • replaceappend 要求文件已存在;create 仅用于创建新文件,目标路径已存在时返回 409 Conflict。目录始终会被拒绝。
  • create 只允许以下文本类扩展名:.md.txt.json.yaml.yml.toml.py.js.ts。父目录会自动创建。
  • 不允许直接写入派生语义文件:.abstract.md.overview.md.relations.json
  • 文件内容会在 API 返回前完成更新;wait 只控制是否等待语义/向量刷新完成。
  • 公共 API 已不再接受 regenerate_semanticsrevectorize;写入后一定会自动刷新相关语义与向量。

Python SDK

python
result = client.write(
    "viking://resources/docs/api.md",
    "# Updated API\n\nFresh content.",
    mode="replace",
    wait=True,
)
print(result["root_uri"])

TypeScript SDK

typescript
await client.write("viking://resources/docs/new.md", "# New document\n", { wait: true });

Go SDK

go
result, err := client.Write(
    ctx,
    "viking://resources/docs/api.md",
    "# Updated API\n\nFresh content.",
    &openviking.WriteOptions{
        Mode: "replace",
        Wait: true,
    },
)
if err != nil {
    return err
}
fmt.Println(result["root_uri"])

HTTP API

POST /api/v1/content/write
bash
curl -X POST "http://localhost:1933/api/v1/content/write" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-key" \
  -d '{
    "uri": "viking://resources/docs/api.md",
    "content": "# Updated API\n\nFresh content.",
    "mode": "replace",
    "wait": true
  }'

CLI

bash
openviking write viking://resources/docs/api.md \
  --content "# Updated API\n\nFresh content." \
  --wait

响应

json
{
  "status": "ok",
  "result": {
    "uri": "viking://resources/docs/api.md",
    "root_uri": "viking://resources/docs",
    "context_type": "resource",
    "mode": "replace",
    "written_bytes": 29,
    "content_updated": true,
    "semantic_status": "complete",
    "vector_status": "complete",
    "queue_status": {
      "Semantic": {
        "processed": 1,
        "error_count": 0,
        "errors": []
      },
      "Embedding": {
        "processed": 2,
        "error_count": 0,
        "errors": []
      }
    }
  }
}

batch_write()

在一个 Resource 或 Memory 目录下执行一组带前置条件的文件写入,并在同一次请求中刷新受影响的语义与向量索引。

参数

参数类型必填默认值说明
root_uristring-包含所有写入目标的已存在 Resource 或 Memory 目录
operationsarray-要校验并执行的文件写入
waitbooleantrue是否等待语义/向量刷新
timeoutnumbernullwait=true 时的刷新超时时间(秒)
telemetryboolean/objectfalse是否返回操作遥测信息

每个 operation 包含:

字段类型必填说明
uristring位于 root_uri 下的目标文件 URI
contentstring条件必填UTF-8 文本;与 content_base64 必须且只能提供一个
content_base64string条件必填Base64 编码的字节;Memory 目标不支持
precondition.kindstringcreate_if_absentreplace_if_hash
precondition.base_hashstring条件必填replace_if_hash 必填,格式为 sha256:<小写十六进制>

说明

  • 单次请求最多包含 128 个 operation,单文件不超过 8 MiB,总内容不超过 16 MiB。
  • 所有目标必须是 root_uri 下的文件、属于同一 context type,且 canonical URI 不能重复。
  • Resource 目标允许任意安全文件扩展名;Memory 目标仍使用文本扩展名白名单,且不接受二进制内容。
  • 系统会在目标 tree lock 内、首次产生新写入之前检查所有非幂等前置条件;不满足时返回 409 Conflict
  • 如果目标已经包含期望字节,则归入 unchanged;因此刷新失败后可以安全重试,而不会重复写入相同内容。
  • API 能保证前置条件冲突不会产生新写入,但底层 I/O 中途失败时,本批次较早完成的写入仍可能已经可见。

Python SDK

python
result = client.batch_write(
    root_uri="viking://resources/wiki",
    operations=[
        {
            "uri": "viking://resources/wiki/new.md",
            "content": "# 新页面\n",
            "precondition": {"kind": "create_if_absent"},
        },
        {
            "uri": "viking://resources/wiki/existing.md",
            "content": "# 更新后的页面\n",
            "precondition": {
                "kind": "replace_if_hash",
                "base_hash": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
            },
        },
    ],
    wait=True,
)

HTTP API

POST /api/v1/content/batch-write
bash
curl -X POST http://localhost:1933/api/v1/content/batch-write \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-key" \
  -d '{
    "root_uri": "viking://resources/wiki",
    "operations": [
      {
        "uri": "viking://resources/wiki/new.md",
        "content": "# 新页面\n",
        "precondition": {"kind": "create_if_absent"}
      }
    ],
    "wait": true
  }'

响应

json
{
  "status": "ok",
  "result": {
    "root_uri": "viking://resources/wiki",
    "created": ["viking://resources/wiki/new.md"],
    "updated": [],
    "unchanged": [],
    "queue_status": {
      "Semantic": {
        "processed": 1,
        "error_count": 0,
        "errors": []
      }
    }
  }
}

TypeScript、Go SDK 和 CLI 当前不直接暴露 batch write。


download()

以原始字节流下载文件,适用于图片、PDF 和其他非文本内容。响应使用 application/octet-stream,并通过 Content-Disposition 返回文件名。

参数类型必填说明
uristring要下载的文件 URI

HTTP API

http
GET /api/v1/content/download?uri={uri}
bash
curl --get http://localhost:1933/api/v1/content/download \
  -H "X-API-Key: your-key" \
  --data-urlencode "uri=viking://resources/images/logo.png" \
  --output logo.png

响应

成功时返回 HTTP 200 和文件原始字节,不使用标准 JSON 响应包:

http
HTTP/1.1 200 OK
Content-Type: application/octet-stream
Content-Disposition: attachment; filename*=UTF-8''logo.png

<binary body>

公共 SDK 和 CLI 当前没有独立的原始字节下载方法,因此本节只展示 HTTP Tab。


set_tags()

设置用于检索过滤的显式 k=v 标签。replace 替换已有标签,append 追加标签;对目录设置 recursive=true 时会更新目录下的文件。

Python SDK

python
result = client.set_tags(
    "viking://resources/project/",
    ["team=search", "env=prod"],
    mode="replace",
    recursive=True,
)

TypeScript SDK

typescript
const result = await client.setTags(
  "viking://resources/project/",
  ["team=search", "env=prod"],
  { mode: "replace", recursive: true },
);

Go SDK

go
result, err := client.SetTags(
    ctx,
    "viking://resources/project/",
    []string{"team=search", "env=prod"},
    &openviking.SetTagsOptions{Mode: "replace", Recursive: true},
)

HTTP API

http
POST /api/v1/content/set_tags
Content-Type: application/json
bash
curl -X POST http://localhost:1933/api/v1/content/set_tags \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-key" \
  -d '{
    "uri":"viking://resources/project/",
    "tags":["team=search","env=prod"],
    "mode":"replace",
    "recursive":true
  }'

POST /api/v1/fs/attrs/set_tags 是等价兼容路径,当前 Python、TypeScript、Go SDK 和 CLI 使用该路径。

CLI

bash
ov set-tags viking://resources/project/ \
  --tags team=search,env=prod \
  --mode replace \
  --recursive

响应

json
{
  "status": "ok",
  "result": {
    "uri": "viking://resources/project/",
    "updated_uris": [
      "viking://resources/project/guide.md"
    ],
    "root_uri": "viking://resources/project/",
    "context_type": "resource",
    "tags": [
      "team=search",
      "env=prod"
    ],
    "mode": "replace",
    "success_count": 1,
    "skipped_count": 0,
    "failed_count": 0,
    "tags_updated": true
  }
}

updated_uris 是实际更新的语义记录 URI;目录递归更新时,success_countskipped_countfailed_count 汇总各目标的处理结果。


reindex()

对已经存储在 OpenViking 中的现有内容,重新构建语义产物和/或向量索引。这是一个运维维护接口,适用于 embedding 模型更换、VLM 更换、向量库重刷、版本升级后修复历史索引等场景。

这个接口面向已有的 viking://... 内容,不负责导入新文件。常规导入请使用 Resources

认证

  • HTTP 端点:在开启认证时要求 admin/root 角色。api_key 模式下,租户内容重建请使用 admin key;裸 root key 不能访问租户级数据。
  • Python embedded 模式:使用当前 service context
  • Python HTTP client / CLI:使用当前认证身份发起请求

参数

参数类型必填默认值说明
uristr-要重新索引的 Viking URI
modestrvectors_only重建模式:vectors_onlysemantic_and_vectorsprune_orphans
waitbooltrue是否等待任务完成
dry_runboolfalse仅适用于 mode="prune_orphans";只报告 orphan 向量记录,不实际删除

HTTP 请求体不接受未知字段。uri 可以使用其他 content API 支持的 OpenViking 路径变量,服务端会先解析再校验。

支持的 URI 范围

  • viking://
  • viking://user
  • viking://user/<user_id>
  • viking://resources
  • viking://resources/...
  • viking://user/<user_id>/memories/...
  • viking://user/<user_id>/skills
  • viking://user/<user_id>/skills/<skill_name>

reindex() 不支持会话命名空间。请求 viking://session/...viking://user/<user_id>/sessions/... 会被拒绝;重建更大的 user 命名空间时, session 子树会被跳过。

模式说明

  • vectors_only:基于当前仍可恢复的源数据重建向量库记录,不会重写 .abstract.md.overview.md
  • semantic_and_vectors:先重新生成语义产物,再基于新的语义结果重建向量
  • prune_orphans:删除请求 URI 范围内源文件已不存在的向量库记录。设置 dry_run=true 时,只报告会删除多少记录,不实际删除。

对于 resourceskillsemantic_and_vectors 会刷新目录/文件语义产物,包括 .abstract.md.overview.md。对于 memory,它会重建当前已持久化 memory 子树的语义和向量,但不会回放历史记忆抽取顺序。

对于 semantic_and_vectors,语义刷新和向量重建由 reindex executor 串行编排。语义刷新阶段不会再额外向后台 embedding queue 投递自己的向量化任务;向量由 reindex 阶段统一重建,因此 wait=true 表示等待 reindex 操作本身完成。

对于 prune_orphans,源文件是否存在以当前文件系统为准。如果整个目录已经不存在,该目录下的正文文件向量和语义 sidecar 向量(例如 .abstract.md.overview.md)会一起清理。dry_run 用在其他模式时会被拒绝。

Python SDK

python
result = client.reindex(
    uri="viking://resources",
    mode="vectors_only",
    wait=True,
)
print(result)
python
result = client.reindex(
    uri="viking://user/default/skills",
    mode="semantic_and_vectors",
    wait=False,
)
print(result["status"])
python
result = client.reindex(
    uri="viking://resources",
    mode="prune_orphans",
    dry_run=True,
)
print(result["would_delete_records"])

TypeScript SDK

typescript
console.log(await client.reindex("viking://resources/docs/"));

Go SDK

go
result, err := client.Reindex(ctx, "viking://resources", &openviking.ReindexOptions{
    Mode: "vectors_only",
    Wait: true,
})
if err != nil {
    return err
}
fmt.Println(result["status"])
go
result, err := client.Reindex(ctx, "viking://resources", &openviking.ReindexOptions{
    Mode: "prune_orphans",
    Wait: true,
    DryRun: true,
})
if err != nil {
    return err
}
fmt.Println(result["would_delete_records"])

HTTP API

POST /api/v1/content/reindex

不存在 /api/v1/maintenance/reindex 端点。请使用 /api/v1/content/reindex

bash
curl -X POST http://localhost:1933/api/v1/content/reindex \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-key" \
  -H "X-OpenViking-Account: default" \
  -d '{
    "uri": "viking://resources",
    "mode": "prune_orphans",
    "wait": true,
    "dry_run": true
  }'

CLI

bash
openviking reindex viking://resources --mode vectors_only
bash
openviking reindex viking://user/default/skills --mode semantic_and_vectors --wait false
bash
openviking reindex viking://resources --mode prune_orphans --dry-run

同步响应(wait=true

json
{
  "status": "ok",
  "result": {
    "uri": "viking://resources",
    "mode": "vectors_only",
    "status": "completed",
    "object_type": "resource",
    "scanned_records": 120,
    "rebuilt_records": 118,
    "deleted_records": 0,
    "would_delete_records": 0,
    "unsupported_records": 2,
    "failed_records": 0,
    "duration_ms": 1284,
    "warnings": []
  },
  "time": 0.1
}

异步响应(wait=false

json
{
  "status": "ok",
  "result": {
    "uri": "viking://resources",
    "mode": "vectors_only",
    "object_type": "resource",
    "status": "accepted",
    "task_id": "task_xxx"
  },
  "time": 0.1
}

使用返回的 task 查询后台任务:

bash
curl -X GET http://localhost:1933/api/v1/tasks/task_xxx \
  -H "X-API-Key: your-key" \
  -H "X-OpenViking-Account: default"

Reindex 后台任务的 task_typeadmin_reindexresource_id 等于请求中的 uri,也可以这样列出:

text
GET /api/v1/tasks?task_type=admin_reindex&resource_id=viking://resources

任务记录持久化在 /local/{account_id}/_system/tasks/{user_id}/{task_id}.json,服务重启后仍可查询。

结果字段

字段说明
status同步完成时为 completed,后台执行时为 accepted
uri解析路径变量后的请求 URI
object_type推断出的目标类型,例如 resourceskillmemoryuser_namespaceskill_namespaceglobal_namespace
mode实际执行的 reindex 模式
scanned_records被检查的记录或语义源数量
rebuilt_records成功重建的向量记录数量
deleted_recordsprune_orphans 实际删除的向量记录数量;dry_run=true 时为 0
would_delete_recordsprune_orphans dry-run 模式下将会删除的向量记录数量
unsupported_records因没有可用向量来源而跳过的记录数量
failed_records重建失败的记录数量
duration_ms同步执行耗时,单位毫秒
warnings可恢复的单条记录级 warning
task_id后台任务 ID,仅 wait=false 时返回

行为说明

  • vectors_onlysemantic_and_vectors 是非破坏式的,采用重建/覆盖写入,不需要先 drop 向量集合。
  • prune_orphans 除非设置 dry_run=true,否则会删除源文件已经不存在的向量记录。
  • viking:// 发起 reindex 时,会向下分发到支持的顶层命名空间,并显式排除 session
  • 命名空间级 reindex,例如 viking://user,会继续传播到其支持的子内容类型。
  • 如果只是 embedding 模型或向量索引需要刷新,应使用 vectors_only
  • 如果语义产物本身也需要重建,再做重向量化,应使用 semantic_and_vectors
  • 如果文件系统曾绕过正常 API 发生删除,向量库可能还残留已删除路径的记录,应使用 prune_orphans
  • 同一个 URI 和 owner 同时只能运行一个 reindex 任务。对同一目标的并发请求会返回 conflict。
  • 对 resource 文件,文本文件在没有 summary 时可以使用文件正文;非文本文件需要已生成的 summary 或已有向量记录 fallback,否则会计为 unsupported。

当前限制

  • Reindex 会使用当前系统中“尽可能可恢复”的输入进行重建,不保证所有场景都能逐字节回放历史当时的 embedding 输入。
  • Memory 的 semantic reindex 基于当前已持久化的 memory 树,不会重建最初按时间顺序执行的记忆抽取流水线。

相关文档

Released under the Apache-2.0 License.