JAVA实现人工智能,采用框架SpringAI

Spring AI介绍

Spring
AI是AI工程师的一个应用框架,它提供了一个友好的API和开发AI应用的抽象,旨在简化AI应用的开发工序,例如开发一款基于ChatGPT的对话应用程序。

目前该项目已经集成了OpenAI、Azure OpenAI、Hugging
Face、Ollama等API。不过,对于集成了OpenAI接口的项目,只要再搭配One-API项目,就可以调用目前主流的大语言模型了。

使用介绍

在介绍如何使用Spring AI开发一个对话接口之前,我先介绍下ChatGPT应用的开发原理。

首先,ChatGPT是OpenAI推出的一款生成式人工智能大语言模型,OpenAI为了ChatGPT能够得到广泛应用,向开发者提供了ChatGPT的使用接口,开发者只需使用OpenAI为开发者提供的Key,向OpenAI提供的接口地址发起各种形式的请求就可以使用ChatGPT。因此,开发一款ChatGPT应用并不是让你使用人工智能那套技术进行训练和开发,而是作为搬运工,通过向OpenAI提供的ChatGPT接口发起请求来获取ChatGPT响应,基于这一流程来开发的。

项目前提

本人已经本地部署chatglm3-6b+oneapi 项目环境

项目结构

在这里插入图片描述

第一种方式采用openai
1. pom文件:

SpringAI 官网 新版本,由于我本地chatglm3-6b openai 接口实现暂不支持请求体解析,所以使用0.8.1-SNAPSHOT 版本进行集成

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-bom</artifactId>
	<version>1.0.0-SNAPSHOT</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>
<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>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.4</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>

  <groupId>com.lvyuanj.core</groupId>
  <artifactId>micro-open-ai</artifactId>
  <version>1.0-SNAPSHOT</version>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-bom</artifactId>
        <version>0.8.1-SNAPSHOT</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </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-openai</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.ai</groupId>
      <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.ai</groupId>
      <artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
    </dependency>
  </dependencies>
  <repositories>
    <repository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/milestone</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
    <repository>
      <id>spring-snapshots</id>
      <name>Spring Snapshots</name>
      <url>https://repo.spring.io/snapshot</url>
      <releases>
        <enabled>false</enabled>
      </releases>
    </repository>
  </repositories>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>
2. application.yml 配置
spring:
  ai:
    openai:
      api-key: XXXXXXXXXXXXXXXXXXXXXX
      base-url: XXXXXXXXXXXXXXXXXXXXXXX
      chat:
        enabled: true
        options:
          model: chatglm3-6b
          temperature: 0.3F  # 温度越高,回答得比较有创新性,但是准确率会下降,温度越低,回答的准确率会更好
    #ollama模型
    ollama:
      api-key: XXXXXXXXXXXXXXXXXXXX
      base-url: XXXXXXXXXXXXXXXXXXXXXXXXX
      chat:
        enabled: false
        options:
          model: chatglm3-6b

3.controller 实现层
package com.lvyuanj.core.ai.controller;


import jakarta.annotation.Resource;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

@RestController
@RequestMapping("open-ai")
class OpenAiController {

	@Resource
	private OpenAiChatClient openAiChatClient;

	/**
	 * 调用OpenAI的接口-默认参数
	 * @param msg
	 * @return
	 */
	@GetMapping("/chat")
	public String completion(@RequestParam("msg") String msg) {
		return openAiChatClient.call(msg);
	}

	/**
	 * 调用OpenAI的接口-默认参数
	 * @param msg-输入的文本
	 * @return
	 */
	@RequestMapping(value = "/chat2")
	public Object chat2(@RequestParam(value = "msg") String msg) {
		ChatResponse chatResponse = openAiChatClient.call(new Prompt(msg));
		return chatResponse.getResult().getOutput().getContent();
	}

	/**
	 * 调用OpenAI的接口-自定义参数
	 * @param msg-输入的文本
	 * @return
	 */
	@RequestMapping(value = "/chat3")
	public Object chat3(@RequestParam(value = "msg") String msg) {
		//可选参数在配置文件中配置了,在代码中也配置了,那么以代码的配置为准,也就是代码的配置会覆盖掉配置文件中的配置
		ChatResponse chatResponse = openAiChatClient.call(new Prompt(msg, OpenAiChatOptions.builder()
				//.withModel("gpt-4-32k") //gpt的版本,32k是参数量
				.withTemperature(0.4F) //温度越高,回答得比较有创新性,但是准确率会下降,温度越低,回答的准确率会更好
				.build()));
		return chatResponse.getResult().getOutput().getContent();
	}


	/**
	 * 调用OpenAI的接口-流式接口
	 * @param msg-输入的文本
	 * @return
	 */
	@RequestMapping(value = "/chat4")
	public Object chat4(@RequestParam(value = "msg") String msg) {
		//可选参数在配置文件中配置了,在代码中也配置了,那么以代码的配置为准,也就是代码的配置会覆盖掉配置文件中的配置
		Flux<ChatResponse> flux = openAiChatClient.stream(new Prompt(msg, OpenAiChatOptions.builder()
				//.withModel("gpt-4-32k") //gpt的版本,32k是参数量
				.withTemperature(0.4F) //温度越高,回答得比较有创新性,但是准确率会下降,温度越低,回答的准确率会更好
				.build()));

		flux.toStream().forEach(chatResponse -> {
			System.out.println(chatResponse.getResult().getOutput().getContent());
		});
		return flux.collectList(); //数据的序列,一序列的数据,一个一个的数据返回
	}
    
    /**
    * 字转向量进行数据查询
    **/
    @PostMapping("/embedding")
	public void pgQuery(@RequestBody List<String> wordList) {
		EmbeddingRequest embeddingRequest = new EmbeddingRequest(wordList, OpenAiEmbeddingOptions.builder().build());
		EmbeddingResponse response = openAiEmbeddingClient.call(embeddingRequest);
		List<Double> wordVectors = response.getResult().getOutput();
		List<Float> vectors = wordVectors.stream().map(o -> o.floatValue()).collect(Collectors.toList());
		Object[] neighborParams = new Object[] { new PGvector(vectors) };
		List<Map<String, Object>> rows = jdbcTemplate.queryForList("SELECT * FROM modeldata ORDER BY embedding <-> ? LIMIT 5", neighborParams);
		if (Objects.nonNull(rows) && rows.size() > 0) {
			for (Map<String, Object> row : rows) {
				for (Map.Entry<String, Object> entry : row.entrySet()) {
					String key = entry.getKey();
					Object value = entry.getValue();
					System.out.println("key:"+key + ",value:" + value);
				}
			}
		}
	}

}
项目测试

在这里插入图片描述
接下来继续接入文字、图片、视频对接实现

Logo

更多推荐