Milvus向量数据库
之前 RAG 用的是内存向量数据库,实际 AI Agent 产品都用 Milvus 这种专业向量数据库。就像 Web 应用用 MySQL 存数据,AI Agent 应用用 Milvus 存知识和记忆。Milvus 支持向量字段,用余弦相似度做语义检索,这是 MySQL 做不到的。核心流程:Docker 部署 Milvus → 创建 Collection(定义 Schema + 向量索引)→ 插入数据时用嵌入模型向量化 → 检索时 query 向量化做相似度匹配 → 结合 RAG 给大模型当上下文。增删改查都走 SDK,删除不需要向量化。
类比:Web 应用用 MySQL 存数据做增删改查,AI Agent 应用用 Milvus 存知识和记忆做检索增删改。
核心区别:MySQL 只能按 id / 关键词检索,Milvus 支持向量语义检索。
# Docker 部署 Milvus
docker compose -f ./milvus-standalone-docker-compose.yml up -d
- 端口:19530(数据库服务)
- 健康检查:
http://localhost:9091/healthz - GUI 工具:Attu
# 安装依赖
pnpm install @zilliz/milvus2-sdk-node @langchain/openai dotenv
# 创建 Collection(定义 Schema + 索引)
import { MilvusClient, DataType, IndexType, MetricType } from '@zilliz/milvus2-sdk-node';
const client = new MilvusClient({ address: 'localhost:19530' });
// 创建集合,定义 Schema
await client.createCollection({
collection_name: 'ai_diary',
fields: [
{ name: 'id', data_type: DataType.VarChar, max_length: 50, is_primary_key: true },
{ name: 'vector', data_type: DataType.FloatVector, dim: 1024 }, // 向量字段
{ name: 'content', data_type: DataType.VarChar, max_length: 5000 },
{ name: 'date', data_type: DataType.VarChar, max_length: 50 },
{ name: 'mood', data_type: DataType.VarChar, max_length: 50 },
{ name: 'tags', data_type: DataType.Array, element_type: DataType.VarChar, max_capacity: 10, max_length: 50 },
],
});
// 创建向量索引(余弦相似度)
await client.createIndex({
collection_name: 'ai_diary',
field_name: 'vector',
index_type: IndexType.IVF_FLAT,
metric_type: MetricType.COSINE, // 用余弦相似度
params: { nlist: 1024 },
});
// 加载集合到内存
await client.loadCollection({ collection_name: 'ai_diary' });
# 插入数据(需要向量化)
async function getEmbedding(text) {
return await embeddings.embedQuery(text);
}
const diaryData = await Promise.all(
diaryContents.map(async (diary) => ({
...diary,
vector: await getEmbedding(diary.content), // 嵌入模型向量化
}))
);
await client.insert({
collection_name: 'ai_diary',
data: diaryData,
});
# 检索(query 向量化 + 余弦相似度)
const queryVector = await getEmbedding('我想看看关于户外活动的日记');
const searchResult = await client.search({
collection_name: 'ai_diary',
vector: queryVector,
limit: 2,
output_fields: ['id', 'content', 'date', 'mood', 'tags'],
});
// searchResult.results 包含相似度分数和数据
# 结合 RAG 完整流程
// 1. 检索相关日记
const retrievedDiaries = await retrieveRelevantDiaries(question, k);
// 2. 拼成上下文
const context = retrievedDiaries
.map((diary, i) => `[日记 ${i + 1}]\n日期: ${diary.date}\n内容: ${diary.content}`)
.join('\n\n━━━━━\n\n');
// 3. 构建 prompt 调用大模型
const prompt = `基于以下日记内容回答问题:\n${context}\n\n问题: ${question}`;
const response = await model.invoke(prompt);
# 更新数据(upsert,需要重新向量化)
const vector = await getEmbedding(updatedContent.content);
await client.upsert({
collection_name: 'ai_diary',
data: [{ ...updatedContent, vector }], // 带 id 就是更新
});
# 删除数据(不需要向量化)
// 单条删除
await client.delete({
collection_name: 'ai_diary',
filter: 'id == "diary_005"',
});
// 批量删除
await client.delete({
collection_name: 'ai_diary',
filter: 'id in ["diary_002", "diary_003"]',
});
// 条件删除
await client.delete({
collection_name: 'ai_diary',
filter: 'mood == "sad"',
});
# 流程图
AI Agent 应用
↓
Milvus 向量数据库(存知识、记忆)
├── 插入:文本 → 嵌入模型 → 向量化 → 存入
├── 检索:query → 嵌入模型 → 向量化 → 余弦相似度匹配
├── 更新:文本 → 嵌入模型 → 重新向量化 → upsert
└── 删除:直接按 id / 条件删,不需要向量化
# 要点
- Milvus 是 AI Agent 的"数据库" — 就像 MySQL 之于 Web 应用
- 核心区别是向量语义检索 — MySQL 按关键词,Milvus 按语义相似度
- 增删改查四件套 — 插入/更新/检索需要嵌入模型向量化,删除不需要
- Schema 定义 Collection 结构 — 关键是 FloatVector 类型的向量字段
- 索引用余弦相似度 — MetricType.COSINE,和之前 RAG 的原理一致
- RAG 流程 — 检索相关文档 → 拼成上下文 → 调用大模型生成回答
编辑 (opens new window)
上次更新: 2026/06/17, 14:57:34