Spring AI整合通义千问

SpringAI整合AI大模型(1)

1.SpringAI简介

引言
随着人工智能(AI)技术的快速发展,越来越多的传统软件开发框架开始尝试与 AI 技术结合,以提升开发效率、优化系统性能并提供更智能的功能。作为 Java 生态中最流行的开发框架之一,Spring Framework 在企业级应用开发中占据重要地位。而 SpringAI 是一个假设性但极具前瞻性的概念,它代表了 Spring 框架与人工智能技术深度融合的可能性。本文将探讨 SpringAI 的潜在定义、应用场景以及未来发展方向。

什么是 SpringAI?
SpringAI 并不是一个当前存在的具体项目或工具,而是对 Spring Framework 在未来可能集成人工智能技术的一种设想。可以将其理解为一种扩展或增强版的 Spring Framework,旨在通过引入 AI 技术,使开发者能够更高效地构建智能化应用程序。

核心理念
自动化与智能化:利用机器学习和深度学习算法,自动完成代码生成、测试用例创建、性能调优等任务。
动态适应性:通过实时分析运行时数据,调整应用程序的行为以适应不同的负载条件或用户需求。
增强开发者体验:通过自然语言处理(NLP)技术,让开发者可以通过语音或文本指令与开发工具交互。

2.Spring AI 使用 (采用springAi alibaba,因为原生的springAi 对国内大模型并不友好)

2.1 pom.xml

添加Maven存储库: 在项目的pom.xml中添加spring-ai-alibaba-starter。

        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <artifactId>spring-ai-alibaba-starter</artifactId>
            <version>1.0.0-M5.1</version>
        </dependency>

2.2 应用场景

生成式AI:
借助 Spring AI 的生成式AI能力,开发者可以通过简明的API调用,实现高质量的文本生成、多语言翻译、智能摘要提取等功能。这些功能基于先进的自然语言处理(NLP)技术,能够显著提升应用的内容生成能力和用户体验。

矢量数据库
在需要对大规模文本数据进行语义搜索和相似性匹配时,Spring AI 提供了高效的矢量数据库支持。通过集成最新的向量检索技术,开发者可以轻松实现高精度的语义搜索功能,大幅提升数据查询的效率与相关性。

AI绘画:
针对将文本描述转化为视觉内容的需求,Spring AI 提供了强大的AI绘画功能。该功能基于生成对抗网络(GAN)和其他前沿图像生成技术,能够无缝集成到各类应用场景中,如创意设计、虚拟场景构建等,为用户提供从文本到图像的智能化转换能力。

通过以上核心功能,Spring AI 不仅简化了AI技术的应用开发流程,还为企业和开发者提供了高效、灵活的智能化解决方案。

3.Spring Cloud Alibaba AI 实践

3.1 版本选择

注意:因为 Spring AI Alibaba 基于 Spring Boot 3.x 开发,因此本地 JDK 版本要求为 17 及以上。
我选择了 JDK 17 作为运行环境,Spring Boot 3.4.3 框架。

3.2 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.an</groupId>
    <artifactId>aiApiClient</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>aiApiClient</name>
    <description>aiApiClient</description>

    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <artifactId>spring-ai-alibaba-starter</artifactId>
            <version>1.0.0-M5.1</version>
        </dependency>

        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-s3</artifactId>
            <version>1.12.261</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-core</artifactId>
            <version>5.8.31</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-crypto</artifactId>
            <version>5.8.31</version>
        </dependency>

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>32.1.3-jre</version>
        </dependency>


        <!--mybatis-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
            <version>3.5.5</version>
        </dependency>
        <!-- druid 连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-3-starter</artifactId>
            <version>1.2.20</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>3.0.4</version>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
        </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter-test</artifactId>
        <version>3.0.4</version>
        <scope>test</scope>
    </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.34</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
<!--            <plugin>-->
<!--                <groupId>org.apache.maven.plugins</groupId>-->
<!--                <artifactId>maven-compiler-plugin</artifactId>-->
<!--                <configuration>-->
<!--                    <annotationProcessorPaths>-->
<!--                        <path>-->
<!--                            <groupId>org.projectlombok</groupId>-->
<!--                            <artifactId>lombok</artifactId>-->
<!--                        </path>-->
<!--                    </annotationProcessorPaths>-->
<!--                </configuration>-->
<!--            </plugin>-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

3.2 配置文件

此处很多配置属于自定义配置如果只想实现简单的聊天功能,配置一下端口号就好

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      username: ${MYSQL_USER:root}
      password: ${MYSQL_PWD:root}
      url: jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/${MYSQL_DB:ai}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
  ai:
    nacos:
      prompt:
        template:
          enabled: false
  application:
    name: aiApiClient
  autoconfigure:
    exclude:
      - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
