利用 Milvus + RustFS,快速打造一个 RAG!

news/2025/9/24 11:24:07/文章来源:https://www.cnblogs.com/rustfs/p/19108824

本分分享使用 Docker Compose 安装 milvus 实例,并用 RustFS 作为对象存储后端,最后再使用 FastAPI 和 Next.JS 来实现一个 Chatbot 的整个实践过程。

整个过程涉及的步骤:

  • milvus & rustfs 的安装;
  • RustFS 中文文档的向量化;
  • 向量化数据在 milvus 中的存储;
  • milvus + llm 实现 RAG;
  • fastapi + next.js 实现 chatbot;

Milvus & RustFS 的安装

关于 Milvus

Milvus 是一款开源的向量数据库项目,由 Zilliz 开发,目前该项目已经捐赠给了 LF AI & Data 基金会。向量数据库是 AIGC 发展的重要基础设施。一次该项目在 GitHub 上已经有超 37.5k star。

关于 RustFS

RustFS 是一款开源的对象存储系统,用 Rust 语言编写,完全兼容 S3,可以使用二进制、Docker、Helm chart 进行安装。本地实践正好将其作为 milvus 向量数据库的存储后端。

使用 docker compose 安装

Milvus 官方提供的docker-compose.yml文件中包含了对于 milvus、minio 的安装。但是本次使用 RustFS 来替代 minio,因此需要做一些变更。关于 minio 的信息主要包括:

minio:address: localhost:9000port: 9000accessKeyID: rustfsadminsecretAccessKey: rustfsadminuseSSL: falsebucketName: "rustfs-bucket"

这部分内容包含在 milvus repo的 configs/milvus.yaml 文件中,所以要将上述内容替换,有两种方式:

  • configs/milvus.yaml 文件存放到本地,将内容替换为 RustFS 的,然后在 docker compose 中通过 volume 挂载即可;
  • 修改 milvus 容器的 command,在服务启动前先用 yq 命令对 configs/milvus.yaml(在容器中地址变为 /milvus/configs/milvus.yaml)中的 minio 信息进行修改,然后启动 milvus 服务;

本地实践选择了第一种方式,所以会在 docker-compose.yml 文件中 milvus 服务的 volume 中增加了一个:

- ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/milvus/milvus.yaml:/milvus/configs/milvus.yaml:ro

整体的 docker-compose.yml 文件包含的服务有:

etcd

milvus 依赖于 etcd:

etcd:container_name: milvus-etcdimage: quay.io/coreos/etcd:v3.5.18environment:- ETCD_AUTO_COMPACTION_MODE=revision- ETCD_AUTO_COMPACTION_RETENTION=1000- ETCD_QUOTA_BACKEND_BYTES=4294967296- ETCD_SNAPSHOT_COUNT=50000volumes:- ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/etcd:/etcdcommand: etcd -advertise-client-urls=http://etcd:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcdhealthcheck:test: ["CMD", "etcdctl", "endpoint", "health"]interval: 30stimeout: 20sretries: 3

attu

可以可视化查看 milvus 情况的一个服务,也是有 zilliz 研发且开源的(注意 2.6 以后是闭源的)

attu:container_name: milvus-attuimage: zilliz/attu:v2.6environment:- MILVUS_URL=milvus-standalone:19530ports:- "8000:3000"restart: unless-stopped

rustfs 服务

作为对象存储后端,存储 milvus 中的数据:

rustfs:container_name: milvus-rustfsimage: rustfs/rustfs:1.0.0-alpha.58environment:- RUSTFS_VOLUMES=/data/rustfs0,/data/rustfs1,/data/rustfs2,/data/rustfs3- RUSTFS_ADDRESS=0.0.0.0:9000- RUSTFS_CONSOLE_ADDRESS=0.0.0.0:9001- RUSTFS_CONSOLE_ENABLE=true- RUSTFS_EXTERNAL_ADDRESS=:9000  # Same as internal since no port mapping- RUSTFS_CORS_ALLOWED_ORIGINS=*- RUSTFS_CONSOLE_CORS_ALLOWED_ORIGINS=*- RUSTFS_ACCESS_KEY=rustfsadmin- RUSTFS_SECRET_KEY=rustfsadminports:- "9000:9000" # S3 API port- "9001:9001" # Console portvolumes:- rustfs_data_0:/data/rustfs0- rustfs_data_1:/data/rustfs1- rustfs_data_2:/data/rustfs2- rustfs_data_3:/data/rustfs3- logs_data:/app/logsrestart: unless-stoppedhealthcheck:test:["CMD","sh", "-c","curl -f http://localhost:9000/health && curl -f http://localhost:9001/health"]interval: 30stimeout: 10sretries: 3start_period: 40s

