首页
/ OpenViking Go SDK 实战指南:用 Go 语言操作自进化上下文数据库的完整方案

OpenViking Go SDK 实战指南:用 Go 语言操作自进化上下文数据库的完整方案

2026-09-09 19:50:46作者:农烁颖Land

本指南以 sdk/go/README.md 为核心,系统讲解 OpenViking Go SDK 的安装、客户端配置、身份认证、资源/技能/会话/记忆等核心 API 的用法,并深入其源码实现(客户端初始化、HTTP 传输封装、目录打包上传、图像输入归一化等)。读完本文,你将掌握如何在一个运行中的 OpenViking 服务器之上,用 Go 语言完成资源导入、语义检索、技能管理、会话记忆提交与 Peer 级记忆隔离等全套 Agent 上下文工程操作。

一、SDK 定位:一个 HTTP 客户端,而非独立服务

OpenViking 是一个面向 AI Agent 的"自进化上下文数据库"(Self-evolving Context Database),统一了 Agent 记忆(Memory)、知识检索(Knowledge RAG)与技能(Skills)。Go SDK 不是服务端组件,而是运行中 OpenViking 服务器的 HTTP 客户端,它作为独立 Go module 内嵌于主仓库中(见 sdk/go/go.modmodule github.com/volcengine/OpenViking/sdk/go,要求 Go 1.22+)。

client.go 可以看到,Client 结构体只持有 baseURLhttpClient、身份字段(apiKeyaccountuseractorPeerID)以及 profileuploadMode 等轻量状态——所有真实逻辑都在服务端,SDK 只负责把请求编码为 OpenViking 的 HTTP 协议并解析统一响应信封。

安装方式(在当前仓库的 sdk/go 目录下运行测试,或在你自己的 Go 工程中引入):

go get github.com/volcengine/OpenViking/sdk/go

二、客户端初始化:Config 配置项与默认值

2.1 最小可用示例

package main

import (
	"context"
	"fmt"
	"log"
	"time"

	openviking "github.com/volcengine/OpenViking/sdk/go"
)

func main() {
	ctx := context.Background()

	client, err := openviking.NewClient(openviking.Config{
		BaseURL: "http://localhost:1933",
		APIKey:  "your-key",
		Timeout: 120 * time.Second,
	})
	if err != nil {
		log.Fatal(err)
	}
	defer client.CloseIdleConnections()

	ok, err := client.Health(ctx)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("healthy:", ok)
}

2.2 Config 完整字段与源码语义

Config 定义在 types.go,结合 client.go 的初始化逻辑,各字段语义如下:

字段 类型 说明
BaseURL string 必填。SDK 会 TrimRight 末尾 / 并校验 URL 的 scheme 与 host,非法 URL 直接返回错误
APIKey string API 密钥,映射为 X-API-Key 请求头
Account string 账号标识,映射为 X-OpenViking-Account
User string 用户标识,映射为 X-OpenViking-User
ActorPeerID string Actor(Agent)Peer 标识,映射为 X-OpenViking-Actor-Peer,是"新 SDK 身份体系"的核心
Timeout time.Duration HTTP 客户端超时,为 0 时默认 60 秒client.go
HTTPClient *http.Client 自定义 HTTP 客户端,传入后 SDK 不再自行构造(可用它注入传输层中间件)
ExtraHeaders map[string]string 追加任意自定义请求头
Profile bool 为 true 时每次请求自动追加 profile=1 查询参数,开启服务端性能剖析输出
UploadMode string 上传临时文件时作为 upload_mode 表单字段传给服务端

2.3 统一响应信封与请求管线

所有 JSON 请求都经过 transport.gonewRequestdoJSON

  • 请求路径自动补 / 前缀,query 参数合并;
  • 身份头按非空原则逐一注入(见下节);
  • 服务端响应统一为 {status, result, error, telemetry, profile} 信封(responseEnvelope),doJSON 会解包 result 反序列化到目标结构,error 非空时转为 *openviking.Error
  • 响应体为空或 resultnull 时返回 nil,不触发反序列化。

三、身份头与多租户模型:APIKey 够用,Account/User 慎用

Go SDK 发送与 Python HTTP 客户端完全一致的身份头(映射实现在 transport.go):

Config 字段 HTTP 请求头
APIKey X-API-Key
Account X-OpenViking-Account
User X-OpenViking-User
ActorPeerID X-OpenViking-Actor-Peer

