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

基于Spring AI alibaba组件AI问答功能开发示例

基于Spring AI alibaba组件AI问答功能开发示例

功能效果图:
在这里插入图片描述
http://localhost:9999/ai/test
http://localhost:9999/ai/chat?input=ai

配置 application.yaml 指定 API-KEY(可通过访问阿里云百炼模型服务平台获取,有免费额度可用。)
阿里云百炼
阿里云百炼模型服务平台
https://ai.aliyun.com/

架构版本
JDK17
SpringBoot3.3.3
Spring-AI 1.0.0-M3
Spring-AI-Alibaba1.0.0-M3.1
vue3

架构版本JDK17
SpringBoot3.3.3
Spring-AI 1.0.0-M3
Spring-AI-Alibaba1.0.0-M3.1
vue3

aiApplication.java入口类

package com.cwgis;

import com.cwgis.pg.function.MockOrderService;
import com.cwgis.pg.function.Response;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Description;

import java.util.function.Function;

/**
 * Hello world!
 */
@SpringBootApplication
public class aiApplication {
    public static void main(String[] args) {
        SpringApplication.run(aiApplication.class, args);
        System.out.println("===============");
        System.out.println("ai服务正在运行中!");
        System.out.println("===============");
    }

    @Bean
    @Description("根据用户编号和订单编号查询订单信息")
    public Function<MockOrderService.Request, Response> getOrderFunction(
            MockOrderService mockOrderService) {
        return mockOrderService::getOrder;
    }
}

ChatController.java问答服务类

package com.cwgis;

import com.cwgis.pg.core.AjaxResult;
import com.cwgis.pg.function.MJDLTBService;
import com.cwgis.pg.function.MockWeatherService;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.util.Objects;


@RestController
@RequestMapping("/ai")
public class ChatController {
    private final ChatClient chatClient;

    public ChatController(ChatClient.Builder builder) {
        this.chatClient = builder.build();
    }

    @GetMapping("/test")
    public AjaxResult test() {
        String r= this.chatClient.prompt().user("测试").call().content();
        return AjaxResult.success(r);
    }

    //自动加载自定义function函数
    @PostMapping("/chat")
    public AjaxResult chat(String input) {
        String r= this.chatClient.prompt()
                .function("getWeather", "根据城市查询天气", new MockWeatherService())
                .functions("getOrderFunction")     //获取aiApplication类中注册的Bean函数
                .function("MJDLTBService","根据城市和地类名称查询地类图斑面积",new MJDLTBService())
                .user(input).call().content();
        return AjaxResult.success(r);
    }

    @PostMapping("/stream")
    public AjaxResult stream(String input) {

        Flux<String> content = this.chatClient.prompt().user(input).stream().content();
        String r= Objects.requireNonNull(content.collectList().block()).stream().reduce((a, b) -> a + b).get();
        return AjaxResult.success(r);
    }
    //函数调用
    @PostMapping("/weather-service")
    public AjaxResult weatherService(String subject) {
        String r= chatClient.prompt()
                .function("getWeather", "根据城市查询天气", new MockWeatherService())
                .user(subject)
                .call()
                .content();
        return AjaxResult.success(r);
    }
    @PostMapping("/order-detail")
    public AjaxResult orderDetail() {
        String r= chatClient.prompt()
                .functions("getOrderFunction")     //获取aiApplication类中注册的Bean函数
                .user("帮我查询一下订单, 用户编号为1001, 订单编号为2001")
                .call()
                .content();
        return AjaxResult.success(r);
    }
    //
}

MJDLTBService.java自定义服务函数

package com.cwgis.pg.function;

import com.fasterxml.jackson.annotation.JsonClassDescription;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;

import java.util.function.Function;

//采用AI问答模式,从本地数据库中查询地类面积值的功能
public class MJDLTBService implements Function<MJDLTBService.Request, Response> {

