当前位置: 首页 > news >正文

JAVA中向量数据库(Milvus)怎么配合大模型使用

在 Java 中,向量数据库(以 Milvus 为例)与大模型的配合是实现 "增强大模型能力" 的核心方案,主要用于解决大模型 "知识时效性差"、"上下文长度有限"、"幻觉生成" 等问题。其核心逻辑是:用 Milvus 存储大模型生成的向量数据(如文本嵌入),通过向量相似性搜索为大模型提供精准上下文,再让大模型基于该上下文生成回答

一、核心原理:向量数据库与大模型的协作流程

  1. 数据预处理与向量生成
    将原始数据(如文档、图片、音频)通过大模型(或专门的嵌入模型)转换为高维向量(Embedding)。例如:用 BERT 将 "Java 是一种编程语言" 转换为 768 维向量。

  2. 向量存储与索引
    将生成的向量及对应原始数据(或元信息)存入 Milvus,Milvus 通过向量索引(如 IVF_FLAT、HNSW)实现高效的相似性搜索(毫秒级返回 TopK 结果)。

  3. 查询与增强生成
    当用户提问时:

    • 先用相同的嵌入模型将问题转换为向量;
    • 在 Milvus 中搜索与问题向量最相似的 TopN 向量,获取对应的原始数据(作为 "上下文知识");
    • 将 "问题 + 上下文知识" 输入大模型(如 GPT、LLaMA),让大模型基于外部知识生成准确回答。

二、环境准备

1. 基础依赖
  • Milvus 服务:安装并启动 Milvus(参考Milvus 官方文档),获取服务地址(如localhost:19530)。

  • Java 开发环境:JDK 11+,Maven/Gradle。

  • 依赖库

    • Milvus Java SDK(用于操作 Milvus);
    • 大模型 / 嵌入模型客户端(如 OpenAI SDK、Hugging Face Java 客户端,或通过 HTTP 调用 API)。

    Maven 依赖示例:

    <!-- Milvus Java SDK -->
    <dependency><groupId>io.milvus</groupId><artifactId>milvus-sdk-java</artifactId><version>2.3.4</version> <!-- 需与Milvus服务版本兼容 -->
    </dependency><!-- 用于调用OpenAI API(生成向量和回答) -->
    <dependency><groupId>com.theokanning.openai-gpt3-java</groupId><artifactId>client</artifactId><version>0.18.0</version>
    </dependency><!-- JSON处理 -->
    <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.15.2</version>
    </dependency>
    

三、具体实现步骤(以 "文档问答系统" 为例)

步骤 1:初始化 Milvus 客户端

首先创建 Milvus 连接,用于后续操作集合(Collection):

import io.milvus.client.MilvusClient;
import io.milvus.client.MilvusServiceClient;
import io.milvus.param.ConnectParam;public class MilvusUtils {// 初始化Milvus客户端public static MilvusClient getMilvusClient() {ConnectParam connectParam = ConnectParam.newBuilder().withHost("localhost") // Milvus服务地址.withPort(19530)      // 端口(默认19530).build();return new MilvusServiceClient(connectParam);}
}
步骤 2:创建 Milvus 集合(存储向量与元数据)

需要定义集合的 Schema,包含:

  • 向量字段(存储嵌入向量,维度需与嵌入模型一致,如 BERT 的 768 维);
  • 主键字段(唯一标识);
  • 元数据字段(如原始文本、文档 ID 等,用于后续提取上下文)。
import io.milvus.param.collection.*;
import io.milvus.grpc.DataType;public class CollectionManager {private static final String COLLECTION_NAME = "document_embeddings"; // 集合名称private static final int VECTOR_DIM = 768; // 向量维度(与嵌入模型一致)// 创建集合public static void createCollection(MilvusClient client) {// 检查集合是否已存在,存在则删除(示例用)if (client.hasCollection(HasCollectionParam.newBuilder().withCollectionName(COLLECTION_NAME).build())) {client.dropCollection(DropCollectionParam.newBuilder().withCollectionName(COLLECTION_NAME).build());}// 定义SchemaFieldType idField = FieldType.newBuilder().withName("id")          // 主键字段名.withDataType(DataType.Int64) // 数据类型.withPrimaryKey(true)    // 设为主键.withAutoID(true)        // 自动生成ID.build();FieldType vectorField = FieldType.newBuilder().withName("embedding")   // 向量字段名.withDataType(DataType.FloatVector) // 浮点向量.withDimension(VECTOR_DIM) // 向量维度.build();FieldType textField = FieldType.newBuilder().withName("original_text") // 原始文本字段(元数据).withDataType(DataType.VarChar) // 字符串类型.withMaxLength(2048)       // 最大长度.build();// 创建集合CreateCollectionParam createParam = CreateCollectionParam.newBuilder().withCollectionName(COLLECTION_NAME).addFieldType(idField).addFieldType(vectorField).addFieldType(textField).withConsistencyLevel(ConsistencyLevelEnum.STRONG) // 一致性级别.build();client.createCollection(createParam);System.out.println("集合创建成功:" + COLLECTION_NAME);}// 创建向量索引(加速搜索)public static void createIndex(MilvusClient client) {IndexType indexType = IndexType.IVF_FLAT; // 常用索引类型(平衡速度与精度)String indexParam = "{\"nlist\": 1024}"; // 索引参数(nlist:聚类数量)CreateIndexParam createIndexParam = CreateIndexParam.newBuilder().withCollectionName(COLLECTION_NAME).withFieldName("embedding") // 对向量字段创建索引.withIndexType(indexType).withIndexParam(indexParam).build();client.createIndex(createIndexParam);System.out.println("向量索引创建成功");}
}
步骤 3:用大模型生成向量并插入 Milvus