部署模式决定了你要填哪些字段:

  • 常见的 api_key 部署模式:只填 APIKey 即可,服务器会根据密钥推导出 account 与 user 身份;
  • 可信部署或网关透传场景:仅当上游显式通过 OpenViking 头转发租户身份时,才设置 AccountUser
  • SDK 不实现旧的 agent_id 兼容逻辑(README 明确说明),Peer 隔离一律通过 ActorPeerID 表达。这也是 examples/basic_usage/main.go 中"创建第二个仅带 ActorPeerID 的客户端来检索 Peer 级记忆"(见 main.go)能够生效的原因。

四、核心操作实战:资源、内容、检索、会话

README 的"Common Operations"一节演示了最常用的四类操作,这里逐段展开并补充参数细节:

// 1. 添加本地文件或远程 URL。本地文件/目录会先上传。
resource, err := client.AddResource(ctx, "./docs/readme.md", &openviking.AddResourceOptions{
	To:   "viking://resources/docs",
	Wait: true,
})

// 2. 读取与更新内容。
content, err := client.Read(ctx, "viking://resources/docs/readme.md", 0, -1)
updated, err := client.Write(ctx, "viking://resources/docs/readme.md", content+"\n\nUpdated.", &openviking.WriteOptions{
	Mode: "replace",
	Wait: true,
})

// 3. 语义检索相关上下文。
results, err := client.Find(ctx, "how do I configure auth?", &openviking.FindOptions{
	TargetURI:   "viking://resources/docs",
	Limit:       10,
	ContextType: []string{"resource"},
})
for _, item := range results.Resources {
	fmt.Println(item.URI, item.Score)
}

// 4. 按图像检索。Image 接受本地路径、viking:// URI、HTTP URL 或 data:image URI。
imageResults, err := client.Find(ctx, "", &openviking.FindOptions{
	TargetURI: "viking://resources/images",
	Image:     "./query.png",
	Limit:     5,
})
similarPosters, err := client.Search(ctx, "similar poster", &openviking.SearchOptions{
	TargetURI: "viking://resources/images",
	Image:     "viking://resources/images/poster.png",
	Limit:     5,
})

4.1 AddResource 的路径类型判断

AddResourceresources.go)把第一个参数 path 交给 addLocalUpload 分流处理:

  • http://https://git@ssh://git:// 开头 → 视为远程地址,直接以 path 字段提交;
  • 本地普通文件 → 先走 /api/v1/resources/temp_upload 上传,请求体携带 temp_file_idsource_name
  • 本地目录 → SDK 先打包为 zip(见下文),再走临时上传;
  • 路径不存在 → 原样透传 path 交给服务端判断。

注意 ToParent 互斥,同时指定会返回错误;Args 仅在非空时才序列化进请求体(resources.go),这是为了避免向较早版本服务端发送空 args 对象触发 body.args: Extra inputs are not permitted 校验错误,行为与 Python SDK 的 _compact_request_body、Rust CLI 的 compact_request_body 对齐。

4.2 Find 与 Search 的结构化结果

Find/Search 都返回 *FindResulttypes.go),内部按 MemoriesResourcesSkills 三类命中分区,并可选附带 QueryPlan(查询改写/多路召回的计划)与 Total。单个命中为 MatchedContext,暴露 URIContextTypeLevelAbstractContentOverviewScoreMatchReasonTags 等字段,其中 tags 与服务端 search_tags 对齐,便于与 Find/Search 的 Tags 过滤参数配合使用。

4.3 图像输入归一化

Image 字段支持本地路径、viking:// URI、HTTP(S) URL、data:image/... URI 四种形式,判断逻辑在 normalizeImageInput:只有本地文件会被读取并 base64 编码为 data:<mime>;base64,...(MIME 按扩展名推断,非 image/* 或未知时回退为 image/png),其他形式原样透传。路径存在与否是分流依据:本地不存在的路径不会被误读为文件。

4.4 会话、消息与记忆提交

session, err := client.CreateSession(ctx, &openviking.CreateSessionOptions{
	SessionID: "demo-session",
	MemoryExtractionConfig: map[string]any{
		"events": map[string]any{
			"tags": []string{"team=search", "channel=web"},
		},
	},
})
_, err = client.CreateSession(ctx, &openviking.CreateSessionOptions{
	SessionID:         "manual-session",
	DisableAutoCommit: true,
})
_, err = client.UpdateSessionConfig(ctx, "demo-session", &openviking.UpdateSessionConfigOptions{
	AutoCommitPolicy: openviking.Map(map[string]any{"message_count_threshold": 25}),
	MemoryExtractionConfig: map[string]any{
		"events": map[string]any{"tags": []string{"team=search", "channel=app"}},
	},
})
_, err = client.UpdateSessionConfig(ctx, "demo-session", &openviking.UpdateSessionConfigOptions{
	AutoCommitPolicy: openviking.Map(nil), // 显式 JSON null 关闭自动提交
})
_, err = client.AddMessage(ctx, "demo-session", openviking.Message{
	Role:    "user",
	Content: openviking.String("remember this deployment decision"),
})
commit, err := client.CommitSession(ctx, "demo-session", &openviking.CommitSessionOptions{
	KeepRecentCount: openviking.Int(2),
	EventTags:       []string{"team=search", "channel=web"},
})