milvus

milvus 向量数据库,采用 standalone 模式:

standalone:container_name: milvus-standaloneimage: milvusdb/milvus:v2.6.0command: ["milvus", "run", "standalone"]security_opt:- seccomp:unconfinedenvironment:ETCD_ENDPOINTS: etcd:2379MINIO_ADDRESS: rustfs:9000MQ_TYPE: woodpeckervolumes:- ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/milvus:/var/lib/milvus- ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/milvus/milvus.yaml:/milvus/configs/milvus.yaml:rohealthcheck:test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]interval: 30sstart_period: 90stimeout: 20sretries: 3ports:- "19530:19530"- "9091:9091"depends_on:- "etcd"- "rustfs"

配置好相关参数后,直接执行命令即可启动所有服务:

docker compose -f docker-compose.yml up -d

启动的容器有:

docker ps
CONTAINER ID   IMAGE                                             COMMAND                  CREATED          STATUS                      PORTS                                                                                      NAMES
4404b5cc6f7e   milvusdb/milvus:v2.6.0                            "/tini -- milvus run…"   53 minutes ago   Up 53 minutes (healthy)     0.0.0.0:9091->9091/tcp, :::9091->9091/tcp, 0.0.0.0:19530->19530/tcp, :::19530->19530/tcp   milvus-standalone
40ddc8ed08bb   zilliz/attu:v2.6                                  "docker-entrypoint.s…"   53 minutes ago   Up 53 minutes               0.0.0.0:8000->3000/tcp, :::8000->3000/tcp                                                  milvus-attu
3d2c8d80a8ce   quay.io/coreos/etcd:v3.5.18                       "etcd -advertise-cli…"   53 minutes ago   Up 53 minutes (healthy)     2379-2380/tcp                                                                              milvus-etcd
d760f6690ea7   rustfs/rustfs:1.0.0-alpha.58                      "/entrypoint.sh rust…"   53 minutes ago   Up 53 minutes (unhealthy)   0.0.0.0:9000-9001->9000-9001/tcp, :::9000-9001->9000-9001/tcp                              milvus-rustfs

其中,milvus 在 ip:19530 可用;rustfs 在 ip:9000 可用;attu 在 ip:8000 可用。

RustFS 文档的向量化

本次实践以 RustFS 中文文档包含的 80 个 Markdown 文件为基础数据,将其进行分片并向量化。通过 Python 来实现。代码如下:

# 3. 读取 Markdown 文件
def load_markdown_files(folder):files = glob.glob(os.path.join(folder, "**", "*.md"), recursive=True)docs = []for f in files:with open(f, "r", encoding="utf-8") as fp:docs.append(fp.read())return docs# 4. 切分文档(简单按段落)
def split_into_chunks(text, max_len=500):chunks, current = [], []for line in text.split("\n"):if len(" ".join(current)) + len(line) < max_len:current.append(line)else:chunks.append(" ".join(current))current = [line]if current:chunks.append(" ".join(current))return chunks

整体思路就是遍历 RustFS 中文文档下面的 Mardown 文件,然后将其内容输出为 docs 列表,然后再根据换行符(\n)将内容切片处理(这个地方的方式还可以更加精细化,感兴趣地可以自行调整),最终输出切片后的字符串列表(chunks)。

接下来通过使用 text-embedding-3-large 模型将上述的字符串列表进行向量化:

def embed_texts(texts):response = client.embeddings.create(model="text-embedding-3-large",input=texts)return [d.embedding for d in response.data]

接下来就可以将这些数据存储到 milvus 中了。

将向量化数据存储到 milvus

milvus 中使用 collection 和 schema 来对数据进行存储管理:

