Spring AI 嵌入模型

提示:如果不能访问 OpenAI,请点击 AiCode API 注册账号,通过代理访问。  

Spring AI 提供了对嵌入模型(Embedding Models)的支持,支持的嵌入模型包括 OpenAI、Hugging Face、Azure OpenAI 等。这些模型能够将文本转换为向量表示,常用于语义搜索、文本相似性比较等场景。

嵌入模型介绍

AI 嵌入模型(AI Embedding Model)是一种将非结构化数据(如文本、图像、音频、视频等)或结构化数据(如表格数据等)转换为低维、稠密的数值向量(即 “嵌入向量 / Embedding Vector”)的人工智能模型。其核心目标是让转换后的向量能 “捕捉” 原始数据的核心语义、特征或关联关系,且向量间的数学距离(如欧氏距离、余弦相似度)可直接对应原始数据的 “相似性”—— 例如,语义相近的两个句子,其嵌入向量在空间中会更接近。

核心本质:从“原始数据”到“机器可理解的向量”

计算机无法直接理解自然语言、图像等非结构化数据,而嵌入模型的核心作用就是搭建“桥梁”:

(1)对文本:将“猫喜欢吃鱼”这句话转换为 [0.21, -0.56, 0.89, ..., 0.12](假设维度为 768)的向量,且 “猫咪爱吃鱼” 的向量会与它高度相似。

(2)对图像:将一张猫的照片转换为向量后,会与其他猫的照片向量更接近,而与狗的照片向量距离更远。

(3)对用户 ID:将频繁购买母婴用品的用户 ID 转换为向量后,会与其他母婴用品消费者的向量更相似。注意,这里不是真对用户 ID 转换为向量,而是对用户 ID 对应的用户画像转换为向量,如通过一个数组统计用户喜好 [ 运动, 购物, 学习, 旅行],用户 A 的为 [8,1,4,0],用户 B 的为 [1,7,2,0],用户 C 的为 [7,2,3,1],通过数据是不是不难发现用户 A 和 用户 C 的兴趣爱好更接近。

简单示例

下面示例将演示如何使用 Spring AI 调用嵌入模型,计算文本的嵌入向量。详细步骤如下:

依赖配置

首先,需要在 pom.xml 中添加相关依赖(以 OpenAI 为例):

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-openai</artifactId>
</dependency>

完整的 pom.xml 请参考“Spring AI 聊天模型”。

配置模型

创建 application.yml 配置文件,配置 API 密钥,如下:

spring:
  application:
    name: springai_demo1
  #...
  # AI配置
  ai:
    # openai相关配置
    openai:
      # 基础地址
      # 访问 https://api.xty.app/register?aff=pO2q 地址注册账号即可访问 OpenAI 了
      base-url: https://api.xty.app
      # AI KEY
      # 高级接口key
      api-key: sk-vHTHX8D3wNZBfRya831***************
      # 聊天模型配置
      chat:
        options:
          model: gpt-4-turbo # gpt-3.5-turbo
      # 图片模型配置
      image:
        options:
          # 需要高级接口
          model: dall-e-3
    chat:
      memory:
        # 会话历史持久化
        repository:
          jdbc:
            # 启动时不自动执行初始化SQL脚本,手动创建数据表
            initialize-schema: never
      client:
        # true 开启,自动注入 ChatClient,false 关闭,需要手动创建 ChatClient
        enabled: true

# 日志配置
logging:
  charset:
    console: UTF-8
  level:
    root: info
    org.springframework.ai: debug

上述配置中,包含了模型和日志配置。

Java 代码

下面代码使用 OpenAiEmbeddingModel 类来将文本转换为嵌入向量。

OpenAiEmbeddingModel 类是 Spring AI 框架对 OpenAI 嵌入模型的封装,用于便捷地将文本转换为嵌入向量(Embedding Vector),是实现语义检索、文本相似度计算等功能的核心组件。它整合了 OpenAI API 的调用逻辑,同时适配 Spring 生态的设计规范,简化了在 Spring 应用中使用 OpenAI 嵌入服务的流程。

代码如下:

package com.hxstrive.springai.springai_openai.example.embedding_model;