    @Override
    public Response apply(MJDLTBService.Request request) {
        String city=request.city();
        String dlmc=request.dlmc();
        if(city!=null && dlmc!=null)
        {
            //到数据库中去查询,用sql语句查询
            String sql="select sum(tbmj) from dltb where zldwmc like '%"+request.city()+"%' and dlmc like '%"+request.dlmc()+"%'";
            //sde.getValueDouble(sql);
            return new Response(String.format("%s%s的地类面积为查询后面积值500亩", request.city(),request.dlmc()));
        }
        else {
            return new Response(String.format("暂时无法查询%s的地类面积。", request.city()));
        }
    }

    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonClassDescription("根据城市和地类名称查询地类图斑面积")
    public record Request(
            @JsonProperty(required = true, value = "city") @JsonPropertyDescription("城市, 比如杭州") String city,
            @JsonProperty(required = true, value = "dlmc") @JsonPropertyDescription("地类, 比如水田、旱地、耕地、园地、林地、草地、建设用地、农用地、未利用地") String dlmc) {
    }

}

MockWeatherService.java自定义天气查询服务

package com.cwgis.pg.function;

import java.util.function.Function;

import com.fasterxml.jackson.annotation.JsonClassDescription;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;

public class MockWeatherService implements Function<MockWeatherService.Request, Response> {

    @Override
    public Response apply(Request request) {
        if (request.city().contains("杭州")) {
            return new Response(String.format("%s%s晴转多云, 气温32摄氏度。", request.date(), request.city()));
        }
        else if (request.city().contains("上海")) {
            return new Response(String.format("%s%s多云转阴, 气温31摄氏度。", request.date(), request.city()));
        }
        else if (request.city().contains("成都")) {
            return new Response(String.format("%s%s阴转小雨, 气温5摄氏度。", request.date(), request.city()));
        }
        else {
            return new Response(String.format("暂时无法查询%s的天气状况。", request.city()));
        }
    }

    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonClassDescription("根据日期和城市查询天气")
    public record Request(
            @JsonProperty(required = true, value = "city") @JsonPropertyDescription("城市, 比如杭州") String city,
            @JsonProperty(required = true, value = "date") @JsonPropertyDescription("日期, 比如2024-08-22") String date) {
    }

}
public record Response(String description) {
}

resources/application.yml应用配置参数