# 链接 milvus
connections.connect("default", host="ip", port="19530")# 定义 Collection Schema
fields = [FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),FieldSchema(name="content", dtype=DataType.VARCHAR, max_length=2000),FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=3072),
]
schema = CollectionSchema(fields, description="Markdown docs collection")# 创建 collection
if utility.has_collection("docs_collection"):utility.drop_collection("docs_collection")collection = Collection(name="docs_collection", schema=schema)# 插入数据
collection.insert([all_chunks, embeddings])
collection.flush()

可以在 attu 服务上查看,在 collections 中有一个 docs_collection

attu-collections-check

可以在 RustFS 上看到存储的数据:

rustfs-data

milvus + llm,构建 RAG

Milvus 已经存储了 RustFS 中文文档的向量化数据,再配合 llm(本次实践选择 GPT),就可以构造一个简单的 RAG。整体思路是:将查询向量化,然后在 milvus 中检索相似的文档(或片段),然后拼接好 prompt,最后点用 llm,获得最终答案。代码如下:

query_embedding = embed_texts(query)# 2. 从 Milvus 检索相似文档search_params = {"metric_type": "COSINE", "params": {"nprobe": 10}}results = collection.search(data=[query_embedding],anns_field="embedding",param=search_params,limit=3,output_fields=["content"])docs = [hit.entity.get("text") for hit in results[0]]# 3. 拼接 RAG Promptprompt = f"你是一个 RustFS 专家,请基于以下文档回答:\n\n{docs}\n\n用户问题:{query}"# 4. 调用 LLMresponse = client.chat.completions.create(model="gpt-5-chat", messages=[{"role": "user", "content": prompt}],# max_tokens=16384,# temperature=1.0,# top_p=1.0,)answer = response.choices[0].message.contentreturn {"answer": answer, "sources": docs}

测试查询语句为:

如何在 Docker 中安装 RustFS

返回结果:

根据你提供的文档,在 Docker 中安装 RustFS 的步骤如下:


Docker 安装 RustFS 步骤

1. 确认环境要求

  • 宿主机已安装 Docker(版本 ≥ 20.10)
  • 预留一个本地路径作为数据挂载目录,例如:
    /mnt/rustfs/data
    
  • 确保宿主机 9000 端口(或自定义端口)开放

2. 准备配置文件

在宿主机创建配置文件 /etc/rustfs/config.toml,示例内容如下:

RUSTFS_ACCESS_KEY=rustfsadmin
RUSTFS_SECRET_KEY=rustfsadmin
RUSTFS_VOLUMES="/data/rustfs{0...3}"
RUSTFS_ADDRESS=":9000"
#RUSTFS_SERVER_DOMAINS="play.rustfs.com:7000"
RUSTFS_CONSOLE_ENABLE=true
RUSTFS_OBS_ENDPOINT=""
RUSTFS_TLS_PATH="/opt/tls"

注:路径 /data/rustfs{0...3} 会在容器中映射为实际的宿主机存储路径


3. 拉取官方 RustFS 镜像

docker pull rustfs/rustfs

4. 运行 RustFS 容器

执行以下命令启动:

docker run -d \--name rustfs \-p 9000:9000 \-v /mnt/rustfs/data:/data \-v /etc/rustfs/config.toml:/etc/rustfs/config.toml \rustfs/rustfs

说明:

  • -v /mnt/rustfs/data:/data 绑定数据存储目录
  • -v /etc/rustfs/config.toml:/etc/rustfs/config.toml 挂载配置文件
  • -p 9000:9000 暴露 S3 兼容 API 端口

5. 验证安装

启动完成后,在浏览器或 S3 客户端访问:

http://<宿主机IP>:9000

使用配置文件中的 Access KeySecret Key(如 rustfsadmin / rustfsadmin)进行登录即可。


总结
在 Docker 中安装 RustFS 的核心步骤是:

  1. 准备宿主机数据目录和配置文件
  2. 拉取官方 rustfs/rustfs 镜像
  3. 使用 docker run 启动容器并映射端口和数据卷
  4. 使用配置文件中的账号密码访问 S3 服务

更进一步:DIY 一个 chatbot

