从零搭建AI日记本:Milvus向量数据库实战指南
当AI Agent有了“记忆”它就不再是简单的对话工具而成为了一个懂你的伙伴。最近我在开发一个AI日记本应用发现传统的MySQL很难实现“语义搜索”——比如你想找“心情愉快的日子”但日记里并没有这个词。这时向量数据库就派上了用场。本文我将分享如何使用Milvus以及全托管服务Zilliz结合OpenAI Embeddings快速构建一个具备记忆与检索能力的AI日记助手。一、为什么需要向量数据库我们熟悉的MySQL、PostgreSQL擅长存储结构化数据通过id或LIKE进行精确或模糊匹配。但AI应用中的数据往往是非结构化的——文本、图像、音频。当我们希望根据语义来检索时比如“查找关于户外活动的日记”传统数据库就力不从心了。向量数据库应运而生。它将数据转换成高维向量通过计算向量间的距离余弦相似度、欧氏距离等来实现语义相似性检索。像Milvus这样的系统专为海量高维向量设计已经成为AI Agent记忆系统的标配。如果说MySQL是结构化数据的仓库那Milvus就是向量数据的图书馆——你不再需要记住书名关键词只需描述你想看的内容它就能帮你找到“懂你”的那本书。二、Milvus与Zilliz你的向量数据库选择Milvus开源向量数据库支持十亿级向量检索提供多种索引IVF_FLAT、HNSW等底层用C实现性能强悍。Zilliz基于Milvus的全托管云服务免运维提供API Key接入适合快速开发和线上部署。本文使用Zilliz免费版省去自建集群的繁琐。注册后你会获得一个ADDRESS如https://xxxx.zillizcloud.com和TOKEN填入.env即可。三、环境准备npm install zilliz/milvus2-sdk-node langchain/openai dotenv创建.env文件MILVUS_ADDRESShttps://your-instance.zillizcloud.com MILVUS_TOKENyour-api-token OPENAI_API_KEYsk-xxx OPENAI_BASE_URLhttps://api.openai.com/v1 # 或代理地址 EMBEDDINGS_MODEL_NAMEtext-embedding-3-small MODEL_NAMEgpt-4o-mini四、初次接触连接与基础操作我们先写一个简单脚本连接Zilliz创建集合插入两条测试向量并执行一次搜索。4.1 连接与健康检查import { MilvusClient, IndexType, MetricType } from zilliz/milvus2-sdk-node; import dotenv/config; const client new MilvusClient({ address: process.env.MILVUS_ADDRESS, token: process.env.MILVUS_TOKEN, }); const check await client.checkHealth(); if (!check.isHealthy) throw new Error(连接失败);4.2 创建集合Collection在Milvus中集合相当于MySQL的表。我们定义一个4维向量字段仅为演示自动生成ID。const COLLECTION_NAME test; const DIMENSION 4; await client.createCollection({ collection_name: COLLECTION_NAME, dimension: DIMENSION, auto_id: true, });4.3 创建索引——让查询快如闪电没有索引的向量检索是全量遍历O(n)数据量一大就慢得无法接受。索引好比书的目录能大幅缩小搜索范围。await client.createIndex({ collection_name: COLLECTION_NAME, field_name: vector, index_type: IndexType.AUTOINDEX, // 自动选择最优索引 metric_type: MetricType.COSINE, // 相似度度量 });AUTOINDEX是Milvus 2.3提供的智能索引会基于数据自动调整新手友好。生产环境可根据数据量选用IVF_FLAT、HNSW等。4.4 插入数据Milvus的数据插入非常灵活直接传入JSON数组即可无需写SQL。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: COLLECTION_NAME, data });4.5 执行向量搜索const searchRes await client.search({ collection_name: COLLECTION_NAME, data: [[0.5, 0.5, 0.6, 0.8]], // 查询向量 limit: 2, output_fields: [content], }); console.log(searchRes.results);你会得到按相似度排序的结果并附带score得分越接近1表示越相似。五、进阶AI日记本的核心——文本向量化上面的例子用的是手工构造的向量现实中我们需要将文本转换为向量。这通常由Embedding模型完成如OpenAI的text-embedding-3-small。5.1 定义集合结构带丰富元数据我们的日记不仅有内容还有日期、心情、标签等结构化字段。Milvus支持多种数据类型我们定义一个更完整的schemaconst COLLECTION_NAME ai_dairy; const VECTOR_DIM 1024; // 与embedding模型维度一致 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 }, ] });这里用到了Array类型来存储标签非常方便。5.2 使用LangChain生成Embeddingimport { OpenAIEmbeddings } from langchain/openai; const embeddings new OpenAIEmbeddings({ apiKey: process.env.OPENAI_API_KEY, model: process.env.EMBEDDINGS_MODEL_NAME, dimensions: VECTOR_DIM, }); async function getEmbedding(text) { return await embeddings.embedQuery(text); }5.3 插入带有向量的日记假设我们有5条日记内容我们遍历每条调用getEmbedding生成向量然后批量插入。const diaryData await Promise.all( diaryContents.map(async (diary) ({ ...diary, vector: await getEmbedding(diary.content), })) ); await client.insert({ collection_name: COLLECTION_NAME, data: diaryData });注意插入前需要先loadCollection将集合加载到内存否则搜索会报错。await client.loadCollection({ collection_name: COLLECTION_NAME });六、语义搜索用自然语言找日记现在用户输入“我想看看关于户外活动的日记”我们先将问题向量化然后去Milvus中搜索。const query 我想看看关于户外活动的日记; const queryVector await getEmbedding(query); const result await client.search({ collection_name: COLLECTION_NAME, vector: queryVector, limit: 2, metric_type: MetricType.COSINE, output_fields: [id, content, date, mood, tags] });输出的结果会包含相似度得分并且按得分降序排列。你可能会发现即使日记中没有“户外”二字只要内容提到“爬山”、“散步”等也会被检索出来——这就是语义检索的魅力。七、RAG让大模型结合记忆来回答RAG检索增强生成是目前AI应用的主流范式。我们检索出相关的日记然后作为上下文喂给大模型让它生成一个既基于事实又有人情味的回答。7.1 检索相关日记封装一个函数async function retrieveRelevantDiaries(question, k 2) { const vec await getEmbedding(question); const res await client.search({ collection_name: COLLECTION_NAME, vector: vec, limit: k, output_fields: [id, content, date, mood, tags] }); return res.results; }7.2 构建Prompt与调用LLMimport { ChatOpenAI } from langchain/openai; const model new ChatOpenAI({ temperature: 0.1, model: process.env.MODEL_NAME, }); async function answerDiaryQuestion(question) { const diaries await retrieveRelevantDiaries(question, 2); if (!diaries.length) return 没有找到相关日记; const context diaries.map((d, i) [日记${i1}] 日期:${d.date} 心情:${d.mood} 内容:${d.content} ).join(\n\n); const prompt 你是一个温暖的AI日记助手。根据以下日记内容回答用户问题 ${context} 用户问题${question} 要求 - 如果日记中有相关信息请结合给出详细回答。 - 用“你”称呼日记作者语气亲切。 - 如果信息不足请温和地说明。 回答 ; const response await model.invoke(prompt); console.log(response.content); }7.3 效果演示当用户问“我最近做了什么让我感到快乐的事情”时系统会检索出得分最高的日记比如“完成项目里程碑”和“散步赏花”然后大模型会总结出这些快乐时刻并给予温暖的回应。这时候AI不再是一个冷冰冰的问答机而是真正“读过”你的日记成为了懂你的朋友。八、踩坑与优化建议索引创建时机最好在插入数据前创建索引否则插入后需手动构建。loadCollection每次操作前确保集合已加载否则搜索报错。维度一致向量维度必须与Embedding模型输出维度一致否则插入失败。批量插入插入大量数据时分批进行每批几百条避免超时。连接管理使用client.connectPromise确保连接完成再操作SDK 2.x版本。相似度度量COSINE适合文本IP内积和L2也有各自适用场景根据数据特点选择。九、总结与展望通过本文你已经掌握了向量数据库的核心概念与Milvus基本操作如何结合Embedding模型将文本向量化如何实现语义搜索和RAG问答我们构建的AI日记本只是一个起点同样的架构可以应用到客服知识库、推荐系统、AI Agent记忆系统等众多场景。当AI拥有了“长期记忆”它的能力边界将被大大拓展。最后送大家一句心得“数据决定智能的上限向量数据库就是承载这些数据的骨骼。”愿你的AI应用都能拥有聪明而持久的记忆。

