修复OpenViking记忆文件已生成但搜索不到的问题
在 Windows 上给 DeepSeek Harness 接入 OpenViking 记忆插件:一次「看似简单却踩了一路坑」的记录
记录一次从零安装、反复排查、最终定位并修复 OpenViking 本地向量库 bug 的全过程。
背景
我用的 DeepSeek Harness(以下简称 dsh)是一个 AI WebUI,希望在对话里具备「长期记忆」能力。于是我想接入 OpenViking——一个面向 AI Agent 的上下文/记忆存储服务端。
我的环境:
| 项目 | 值 |
|---|---|
| 操作系统 | Windows |
| Python | 3.14.7 |
| OpenViking | 0.4.14 |
| dsh profile | web |
| 记忆插件 | @openviking/dsh-memory-plugin |
| Embedding | 本地 GGUF 模型(512 维) |
| VLM | OpenCode Go(deepseek-v4-flash) |
表面上看,这只是「装一个插件」;实际做下来发现,它等于:
1 | 装 dsh 插件 |
一、先搞清楚:插件和服务端的关系
OpenViking 是独立的后端服务,而 dsh 插件只是「让 dsh 自动使用这个后端的桥」。
| 组件 | 角色 |
|---|---|
| OpenViking | 记忆存储 / 向量搜索 / 模型调用的服务端 |
| dsh-memory-plugin | 客户端集成:自动捕获消息、提交会话、注入记忆、暴露 viking_* 工具 |
所以:
- OpenViking 需要单独启动、单独配置
- dsh 插件让 dsh 在后台自动调用它,不需要手动手动导数据
二、安装过程中踩的坑
坑 1:一开始装错了对象
我最初误以为是装 OpenCode 插件,结果装到了 OpenCode 配置里。后来确认目标是 dsh 插件,清理掉误建内容后重新来。
教训:先确认目标平台,再动手。
坑 2:dsh 插件没有发布到 npm
执行:
1 | dsh plugin --profile web add @openviking/dsh-memory-plugin |
返回 404。
原因:@openviking/dsh-memory-plugin 当时没有发布到 npm registry。
解决:改用 GitHub 源码安装,把插件放进 dsh 的 web profile 里。
坑 3:OpenCode Go 不支持 embedding
我的模型 API 只有 OpenCode Go 订阅,但它只提供 OpenAI 兼容的 chat/completions 接口,测试 /embeddings 返回 404。
结论:
- OpenCode Go 可以当 VLM,用来做记忆提取、总结
- 但它不能做向量搜索
解决:采用混合方案:
1 | OpenCode Go -> VLM(总结 / 记忆提取) |
坑 4:本地 embedding 编译失败
安装 openviking[local-embed] 时,llama-cpp-python 在 Python 3.14 上构建失败。
原因:临时目录/沙箱权限问题。
解决:用完整权限重试后构建成功。
坑 5:模型下载慢 / HuggingFace 连不上
- HuggingFace 直连卡在 0 字节
- f16 模型约 45MB,又慢又断
解决:
- 换成
hf-mirror.com - 改用更小的 q4 量化模型(约 15MB)
- 写自动重试下载脚本
坑 6:记忆文件生成了,但搜索不到(核心问题)
这是最折磨人的一个。
现象:
- OpenViking 服务正常
- 记忆文件正常生成
- 但
ov find/viking_search全部返回空
服务日志出现:
1 | openviking.storage.viking_vector_index_backend - ERROR - Error reading existing record before partial update: Strings must be encoded before hashing |
第一层原因:向量维度不一致
一开始配置的是 768 维 embedding,后来换成 512 维本地模型,导致向量库 schema 不匹配。
解决:重置向量库,让它按当前维度重建。
但重建后仍然搜不到,说明还有更深的问题。
第二层原因:真正的 bug——xxhash 编码问题
最终定位到 OpenViking 的这个文件:
1 | openviking/storage/vectordb/utils/str_to_uint64.py |
代码:
1 | def str_to_uint64(input_string: str) -> int: |
xxhash 在 Python 3 中要求传入 bytes,不能直接传 str,所以报错:
1 | Strings must be encoded before hashing |
这导致:
- 记忆 Markdown 文件正常写入 ✅
- 但向量没有成功写进向量库 ❌
- 所以记忆文件存在,却搜索不到
修复:
1 | def str_to_uint64(input_string: str) -> int: |
修复后记忆搜索恢复正常。
坑 7:移动目录后启动失败
把 OpenViking 从 D:\LoopingIsle 搬到 D:\OpenViking 后,启动报:
1 | Existing collection embedding metadata does not match current configuration. |
原因:向量库元数据还记录着旧路径。
解决:因为模型没变、向量维度没变,只是路径变了,所以在配置里加:
1 | { |
坑 8:端口被占用导致重复启动失败
再启动一个 OpenViking 时:
1 | Application startup failed. Exiting. |
原因:1933 端口已经有一个实例在运行。
解决:启动脚本先检测端口,避免重复启动。
三、为什么这个 bug 很多人没遇到?
这个 bug 主要在以下组合下出现:
- Windows
- Python 3.14
- 本地向量库(
backend: local) - 本地 GGUF embedding 模型
而大多数用户使用的是:
- Linux + Docker
- 云端 embedding API
- 云端/托管向量数据库
- 较旧的 Python 版本
所以这条「本地 + Windows + 新 Python」的路径测试覆盖较少。
另外这个 bug 是「半坏」的:
- 服务能启动
- 记忆文件能生成
- 只有搜索时静默返回空
这种问题往往最难被发现。
四、排查经验总结
这次最大的收获是:看到「表面正常」时要学会怀疑更深一层。
排查思路:
- 先确认服务健康:
/health - 再确认记忆文件是否存在:
ov ls viking://user/default/memories - 再用命令行直接搜:
ov find - 最后一定去看服务日志——日志里的堆栈往往才是真正原因
这题如果没有看服务日志,可能永远定位不到 xxhash 这种「八竿子打不着」的地方。
五、最终状态
- 插件已装在 dsh web profile
- OpenViking 服务已从
D:\OpenViking正常运行 - 记忆写入、搜索都正常
- LoopingIsle 项目目录已保持干净
相关补丁和说明已整理成一个仓库:
1 | https://github.com/Retr67/openviking-xxhash-fix |
六、给后来者的话
- OpenViking 是独立服务端,dsh 插件只是客户端桥,两者都要配好。
- 如果只用 LLM API,注意它不一定支持 embedding,可能需要本地模型。
- 本地向量库 + 新 Python + Windows 是容易踩雷的组合,建议多看服务日志。
- 遇到「文件生成了但搜不到」,多半是索引/向量写入层出了问题,而不是记忆本身没存。