既然 RAG 已经可用了,那就干脆做一个 chatbot web 吧,不用每次都执行 python 脚本,在 web 页面上问问题多好。

问了一下 GPT,给出的方案是 fastapi(因为 RAG 构建代码是 python 写的)+ Next.js(用来做一个简单的用 web 页面)。

FastAPI 的作用是将 RAG “封装起来”,暴露出一个 API,然后给前端使用:

app = FastAPI()@app.post("/chat")
def chat(req: ChatRequest):query = req.query......

运行应用:

uvicorn main:app --reload --host 0.0.0.0 --port 9999
INFO:     Will watch for changes in these directories: ['/home/xiaomage/milvus/chatbot/.venv']
INFO:     Uvicorn running on http://0.0.0.0:9999 (Press CTRL+C to quit)
INFO:     Started reloader process [2071374] using WatchFiles
INFO:     Started server process [2071376]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

Next.js 的核心代码如下:

try {const res = await fetch('http://localhost:9999/chat', {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify({ query: input }),});const data = await res.json();const botMessage: Message = { role: 'bot', content: data.answer || 'No response' };setMessages(prev => [...prev, userMessage, botMessage]);} catch (error) {console.error(error);const botMessage: Message = { role: 'bot', content: 'Error connecting to server.' };setMessages(prev => [...prev, botMessage]);} finally {setLoading(false);}

运行应用:

pnpm run dev -H 0.0.0.0 -p 3000> rag-chatbot@0.1.0 dev /home/xiaomage/milvus/chatbot-web/rag-chatbot
> next dev --turbopack -H 0.0.0.0 -p 3000▲ Next.js 15.5.3 (Turbopack)- Local:        http://localhost:3000- Network:      http://0.0.0.0:3000✓ Starting...✓ Ready in 1288ms

在浏览器中访问 http:ip:3000/chat,出现如下界面:

chat-web

在对话框中输入:

如何在 Docker 中安装 RustFS?

返回结果:

chatbot-result

简单的 Chatbot 就此完成。

写在最后

整个过程中也遇到了一些问题,通过解决问题的过程对于 milvus、向量化、RAG 有了更进一步的了解。当然,由于 Vibe Coding 确实很爽,导致需求一直不收敛,从最初始的 milvus 安装到 RAG,再到 Chatbot 的打造,后面还想继续优化整个过程,将这些代码都打包到 Dockerfile 里面,用 docker compose 运行。%

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/915633.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker 私有镜像仓库 Harbor 安装部署带签名认证

Docker 私有镜像仓库 Harbor 安装部署带签名认证1. 准备工作 1.1 服务器信息IP 主机名 内存(GB) CPU核数 磁盘 操作系统 CPU 架构 Docker 版本 角色10.0.0.13 arc-pro-dc01 8 1 500GB CentOS 7.9.2009 x86_64 docker…

ARC180 做题记

训A () 题意 题解 \(\bf{record}\) B () 题意 题解 \(\bf{record}\) C () 题意 题解 \(\bf{record}\) D () 题意 题解 \(\bf{record}\)

借助Aspose.HTML控件,使用 Python 编辑 HTML

通过编程方式重构HTML文件可以节省时间和精力。Aspose.HTML SDK提供了一种强大且无缝的使用 Python 编辑 HTML 的方法。使用此 SDK,您可以自动化修改现有 HTML 文件。通过编程方式重构HTML文件可以节省时间和精力。As…

微前端 micro-app 在vue 中的路由跳转问题

微前端 micro-app 在vue 中的路由跳转问题end .

汕头模板建站平台有没有免费的seo网站

IIS-Apache-Tomcat的区别 IIS与Tomcat的区别 IIS是微软公司的Web服务器。主要支持ASP语言环境. Tomcat是Java Servlet 2.2和JavaServer Pages 1.1技术的标准实现&#xff0c;是基于Apache许可证下开发的SJP语言环境容器,严格得说不能算是一个WEB服务器,而是Apache服务适配器。 …

南城区网站仿做手机照片制作成相册

首先机器人端启动摄像头。 pc端用rqt_image_view就可以打开rqt工具&#xff0c;然后选择话题&#xff0c;就看到摄像头图像了。 下面是compressed话题和不是compressed话题的对比&#xff0c;这两个话题带宽有倍数级差异。 然后就可以用opencv做一些事情。下面这个其实就是机器…