相关新闻

Vue3核心特性与Composition API实战指南

Vue3核心特性与Composition API实战指南

1. Vue3核心特性与设计哲学Vue3作为当前主流前端框架的里程碑版本,其核心设计围绕"更小、更快、更强"的理念展开。与Vue2相比,Vue3在性能优化方面实现了显著突破:打包体积减少41%、初次渲染快55%、更新快133%。这些提升主要得益于全…

2026/10/20 2:54:43 阅读更多 →
基于HSV颜色空间与串口通信的Micro:bit实时视觉点阵显示项目实践

基于HSV颜色空间与串口通信的Micro:bit实时视觉点阵显示项目实践

1. 项目概述:从视频到点阵的实时视觉魔法如果你手头有一块Micro:bit,并且已经玩腻了内置的5x5 LED点阵,想要让它显示更丰富、更动态的内容,比如实时显示摄像头捕捉到的图像轮廓,那么这个项目就是为你准备的。这次我们不…

2026/10/19 7:10:11 阅读更多 →
[Android] Netmonitor -高级版+基站网络实时监测工具

[Android] Netmonitor -高级版+基站网络实时监测工具

[Android] Netmonitor -高级版基站网络实时监测工具 链接:https://pan.xunlei.com/s/VOyXgd1aIiO3fWMVNkK0ff8SA1?pwdmbpy# 支持4G、5G与WiFi网络监测,实时查看网络速度与连接状态,精准检测信号强弱区域,自动标注周边基站位置…

