📖 什么是向量数据库?
凌晨4点11分,我在搜索"OpenClaw Skills开发文档"——传统SQL数据库会找"包含所有关键词的书籍",结果因为拼写错误而找不到。但向量数据库不同,它知道"OpenClaw" ≈ "OpenClaw","Skills" ≈ "Skill System"。
向量数据库(Vector Database) 是一种专门存储和搜索"向量"(高维数值数组)的数据库。与传统数据库不同,它不做精确匹配,而是做"近似度搜索"——找最相似的内容。
💡 妙趣比喻: 传统数据库就像一个强迫症图书管理员,你必须给出确切的书名才能找到书。而向量数据库就像一个懂你的朋友,你说"我想看那本关于AI的、有点幽默的、最近比较火的书",他就能给你推荐,虽然他可能不完全理解每个词的意思,但"感觉"对了!这就是向量数据库的魔力——没有关键词,用心去感受。
🧠 核心概念
什么是向量?
"向量"就是一堆数字组成的数组,用来表示某个东西的"语义特征":
# AI模型的"向量世界" "猫" → [0.12, -0.34, 0.56, 0.78, -0.23, ...] (256维向量) "狗" → [0.11, -0.31, 0.52, 0.81, -0.20, ...] (256维向量) "苹果" → [0.45, 0.23, -0.12, 0.67, 0.34, ...] (256维向量) "iPhone" → [0.44, 0.25, -0.10, 0.69, 0.33, ...] (256维向量) # 向量相似度 # 猫 vs 狗 = 0.85 (很相似,因为都是宠物) # 猫 vs 苹果 = 0.12 (不相似) # 苹果 vs iPhone = 0.78 (中等相似,因为都跟水果/品牌有关)
相似度搜索
向量数据库使用三种主要距离计算方法:
📐 余弦相似度
衡量方向是否一致:cos(θ) = 越接近1越相似
适用: 文本语义搜索
📏 欧几里得距离
衡量空间中的绝对距离:越小越相似
适用: 图像搜索、聚类
🎯 点积相似度
正数=相似,负数=相反
适用: OpenAI Embedding模型
📊 主流向量数据库对比
| 产品 | 部署方式 | 性能 | 适用场景 | 价格 |
|---|---|---|---|---|
| Pinecone | 云托管 | ⭐⭐⭐⭐⭐ | 生产环境、大规模 | 付费(有免费档) |
| Chroma | 嵌入式 | ⭐⭐⭐⭐ | 原型开发、小团队 | 免费开源 |
| Weaviate | 自托管/云 | ⭐⭐⭐⭐ | 企业级、混合搜索 | 开源+付费 |
| Qdrant | 自托管/云 | ⭐⭐⭐⭐⭐ | 高性能、Rust编写 | 开源+付费 |
| Milvus | 分布式 | ⭐⭐⭐⭐⭐ | 亿级规模、大数据 | 开源 |
🛠️ OpenClaw 中的向量数据库应用
场景: 智能搜索引擎
# 妙趣AI网站的向量搜索功能
## 数据结构
每个页面存储为向量记录:
{
"id": "url-slug",
"title": "MCP Protocol详解",
"content": "MCP是Model Context Protocol...",
"category": "glossary",
"tags": ["mcp", "protocol", "agent"],
"vector": [0.12, -0.34, ...], # 256维Embedding
"url": "https://miaoquai.com/glossary/mcp-protocol.html"
}
## 搜索流程
用户搜索:"OpenClaw怎么用MCP?"
1. 用户查询向量化
2. 向量数据库相似度搜索
3. 返回Top-5相关结果
4. 结合RAG生成回答
5. 展示搜索卡片(标题+摘要+评分)
使用OpenClaw访问向量数据库
# 通过MCP Server连接Chroma向量数据库
# 配置 chroma MCP Server
{
"mcpServers": {
"chroma": {
"command": "npx",
"args": ["-y", "@mcp-chroma/server"],
"env": {
"CHROMA_URL": "http://localhost:8000"
}
}
}
}
# OpenClaw Agent中使用
# 用户: "帮我找和MCP相关的页面"
# Agent自动调用:
# 1. 搜索向量数据库 → "MCP" embedding 查询
# 2. 获取相关页面列表
# 3. 返回给用户
# 代码示例
async function searchVectorDB(query) {
const embedding = await getEmbedding(query);
const results = await mcpClient.callTool("chroma", "query", {
collection: "miaoquai_pages",
query_embedding: embedding,
n_results: 5
});
return results.map(r => ({
title: r.metadata.title,
url: r.metadata.url,
score: r.distance,
snippet: r.document.substring(0, 200)
}));
}