1. 设计模式--工厂办法模式

1. 设计模式--工厂办法模式pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", …

汽车视频总线采集过程中,如何兼顾响应速度和可靠性?

汽车测试中“快速响应”与“技术可靠”难以兼得?本文详解如何基于ADTF模块化平台,通过图形化连接Filter组件,无需编码即可快速集成多路视频与总线数据,实现高精度同步采集与无丢包采集录制,破解多设备同步与高带宽…

P8865 [NOIP2022] 种花

P8865 [NOIP2022] 种花#include <bits/stdc++.h> using namespace std;const int mod = 998244353,maxn = 1e3 + 10; int a[maxn][maxn],down[maxn][maxn],r[maxn][maxn],up[maxn][maxn];int main(){int T,id;ci…

traefik 反向代理 + IdentityServer4

traefik 反向代理 + IdentityServer4

店铺的网站怎么做精品成品网站1688

1、安装 docker a、使用 Homebrew 安装 brew install --cask --appdir/Applications docker b、手动下载安装 1、安装包下载地址&#xff1a;Install Docker Desktop on Mac | Docker Docs 根据自己的笔记本型号选择&#xff0c;我这边选择的是 intel chip 2、下载安装即可&a…

在线一键建站系统wordpress 登陆 403

文章目录 一、问题描述二、解决方法 一、问题描述 当我们在代码页面上引入Vue.js(开发版本)时&#xff0c;运行代码会出现以下提示&#xff0c;这句话的意思是&#xff1a;您正在开发模式下运行Vue&#xff0c;在进行生产部署时&#xff0c;请确保打开生产模式 You are runni…

麦角硫因制备关键技术和设备

麦角硫因制备概述 麦角硫因(L-Ergothioneine,简称EGT)是一种天然的稀有手性氨基酸衍生物,具有强大的抗氧化、抗衰老和细胞保护功能。它最初于1909年从麦角真菌中分离而出,现广泛应用于化妆品、食品和医药领域。由…

2025年十大好用网盘推荐:功能、口碑与性价比大对比

不知如何选择网盘?本文为解决此难题,深度评测并盘点了2025年十大热门网盘,涵盖坚果云、百度网盘、阿里云盘等。文章从功能特色、数据安全、团队协作等多维度进行对比分析,旨在帮助用户依据自身需求,精准挑选出最适…

Word-通过宏格式化文档中的表格和图片

1、打开Word文档,找到视图。 2、创建宏脚本Sub 表格格式化()On Error Resume Next 忽略合并单元格等错误Application.ScreenUpdating = FalseDim tbl As Table, col As ColumnDim counter As Integer: counter = …

常用网站建设软件wordpress 幻灯片标签

摘要 本论文主要论述了如何使用JAVA语言开发一个音乐网站与分享平台 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述音乐网站与分享平台的当前背景以及系统开…

有多少个购物网站网站建设与管理模拟试卷

很多媒体大肆宣扬Fortnite和Roblox是元宇宙UGC平台巨头的竞争对手,但实际上它们似乎各自占据了UGC游戏市场的不同部分。对于Fortnite来说,主要是射击游戏;而对于Roblox来说,则是其他所有类型的游戏。 至少在目前,这两个平台在市场定位和用户群体上有着明显的差异,它们的…

徐州企业网站排名优化微信用大型网站站做跳板

本文为第0篇 专栏简介 本专栏是优质Rust技术专栏&#xff0c;推荐精通一门技术栈的蟹友&#xff0c;不建议基础的同学&#xff08;无基础学Rust也是牛人[手动捂脸]&#xff09; 感谢Rust圣经开源社区的同学&#xff0c;为后来者提供了非常优秀的Rust学习资源 本文使用&…

反向代理 traefik - 健康检查

反向代理 traefik 配置end.

一些想法 - CelestialZ

引言 这并不是我开通的第一个博客,我在中学时期也在zhihu、bilibili上记录数学学习经历。我希望这个因辅修cs而创建的博客账号,能记录一些我学习cs的历程。以下是我对后续博客内容的展望,可能与实际情况有出入,可能…