2026/10/19 6:25:02 阅读更多 →

最新新闻

Python基于Vue的物业管理系统毕业设计实战:从数据库设计到部署上线

Python基于Vue的物业管理系统毕业设计实战:从数据库设计到部署上线

做物业管理系统这个项目,我自己前前后后带过好几个同学完整走了一遍,从选题、画原型、建表到前后端联调,最后部署上线,整套流程可以说非常熟悉了。这个题目在毕业设计里出现频率极高,核心原因不是它有多简单&#xff0…

2026/10/20 8:06:24 阅读更多 →
MySQL传统主从复制实战:从binlog原理到配置与排障

MySQL传统主从复制实战:从binlog原理到配置与排障

聊到MySQL高可用和读写分离,我估计不少人都被问过这么一句话:“你先搞个主从复制把读流量分流一下。” 这句话背后藏着MySQL最经典、也最绕不开的一个技术底座——基于binlog的传统主从复制。这篇文章我就把这个老牌方案从头到尾拆一遍,从bin…

2026/10/20 8:06:24 阅读更多 →
Mac本地部署Open-AutoGLM:手把手让大模型自动操作手机

Mac本地部署Open-AutoGLM:手把手让大模型自动操作手机

最近一直在折腾 AI Agent,折腾来折腾去,最后停在了一个叫 Open-AutoGLM 的开源项目上。简单说,它是一套让大模型直接操作手机的开源方案:模型跑在本地,手机通过 USB 连到电脑,你给它一句“帮我在日历里建一…

2026/10/20 8:06:24 阅读更多 →
MySQL调优核心:深入解析redo log落盘机制与架构分工

MySQL调优核心:深入解析redo log落盘机制与架构分工

做MySQL调优这几年,接触过不少慢查询、死锁、主从延迟的案例,最后几乎都绕回两个底层问题:MySQL整体架构是如何分工的,以及redo log到底在什么时机落盘。很多人把索引优化、SQL改写玩得很溜,但一遇到“磁盘IO突然飙高”…

2026/10/20 8:06:24 阅读更多 →
流放之路2国际服交易工具汉化与查价器使用全攻略

流放之路2国际服交易工具汉化与查价器使用全攻略

在流放之路2 的国际服交易玩法里,网页市集、忍者网和 Path of Building 几乎是每个玩家都会用到的工具组合。不过对于不熟悉英文界面的玩家,满屏词缀、陌生术语和复杂的查询参数,很容易让人在配装、比价时一头雾水。这篇文章打算把网页市集汉…

2026/10/20 8:06:24 阅读更多 →
raylib解压即用开发环境:一条gcc命令从窗口到Makefile工程化

raylib解压即用开发环境:一条gcc命令从窗口到Makefile工程化

简介:raylib 是一套以简单易用著称的开源游戏编程库,这份压缩包正是其整合发布版,面向希望快速上手 C/C 图形编程的开发者与游戏原型爱好者,适合从零搭建图形窗口、绘制基本图形、处理输入事件并产出可运行的跨平台演示程序。包内…

2026/10/20 8:05:23 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →