从零实战Milvus向量数据库:用RAG打造你的AI日记助手

从零实战Milvus向量数据库:用RAG打造你的AI日记助手

本文将带你从零开始,基于 Milvus 向量数据库 + OpenAI Embedding + LangChain ,通过 RAG(检索增强生成) 技术,构建一个能理解你心情、回忆你过往的 AI 日记助手。全文包含完整可运行的代码,建议收藏后跟着敲一遍。


一、前言:为什么传统数据库"不懂"你的日记?

想象一下这个场景:你写了一年的日记,某天突然想问:"我最近做了什么让我感到快乐的事情?"

如果用传统的关系型数据库(如 MySQL),你只能依赖关键词匹配:

sql 复制代码
SELECT * FROM diaries WHERE content LIKE '%快乐%' OR content LIKE '%开心%';

但问题是------你写日记时可能根本没用过"快乐"这个词,而是写了"今天天气很好,去公园散步了,心情愉快"。关键词匹配找不到这条记录,但语义上它完全相关。

这就是向量数据库 要解决的问题:让数据库理解语义,而不是只匹配字符。


二、核心概念:向量数据库与 Embedding

2.1 什么是向量数据库?

向量数据库(Vector Database)是一种专门用于存储和检索高维向量 的数据库。与传统数据库通过 ID 或关键词查询不同,向量数据库通过语义相似度来检索数据。

特性 传统数据库(MySQL) 向量数据库(Milvus)
存储内容 结构化数据(文本、数字) 高维向量(Embedding)
查询方式 精确匹配(=、LIKE) 相似度搜索(ANN)
查询语义 "包含哪些字" "意思有多接近"
典型应用 订单查询、用户管理 语义搜索、推荐系统、RAG

2.2 Embedding:把文字变成"坐标"

Embedding 是将文本、图片、音频等非结构化数据转换为高维数值向量的过程。语义相近的内容,在向量空间中的距离也更近。

scss 复制代码
"今天天气很好"  →  [0.12, -0.34, 0.56, ..., 0.89]  (1024维)
"今天阳光明媚"  →  [0.15, -0.31, 0.59, ..., 0.85]  (1024维)
"向量数据库教程" →  [-0.78, 0.45, -0.12, ..., 0.33] (1024维)

在 1024 维的空间里,前两个句子的向量距离很近,第三个则很远------这就是语义理解的基础。

2.3 RAG:检索增强生成

RAG(Retrieval-Augmented Generation)是一种将信息检索大语言模型生成结合的技术框架:

复制代码
用户提问 → 向量化查询 → 向量库检索相关内容 → 将检索结果注入 Prompt → LLM 生成回答

RAG 的优势:

  • 让大模型基于你的私有数据回答,而非仅依赖训练知识
  • 减少"幻觉",回答可追溯、可验证
  • 数据更新无需重新训练模型

三、Milvus:专为 AI 而生的向量数据库

3.1 为什么选择 Milvus?

Milvus 是一款开源的向量数据库,专为处理海量高维向量数据而设计。AI Agent、RAG 系统几乎都在用类似 Milvus 的 Vector Store。

核心能力 说明
海量向量存储 支持十亿级向量数据的存储与检索
近似最近邻搜索(ANN) 毫秒级响应,平衡精度与速度
多种索引类型 IVF_FLAT、HNSW、AUTOINDEX 等
多种相似度度量 COSINE(余弦相似度)、L2(欧氏距离)、IP(内积)
云原生架构 支持分布式部署,弹性扩缩容

3.2 Zilliz Cloud:零运维的托管服务

对于学习和中小项目,Zilliz Cloud 提供了基于 Milvus 的全托管服务:

  • 无需自己部署和维护 Milvus 集群
  • 提供免费的 Starter 套餐(适合学习)
  • 通过 @zilliz/milvus2-sdk-node 即可连接

四、实战:从零搭建 AI 日记助手

4.1 项目结构

bash 复制代码
ai-diary-rag/
├── .env              # 环境变量配置
├── package.json
├── main.mjs          # Milvus 基础操作
├── index.mjs         # 创建集合 + 插入日记数据
├── query.mjs         # 语义搜索查询
└── rag.mjs           # 完整 RAG 实现

4.2 环境准备

安装依赖:

bash 复制代码
npm init -y
npm install @zilliz/milvus2-sdk-node @langchain/openai dotenv

.env 配置文件:

