Spring AI 从入门到精通-Embedding 7. EmbeddingAI 的理解从数字开始7.1 一个比喻气味地图想象你走进一家咖啡店你闻到咖啡的香气、烤面包的焦味、还有一点点奶香。你的大脑不需要看到咖啡豆三个字就能判断这是咖啡店。Embedding嵌入就是这个过程的数字版。它把一段文字转换成一串浮点数向量这串数字代表了文字的含义。语义相近的文字向量在空间中距离也近。距离近距离远咖啡[0.23, -0.45, 0.78, ...]拿铁[0.21, -0.42, 0.80, ...]汽车[-0.67, 0.12, -0.33, ...]7.2 EmbeddingModel 接口Spring AI 的EmbeddingModel接口极其简洁publicinterfaceEmbeddingModelextendsModelEmbeddingRequest,EmbeddingResponse{// 嵌入一段文本float[]embed(Stringtext);// 嵌入一个 Document 对象float[]embed(Documentdocument);// 批量嵌入Listfloat[]embed(ListStringtexts);// 嵌入并返回完整响应含元数据EmbeddingResponseembedForResponse(ListStringtexts);// 获取向量维度intdimensions();}7.3 第一个 Embedding 示例AutowiredprivateEmbeddingModelembeddingModel;publicvoiddemo(){// 嵌入一段文本float[]vectorembeddingModel.embed(Spring AI 是一个强大的 AI 框架);System.out.println(向量维度: vector.length);// 比如 1536OpenAI或 768OllamaSystem.out.println(前 5 个值: Arrays.toString(Arrays.copyOf(vector,5)));// 输出示例: [0.0123, -0.0456, 0.0789, 0.0234, -0.0567]// 批量嵌入Listfloat[]vectorsembeddingModel.embed(List.of(Java 编程语言,Python 编程语言,今天天气很好));// 计算余弦相似度doublesimilaritycosineSimilarity(vectors.get(0),vectors.get(1));System.out.println(Java 和 Python 的相似度: similarity);// 应该很高比如 0.85doublesimilarity2cosineSimilarity(vectors.get(0),vectors.get(2));System.out.println(Java 和天气的相似度: similarity2);// 应该很低比如 0.12}// 余弦相似度计算衡量两个向量在方向上的相似程度// 值越接近 1 表示语义越相似越接近 0 表示越不相关privatedoublecosineSimilarity(float[]a,float[]b){doubledot0,normA0,normB0;for(inti0;ia.length;i){dota[i]*b[i];normAa[i]*a[i];normBb[i]*b[i];}returndot/(Math.sqrt(normA)*Math.sqrt(normB));}7.4 支持的 Embedding 模型提供商依赖维度特点OpenAIspring-ai-starter-model-openai1536/3072最常用Azure OpenAIspring-ai-starter-model-azure-openai1536企业合规Ollamaspring-ai-starter-model-ollama768/4096免费本地Transformers (ONNX)spring-ai-starter-model-transformers384/768纯本地无网络Vertex AIspring-ai-starter-model-vertex-ai768Google 生态Bedrockspring-ai-starter-model-bedrock1024/1536AWS 生态Mistral AIspring-ai-starter-model-mistral-ai1024欧洲厂商7.5 配置 Embedding 模型# OpenAI Embedding spring.ai.openai.api-key${OPENAI_API_KEY} spring.ai.openai.embedding.options.modeltext-embedding-3-small # Ollama Embedding免费本地 spring.ai.ollama.embedding.options.modelnomic-embed-text7.6 Document 对象带元数据的文本在 RAG 场景中我们不只嵌入纯文本而是嵌入带元数据的Document对象DocumentdocnewDocument(Spring AI 是 Spring 生态的 AI 框架支持多种模型和向量数据库。,Map.of(source,官方文档,page,1,author,Spring 团队,category,AI));float[]embeddingembeddingModel.embed(doc);// 元数据可用于后续过滤7.7 一个完整的相似度搜索 DemoServicepublicclassSemanticSearchService{privatefinalEmbeddingModelembeddingModel;publicSemanticSearchService(EmbeddingModelembeddingModel){this.embeddingModelembeddingModel;}/** * 在候选文档中搜索与查询最相似的文档 */publicListScoredDocumentsearch(Stringquery,ListDocumentcandidates,inttopK){// 1. 嵌入查询float[]queryEmbeddingembeddingModel.embed(query);// 2. 嵌入所有候选文档批量Listfloat[]candidateEmbeddingsembeddingModel.embed(candidates.stream().map(Document::getText).toList());// 3. 计算相似度并排序returnIntStream.range(0,candidates.size()).mapToObj(i-newScoredDocument(candidates.get(i),cosineSimilarity(queryEmbedding,candidateEmbeddings.get(i)))).sorted((a,b)-Double.compare(b.score,a.score)).limit(topK).toList();}}recordScoredDocument(Documentdocument,doublescore){}