#基本配置
server.port: 9999
server.tomcat.max-http-form-post-size: 5120MB
spring:
  application:
    name: galaxy-ai

  ai:
    dashscope:
      api-key: sk-111111111111111111111111111

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.cwgis</groupId>
  <artifactId>galaxy-ai</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>galaxy-ai</name>
  <description>Building AI applications with Spring Boot</description>
  <!-- FIXME change it to the project's website -->
  <url>http://www.cwgis.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>17</java.version>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>

    <spring-boot.version>3.3.3</spring-boot.version>

    <commons.io.version>2.13.0</commons.io.version>
    <commons.text.version>1.6</commons.text.version>
    <commons.lang3.version>3.12.0</commons.lang3.version>
    <commons.fileupload.version>1.3.3</commons.fileupload.version>

    <!-- Spring AI -->
    <spring-ai.version>1.0.0-M3</spring-ai.version>
    <spring-ai-alibaba.version>1.0.0-M3.1</spring-ai-alibaba.version>
    <dashscope-sdk-java.version>2.15.1</dashscope-sdk-java.version>

    <!-- plugin versions -->
    <maven-compiler-plugin.version>3.11.0</maven-compiler-plugin.version>
    <maven-surefire-plugin.version>3.1.2</maven-surefire-plugin.version>
    <maven-failsafe-plugin.version>3.1.2</maven-failsafe-plugin.version>
    <maven-javadoc-plugin.version>3.5.0</maven-javadoc-plugin.version>
    <maven-source-plugin.version>3.3.0</maven-source-plugin.version>
    <jacoco-maven-plugin.version>0.8.10</jacoco-maven-plugin.version>
    <flatten-maven-plugin.version>1.5.0</flatten-maven-plugin.version>
    <maven-deploy-plugin.version>3.1.1</maven-deploy-plugin.version>
    <asciidoctor-maven-plugin.version>2.2.3</asciidoctor-maven-plugin.version>
    <maven-assembly-plugin.version>3.7.0</maven-assembly-plugin.version>
    <maven-dependency-plugin.version>3.5.0</maven-dependency-plugin.version>
    <maven-site-plugin.version>4.0.0-M13</maven-site-plugin.version>
    <maven-project-info-reports-plugin.version>3.4.5</maven-project-info-reports-plugin.version>
    <maven-jar-plugin.version>3.3.0</maven-jar-plugin.version>
    <spring-javaformat-maven-plugin.version>0.0.39</spring-javaformat-maven-plugin.version>
    <maven-gpg-plugin.version>3.0.1</maven-gpg-plugin.version>
  </properties>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.junit</groupId>
        <artifactId>junit-bom</artifactId>
        <version>5.11.0</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>

      <!--常用工具类 -->
      <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>${commons.io.version}</version>
      </dependency>
      <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-text</artifactId>
        <version>${commons.text.version}</version>
      </dependency>
      <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>common-lang3</artifactId>
        <version>${commons.lang3.version}</version>
      </dependency>
      <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>${hutool.version}</version>
      </dependency>

      <!--add alibaba java lib -->
      <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dashscope-sdk-java</artifactId>
        <version>${dashscope-sdk-java.version}</version>
        <exclusions>
          <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
          </exclusion>
          <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
          </exclusion>
        </exclusions>
      </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>${spring-boot.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <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.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <scope>test</scope>
    </dependency>
    <!-- Optionally: parameterized tests support -->
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-params</artifactId>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.12.0</version> <!-- 检查是否有新版本并相应更新 -->
    </dependency>

    <dependency>
      <groupId>com.alibaba.cloud.ai</groupId>
      <artifactId>spring-ai-alibaba-starter</artifactId>
      <version>${spring-ai-alibaba.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <version>${spring-boot.version}</version>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <groupId>io.spring.javaformat</groupId>
          <artifactId>spring-javaformat-maven-plugin</artifactId>
          <version>${spring-javaformat-maven-plugin.version}</version>
          <executions>
            <execution>
              <phase>validate</phase>
              <inherited>true</inherited>
              <goals>
                <goal>validate</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-site-plugin</artifactId>
          <version>${maven-site-plugin.version}</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>${maven-compiler-plugin.version}</version>
          <configuration>
            <release>${java.version}</release>
            <compilerArgs>
              <compilerArg>-parameters</compilerArg>
            </compilerArgs>
          </configuration>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>${maven-surefire-plugin.version}</version>
          <configuration>
            <argLine>${surefireArgLine}</argLine>
          </configuration>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-jar-plugin</artifactId>
          <version>${maven-jar-plugin.version}</version>
          <configuration>
            <archive>
              <manifestEntries>
                <Implementation-Title>${project.artifactId}</Implementation-Title>
                <Implementation-Version>${project.version}</Implementation-Version>
              </manifestEntries>
            </archive>
          </configuration>
        </plugin>
        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>flatten-maven-plugin</artifactId>
          <version>${flatten-maven-plugin.version}</version>
          <executions>
            <execution>
              <id>flatten</id>
              <phase>process-resources</phase>
              <goals>
                <goal>flatten</goal>
              </goals>
              <configuration>
                <updatePomFile>true</updatePomFile>
                <flattenMode>ossrh</flattenMode>
                <pomElements>
                  <distributionManagement>remove</distributionManagement>
                  <dependencyManagement>remove</dependencyManagement>
                  <repositories>remove</repositories>
                  <scm>keep</scm>
                  <url>keep</url>
                  <organization>resolve</organization>
                </pomElements>
              </configuration>
            </execution>
            <execution>
              <id>clean</id>
              <phase>clean</phase>
              <goals>
                <goal>clean</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>${maven-deploy-plugin.version}</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>

  <repositories>
    <repository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/milestone</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>
</project>

ai.ts前端访问代码

import request from "@/utils/request"

export function chat(msg) {    
    let data={
        input:msg
    };
    //let ai_url=config.ai_url;
      //var jsonStr=JSON.stringify(data);
     return request({baseURL:"/ai",url:'/ai/chat?input='+msg,method:'post'});    
}

export function test() {
     // var jsonStr=JSON.stringify(data);
     //let ai_url=config.ai_url;
     return request({baseURL:"/ai",url:'/ai/test',method:'get'});    
}

export function weatherService(msg) {    
    let data={
        input:msg
    };
    //let ai_url=config.ai_url;
      //var jsonStr=JSON.stringify(data);
     return request({baseURL:"/ai",url:'/ai/weather-service?subject='+msg,method:'post'});    
}

export function orderDetail() {
    // var jsonStr=JSON.stringify(data);
    //let ai_url=config.ai_url;
    return request({baseURL:"/ai",url:'/ai/order-detail',method:'post'});    
}

前端index.vue页面

<template>
    <div v-loading="loading" class="app" element-loading-text="数据请求中">      
      <div class="app_content">请在下面输入框提问后搜索</div>

      <a-textarea v-model:value="msgAsk" placeholder="Basic usage" :rows="20" />

      <a-input-search
      v-model:value="msg"
      placeholder="请输入要搜索的信息"
      enter-button="搜索"
      size="large"      
      @search="searchClick"
    />
    </div>    
</template>
<script setup lang="ts">
import * as page    from "@/api/vuePage"
import * as ai      from "@/api/ai"

//
const loading = page.ts_ref(false);
let msg=page.ts_ref("");
let msgAsk=page.ts_ref("");

const  searchClick=async function(){
    loading.value=true;
    //page.showMsg(msg.value);

    let r=await ai.chat(msg.value);
    msgAsk.value=r.msg;

    //console.log(r);
    //debugger;

    //let r=await ai.orderDetail();
    //msgAsk.value=r.msg;

    //let r=await ai.weatherService(msg.value);
    //msgAsk.value=r.msg;
    //
    loading.value=false;
}

</script>

<style scoped lang="less">
.app{
  border: 1px solid #ccc;
  height: 99%;
  margin: 0 auto;
  width: 1024px;
  background-color: white;
  box-shadow: 0 0 20px 3px #ccc;

  .app_header {
    text-align: center;
    border-bottom: 1px solid #9a9a9a;
    height: 90px;

    .app_title {
      font-size: 24px;
      font-weight: bolder;
      height: 90px;
      line-height: 90px;
      box-sizing: border-box;
      color: #2f2f2f;
    }

    .date {
      margin-top: 10px;
      font-size: 15px;
      height: 40px;
      color: #8a8a8a;
      background-color: #ebe6eb;
      line-height: 40px;
    }
  }

  .app_content {
    margin-top: 15px;
    min-height: 30px;
    padding: 20px;
    box-sizing: border-box;
    overflow: auto;
    height: 12%;
  }
}
</style>

本blog地址:https://blog.csdn.net/hsg77


http://www.kler.cn/a/404464.html

相关文章:

  • web钩子什么意思
  • 输出比较简介
  • 23种设计模式速记法
  • 51c自动驾驶~合集31
  • Sourcetree登录GitLab账号
  • centos7.9单机版安装K8s
  • SpringBoot提交参数去除前后空格
  • Linux firewall防火墙规则
  • Spring Security 安全认证框架
  • 详解Oracle表的类型(一)
  • Makefile 之 join
  • 2024年亚太地区数学建模大赛A题-复杂场景下水下图像增强技术的研究
  • #Uniapp篇:支持纯血鸿蒙发布适配UIUI
  • Spring Boot教程之Spring Boot简介
  • mysql 唯一键
  • ssm157基于Vue框架的订餐系统+vue(论文+源码)_kaic
  • 45.坑王驾到第九期:Mac安装typescript后tsc命令无效的问题
  • 鸿蒙学习高效开发与测试-应用程序框架和HarmonyOS SDK(3)
  • 【网络工程】查看自己电脑网络IP,检查网络是否连通
  • 算法【最长递增子序列问题与扩展】
  • 移动应用开发:Android Studio实现简易注册页(数据存放以SharedPreferences形式)
  • 奇异值分解和深度学习
  • Linux-Nginx虚拟主机
  • 【智谱清言-注册_登录安全分析报告】
  • MACOS开发、使用常见问题汇总
  • 算法全解析:从分治法到双指针的详细指南