会话 API 的底层行为可从 sessions.go 确认:

  • CreateSession(L12-L32)在 DisableAutoCommit 为 true 时把 auto_commit_policy 显式置为 JSON null,而不是省略字段;
  • UpdateSessionConfig(L53-L69)走 PATCH /api/v1/sessions/{id}/configAutoCommitPolicy 为指针类型,openviking.Map(nil) 才能表达"显式关闭",传 nil 则省略字段——这是指针参数(helpers.go 中的 String/Bool/Int/Float64/Map 辅助函数)存在的意义:区分"省略"与"零值/空值";
  • CommitSession(L148-L172)在设置 EventTags 时,会将其封装进 extraction_metadata.event.tags 结构,作为记忆抽取的事件标签元数据;
  • GetSessionContext(L84-L93)的 token_budget 传 0 时默认使用 128000 token 预算;
  • GetTask(L175-L189)在任务不存在时返回 (nil, nil) 而非报错,方便轮询代码直接判空;
  • 额外的 CancelTaskBatchAddMessages(一次请求批量追加多条 Message,消息体支持 Parts 多模态结构)也是会话能力的一部分。

五、API 覆盖矩阵:已实现与刻意未实现

Go SDK v1 有意与 Python HTTP 客户端的能力面保持一致。README 给出了完整矩阵:

已实现

领域 Go 方法
资源与技能导入 AddResourceAddSkillWaitProcessed
技能管理 ListSkillsFindSkillsValidateSkillGetSkillUpdateSkillDeleteSkill
Watch 管理 ListWatchesGetWatchUpdateWatchDeleteWatchTriggerWatch
文件系统与内容 ListTreeStatAttrsMkdirRemoveMoveReadAbstractOverviewWriteSetTagsReindex
检索 FindSearchGrepGlob
会话与任务 CreateSessionListSessionsGetSessionUpdateSessionConfigSessionExistsGetSessionContextGetSessionArchiveDeleteSessionAddMessageBatchAddMessagesCommitSessionGetTaskListTasks
Packs ExportOVPackBackupOVPackImportOVPackRestoreOVPack
系统与观测 HealthCheckConsistencyGetStatusIsHealthyQueueStatusVikingDBStatusModelsStatus
管理端 AdminCreateAccountAdminCreateAccountWithOptionsAdminListAccountsAdminDeleteAccountAdminRegisterUserAdminRegisterUserWithOptionsAdminListUsersAdminRemoveUserAdminSetRoleAdminRegenerateKeyAdminRegenerateKeyWithOptionsAdminMigrate

未实现(刻意排除)

领域 原因
agent_id 兼容 新 SDK 只使用 ActorPeerID
Privacy 配置路由 目前仅服务端管理面,Python HTTP 客户端也没有
Metrics 端点 Prometheus 文本抓取端点,不属于 JSON SDK API
Console/debug/backend-sync/session tool-result 端点 运维或服务端专用端点,超出 Python HTTP 客户端对等范围

5.1 README 未列出的额外能力

源码中还存在少量超出上表的方法,可作为补充:

  • 上下文组装SearchContextretrieval.go)执行服务端上下文组装,返回 SearchContextResultEntries/Rendered/Digest/Stats),SearchContextOptionstypes.go)支持 MaxTokensQuotasPurposeExcludeURIsPeerScopeOtherPeerPenaltyRewrite 等组装级参数;
  • 编译Compilecompile.go);
  • ACLACL/SetACL/SetACLMode/GrantACL/RevokeACL/DeleteACLacl.go);
  • Agent 进化观测ListExperienceTrajectoriesGetExperienceOutcomesagent_evolution.go);
  • OpenViking AssetsResolveOpenVikingAssetsPreflightOpenVikingAssetopenviking_assets.go),后者支持 AssetGitAuth 一次性 Git 认证做访问预检;
  • 组管理AdminCreateGroupAdminListGroupsAdminDeleteGroupAdminListGroupMembersAdminAddGroupMemberAdminRemoveGroupMemberadmin.go);
  • Agent Evolution 全局开关AdminGetAgentEvolutionAdminSetAgentEvolutionAdminGetAccountSettingsAdminSetAccountAgentEvolutionadmin.go)。

