接下啦,我们利用SpringAI发起大模型的第一次对话。

Java领域实现大模型开发,有两个非常重要的框架

SpringAI   LangChin4j

SpringAI最低支持的jdk版本是17

L盎Chin4j最低支持的版本是8

1、快速入门

 创建工程

        创建一个新的SpringBoo工程,勾选Web、MySQL驱动即可:

引入依赖

        SpringAI完全适配了SpringBoot的自动装配功能,而且给不同的大模型提供了不同的starter,比如:

模型/平台

starter

Anthropic

<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-anthropic-spring-boot-starter</artifactId> </dependency>

Azure OpenAI

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

DeepSeek

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

Hugging Face

<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-huggingface-spring-boot-starter</artifactId> </dependency>

Ollama

<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-ollama-spring-boot-starter</artifactId> </dependency>

OpenAI

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

        我们可以根据自己选择的平台来选择引入不同的依赖。这里我们先以OpenAI为例。

        首先,在项目pom.xml中添加spring-ai的版本信息:

<spring-ai.version>1.0.0-SNAPSHOT</spring-ai.version>

        然后,添加spring-ai的依赖管理项:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>${spring-ai.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

        最后,引入spring-ai-openai的依赖:

<dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-openai</artifactId>
            <version>${spring-ai.version}</version>
        </dependency>

        为了方便后续开发,我们再手动引入一个Lombok依赖:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.22</version>
</dependency>

        注意:千万不要用start.spring.io提供的lombok,有bug!!!

全部的完整的pom文件如下:

<?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.5.9</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.ruangong</groupId>
    <artifactId>SpringAIDemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>SpringAIDemo</name>
    <description>SpringAIDemo</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>17</java.version>
        <spring-ai.version>1.0.0-SNAPSHOT</spring-ai.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>${spring-ai.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-openai</artifactId>
            <version>${spring-ai.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

配置模型信息

        接下来,我们还要在配置文件中配置模型的参数信息。

        以openai为例,我们将application.properties修改为application.yaml,然后添加下面的内容:

spring:
  application:
    name: ai-demo
  # Spring AI配置
  ai:
    openai:
      api-key: sk-qramtwqoiatggvuqzeihfesuxpaoeguqwprzdtgtaceajnfd
      base-url: https://api.siliconflow.cn
      chat:
        options:
          model: deepseek-ai/DeepSeek-V3
          temperature: 0.7
        completions-path: /v1/chat/completions

ChatClient

        ChatClient中封装了与AI大模型对话的各种API,同时支持同步或响应式交互。不过,在使用之前,首先我们需要声明一个ChatClient。

        在对应配置文件包下创建一个CommonConfiguration类

package com.ruangong.springai.config;



import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CommonConfiguration {

    

    /**
     * 配置 ChatClient - OpenAI兼容的聊天客户端
     *
     * Spring AI 会自动扫描带有 @Tool 注解的方法,无需手动注册
     *
     * @param openAiChatModel OpenAI Chat模型(由Spring AI自动配置)
     * @param chatMemory 会话记忆存储
     * @return ChatClient 实例
     */
    @Bean("open-ai")
    public ChatClient openAIChatClient(
            OpenAiChatModel openAiChatModel,
            ChatMemory chatMemory) {
        return ChatClient.builder(openAiChatModel)
                .build();
    }
}

 代码解读:

        ChatClient.builder:会得到一个ChatClient.Builder工厂对象,利用它可以自由选择模型、添加各种自定义配置

        OpenAiChatModel:如果你引入了openai的starter,这里就可以自动注入OpenAiChatModel对象。

同步调用

        接下来,我们定义一个Controller,在其中接收用户发送的提示词,然后把提示词发送给大模型,交给大模型处理,拿到结果后返回。

package com.ruangong.springai.controller;

import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RestController
@RequestMapping("/ai")
public class ChatController {

    private final ChatClient chatClient;
    // 请求方式和路径不要改动,将来要与前端联调
    @RequestMapping("/chat")
    public String chat(@RequestParam(defaultValue = "讲个笑话") String prompt) {
        return chatClient
                .prompt(prompt) // 传入user提示词
                .call() // 同步请求,会等待AI全部输出完才返回结果
                .content(); //返回响应内容
    }
}

        请求地址:http://localhost:8080/ai/chat

        注意,基于call()方法的调用属于同步调用,需要所有响应结果全部返回后才能返回给前端。启动项目,在浏览器中访问:http://localhost:8080/ai/chat?prompt=你好

流式调用

        同步调用需要等待很长时间页面才能看到结果,用户体验不好。为了解决这个问题,我们可以改进调用方式为流式调用。

        在SpringAI中使用了WebFlux技术实现流式调用。

        在chatController中添加了chat2方法

// 注意看返回值,是Flux<String>,也就是流式结果,另外需要设定响应类型和编码,不然前端会乱码
@RequestMapping(value = "/chat2", produces = "text/html;charset=UTF-8")
public Flux<String> chat2(@RequestParam(defaultValue = "讲个笑话") String prompt) {
    return chatClient
    .prompt(prompt)
    .stream() // 流式调用
    .content();
}

        重启测试,再次访问,会一点点生成数据展示在页面上。

System设定

        可以发现,当我们询问AI你是谁的时候,它回答自己是DeepSeek-R1,这是大模型底层的设定。如果我们希望AI按照新的设定工作,就需要给它设置System背景信息。

        在SpringAI中,设置System信息非常方便,不需要在每次发送时封装到Message,而是创建ChatClient时指定即可。

        我们修改CommonConfiguration中的代码,给ChatClient设定默认的System信息:

@Bean
    public ChatClient chatClient(OpenAiChatModel model) {
        return ChatClient.builder(model) // 创建ChatClient工厂实例
                .defaultSystem("您是一家专门做非遗产品的客户聊天助手,你的名字叫小一。请以友好、乐于助人和愉快的方式解答学生的各种问题。")
                .defaultAdvisors(new SimpleLoggerAdvisor())
                .build(); // 构建ChatClient实例

    }

        我们再次询问“你是谁?”

  上下文设定

        假如你问它 假如你有12个苹果分给2个人,每个人分几个? 它回答完了,你再问他(分给三个人呢?)它不知道要分配苹果,并且也不知道是12个苹果,说明当前的chatAI不具备了解上下文的能力?怎么办?

        CommonConfig 添加如下方法:

public static final Integer MAX_MEMORY_MESSAGE_SIZE = 30;

    /**
     * 配置 ChatMemory - 内存存储的会话记忆
     *
     * @return ChatMemory 内存存储的会话记忆实例
     */
    @Bean
    public ChatMemory chatMemory() {
        return MessageWindowChatMemory.builder()
                .maxMessages(MAX_MEMORY_MESSAGE_SIZE) // 窗口最大消息数目,保留最近30条消息
                .build();
    }

      并且调用:

@Bean("open-ai")
    public ChatClient openAIChatConfig(OpenAiChatModel openAiChatModel,ChatMemory chatMemory){
        return ChatClient.
                builder(openAiChatModel)
                .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory()).build())
                .build();
    }

        然后重试,发现可行:

2、日志功能

        默认情况下,应用于AI的交互时不记录日志的,我们无法得到SpringAI组织的提示词到底长什么样,有没有问题。这样不方便我们调试。

        Advisor

        SpringAI基于AOP机制实现与大模型对话过程的增强、拦截、修改等功能。所有的增强通知都需要实现Advisor接口。

        Spring提供了一些Advisor的默认实现,来实现一些基本的增强功能。

        SimpleLoggerAdvisor:日志记录的Advisor

        MessageChatMemoryAdvisor:会话记忆的Advisor

        QuestionAnswerAdvisor:实现RAG的Advisor

当然,我们也可以自定义Advisor,具体可以参考:

https://docs.spring.io/spring-ai/reference/1.0/api/advisors.html#_implementing_an_advisor

        添加日志Advisor

        首先,我们需要修改CommonConfiguration,给ChatClient添加日志Advisor:

@Bean("open-ai")
    public ChatClient openAIChatConfig(OpenAiChatModel openAiChatModel,ChatMemory chatMemory){
        return ChatClient.
                builder(openAiChatModel)
                .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory()).build())
                .defaultAdvisors(new SimpleLoggerAdvisor())
                .build();
    }

        修改日志级别

        接下来,我们在application.yaml中添加日志配置,更新日志级别:

        位置要顶格写,不要写在spring标签的下面