import org.springframework.ai.embedding.Embedding;
import org.springframework.ai.openai.OpenAiEmbeddingModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.Arrays;
import java.util.List;

@SpringBootApplication
public class EmbeddingExample implements CommandLineRunner {

    // 注入 OpenAI 嵌入客户端
    @Autowired
    private OpenAiEmbeddingModel embeddingModel;

    public static void main(String[] args) {
        SpringApplication.run(EmbeddingExample.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        // 示例文本
        List<String> texts = List.of(
            "The quick brown fox jumps over the lazy dog",
            "A fast brown fox leaps over a sleepy dog",
            "Java is a programming language"
        );

        // 生成嵌入向量
        List<float[]> embeddings = embeddingModel.embed(texts);

        // 输出结果
        for (int i = 0; i < texts.size(); i++) {
            System.out.println("文本: " + texts.get(i));
            System.out.println("嵌入向量长度: " + embeddings.get(i).length);

            float[] arr = new float[10];
            System.arraycopy(embeddings.get(i), 0, arr, 0, arr.length);
            System.out.println("前5个向量值: " + Arrays.toString(arr));
            System.out.println("--------------------------------------------------");
        }

        // 计算文本相似度(使用余弦相似度)
        double similarity1 = cosineSimilarity(embeddings.get(0), embeddings.get(1));
        double similarity2 = cosineSimilarity(embeddings.get(0), embeddings.get(2));

        System.out.println("文本1和文本2的相似度: " + similarity1);
        System.out.println("文本1和文本3的相似度: " + similarity2);
    }

    // 计算余弦相似度
    private double cosineSimilarity(float[] vec1, float[] vec2) {
        double dotProduct = 0.0;
        double norm1 = 0.0;
        double norm2 = 0.0;
        
        for (int i = 0; i < vec1.length && i < vec2.length; i++) {
            dotProduct += vec1[i] * vec2[i];
            norm1 += Math.pow(vec1[i], 2);
            norm2 += Math.pow(vec2[i], 2);
        }
        
        return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2));
    }
}

直接运行上述代码,输出如下:

文本: The quick brown fox jumps over the lazy dog
嵌入向量长度: 1536
前5个向量值: [-0.0035696456, 0.00830194, -0.014215737, -0.0045437566, -0.015460085, 0.018627517, -0.020475186, -0.010218739, -0.012883404, -0.028129812]
--------------------------------------------------
文本: A fast brown fox leaps over a sleepy dog
嵌入向量长度: 1536
前5个向量值: [-0.0030607197, 0.008283801, -0.015861526, -0.00885749, -0.016554995, 0.026200516, -0.0018818225, -0.013188518, -0.0038708174, -0.025292702]
--------------------------------------------------
文本: Java is a programming language
嵌入向量长度: 1536
前5个向量值: [0.005201417, -0.0027674206, -0.008592817, -0.014226098, -0.015890043, 0.0071448036, -0.03221195, -0.023549272, 0.0025594274, -0.03650518]
--------------------------------------------------
文本1和文本2的相似度: 0.9463748400918686
文本1和文本3的相似度: 0.782855753697816

余弦相似度用于衡量两个向量(vec1 和 vec2)在方向上的相似程度。计算过程如下:

  • 计算向量点积(dotProduct):通过遍历两个向量的对应元素并相乘后累加,得到点积结果。点积越大,说明向量在方向上越接近。

  • 计算向量的模长(norm1、norm2):分别计算两个向量各元素的平方和,再通过开平方得到模长(向量的长度)。

  • 计算余弦相似度:根据公式 余弦相似度 = 点积 / (向量1的模长 × 向量2的模长),得到最终结果。

结果含义:

  • 余弦相似度的取值范围是 [-1, 1]。

  • 越接近 1:两个向量方向越相似(如语义相近的文本嵌入向量)。

  • 越接近 0:两个向量相关性越低。

  • 越接近 -1:两个向量方向越相反。

注意,要使用其他嵌入模型,只需替换相应的依赖和客户端,并配置对应的 API 密钥或模型路径即可。

 

提示:如果不能访问 OpenAI,请点击 AiCode API 注册账号,通过代理访问。  

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号