server:
  port: 8080
ai:
  chat:
    scene: 我想咨询你一些医学上的问题,你需要初步判断我的症状,以及给出开药建议以及生活方式建议,以及推荐一些医生治疗
    topP: 0.8
    model: qwen-vl-max-latest
    enableSearch: true
    multiModel: true

file:
  bucketName: ai # 默认存储桶名称
  local: # 本地文件配置信息
    enable: true # 是否开启
    basePath: D:/local/files # 默认路径
    domain: http://localhost:${server.port}

logging:
  level:
    com: DEBUG


阿里云申请api-key:获取api-key
在这里插入图片描述
说明
仅主账号拥有查看全部API-KEY的权限。主账号可以获取所有子账号的API Key,子账号仅能获取自己的API Key。
请不要将API Key以任何方式公开,避免因未经授权的使用造成安全风险或资金损失。
API Key是您的重要资产,请务必妥善保管。如果您单击操作列的删除将已有API Key删除,您将无法继续通过该Key访问百炼大模型提供的各项服务,如果您之前在某些应用程序或服务中集成了这个API Key,那么这些应用将会因为认证失败而无法正常工作。

在这里插入图片描述

3.3 设置 AI_DASHSCOPE_API_KEY 环境变量

AI_DASHSCOPE_API_KEY=阿里云上获取的apiKey
在这里插入图片描述

3.4 对接文本模型

@RestController
@RequestMapping("/api/v1")
public class AlController {


    private final ChatClient dashScopeChatClient;

    
    public AlController(ChatClient dashScopeChatClient) {
        this.dashScopeChatClient = dashScopeChatClient;
    }

    /**
     * 纯文本聊天接口
     * @param query 文本
     * @return ai回复内容
     */
    @GetMapping("/simple/chat")
    public String simpleChat(String query) {
        return dashScopeChatClient.prompt(query).call().content();
    }
 }

3.5 文本加图片输入

@RestController
@RequestMapping("/api/v1")
public class AlController {


    private final ChatClient dashScopeChatClient;


    public AlController(ChatClient dashScopeChatClient) {
        this.dashScopeChatClient = dashScopeChatClient;
    }

    /**
     * 纯文本聊天接口
     * @param query 文本
     * @return ai回复内容
     */
    @GetMapping("/simple/chat")
    public String simpleChat(String query) {
        return dashScopeChatClient.prompt(query).call().content();
    }

    /**
     * 图片+文本接口
     * @param prompt 文本
     * @param imageFile 文件
     * @param response 响应体
     * @return ai回复内容
     */
    @PostMapping("/imageRecognition")
    public String imageRecognition(
            @RequestParam(value = "prompt") String prompt,
            @RequestPart(value = "image",required = false) MultipartFile imageFile,
            HttpServletResponse response) throws IOException {

        if (Objects.isNull(imageFile)) {
            return dashScopeChatClient
                    .prompt(prompt)
                    .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, DEFAULT_CHAT_MEMORY_CONVERSATION_ID)
                            .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10))
                    .call().content();
        }
        UserMessage message = buildAlMsg(prompt, imageFile, response);

        return dashScopeChatClient.prompt(
                new Prompt(message)
        ).advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, DEFAULT_CHAT_MEMORY_CONVERSATION_ID)
                .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10)).call().content();
    }


    /**
     * 图片+文本接口
     * @param prompt 文本
     * @param url 图片资源url
     * @return ai回复内容
     */
    @PostMapping("/recognition")
    public String recognition(
            @RequestParam(value = "prompt") String prompt,
            @RequestParam(value = "url",required = false) String url) throws IOException {

        if (StrUtil.isBlank(url)) {
            return dashScopeChatClient
                    .prompt(prompt)
                    .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, DEFAULT_CHAT_MEMORY_CONVERSATION_ID)
                            .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10))
                    .call().content();
        }

        Resource resource = convertUrlToResource(url);

        // 创建 MimeType 对象
        MimeType mimeType = MimeTypeUtils.parseMimeType(Objects.requireNonNull(APPLICATION_OCTET_STREAM));

        List<Media> mediaList = List.of(new Media(mimeType, resource));
        UserMessage message = new UserMessage(prompt, mediaList);
        message.getMetadata().put(DashScopeChatModel.MESSAGE_FORMAT, MessageFormat.IMAGE);

        return dashScopeChatClient.prompt(
                new Prompt(message)
        ).advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, DEFAULT_CHAT_MEMORY_CONVERSATION_ID)
                .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10)).call().content();

    }

    public static Resource convertUrlToResource(String urlString) throws MalformedURLException {
        URL url = new URL(urlString);

        return new UrlResource(url);
    }

完整代码地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值