🚀 从零上手 Milvus 向量数据库:打造一个 AI 智能日记本
本文是一篇沉浸式学习日志,记录了从「向量数据库是什么」到「亲手构建一个基于 RAG 的 AI 日记问答系统」的完整过程。如果你也在学习 Milvus 或者想了解向量数据库如何落地到 AI Agent 中,这篇文章就是为你准备的。
📖 目录
- 为什么需要向量数据库?
- [Milvus 是什么?](#Milvus 是什么? "#2-milvus-%E6%98%AF%E4%BB%80%E4%B9%88")
- [Zilliz Cloud:全托管的 Milvus 云服务](#Zilliz Cloud:全托管的 Milvus 云服务 "#3-zilliz-cloud%E5%85%A8%E6%89%98%E7%AE%A1%E7%9A%84-milvus-%E4%BA%91%E6%9C%8D%E5%8A%A1")
- [项目概览:AI 日记本](#项目概览:AI 日记本 "#4-%E9%A1%B9%E7%9B%AE%E6%A6%82%E8%A7%88ai-%E6%97%A5%E8%AE%B0%E6%9C%AC")
- 环境准备与依赖安装
- [第一步:Hello World --- 4 维向量的增删查](#第一步:Hello World — 4 维向量的增删查 "#6-%E7%AC%AC%E4%B8%80%E6%AD%A5hello-world--4-%E7%BB%B4%E5%90%91%E9%87%8F%E7%9A%84%E5%A2%9E%E5%88%A0%E6%9F%A5")
- 第二步:日记数据建模与向量化入库
- [第三步:语义搜索 --- 用"意思"找日记](#第三步:语义搜索 — 用"意思"找日记 "#8-%E7%AC%AC%E4%B8%89%E6%AD%A5%E8%AF%AD%E4%B9%89%E6%90%9C%E7%B4%A2--%E7%94%A8%E6%84%8F%E6%80%9D%E6%89%BE%E6%97%A5%E8%AE%B0")
- [第四步:RAG 完整链路 --- AI 回答日记问题](#第四步:RAG 完整链路 — AI 回答日记问题 "#9-%E7%AC%AC%E5%9B%9B%E6%AD%A5rag-%E5%AE%8C%E6%95%B4%E9%93%BE%E8%B7%AF--ai-%E5%9B%9E%E7%AD%94%E6%97%A5%E8%AE%B0%E9%97%AE%E9%A2%98")
- 核心概念总结
- 踩坑与心得
1. 为什么需要向量数据库?
1.1 传统数据库的局限
我们日常开发中用的 MySQL、PostgreSQL、SQLite,本质上都是对结构化数据 做 CRUD:
sql
-- 传统查询:精确匹配或模糊匹配
SELECT * FROM diaries WHERE id = 'diary_001';
SELECT * FROM diaries WHERE content LIKE '%散步%';
这种查询方式有两个致命问题:
| 问题 | 说明 |
|---|---|
| 只能精确/模糊匹配 | 搜"散步"找不到"在公园走了走",但它们是同一个意思 |
| 无法理解语义 | 搜"开心的经历",数据库完全不理解什么叫"开心" |
1.2 向量数据库解决什么?
向量数据库的核心思路是:
文本 → Embedding 模型 → 向量(一串数字)→ 存入向量数据库
查询时:
查询文本 → Embedding 模型 → 查询向量 → 向量相似度搜索 → 返回最相关的数据
举个直观的例子:
js
// 传统数据库:关键词匹配
"今天去公园散步了" ←→ "散步" ✅ 能匹配
"今天在公园走了走" ←→ "散步" ❌ 匹配不到,但意思一样!
// 向量数据库:语义匹配
"今天去公园散步了" → [0.12, -0.34, 0.56, ...] (1024维向量)
"今天在公园走了走" → [0.11, -0.32, 0.55, ...] (向量非常接近!)
// 距离 ≈ 0.02 → 高度相似 ✅
🧠 本质区别 :传统数据库用
=或LIKE做关键词匹配,向量数据库用余弦相似度(Cosine Similarity)做语义匹配。
2. Milvus 是什么?
Milvus 是当今最流行的开源向量数据库,专为处理海量高维向量数据而设计。
2.1 核心概念对照表
把 Milvus 和 MySQL 做一个类比,可以帮助你快速理解:
| 概念 | MySQL | Milvus |
|---|---|---|
| 数据库 | Database | Database |
| 表 | Table | Collection(集合) |
| 行 | Row | Entity(实体) |
| 列 | Column | Field(字段) |
| 主键 | Primary Key | Primary Key(支持自动生成) |
| 索引 | B+Tree / Hash | IVF_FLAT / HNSW / AUTOINDEX |
| 查询方式 | SELECT ... WHERE ... |
向量相似度搜索(vector search) |
| 相似度 | 无 | COSINE / IP(内积) / L2(欧氏距离) |
2.2 Milvus 的架构
Milvus 采用 C/S 架构(客户端/服务端),和我们熟悉的 MySQL 一样:
scss
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Node.js SDK │ ──→ │ Milvus 服务 │ ──→ │ 底层存储 │
│ (客户端) │ ←── │ (核心引擎) │ ←── │ (MinIO等) │
└──────────────┘ └──────────────┘ └──────────────┘
2.3 Milvus 中的索引类型
向量数据库动辄存几百万条高维向量。如果没有索引,每次查询都要遍历全部向量逐一计算相似度(时间复杂度 O(n)),数据量一大就完全没法用。
📚 类比:在图书馆找《三体》,没有索引就要每一本都翻。有索引就能直接定位到"文学馆 → 小说 → 科幻"。
Milvus 支持的常用索引:
| 索引类型 | 原理 | 适用场景 |
|---|---|---|
| IVF_FLAT | 聚簇索引:先用 K-Means 将向量分成多个簇,查询时只搜最近的几个簇 | 百万级数据,毫秒级响应 |
| HNSW | 图索引:构建多层可导航小世界图 | 高精度场景,内存占用较大 |
| AUTOINDEX | Milvus 自动选择最优索引策略 | 不想手动调参的首选 |
3. Zilliz Cloud:全托管的 Milvus 云服务
自己搭建 Milvus 服务需要配置存储、计算节点、负载均衡......门槛不低。
Zilliz Cloud 是基于 Milvus 的全托管云服务(类比:MySQL 和阿里云 RDS 的关系),由 Milvus 的原创团队打造。
本项目中我们使用的就是 Zilliz Cloud 的 Serverless 版本:
env
# .env 中的 Zilliz Cloud 配置
MILVUS_ADDRESS=in03-xxxxx.serverless.ali-cn-hangzhou.cloud.zilliz.com.cn:443
MILVUS_TOKEN=your-token-here
💡 Serverless 意味着你不用关心服务的运维、扩缩容,按用量付费,非常适合学习和原型开发。
4. 项目概览:AI 日记本
4.1 产品设计
一个AI 日记本,具备两种能力:
| 能力 | 实现方式 | 举例 |
|---|---|---|
| 结构化 CRUD | 传统数据库(MySQL等) | 按日期查日记、修改某篇日记的标题 |
| 语义理解 | Milvus 向量数据库 + LLM | "我最近做过什么让我快乐的事?" |
4.2 技术栈
scss
┌──────────────────────────────────────────────────┐
│ 技术架构 │
├──────────────┬───────────────────────────────────┤
│ LLM 模型 │ 通义千问 qwen-plus (阿里云百炼) │
│ Embedding │ text-embedding-v3 (1024维) │
│ 向量数据库 │ Milvus (Zilliz Cloud Serverless) │
│ Node.js SDK │ @zilliz/milvus2-sdk-node v3.x │
│ LLM 框架 │ @langchain/openai │
│ API 代理 │ DashScope OpenAI 兼容接口 │
└──────────────┴───────────────────────────────────┘
4.3 数据模型
每篇日记的结构:
js
{
id: 'diary_001', // 主键,VARCHAR(50)
vector: [1024个浮点数], // 内容向量,FloatVector(1024)
content: '今天天气很好...', // 日记正文,VARCHAR(5000)
date: '2026-01-10', // 日期,VARCHAR(50)
mood: 'happy', // 心情标签,VARCHAR(50)
tags: ['生活', '散步'], // 标签数组,Array(VARCHAR)
}
4.4 文件结构
bash
milvus-demo/
├── readme.md # 项目说明
└── demo/
├── .env # 环境变量(API Key、Milvus地址等)
├── package.json # 项目依赖
└── src/
├── main.mjs # 入门:4维向量 Hello World
├── index.mjs # 日记数据建模 + 向量化入库
├── query.mjs # 日记语义搜索
└── rag.mjs # 完整 RAG:AI 问答日记
5. 环境准备与依赖安装
5.1 依赖包
json
{
"dependencies": {
"@langchain/openai": "^1.5.5",
"@zilliz/milvus2-sdk-node": "^3.0.3",
"dotenv": "^17.4.2"
}
}
三个包的分工:
| 包 | 作用 |
|---|---|
@zilliz/milvus2-sdk-node |
Milvus 的 Node.js 客户端 SDK |
@langchain/openai |
封装了 OpenAI 兼容的 Embedding 和 Chat 接口 |
dotenv |
从 .env 文件加载环境变量 |
5.2 环境变量配置
env
# ========== LLM 配置 ==========
MODEL_NAME=qwen-plus # 对话模型
EMBEDDINGS_MODEL_NAME=text-embedding-v3 # 向量化模型
OPENAI_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1 # API地址
OPENAI_API_KEY=sk-xxxx # API Key
# ========== Milvus 配置 ==========
MILVUS_ADDRESS=in03-xxxx.serverless.ali-cn-hangzhou.cloud.zilliz.com.cn:443
MILVUS_TOKEN=your-milvus-token-here
⚠️ 关键设计 :阿里云百炼(DashScope)提供了 OpenAI 兼容的 API 接口,所以我们可以直接用
@langchain/openai来调用通义千问的模型,只需修改baseURL即可。
5.3 初始化客户端
js
import { MilvusClient, MetricType, IndexType, DataType } from '@zilliz/milvus2-sdk-node';
import { OpenAIEmbeddings } from '@langchain/openai';
import 'dotenv/config';
// Embedding 模型:把文字变成1024维向量
const embeddings = new OpenAIEmbeddings({
apiKey: process.env.OPENAI_API_KEY,
model: process.env.EMBEDDINGS_MODEL_NAME,
configuration: {
baseURL: process.env.OPENAI_BASE_URL,
},
dimensions: 1024,
});
// Milvus 客户端:连接 Zilliz Cloud
const client = new MilvusClient({
address: process.env.MILVUS_ADDRESS,
token: process.env.MILVUS_TOKEN,
ssl: true, // 云服务必须用 SSL
});
6. 第一步:Hello World --- 4 维向量的增删查
文件:main.mjs
6.1 整体流程
连接 Milvus → 创建 Collection → 创建索引 → 插入向量 → 相似度搜索
6.2 连接检验
js
const checkHealth = await client.checkHealth();
if (!checkHealth.isHealthy) {
console.error('连接失败', checkHealth.reasons);
return;
}
console.log('连接成功,集群状态正常。');
这一步就像 mysql -h xxx -u xxx -p 之后的 SELECT 1; ------ 确认连接通畅。
6.3 创建 Collection(类比建表)
js
await client.createCollection({
collection_name: 'test',
dimension: 4, // 4维向量(Hello World 用简单维度)
auto_id: true, // 主键自动生成
});
这里的简单模式只需要指定维度。当我们需要更复杂的字段结构时(如日记应用),就需要自定义 Schema(后面会讲到)。
6.4 创建索引
js
await client.createIndex({
collection_name: 'test',
field_name: 'vector', // 对哪个字段建索引
index_type: IndexType.AUTOINDEX, // 自动选择索引类型
metric_type: MetricType.COSINE, // 用余弦相似度
});
三种相似度度量方式:
| 度量方式 | 公式思路 | 适用场景 |
|---|---|---|
| COSINE | 两个向量的夹角余弦值,值域 -1, 1,越大越相似 | 文本语义相似度(最常用) |
| IP (内积) | 向量点积,越大越相似 | 需要同时考虑向量长度和方向 |
| L2 (欧氏距离) | 空间直线距离,越小越相似 | 图像特征、位置坐标 |
6.5 插入数据
js
const data = [
{ vector: [0.1, 0.2, 0.3, 0.4], content: '这是第一条数据' },
{ vector: [0.5, 0.6, 0.7, 0.8], content: '这是第二条数据' },
];
await client.insert({ collection_name: 'test', data });
🎉 亮点:Milvus SDK 直接传入 JSON 对象数组即可,不需要写 SQL!
6.6 相似度搜索
js
const searchRes = await client.search({
collection_name: 'test',
data: [[0.5, 0.5, 0.6, 0.8]], // 查询向量
limit: 2, // 返回 top 2
output_fields: ['content'], // 返回的字段
});
console.log(JSON.stringify(searchRes.results, null, 2));
这就是向量数据库的核心价值 :你不需要 WHERE content LIKE '%xxx%',只需要给一个向量,它就能返回最相似的数据。
7. 第二步:日记数据建模与向量化入库
文件:index.mjs
这是从"玩具 Demo"到"真实应用"的关键一步。
7.1 自定义 Schema(多字段)
真实场景中,一条日记除了向量,还需要日期、心情、标签等结构化字段。我们使用自定义 Schema:
js
await client.createCollection({
collection_name: 'ai_dairy',
fields: [
{
name: 'id',
data_type: DataType.VarChar,
max_length: 50,
is_primary_key: true, // 主键
},
{
name: 'vector',
data_type: DataType.FloatVector,
dim: 1024, // 1024维向量
},
{
name: 'content',
data_type: DataType.VarChar,
max_length: 5000, // 日记正文最长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, // 最多10个标签
max_length: 50,
},
],
});
Milvus 支持的数据类型:
| 类型 | 说明 | 示例 |
|---|---|---|
VarChar |
字符串 | 'happy' |
Int64 |
64位整数 | 42 |
FloatVector |
浮点向量 | [0.1, 0.2, ...] |
Array |
数组 | ['生活', '散步'] |
JSON |
JSON 对象 | { key: 'value' } |
7.2 创建索引(必须指定字段名)
js
await client.createIndex({
collection_name: 'ai_dairy',
field_name: 'vector', // 明确指定对 vector 字段建索引
index_type: IndexType.IVF_FLAT, // 聚簇索引
metric_type: MetricType.COSINE, // 余弦相似度
});
7.3 加载 Collection 到内存
js
await client.loadCollection({
collection_name: 'ai_dairy',
});
⚠️ 重要 :在 Milvus 中,Collection 创建后默认是未加载状态。必须调用
loadCollection将其加载到内存,才能执行搜索操作。这类似于 MySQL 中把数据页加载到 Buffer Pool。
7.4 准备日记数据 + 向量化
js
const diaryContents = [
{
id: 'diary_001',
content: '今天天气很好,去公园散步了,心情愉快。看到了很多花开了,春天真美好。',
date: '2026-01-10',
mood: 'happy',
tags: ['生活', '散步'],
},
{
id: 'diary_002',
content: '今天工作很忙,完成了一个重要的项目里程碑。团队合作很愉快,感觉很有成就感。',
date: '2026-01-11',
mood: 'excited',
tags: ['工作', '成就'],
},
// ... 共5篇示例日记
];
7.5 核心逻辑:把文字变成向量再写入
js
// 为每篇日记生成向量
const diaryData = await Promise.all(
diaryContents.map(async (diary) => ({
...diary,
vector: await getEmbeddings(diary.content), // 🔥 核心步骤
}))
);
// 批量写入 Milvus
const insertResult = await client.insert({
collection_name: 'ai_dairy',
data: diaryData,
});
console.log(insertResult.insert_cnt, '条数据插入成功');
数据流:
bash
"今天天气很好,去公园散步了..."
→ text-embedding-v3 模型
→ [0.023, -0.145, 0.387, ..., 0.052] (1024个浮点数)
→ 和 id、date、mood、tags 一起写入 Milvus
8. 第三步:语义搜索 --- 用"意思"找日记
文件:query.mjs
8.1 语义搜索 vs 关键词搜索
假设用户想找"户外活动的日记":
js
const query = '我想看看关于户外活动的日记';
// 关键词搜索 ------ 找不到!
// 因为日记里写的是"去公园散步""去爬山",没有"户外活动"这四个字
// 语义搜索 ------ 找到了!
const queryVector = await getEmbeddings(query); // 先向量化查询
const searchResult = await client.search({
collection_name: 'ai_dairy',
vector: queryVector, // 用向量去搜
limit: 2, // 返回最相似的2条
metric_type: MetricType.COSINE,
output_fields: ['id', 'content', 'date', 'mood', 'tags'],
});
8.2 搜索结果解析
js
searchResult.results.forEach((item, index) => {
console.log(`${index + 1}. [Score: ${item.score.toFixed(4)}]`);
console.log(`
ID: ${item.id}
Date: ${item.date}
Mood: ${item.mood}
Tags: ${item.tags?.join(', ')}
Content: ${item.content}
`);
});
输出的关键信息是 score(相似度分数):
| 分值范围 | 说明 |
|---|---|
0.8 ~ 1.0 |
高度相关 |
0.6 ~ 0.8 |
比较相关 |
0.4 ~ 0.6 |
有一定关联 |
0.0 ~ 0.4 |
基本无关 |
🔍 查询"户外活动"会匹配到"去公园散步"和"去爬山",尽管字面上没有"户外活动"这个词。这就是向量数据库的魅力!
9. 第四步:RAG 完整链路 --- AI 回答日记问题
文件:rag.mjs
9.1 什么是 RAG?
RAG(Retrieval-Augmented Generation) 是 AI Agent 最核心的模式之一:
arduino
┌─────────────────────────────────────────────────┐
│ RAG 流程 │
│ │
│ 用户问题:"我最近做了什么快乐的事?" │
│ │ │
│ ▼ │
│ ┌─────────┐ ┌──────────┐ ┌─────────────┐ │
│ │ Retrieve │ → │ Augment │ → │ Generate │ │
│ │ 检索 │ │ 增强 │ │ 生成 │ │
│ └─────────┘ └──────────┘ └─────────────┘ │
│ │ │ │ │
│ 向量化查询 把检索结果 LLM 阅读上下文 │
│ 相似度搜索 拼入 Prompt 生成人性化回答 │
│ 找出相关日记 作为上下文 │
│ │
└─────────────────────────────────────────────────┘
9.2 初始化 Chat 模型
js
import { ChatOpenAI } from '@langchain/openai';
const model = new ChatOpenAI({
temperature: 0.1, // 低温度 = 更稳定、更依赖事实
apiKey: process.env.OPENAI_API_KEY,
model: process.env.MODEL_NAME, // qwen-plus
configuration: {
baseURL: process.env.OPENAI_BASE_URL,
},
});
9.3 检索模块 (Retrieve)
js
async function retrieveRelatedDiaries(question, k = 2) {
const queryVector = await getEmbeddings(question); // 问题向量化
const searchResult = await client.search({
collection_name: 'ai_dairy',
vector: queryVector,
limit: k,
metric_type: MetricType.COSINE,
output_fields: ['id', 'date', 'mood', 'tags', 'content'],
});
return searchResult.results;
}
9.4 增强 + 生成模块 (Augment + Generate)
这是整个应用的核心------Prompt Engineering:
js
const content = retrievedDiaries.map((diary, i) => `
[日记${i + 1}]
日期:${diary.date}
心情:${diary.mood}
标签:${diary.tags?.join(',')}
内容:${diary.content}
`).join('\n\n------\n\n');
const prompt = `你是一个温暖贴心的AI日记助手。基于用户的日记内容回答问题,用亲切自然的语言。
请根据以下内容回答问题:
${content}
用户问题:${question}
回答要求:
1. 如果日记中有相关信息,请结合日记内容给出详细、温暖的回答
2. 可以总结多篇日记的内容,找出共同点或趋势
3. 如果日记中没有相关信息,请温和告知用户
4. 用第一人称"你"来称呼日记的作者
5. 回答要有同理心,让用户感到被理解和关心
AI 助手的回答:`;
9.5 组装完整流程
js
async function answerDiaryQuestion(question, k = 2) {
// Step 1: Retrieve --- 检索相关日记
const retrievedDiaries = await retrieveRelatedDiaries(question, k);
// Step 2: Augment --- 将检索结果拼入 Prompt
// Step 3: Generate --- 让 LLM 生成回答
const response = await model.invoke(prompt);
console.log(response.content);
}
// 入口
await answerDiaryQuestion('我最近做了什么让我感到快乐的事情?', 2);
9.6 执行效果
当用户问 "我最近做了什么让我感到快乐的事情?" 时,系统会:
-
向量化查询 → 变成 1024 维向量
-
在 Milvus 中搜索 → 找到 score 最高的 2 篇日记(比如"去公园散步"和"爬山")
-
拼入上下文 → 把这两篇日记的完整信息放入 Prompt
-
LLM 生成回答 → 类似这样:
根据你的日记记录,你最近有两件让你感到快乐的事情:
🌳 第一件是1月10日,你去公园散步了,看到了盛开的花朵,
感受到了春天的美好。大自然真的能让人心情愉悦呢!⛰️ 第二件是1月12日,你和朋友一起去爬山了,享受户外的
放松时光。和朋友一起度过的时光总是特别珍贵。看起来户外活动是让你感到快乐的重要来源,记得多出去走走哦~
10. 核心概念总结
10.1 一张图理解整个流程
scss
┌──────────────┐
│ 用户输入 │
└──────┬───────┘
│
┌────────────┴────────────┐
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Embedding 模型│ │ LLM 模型 │
│ (向量化) │ │ (qwen-plus) │
└──────┬───────┘ └──────▲───────┘
│ │
▼ │
┌──────────────┐ ┌───────┴──────┐
│ Milvus 向量库 │ ──────→ │ Prompt 组装 │
│ (语义搜索) │ 检索结果 │ (上下文增强) │
└──────────────┘ └──────────────┘
10.2 关键概念速查表
| 概念 | 一句话解释 |
|---|---|
| Embedding | 把文本变成一串数字(向量),语义相近的文本向量也相近 |
| Collection | Milvus 中的"表",存储一组实体 |
| Field | Collection 中的"列",定义数据类型和约束 |
| Vector Field | 特殊的浮点向量字段,用于相似度搜索 |
| Index | 加速向量搜索的数据结构(类比数据库索引) |
| Metric Type | 相似度的计算方法:COSINE / IP / L2 |
| RAG | 检索增强生成:先检索相关内容,再让 LLM 基于事实回答 |
| loadCollection | 将 Collection 加载到内存,搜索前必须执行 |
11. 踩坑与心得
11.1 踩过的坑
① 连接后必须 loadCollection
创建 Collection 和索引后,一定要调用
loadCollection才能搜索。忘记这步会直接报错。
② Collection 创建后不能重复创建
createCollection如果 Collection 已存在会报错。建议用 try-catch 包裹,或先hasCollection检查。
③ .env 中的 API Key 注意安全
不要把 API Key 提交到 Git!可以在
.gitignore中加上.env。
④ Milvus 客户端的 ssl: true
连接 Zilliz Cloud 时必须设置
ssl: true,本地部署的 Milvus 则不需要。
⑤ package.json 中 "type": "commonjs" 与 .mjs 文件的配合
项目中
.mjs扩展名明确表示 ES Module,而package.json中"type": "commonjs"确保其他.js文件使用 CommonJS。这是一种混合模块策略。
11.2 学习心得
-
向量数据库不是银弹 :它擅长语义搜索,但不适合精确匹配。实际项目中往往是 MySQL + Milvus 双数据库架构------结构化查询走 MySQL,语义搜索走 Milvus。
-
Embedding 质量决定一切 :如果向量化模型不够好,后续的搜索和 RAG 效果都会大打折扣。本项目中用的
text-embedding-v3(1024维)是一个不错的选择。 -
RAG 本质是"给 LLM 提供参考答案":与其让 LLM 凭空编造,不如先把相关资料找出来,让它基于事实回答。这就是 AI Agent 知识库的核心原理。
-
从 4 维到 1024 维的跨越 :
main.mjs用 4 维向量入门,index.mjs用 1024 维向量做真实应用。这个过渡设计得很巧妙------先理解原理(低维度可以可视化理解),再投入实战。
🎯 写在最后
这个项目从 0 到 1 地走通了:
- ✅ Milvus 向量数据库的基本操作(CRUD)
- ✅ 日记数据的 Schema 设计与向量化入库
- ✅ 语义搜索替代传统关键词搜索
- ✅ 完整的 RAG 链路(检索 → 增强 → 生成)
对于 AI Agent 开发者来说,向量数据库是必修课。不管是做知识库问答、长期记忆、还是智能搜索,都离不开它。