六、管理端用户配置:Seed 派生密钥的确定性

当需要为新用户附带服务端初始配置时,使用 options 变体方法。普通 add 调用不需要显式设置 SDK 默认值——省略 To/TargetURI,让服务端解析用户与部署默认值即可。

seed := "alice-seed"
_, err := client.AdminRegisterUserWithOptions(ctx, "acme", "alice", "user", &openviking.AdminRegisterUserOptions{
	Seed: &seed,
	UserConfig: map[string]any{
		"add_targets": map[string]any{
			"resource_uri": "viking://~/resources/project-a",
			"skill_uri":    "viking://~/skills",
		},
	},
})

newSeed := "alice-new-seed"
_, err = client.AdminRegenerateKeyWithOptions(ctx, "acme", "alice", &openviking.AdminRegenerateKeyOptions{
	Seed: &newSeed,
})

关键语义(README 明确给出):

  • 设置 Seed 时,返回的 API 密钥由 sha256(user_id + "\0" + seed) 确定性派生,适合需要可复现密钥的自动化场景;
  • 省略 Seed 则随机生成密钥;
  • nil 表示省略 Seed;传字符串指针(包括空字符串)则显式发送,空字符串会被服务端拒绝。

配合 AdminRegenerateKey(无 options 版本)可随时轮换用户密钥;AdminListAccounts/AdminListUsers 的 options 版本还支持通配符(*?)名称匹配与可选分页(Limit 生效时 Page 才生效,且 Page 从 1 开始)。

七、文件、目录与 Packs:打包上传的底层机制

AddResourceAddSkill 都接受本地文件与目录。目录的处理流程(upload.gozipDirectory + addLocalUpload):

  1. SDK 将目录递归打包为临时 zip(openviking-upload-*.zip);
  2. 符号链接被跳过(目录型 symlink 直接 SkipDir,文件型跳过,非普通文件一律不打包);
  3. 通过 multipart 表单上传到 /api/v1/resources/temp_upload,携带 temp_file_id
  4. 最终 API 调用使用 temp_file_id 而非原始路径;
  5. 上传完成后临时 zip 立即删除。
_, err := client.AddSkill(ctx, "./skills/search-web", &openviking.AddSkillOptions{
	Wait: true,
})

skills, err := client.ListSkills(ctx, nil)
found, err := client.FindSkills(ctx, "search the web", &openviking.FindSkillsOptions{
	Limit: 5,
})
_, _ = skills, found

exported, err := client.ExportOVPack(ctx, "viking://resources/docs", "./backups", nil)
restored, err := client.RestoreOVPack(ctx, exported, &openviking.ImportPackOptions{
	OnConflict: "overwrite",
})

_, _ = exported, restored

Packs 方向:ExportOVPack 把指定 URI 导出为 ovpack 文件(PackOptions.IncludeVectors 控制是否携带向量),BackupOVPack 做整库备份,ImportOVPack/RestoreOVPack 分别支持指定父目录导入与整库恢复,ImportPackOptions.OnConflict(如 overwrite)与 VectorMode 控制冲突与向量处理策略。

八、Watch 管理:让资源持续跟随外部变化

AddResourceWatchInterval 大于 0 时会顺带创建 Watch 任务,之后可用专门的 Watch 方法管理既有任务:

watches, err := client.ListWatches(ctx, &openviking.ListWatchesOptions{
	ActiveOnly: true,
})
updated, err := client.UpdateWatch(ctx, openviking.UpdateWatchOptions{
	ToURI:         "viking://resources/docs",
	WatchInterval: openviking.Float64(30),
	IsActive:      openviking.Bool(true),
})
triggered, err := client.TriggerWatch(ctx, openviking.WatchRef{
	ToURI: "viking://resources/docs",
})

_, _, _ = watches, updated, triggered
  • Watch 任务可通过 WatchRef{TaskID}WatchRef{ToURI} 二选一标识(watches.go);
  • UpdateWatchOptions 支持调整 WatchInterval(秒)、IsActive 开关,以及 Reason/Instruction 说明字段;
  • TriggerWatch 可手动触发一次立即检查,适合在改完源之后立刻同步。

九、错误处理:结构化 API 错误与错误码判定