logging:
  level:
    org.springframework.ai: debug # AI对话的日志级别
    com.ruangong.springai: debug # 本项目的日志级别

        重启项目,再次聊天就能看到AI对话的日志信息了。

         3、对接前端

        在浏览器通过地址访问,非常麻烦,也不够优雅,如果能有一个优美的前端页面就好了。别着急,我提前给大家准备了一个前端页面。而且有两种不同的运行方式。、

        npm运行

        在材料中给大家提供了前端的源代码:

        直接 npm run dev即可启动

        解决CORS问题

        前后端在不同域名,存在跨域问题,因此我们需要在服务器端解决cors问题。在config包中添加一个MvcConfiguration类:



import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MvcConfiguration implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("*")
                .exposedHeaders("Content-Disposition");
    }
}

        重启服务,如果你的服务端接口正常,那么应该就可以聊天了。

        注意:前端访问服务端的默认路径是:http://localhost:8080

        聊天对话的接口是:POST /ai/chat

        请确保你的服务端接口也是这样。

        恭喜您,你的第一个AI对话机器人就完成了。

4、补充说明:

        Ollama(Ollama):ollama 是一个软件,可以在ollama 下载各种大模型

        硅基流动  https://www.siliconflow.cn/

        硅基流动:就是大模型的商店,里面有各种正在售卖的大模型可以被调用

      

        

       

        

       

        

                

        

        

    

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