env 复制代码
# Zilliz Cloud 连接信息
MILVUS_ADDRESS=https://your-cluster-url.zillizcloud.com
MILVUS_TOKEN=your_api_key

# OpenAI 配置
OPENAI_API_KEY=your_openai_api_key
OPENAI_BASE_URL=https://api.openai.com/v1
EMBEDDINGS_MODEL_NAME=text-embedding-3-large
MODEL_NAME=gpt-4o-mini

4.3 第一步:连接 Milvus 与基础操作

main.mjs 演示了 Milvus 的核心操作流程:连接 → 创建集合 → 建索引 → 插入数据 → 向量搜索

javascript 复制代码
import {
  MilvusClient,
  IndexType,    // 索引类型
  MetricType    // 相似度度量方式
} from '@zilliz/milvus2-sdk-node';
import 'dotenv/config';

const ADDRESS = process.env.MILVUS_ADDRESS;
const TOKEN = process.env.MILVUS_TOKEN;

async function main() {
  const client = new MilvusClient({
    address: ADDRESS,
    token: TOKEN
  });

  console.log('正在连接 Zilliz Cloud...');
  const checkHealth = await client.checkHealth();
  if (!checkHealth.isHealthy) {
    console.error('连接失败', checkHealth.reasons);
    return;
  }
  console.log('连接成功,集群状态正常。');

  const COLLECTION_NAME = 'test';
  const DIMENSION = 4;

  try {
    // 1. 创建集合(类似 MySQL 的表)
    // await client.createCollection({
    //   collection_name: COLLECTION_NAME,
    //   dimension: DIMENSION,
    //   auto_id: true
    // });
    // console.log('集合创建成功');

    // 2. 创建索引------向量搜索的"加速器"
    // await client.createIndex({
    //   collection_name: COLLECTION_NAME,
    //   field_name: 'vector',
    //   index_type: IndexType.AUTOINDEX,
    //   metric_type: MetricType.COSINE
    // });
    // console.log('索引创建成功');

    // 3. 插入数据
    // const data = [
    //   { vector: [0.1, 0.2, 0.3, 0.4], content: '这是第一条数据' },
    //   { vector: [0.5, 0.6, 0.7, 0.8], content: '这是第二条数据' }
    // ];
    // const insertRes = await client.insert({
    //   collection_name: COLLECTION_NAME,
    //   data
    // });
    // console.log('插入成功', insertRes.IDs);

    // 4. 向量搜索------找语义最相近的数据
    const searchRes = await client.search({
      collection_name: COLLECTION_NAME,
      data: [[0.5, 0.5, 0.6, 0.8]],  // 查询向量
      limit: 2,                        // 返回前2个最相似的结果
      output_fields: ['content']       // 返回的字段
    });
    console.log(JSON.stringify(searchRes.results, null, 2));

  } catch (err) {
    console.log('操作出错', err.message);
  }
}

main().catch(console.error);

关键概念解析:

概念 作用 类比
Collection(集合) 存储向量和字段的容器 MySQL 的 Table
Vector(向量) 文本/图片的数值化表示 数据的"指纹"
Index(索引) 加速向量检索的数据结构 书籍的目录
MetricType 计算向量间相似度的方法 衡量"有多像"的标尺

为什么必须建索引?

没有索引时,每次查询都要把库里所有向量和查询向量逐一计算相似度(O(n)),数据量大了慢得没法用。索引就像图书馆的分类系统,能迅速缩小查询范围,将搜索复杂度降到 O(log n) 甚至更低。

4.4 第二步:设计 Schema 与插入日记数据

在实际项目中,我们不能只存向量,还需要存储原始内容、日期、心情、标签等元数据。index.mjs 展示了如何定义完整的 Schema:

javascript 复制代码
import 'dotenv/config';
import {
  MilvusClient,
  MetricType,
  IndexType,
  DataType        // 字段数据类型约束
} from '@zilliz/milvus2-sdk-node';
import { OpenAIEmbeddings } from '@langchain/openai';

const ADDRESS = process.env.MILVUS_ADDRESS;
const TOKEN = process.env.MILVUS_TOKEN;
const COLLECTION_NAME = 'ai_diary';    // 集合名称
const VECTOR_DIM = 1024;               // 向量维度(text-embedding-3-large 支持)

// 初始化 Embedding 模型
const embeddings = new OpenAIEmbeddings({
  apiKey: process.env.OPENAI_API_KEY,
  model: process.env.EMBEDDINGS_MODEL_NAME,
  configuration: {
    baseURL: process.env.OPENAI_BASE_URL
  },
  dimensions: VECTOR_DIM
});

