
在和ai会话的时候我们总会给他一堆文件要他处理,有图片,word,excel,pdf等等。会话结束后,在历史会话里面,如何拿到这个文件,就成了问题。文件必须要存储在一个地方,这个地方就是对象数据库。
一.对象数据库
对象数据库 = 让数据库"懂对象" ,也就是用来存储对象的数据库。对象和类直接存进去,免了 ORM 那层转换,适合数据结构复杂、对象关系盘根错节的场景;平时最常见的CRUD业务它并不占优。
上面的概念太笼统,我们不想听,那就想下mysql,mysql是关系型数据库,就是一行一行的保存数据,但是mysql对文件图片的存储是有限制的,你可以把图片转成base64存进去,但是大文档呢?
一般的对象数据库有:MinIO、RustFS、和 阿里云 OSS,MinIO和RustFS是你可以安装到本地的对象数据库,阿里云 OSS是阿里云上的对象存储方案。

二.在ai agent 里面 minIO 使用场景
在一般的企业会将文件都存到对象数据库里面,然后将文件的元数据(文件名字,大小,存储位置,时间等信息)存储到关系型数据库上。
在
ai agent项目里面,会话文件会存储,RAG检索也会有文件存储,一般我们都将文件放到minIO里面,然后将文件的元数据存放在mysql里面。使用的时候,我们会根据mysql的id拿到元数据,再通过元数据去阿里云minIO里面去获取原文件。
具体操作流程如下:

强调:
minIO里面存储的是文档原件,向量数据库milvus存储的是文件块的向量值,文件块和元数据是放在mysql里面的。

对于RAG这个场景,我们做一下系统的梳理:
1.存数据
用户通过前端上传文件,后端代码将上传的原文件存到minIO数据库,然后从这个原文件提取文件元数据(文件名,类型,大小,上传时候等等信息),然后把原文件切成块,将文件块和元数据存到mysql里面,,然后用嵌入模型将切好的文档块转化成向量值,存到向量数据库milvus里面。当然你可以选择postgreSQl数据库,将元数据、文件块、向量都存到postgreSQl数据库里面。

2.取数据
用户提问,先用嵌入模型将问题处理成向量,去milvus里面做余弦相似度比较,找到相似文件块,根据id去mysql里面找到原文件的元信息(文件名,存储位置等等),根据文件位置去minIO里面拿对应的原文件。

三.如何选择阿里云 OSS、MinIO、RustFS
- 如果业务跑在公有云上、想省去运维压力,直接选阿里云 OSS。
- 如果只是小型本地自建知识库、低成本快速落地,优先 MinIO。
- 如果是海量音视频存储、大型集团国产化项目,推荐 RustFS。

四.使用阿里云oss
1.在线使用阿里云oss
官网地址:www.aliyun.com/product/os 五块钱可以用很久。

支付成功进入控制台

进入bucket列表创建一个bucket

上传文件

点击可以查看或者下载

点击详情可以看到上传图片的详细信息,还能拿到url在浏览器上下载

2.在nodejs里面使用oss
进入:oss.console.aliyun.com/vector-buck...
2.1安装包
js
pnpm install dotenv ali-oss
2.2配置信息
js
OSS_REGION=oss-cn-beijing
OSS_ACCESS_KEY_ID=你的id
OSS_ACCESS_KEY_SECRET=你的秘钥
OSS_BUCKET=agent-bucket999
OSS_BUCKET这里取 
OSS_REGION这里取 
OSS_ACCESS_KEY_ID 和 OSS_ACCESS_KEY_SECRET 这里取 

创建个子账号,获取OSS_ACCESS_KEY_ID 和 OSS_ACCESS_KEY_SECRET

2.3nodejs代码
js
import 'dotenv/config';
import OSS from 'ali-oss';
import fs from 'fs';
import { fileURLToPath } from 'url';
import path from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const client = new OSS({
region: process.env.OSS_REGION,
accessKeyId: process.env.OSS_ACCESS_KEY_ID,
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
authorizationV4: true,
bucket: process.env.OSS_BUCKET,
});
async function putStream () {
try {
const stream = fs.createReadStream(path.join(__dirname, 'zao.png'));
let result = await client.putStream('aaa/bbb/first.png', stream);
console.log(result);
} catch (e) {
console.log(e)
}
}
putStream();
执行后查看结果:oss.console.aliyun.com/bucket/oss-...

五.使用@aws-sdk/client-s3
在使用 阿里云oss、minIO、rustFS上他们的api使用方式都差不多,是因为他们三类存储底层全部遵循 S3 标准协议,核心能力基本一致。
所以安装 @aws-sdk/client-s3 这一个aws的包就能对接所有OSS服务,也可以分别用ali-oss、minio来对接。
S3 = Simple Storage Service,AWS 的对象存储服务。
我们用 @aws-sdk/client-s3对接ali-oss试试。
@aws-sdk/client-s3是 AWS 官方 Node.js SDK v3,专门用来操作 S3 对象存储。
js
import 'dotenv/config';
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import fs from 'fs';
import { fileURLToPath } from 'url';
import path from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// 对接阿里云OSS(S3兼容模式)
const s3Client = new S3Client({
// ✅ endpoint必须完整https地址
endpoint: `https://${process.env.OSS_REGION}.aliyuncs.com`,
credentials: {
accessKeyId: process.env.OSS_ACCESS_KEY_ID,
secretAccessKey: process.env.OSS_ACCESS_KEY_SECRET
},
// forcePathStyle: true, // 阿里云S3兼容模式必须开启
region: process.env.OSS_REGION
});
async function putStream() {
try {
const stream = fs.readFileSync(path.join(__dirname, 'shanf.png'));
const command = new PutObjectCommand({
Bucket: process.env.OSS_BUCKET,
Key: 'bbb/ccc/second.png',
Body: stream,
ContentType: 'image/png'
});
const result = await s3Client.send(command);
console.log('上传成功:', result);
} catch (e) {
console.error('上传异常:', e);
}
}
putStream();

六.在aiagent里面使用过oss
如果在和ai聊天的时候使用图片,那么对应的大模型一定是多模态大模型,也就是他自己得会读图片和视频里面的内容才行。
比如这个就是多模态的,他支持文本,图片,视频

比如这个就是单模态的,他只能输入文本

nodejs代码
js
import 'dotenv/config';
import { ChatOpenAI } from '@langchain/openai';
import { HumanMessage } from '@langchain/core/messages';
const model = new ChatOpenAI({
apiKey: process.env.OPENAI_API_KEY,
model: 'qwen-vl-plus',
configuration: {
baseURL: process.env.OPENAI_BASE_URL,
},
});
const response = await model.invoke([
new HumanMessage({
content: [
{ type: 'text', text: '详细描述这张图片的内容' },
{
type: 'image_url',
image_url: {
url: 'https://agent-bucket999.oss-cn-beijing.aliyuncs.com/%E8%8A%B1%E8%8A%B1.png',
},
},
],
}),
]);
console.log('model: qwen-vl-plus');
console.log(response.content);
我们在代码里面要大模型读取一下这个地址的图片看看

查看结果如下