需要将原始文档(如 PDF、TXT)拆分为片段(避免长度过长),再用嵌入模型(如 OpenAI 的text-embedding-ada-002)生成向量,最后插入 Milvus。

import com.theokanning.openai.embedding.Embedding;
import com.theokanning.openai.embedding.EmbeddingRequest;
import com.theokanning.openai.service.OpenAiService;
import io.milvus.param.InsertParam;
import io.milvus.response.InsertResponse;
import java.util.ArrayList;
import java.util.List;public class VectorGenerator {private static final String OPENAI_API_KEY = "your_openai_api_key"; // 替换为实际API Keyprivate static final OpenAiService openAiService = new OpenAiService(OPENAI_API_KEY);// 生成文本的嵌入向量(调用OpenAI嵌入模型)public static List<Float> generateEmbedding(String text) {EmbeddingRequest request = EmbeddingRequest.builder().model("text-embedding-ada-002") // 嵌入模型.input(text).build();List<Embedding> embeddings = openAiService.createEmbeddings(request).getData();return embeddings.get(0).getEmbedding(); // 返回向量(1536维,与示例中768维不同,需统一)}// 插入文档片段及向量到Milvuspublic static void insertDocuments(MilvusClient client, List<String> documentChunks) {List<List<Float>> vectors = new ArrayList<>();List<String> texts = new ArrayList<>();// 生成所有片段的向量for (String chunk : documentChunks) {vectors.add(generateEmbedding(chunk));texts.add(chunk);}// 构造插入数据InsertParam insertParam = InsertParam.newBuilder().withCollectionName(CollectionManager.COLLECTION_NAME).addField("embedding", vectors)    // 向量字段.addField("original_text", texts)  // 原始文本字段.build();InsertResponse response = client.insert(insertParam);System.out.println("插入成功,行数:" + response.getInsertCount());// 插入后加载集合(使数据可搜索)client.loadCollection(LoadCollectionParam.newBuilder().withCollectionName(CollectionManager.COLLECTION_NAME).build());}
}
步骤 4:查询时搜索相似向量并调用大模型生成回答

用户提问后,流程如下:

  1. 生成问题的向量;
  2. 在 Milvus 中搜索 TopN 相似向量,获取对应的文档片段;
  3. 将问题 + 文档片段作为上下文,调用大模型生成回答。