const client = new MilvusClient({
  address: ADDRESS,
  token: TOKEN
});

// 将文本转换为向量
const getEmbedding = async (text) => {
  const result = await embeddings.embedQuery(text);
  return result;
};

async function main() {
  console.log('正在连接 Zilliz Cloud...');
  const checkHealth = await client.checkHealth();
  if (!checkHealth.isHealthy) {
    console.error('连接失败', checkHealth.reasons);
    return;
  }
  console.log('连接成功,集群状态正常。');

  // ===== 1. 创建集合(带完整 Schema)=====
  // await client.createCollection({
  //   collection_name: COLLECTION_NAME,
  //   fields: [
  //     {
  //       name: 'id',
  //       data_type: DataType.VarChar,
  //       max_length: 50,
  //       is_primary_key: true
  //     },
  //     {
  //       name: 'vector',
  //       data_type: DataType.FloatVector,
  //       dim: VECTOR_DIM
  //     },
  //     {
  //       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
  //     }
  //   ]
  // });

  // ===== 2. 创建索引 =====
  // await client.createIndex({
  //   collection_name: COLLECTION_NAME,
  //   field_name: 'vector',
  //   index_type: IndexType.IVF_FLAT,    // 聚簇索引,毫秒级响应
  //   metric_type: MetricType.COSINE     // 余弦相似度
  // });

  // ===== 3. 加载集合到内存 =====
  console.log('Loading collection...');
  await client.loadCollection({ collection_name: COLLECTION_NAME });
  console.log('Collection loaded');

  // ===== 4. 准备日记数据 =====
  const diaryContents = [
    {
      id: 'diary_001',
      content: '今天天气很好,去公园散步了,心情愉快。看到了很多花开了,春天真美好。',
      date: '2026-01-10',
      mood: 'happy',
      tags: ['生活', '散步']
    },
    {
      id: 'diary_002',
      content: '今天工作很忙,完成了一个重要的项目里程碑。团队合作很愉快,感觉很有成就感。',
      date: '2026-01-11',
      mood: 'excited',
      tags: ['工作', '成就']
    },
    {
      id: 'diary_003',
      content: '周末和朋友去爬山,天气很好,心情也很放松。享受大自然的感觉真好。',
      date: '2026-01-12',
      mood: 'relaxed',
      tags: ['户外', '朋友']
    },
    {
      id: 'diary_004',
      content: '今天学习了 Milvus 向量数据库,感觉很有意思。向量搜索技术真的很强大。',
      date: '2026-01-12',
      mood: 'curious',
      tags: ['学习', '技术']
    },
    {
      id: 'diary_005',
      content: '晚上做了一顿丰盛的晚餐,尝试了新菜谱。家人都说很好吃,很有成就感。',
      date: '2026-01-13',
      mood: 'proud',
      tags: ['美食', '家庭']
    }
  ];

  // ===== 5. 生成 Embedding 并插入 =====
  console.log('Generating embeddings...');
  const diaryData = await Promise.all(
    diaryContents.map(async (diary) => ({
      ...diary,
      vector: await getEmbedding(diary.content)   // 将日记内容转为向量
    }))
  );

  const insertResult = await client.insert({
    collection_name: COLLECTION_NAME,
    data: diaryData
  });
  console.log(`${insertResult.insert_cnt} 条记录成功插入。`);
}

main().catch(console.error);

Schema 设计要点:

字段 类型 作用
id VarChar (主键) 唯一标识每条日记
vector FloatVector 内容的 Embedding 向量,用于语义搜索
content VarChar 日记原始文本
date VarChar 日期
mood VarChar 心情标签
tags Array 分类标签数组

4.5 第三步:语义搜索------用自然语言找日记

有了向量化数据,我们就可以用自然语言查询,让数据库"理解"我们的意图。query.mjs 演示了语义搜索:

javascript 复制代码
import 'dotenv/config';
import {
  MilvusClient,
  MetricType
} from '@zilliz/milvus2-sdk-node';
import { OpenAIEmbeddings } from '@langchain/openai';

const ADDRESS = process.env.MILVUS_ADDRESS;
const TOKEN = process.env.MILVUS_TOKEN;
const COLLECTION_NAME = 'ai_diary';
const VECTOR_DIM = 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: VECTOR_DIM
});

