@vintmd/cos-vectors
v1.0.0
Published
OpenClaw plugin: dynamic per-turn skill routing via COS Vectors embedding similarity search
Maintainers
Readme
vintmd-cos-vectors
OpenClaw 插件,集成 腾讯云 COS 向量数据库,实现逐轮动态 Skill 路由。
每次对话时,用户的消息会被向量化,并自动将 top-k 最相关的 skill 注入到 system prompt 中 —— 无需重启会话,下一条消息即时生效。
工作原理
用户消息(每轮触发)
│
▼
Embedding API(兼容 OpenAI 接口)
│ 对消息文本做向量化
▼
COS Vectors(QueryVectors)
│ 返回 top-k 最相似的 skill(按 minScore 过滤)
▼
appendSystemContext ──► LLM- Skill 以向量形式存储在 腾讯云 COS 向量数据库中,通过
cos-vectors-proxyHTTP API 操作。 - 每个 skill 使用任意 兼容 OpenAI 接口的 Embedding API 进行向量化(支持 OpenAI、混元、Azure、本地模型等)。
before_prompt_buildhook 在每次 LLM 调用前触发(而非仅在 session 初始化时),查询 top-k 相关 skill 并注入到可缓存的 system prompt 后缀中。
核心优势:hook 每轮都会触发,因此通过
skill_add/skill_remove添加或删除的 skill,在下一条消息即可生效,无需重开会话或重启 OpenClaw。
前置条件
| 依赖 | 说明 |
|---|---|
| OpenClaw ≥ 3.22 | 使用 plugin-sdk hook API |
| cos-vectors-proxy | 本地或远程运行,提供 PutVectors / QueryVectors / DeleteVectors 接口 |
| 腾讯云账号 | 需要有 COS 向量数据库权限的 SecretId / SecretKey |
| 已存在的向量桶 + 索引 | 不要新建向量桶,绑定已有的桶(如广州区 test-12345678) |
| 兼容 OpenAI 接口的 Embedding API | OpenAI / 混元 / Azure / 本地模型服务均可 |
安装
方式一:通过 npm 安装(推荐)
openclaw plugins install @vintmd/cos-vectorsOpenClaw 会优先从 ClawHub 查找,找不到时自动回退到 npm。安装完成后重启 Gateway 即可。
方式二:本地路径安装(开发 / 自定义)
将本目录放置(或软链接)到 OpenClaw 的 extensions 目录下,然后在 OpenClaw 配置文件中启用:
// openclaw.config.json
{
"plugins": [
{
"id": "vintmd-cos-vectors",
"path": "./extensions/vintmd-cos-vectors"
}
]
}无需执行 npm install —— 插件没有外部依赖,仅使用 Node.js 内置的 crypto 和 fetch。
配置
所有选项可在插件的 config 块中设置,也可通过环境变量配置。配置文件中的值优先级高于环境变量。
配置项说明
| 字段 | 类型 | 默认值 | 环境变量 | 说明 |
|---|---|---|---|---|
| proxyEndpoint | string | http://127.0.0.1:8080 | COSVECTORS_ENDPOINT | cos-vectors-proxy 的访问地址 |
| vectorBucketName | string | openclaw-skills | COSVECTORS_BUCKET | COS 向量桶名称(必须已存在) |
| indexName | string | skills | COSVECTORS_INDEX | 向量桶内的索引名称(必须已存在) |
| secretId | string | — | COSVECTORS_SECRET_ID | 腾讯云 SecretId |
| secretKey | string | — | COSVECTORS_SECRET_KEY | 腾讯云 SecretKey |
| topK | number | 5 | — | 每轮最多注入的 skill 数量 |
| minScore | number | 0.5 | — | 最低相似度阈值(0~1),越低召回越多 |
| embeddingModel | string | text-embedding-3-small | SKILL_ROUTER_EMBEDDING_MODEL | Embedding 模型名称 |
| embeddingBaseUrl | string | https://api.openai.com/v1 | SKILL_ROUTER_EMBEDDING_BASE_URL | Embedding API 的 base URL |
| embeddingApiKey | string | — | SKILL_ROUTER_EMBEDDING_API_KEY / OPENAI_API_KEY | Embedding API 密钥 |
配置示例 — 使用混元 Embedding
{
"plugins": [
{
"id": "vintmd-cos-vectors",
"path": "./extensions/vintmd-cos-vectors",
"config": {
"proxyEndpoint": "http://<cos-vectors-proxy地址>:<端口>",
"vectorBucketName": "your-bucket-name",
"indexName": "skills",
"secretId": "<your-secret-id>",
"secretKey": "<your-secret-key>",
"topK": 5,
"minScore": 0.3,
"embeddingModel": "hunyuan-embedding",
"embeddingBaseUrl": "https://api.hunyuan.cloud.tencent.com/v1",
"embeddingApiKey": "<your-api-key>"
}
}
]
}配置示例 — 环境变量方式
export COSVECTORS_ENDPOINT=http://<cos-vectors-proxy地址>:<端口>
export COSVECTORS_BUCKET=your-bucket-name
export COSVECTORS_INDEX=skills
export COSVECTORS_SECRET_ID=<your-secret-id>
export COSVECTORS_SECRET_KEY=<your-secret-key>
export SKILL_ROUTER_EMBEDDING_BASE_URL=https://api.hunyuan.cloud.tencent.com/v1
export SKILL_ROUTER_EMBEDDING_MODEL=hunyuan-embedding
export OPENAI_API_KEY=<your-api-key> # 作为 embeddingApiKey 的兜底工具(Tools)
插件注册了四个工具,可由 LLM 调用,也可通过 OpenClaw tool API 直接调用:
skill_add
将 skill 向量化后写入 COS Vectors(upsert)。下一条消息即可生效。
{
"name": "python-debugging",
"content": "调试 Python 时,优先查看 traceback 最后一行。交互式调试使用 pdb.set_trace()..."
}skill_remove
按名称删除 skill。下一条消息即可生效。
{ "name": "python-debugging" }skill_list
列出本地内存缓存中的 skill(仅包含当前进程启动后通过 skill_add 添加的条目)。
⚠️ 此工具不会查询 COS Vectors 服务端,只反映当前进程生命周期内的操作记录。如需发现已有 skill,请使用
skill_search。
{}skill_search
按查询文本搜索相关 skill,适合调试路由逻辑。
{
"query": "如何修复 C++ 中的段错误",
"topK": 3
}Skill ID 命名规则
Skill 名称会被规范化为稳定的向量 key,作为 COS Vectors 的文档键:
"Python Debugging" → "skill-python-debugging"
"SQL Optimization" → "skill-sql-optimization"
"deploy-k8s" → "skill-deploy-k8s"注意:skill_add("Python Debugging", ...) 和 skill_add("python-debugging", ...) 会映射到同一个 key,后者会覆盖前者。
相似度分数与调优
COS Vectors 对归一化向量使用内积(IP)距离计算余弦相似度。插件将其转换为 [0, 1] 分数:
score = 1 - distance (截断到 [0, 1])只有 score >= minScore 的 skill 才会被注入。调优参考:
| minScore | 行为 |
|---|---|
| 0.7+ | 高精度,只注入非常相关的 skill |
| 0.5 | 均衡(默认值) |
| 0.3 | 高召回,注入更多 skill,可能包含弱相关内容 |
| 0.0 | 始终注入 top-k,不过滤 |
Embedding 模型的选择同样重要:
- 混元 Embedding(
hunyuan-embedding):1024 维,中英文混合内容效果好 - OpenAI
text-embedding-3-small:1536 维,英文内容效果更佳
动态 Skill 更新(核心特性)
与静态 system prompt 不同,本插件逐轮更新注入的 skill:
第 1 轮:用户问 git 相关 → 注入 git-commit skill
第 2 轮:用户问 SQL 相关 → 注入 sql-optimize skill(git-commit 不注入)
第 3 轮:调用 skill_add("new-skill", ...) → 从第 4 轮起可用
第 4 轮:用户问 new-skill 相关话题 → new-skill 立即被注入这解决了"skill 只在新开会话时才更新"的经典问题。
Token 节省效果
与将所有 skill 全量注入 system prompt 相比:
| 方案 | 注入 skill 数 | 估算 token(10 个 skill) | |---|---|---| | 静态全量注入 | 10 / 10 | ~450 | | 动态 top-k=3 | 3 / 10 | ~165 | | 节省 | — | ~63% |
skill 数量越多,节省效果越显著。
快速开始
- 确保
cos-vectors-proxy已启动并可访问。 - 确认 COS 向量桶和索引已存在(可用
list-indexes.mjs验证)。 - 填写配置文件或设置环境变量。
- 在
openclaw.config.json中启用插件,启动 OpenClaw。 - 让 LLM 添加一个 skill:
"添加一个名为 'git-rebase' 的 skill,内容:合并前始终使用
git rebase -i整理提交记录。" - 在同一个会话中,问任何与 git rebase 相关的问题 —— skill 会自动注入。
验证连通性
在接入 OpenClaw 前,可用内置脚本验证环境:
# 列出向量桶中的所有索引(验证桶和索引是否存在)
node list-indexes.mjs
# 运行完整 E2E 测试:添加 skill、查询、删除、token 对比
node test-real.mjstest-real.mjs 预期输出:
✅ PASS: git-commit skill found in results
✅ PASS: git-commit skill successfully removed
✅ PASS: deploy-k8s skill found
📊 Token reduction: ~63% (saved ~285 tokens)常见问题
Skill 没有出现在回复中
- 检查
minScore是否过高 —— 调低到0.3看是否有 skill 被过滤掉。 - 用
skill_search加上你的查询文本,查看实际返回的分数。 - 确认添加 skill 时使用的 Embedding 模型与当前查询时一致,且向量桶/索引名称匹配。
skill_list 返回空列表
skill_list只显示当前进程通过skill_add添加的 skill,不查询 COS Vectors 服务端。如需发现已有 skill,请用skill_search进行宽泛查询。
COS Vectors 鉴权失败
- 检查
secretId/secretKey是否正确,且具有 COS 向量数据库操作权限。 - 确认
proxyEndpoint从当前机器可以访问。 - 签名使用 HMAC-SHA1,请确保系统时钟准确(误差在 ±5 分钟以内)。
Embedding API 报错
- 使用混元时:base URL 必须为
https://api.hunyuan.cloud.tencent.com/v1,模型名为hunyuan-embedding。 - API key 读取优先级:
config.embeddingApiKey→SKILL_ROUTER_EMBEDDING_API_KEY环境变量 →OPENAI_API_KEY环境变量。
索引维度不匹配
- 同一个索引内所有向量的维度必须一致。切换 Embedding 模型后,需要重建索引或使用新索引。
- 混元 Embedding:1024 维;OpenAI
text-embedding-3-small:1536 维。
