赞
踩
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 项目环境
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>
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
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); } } } } }
接下来继续接入文字、图片、视频对接实现
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。