const client = new MilvusClient({ address: ADDRESS, token: TOKEN });

const getEmbedding = async (text) => {
  const result = await embeddings.embedQuery(text);
  return result;
};

async function main() {
  try {
    console.log('Connecting to Milvus...');
    await client.connectPromise;
    console.log('Connected');

    const query = '我想看看关于户外活动的日记';
    console.log(`QUERY: ${query}`);

    // 1. 将查询语句转为向量
    const queryVector = await getEmbedding(query);

    // 2. 在向量空间中搜索最相近的日记
    const searchResult = await client.search({
      collection_name: COLLECTION_NAME,
      vector: queryVector,              // 查询向量
      limit: 2,                         // 返回最相似的2条
      metric_type: MetricType.COSINE,   // 使用余弦相似度
      output_fields: ['id', 'content', 'date', 'mood', 'tags']
    });

    console.log(`Found ${searchResult.results.length} results`);
    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}
      `);
    });
  } catch (err) {
    console.error('Search error:', err.message);
  }
}

main().catch(console.error);

运行结果示例:

yaml 复制代码
QUERY: 我想看看关于户外活动的日记
Found 2 results
1. [Score: 0.8234]
      ID: diary_003
      Date: 2026-01-12
      Mood: relaxed
      Tags: 户外, 朋友
      Content: 周末和朋友去爬山,天气很好,心情也很放松。享受大自然的感觉真好。

2. [Score: 0.6123]
      ID: diary_001
      Date: 2026-01-10
      Mood: happy
      Tags: 生活, 散步
      Content: 今天天气很好,去公园散步了,心情愉快。看到了很多花开了,春天真美好。

注意: 查询语句"户外活动"并没有直接出现在日记内容中,但 Milvus 通过向量相似度找到了"爬山"和"公园散步"这两条语义相关的日记------这就是语义搜索的威力。

4.6 第四步:RAG 完整实现------让 AI 读懂你的日记

最后,我们将检索到的日记内容注入 Prompt,让大语言模型生成温暖、个性化的回答。rag.mjs 是完整的 RAG 流水线:

javascript 复制代码
import 'dotenv/config';
import { MilvusClient, MetricType } from '@zilliz/milvus2-sdk-node';
import { ChatOpenAI, OpenAIEmbeddings } from '@langchain/openai';

const ADDRESS = process.env.MILVUS_ADDRESS;
const TOKEN = process.env.MILVUS_TOKEN;
const COLLECTION_NAME = 'ai_diary';
const VECTOR_DIM = 1024;

// 初始化 Embedding 模型
const embeddings = new OpenAIEmbeddings({
  apiKey: process.env.OPENAI_API_KEY,
  model: process.env.EMBEDDINGS_MODEL_NAME,
  configuration: { baseURL: process.env.OPENAI_BASE_URL },
  dimensions: VECTOR_DIM
});

// 初始化 LLM
const model = new ChatOpenAI({
  temperature: 0.1,                   // 低温度,回答更稳定
  model: process.env.MODEL_NAME,
  apiKey: process.env.OPENAI_API_KEY,
  configuration: { baseURL: process.env.OPENAI_BASE_URL }
});

const client = new MilvusClient({ address: ADDRESS, token: TOKEN });

const getEmbedding = async (text) => {
  const result = await embeddings.embedQuery(text);
  return result;
};

// ===== Step 1: 检索相关日记(Retrieval)=====
async function retrieveRelevantDiaries(question, k = 2) {
  try {
    const queryVector = await getEmbedding(question);
    const searchResult = await client.search({
      collection_name: COLLECTION_NAME,
      vector: queryVector,
      limit: k,
      metric_type: MetricType.COSINE,
      output_fields: ['id', 'content', 'date', 'mood', 'tags']
    });
    return searchResult.results;
  } catch (err) {
    console.log('检索日记时出错', err.message);
    return [];
  }
}

// ===== Step 2: 生成回答(Generation)=====
async function answerDiaryQuestion(question, k = 2) {
  try {
    console.log('='.repeat(80));
    console.log(`问题: ${question}`);
    console.log('='.repeat(80));

    // R - 检索
    console.log('检索相关日记...');
    const retrievedDiaries = await retrieveRelevantDiaries(question, k);
    if (retrievedDiaries.length === 0) {
      console.log('未找到相关日记');
      return;
    }

    retrievedDiaries.forEach((diary, i) => {
      console.log(`日记${i + 1} 相似度: ${diary.score.toFixed(4)}\n内容:${diary.content}`);
    });

    // 构建上下文
    const context = retrievedDiaries
      .map((diary, i) => `
        [日记 ${i + 1}]
        日期:${diary.date}
        心情: ${diary.mood}
        标签: ${diary.tags?.join(', ')}
        内容:${diary.content}
      `).join('\n\n----\n\n');

    // A - 增强 Prompt
    const prompt = `你是一个温暖贴心的AI日记助手。基于用户的日记内容回答问题,用亲切自然的语言。

请根据以下日记内容回答问题:
${context}

用户问题: ${question}

回答要求:
1. 如果日记中有相关信息,请结合日记内容给出详细、温暖的回答。
2. 可以总结多篇日记的内容,找出共同点或趋势。
3. 如果日记中没有相关信息,请温和告知用户。
4. 用第一人称"你"来称呼日记的作者。
5. 回答要有同理心,让用户感到被理解和关心。

AI助手的回答:`;

    // G - 生成
    console.log('\n[AI 回答]');
    const response = await model.invoke(prompt);
    console.log(response.content);

  } catch (err) {
    console.log('回答生成出错:', err.message);
  }
}

async function main() {
  try {
    console.log('连接到 Milvus...');
    await client.connectPromise;
    console.log('已连接');

    // 测试提问
    await answerDiaryQuestion('我最近做了什么让我感到快乐的事情?', 2);
  } catch (err) {
    console.error('Main error:', err.message);
  }
}

main().catch(console.error);

RAG 流程图:

arduino 复制代码
┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   用户提问      │────▶│  Embedding 编码  │────▶│  Milvus 向量检索 │
│ "最近快乐的事?" │     │  转为查询向量    │     │  找最相似的日记  │
└─────────────────┘     └─────────────────┘     └─────────────────┘
                                                          │
                                                          ▼
┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│  LLM 生成回答   │◀────│  构建 RAG Prompt │◀────│  检索结果上下文  │
│ 温暖贴心回复    │     │ 日记内容 + 问题  │     │  top-k 相关日记  │
└─────────────────┘     └─────────────────┘     └─────────────────┘

运行结果示例:

markdown 复制代码
================================================================================
问题: 我最近做了什么让我感到快乐的事情?
================================================================================
检索相关日记...
日记1 相似度: 0.8532
内容:今天工作很忙,完成了一个重要的项目里程碑。团队合作很愉快,感觉很有成就感。
日记2 相似度: 0.8211
内容:今天天气很好,去公园散步了,心情愉快。看到了很多花开了,春天真美好。

[AI 回答]
看到你最近有不少开心的时刻呢!

1月10日那天,你去公园散步,看到花开,感受春天的美好,那种与自然亲近的愉悦真的很珍贵。

1月11日,你完成了重要的项目里程碑,团队合作的成就感一定让你倍感充实。工作中有这样的高光时刻,说明你真的很棒!

你似乎在工作和生活中都能找到让自己快乐的方式,继续保持这份感知幸福的能力吧~

五、原理深入:为什么 RAG 能"理解"你的日记?

5.1 余弦相似度:度量语义相近程度

Milvus 默认使用 余弦相似度(COSINE) 来衡量两个向量的相似程度:

css 复制代码
cos(θ) = (A · B) / (||A|| × ||B||)
  • 值域:[-1, 1]
  • 1 表示完全同向(语义完全相同)
  • 0 表示正交(语义无关)
  • -1 表示反向(语义相反)

在日记场景中,"爬山"和"户外活动"的向量夹角很小,余弦相似度接近 1;而"爬山"和"数据库"的夹角很大,相似度接近 0。

5.2 IVF_FLAT 索引:聚簇加速

IVF_FLAT(Inverted File with Flat)是一种经典的 ANN 索引:

  1. 聚簇:将所有向量用 K-Means 分成 nlist 个簇
  2. 查询:先找到查询向量最近的几个簇中心,再在这些簇内精确计算相似度
  3. 优势:将全量搜索变为"找簇 + 簇内搜索",大幅降低计算量

5.3 Embedding 模型的选择

模型 维度 特点 适用场景
text-embedding-3-small 1536 速度快、成本低 一般语义搜索
text-embedding-3-large 3072(可降维) 精度高、支持降维 高精度 RAG
text-embedding-ada-002 1536 上一代模型 兼容旧系统

降维技巧text-embedding-3-large 原生输出 3072 维,但可以通过 dimensions 参数降维到 1024 或 256,在精度损失很小的情况下节省存储和计算成本。


六、最佳实践与优化建议

6.1 数据建模建议

javascript 复制代码
// ✅ 好的做法:将结构化字段和向量分离存储
// MySQL 存结构化数据(用户、日期、标签)
// Milvus 存向量 + 关联 ID

// ❌ 避免:所有数据都塞进 Milvus
// Milvus 擅长向量检索,不适合复杂的事务查询

混合架构:

数据类型 存储 查询方式
用户、日期、标签等结构化数据 MySQL / PostgreSQL SQL 精确查询
内容向量 Milvus 语义相似度搜索
关联关系 两者通过 ID 关联 联合查询

6.2 性能优化

javascript 复制代码
// 1. 批量插入,减少网络往返
const insertResult = await client.insert({
  collection_name: COLLECTION_NAME,
  data: largeDataArray   // 一次插入多条
});

// 2. 合理设置 limit,避免返回过多数据
const searchResult = await client.search({
  // ...
  limit: 5,     // 只取最相关的 top-5
});

// 3. 加载集合到内存(搜索前必须)
await client.loadCollection({ collection_name: COLLECTION_NAME });

6.3 成本优化

  • 使用 Zilliz Cloud 免费套餐 进行学习和原型开发
  • 降维存储:将 3072 维降至 1024 维,存储和计算成本降低 66%
  • 合理设置索引参数nlist 越大查询越快,但构建索引越慢

6.4 安全注意事项

javascript 复制代码
// ✅ 使用环境变量管理密钥
const TOKEN = process.env.MILVUS_TOKEN;

// ❌ 永远不要硬编码密钥
const TOKEN = 'your-actual-token-here';  // 危险!

七、总结与展望

7.1 本文核心知识点回顾

markdown 复制代码
传统数据库                    向量数据库(Milvus)
    │                              │
    ▼                              ▼
存储文本/数字 ──▶ Embedding ──▶ 存储高维向量
关键词查询                      语义相似度搜索
精确匹配                        理解上下文含义
    │                              │
    └────────── RAG 结合 ──────────┘
              │
              ▼
    检索相关内容 + LLM 生成 = 智能问答

7.2 本文实现的功能

  1. 向量数据库基础操作:连接 Milvus、创建集合、建索引、插入数据
  2. Schema 设计:多字段集合,支持结构化数据 + 向量
  3. Embedding 生成:使用 LangChain OpenAIEmbeddings 将文本向量化
  4. 语义搜索:自然语言查询,无需关键词匹配
  5. 完整 RAG 流水线:检索 + 增强 Prompt + LLM 生成

7.3 可扩展的方向

方向 思路
多模态日记 将照片也通过 CLIP 模型向量化,支持"找那张海边的照片"
时间线总结 结合日期字段,实现"帮我总结一下2026年1月的心情变化"
情绪分析 接入情感分析模型,自动标注心情,无需手动输入
多用户隔离 在 Schema 中增加 user_id 字段,实现多用户数据隔离
混合搜索 结合标签过滤 + 向量相似度,实现"找户外相关且心情愉快的日记"

八、参考资源


如果这篇文章对你有帮助,欢迎点赞收藏

相关推荐
淼澄研学2 小时前
PyTorch深度学习实战:5个核心方法从0到1构建神经网络
前端·数据库·python
吴声子夜歌2 小时前
MongoDB 4.2——分片简介
数据库·mongodb
腾渊信息科技公司2 小时前
工业时序数据存储选型实战:从PostgreSQL到TDengine,查询从15秒到200ms
数据库·postgresql·tdengine
TDengine (老段)2 小时前
TDengine Node.js 与 C# 连接器 — Web 服务与 .NET 集成
大数据·数据库·node.js·c#·.net·时序数据库·tdengine
l1t2 小时前
PostgreSQL 11–18 中的 SQL 改进:个人精选-1
数据库·sql·postgresql
逃跑的浣熊3 小时前
MySQL 性能分析报告:Page Cache 与 fsync 对读写性能的影响
数据库
eam0511233 小时前
简易AI SQL助手搭建方式
数据库·人工智能·sql
路由侠内网穿透.3 小时前
本地部署开源日志收集系统 Log Bull 并实现外部访问
运维·服务器·网络·数据库·开源
码云数智-大飞4 小时前
PHP 大文件上传、断点续传完整实现思路
数据库