OpenViking API 错误统一返回 *openviking.Error,其结构(errors.go)为 CodeMessageDetailsmap[string]any)、StatusCode

_, err := client.Read(ctx, "viking://resources/missing.md", 0, -1)
if openviking.IsCode(err, "NOT_FOUND") {
	fmt.Println("missing resource")
}

var apiErr *openviking.Error
if errors.As(err, &apiErr) {
	fmt.Println(apiErr.Code, apiErr.StatusCode, apiErr.Details)
}
  • IsCodeerrors.go)用 errors.As 判定错误码,可穿透包装错误;
  • 响应信封中 status == "error" 但缺少 error 对象时,SDK 会兜底构造 Code: "UNKNOWN"transport.go);
  • HTTP 状态码非 2xx 且无结构化错误时,同样返回 UNKNOWN 码并尽量从 detail 字段提取可读信息(transport.go);
  • 这是 SessionExistssessions.go)与 GetTaskNOT_FOUND 当作"不存在"处理的基础——错误码约定贯穿 SDK 内部逻辑。

十、测试与 Smoke Test:验证 SDK 的两种姿势

10.1 单元测试

cd sdk/go
go test ./...

仓库自带 1957 行的 client_test.go,覆盖配置校验、URI 归一化、请求构造、错误解码、图像归一化等行为,是了解各方法边界条件的活文档。

10.2 对真实服务器的冒烟测试

编辑 examples/basic_usage/main.go 顶部的常量(默认 baseURL = "http://localhost:1940"apiKey 留空表示服务器无需认证),然后运行:

cd sdk/go
go run ./examples/basic_usage

该脚本的完整执行流(README 概述 + 源码确认):

  1. 健康检查Health
  2. 导入资源:创建临时 Markdown 文件 → AddResource 导入为 OpenViking 资源 → WaitProcessed 等待后台处理完成;
  3. 列出与读取List(递归、simple)验证目录结构,Read 读取内容;
  4. 写入与检索Write(replace 模式)更新内容 → Find 做语义检索并打印命中 URI 与分数;
  5. Watch 管理:以 WatchInterval: 60 创建资源 → ListWatchesUpdateWatch 暂停/恢复 → TriggerWatch 手动触发,结束前 DeleteWatch 清理;
  6. 技能管理ValidateSkill(strict)→ AddSkillListSkills/GetSkillUpdateSkill(附带 SourceMetadata)→ FindSkills,结束前 DeleteSkill 清理;
  7. 会话提交CreateSessionBatchAddMessages 批量写入 6 条含 user/assistant 与 PeerID 的消息 → GetSessionContext 读取组装上下文 → CommitSessionKeepRecentCount: 0)→ 轮询 GetTask 等待记忆抽取任务完成(最多 3 分钟,见 waitForTask),并用 ListTasks 复查 session_commit 任务;
  8. 记忆检索与 Peer 隔离:用默认客户端 Find 检索用户级记忆 marker;再新建一个仅携带 ActorPeerID 的客户端(main.go),检索 Peer 级记忆 marker,验证记忆按 Peer 隔离。

每一步输出都以 1.2.… 编号打印,缺依赖或行为变化时脚本会以 log.Fatal 直接失败——这是最直观的"SDK + 服务端契约一致性"验收手段。

十一、与其他 SDK 的一致性说明

Go SDK 的 URI 约定(viking:// 前缀归一化,见 NormalizeURI)、身份头体系、响应信封与 Python 版 HTTP 客户端保持同一契约,且均不含旧 agent_id 兼容层。如果你同时维护多语言 Agent 基础设施,可以放心地把身份、检索、会话这三个维度的调用逻辑按相同语义在不同语言间平移。服务端路由(如 /api/v1/resources/api/v1/fs/*/api/v1/content/*/api/v1/sessions/*/api/v1/tasks)对应实现位于 openviking/server/routers 目录,需要深挖协议细节时可对照查阅。

结语

OpenViking Go SDK 以极轻的 HTTP 客户端形态,覆盖了资源导入、语义/图像检索、技能生命周期、会话记忆提交、Watch 同步、ovpack 备份恢复与管理端用户配置等 Agent 上下文工程的完整操作面。配合仓库内的单元测试与端到端冒烟示例,你可以在数分钟内完成从"连接服务器"到"提交一段会演化为长期记忆的会话"的完整闭环,并将 Peer 级身份隔离贯穿始终。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
docsdocs
暂无描述
Markdown
899
5.83 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
925
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
601
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.03 K
525
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
395