import com.theokanning.openai.completion.CompletionRequest;
import io.milvus.param.SearchParam;
import io.milvus.response.SearchResultsWrapper;
import java.util.List;public class QAService {private static final OpenAiService openAiService = new OpenAiService(VectorGenerator.OPENAI_API_KEY);// 搜索与问题相似的文档片段public static List<String> searchSimilarDocs(MilvusClient client, String query, int topK) {// 生成问题的向量List<Float> queryVector = VectorGenerator.generateEmbedding(query);// 构造搜索参数SearchParam searchParam = SearchParam.newBuilder().withCollectionName(CollectionManager.COLLECTION_NAME).withFieldName("embedding") // 搜索向量字段.withQueryVectors(List.of(queryVector)) // 问题向量.withTopK(topK) // 返回前topK个结果.withMetricType(MetricType.L2) // 距离度量(L2:欧氏距离).withParams("{\"nprobe\": 10}") // 搜索参数(nprobe:探测聚类数量,影响精度与速度).addOutField("original_text") // 需要返回的元数据字段.build();// 执行搜索SearchResultsWrapper resultsWrapper = new SearchResultsWrapper(client.search(searchParam).getData());List<String> similarDocs = new ArrayList<>();// 提取结果中的原始文本for (int i = 0; i < resultsWrapper.getRowCount(0); i++) {String text = resultsWrapper.getFieldData(0, i, "original_text", String.class);similarDocs.add(text);}return similarDocs;}// 调用大模型生成回答(结合问题与搜索到的文档)public static String generateAnswer(String query, List<String> contextDocs) {// 构造提示词(将上下文与问题结合)StringBuilder prompt = new StringBuilder();prompt.append("基于以下信息回答问题:\n");for (String doc : contextDocs) {prompt.append("- ").append(doc).append("\n");}prompt.append("问题:").append(query).append("\n回答:");// 调用大模型(如GPT-3.5)CompletionRequest request = CompletionRequest.builder().model("gpt-3.5-turbo-instruct").prompt(prompt.toString()).maxTokens(512) // 最大回答长度.temperature(0.7) // 随机性(0-1,越低越确定).build();return openAiService.createCompletion(request).getChoices().get(0).getText();}
}
步骤 5:整合流程(完整示例)
public class Main {public static void main(String[] args) {// 1. 初始化Milvus客户端MilvusClient client = MilvusUtils.getMilvusClient();// 2. 创建集合和索引CollectionManager.createCollection(client);CollectionManager.createIndex(client);// 3. 准备文档片段(示例:Java相关文档)List<String> documentChunks = List.of("Java是一种跨平台的编程语言,由Sun Microsystems于1995年推出。","Java的特点包括面向对象、平台无关性(通过JVM实现)、安全性等。","Java开发工具包(JDK)包含编译器(javac)、运行时环境(JRE)等工具。");// 4. 插入文档向量到MilvusVectorGenerator.insertDocuments(client, documentChunks);// 5. 模拟用户提问并生成回答String userQuery = "Java的特点有哪些?";List<String> contextDocs = QAService.searchSimilarDocs(client, userQuery, 2); // 搜索前2个相似文档String answer = QAService.generateAnswer(userQuery, contextDocs);System.out.println("用户问题:" + userQuery);System.out.println("回答:" + answer);// 关闭客户端client.close();}
}

四、关键注意事项

  1. 向量维度一致性:嵌入模型生成的向量维度必须与 Milvus 集合中定义的维度完全一致(如示例中若用text-embedding-ada-002,维度为 1536,需修改VECTOR_DIM)。
  2. 索引选择
    • 追求精度:用IVF_FLAT(精确但速度中等);
    • 追求速度:用HNSW(近似但速度快,适合高维向量)。
  3. 文档分块策略:原始文档需拆分(如每 200 字一段),避免长度超过嵌入模型的输入限制(如 GPT 模型通常支持 2048 tokens)。
  4. 大模型选择
    • 嵌入模型:开源可选sentence-transformers(Java 可通过 JNI 调用或 HTTP 服务),闭源可选 OpenAI/Anthropic 的 API;
    • 生成模型:开源可选 LLaMA(需本地部署),闭源可选 GPT-4、Claude 等。

五、应用场景

  • 智能问答:基于企业内部文档回答员工问题(如 "公司年假政策是什么?");
  • 推荐系统:通过用户行为向量与物品向量的相似性推荐内容;
  • 图像检索:将图片转换为向量,搜索相似图片(需配合图像嵌入模型)。

通过这种方式,大模型可以结合外部知识库生成更准确、更具时效性的回答,解决了其原生的知识局限问题。

http://www.dtcms.com/a/341609.html

相关文章:

  • 简笔成画:让AI绘画变得简单而有趣
  • pyecharts可视化图表仪表盘_Gauge:从入门到精通
  • 【Linux】重生之从零开始学习运维之LVS
  • UUID(通用唯一标识符)详解和实践
  • 今日行情明日机会——20250820
  • K8S集群-基于Ingress资源实现域名访问
  • 软件测试面试题真题分享
  • 华为云之基于鲲鹏弹性云服务器部署openGauss数据库【玩转华为云】
  • VMware Workstation | 安装Ubuntu20.04.5
  • 红警国家的注册
  • Linux系统:管道通信
  • 牛津大学xDeepMind 自然语言处理(4)
  • README
  • AVL左旋右旋 学习小得
  • 【机器学习】什么是损失景观(Loss Landscape)?
  • Claude Code Git Commit Push 命令
  • 大模型4位量化 (46)
  • linux内核源码下载
  • CMOS知识点 MOS管不同工作区域电容特性
  • SED项目复现学习实录
  • Linux基础介绍-3——第一阶段
  • oracle服务器导入dmp文件
  • 力扣 hot100 Day79
  • ragflow 通过HuggingFace 配置rerank模型
  • 有序二叉树的删除
  • leetcode 3 无重复字符的最长子串
  • 个人使用AI开发的《PlSqlRewrite4GaussDB(PLSQL自动转换工具)1.0.1 BETA》发布
  • 【OneAI】使用Rust构建的轻量AI网关
  • linux环境问题
  • HyperMesh许可证分配优化策略