Dict.CN 在线词典, 英语学习, 在线翻译 ------------- MyGitee My腾云code My51cto

Happy_EveryDay

可以平凡 不可以平庸 无爱则无忧,无欲则无求,无怒而无敌,无怨才是佛。所有烦恼,都是放不下的执著 开源技群 328035181 MyGitee

博客园 首页 管理

 

image

 

 

 

 

 

1、pom

<properties>
<java.version>17</java.version>
<spring-ai.version>2.0.0-M7</spring-ai.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-ollama</artifactId>
</dependency>
    <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<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>

 

 

2、application.yml

2.1

${OPENAI_API_KEY}

image

 

 2.2

ollama docker容器

宿主机:192.168.91.164

image

 

容器ollama启动模型qwen2.5:0.5b

image

 

访问宿主机模型

http://192.168.91.164:11434/   

image

 

 

 

 

 

 

 

spring:
application:
name: dashscope18088
ai:
openai:
api-key: ${OPENAI_API_KEY}
base-url: https://dashscope.aliyuncs.com/compatible-mode/v1
chat:
model: qwen3.6-plus
# chat:
# model: qwen3.6-plus
# 可选:超时/重试配置
ollama:
base-url: http://192.168.91.164:11434
chat:
model: qwen2.5:0.5b
# options:
# temperature: 0.7
# max-tokens: 2000
server:
port: 18088

#.defaultAdvisors(new MySimpleLoggerAdvisor())//添加日志拦截器
logging:
level:
org.springframework.ai: debug



3、config

import com.sb.dashscope18088.advisor.MySimpleLoggerAdvisor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AiConfiguration {

@Bean
public ChatClient chatClient(OpenAiChatModel model){
return ChatClient
.builder(model) // 创建ChatClient对象,以及设置模型model
.defaultAdvisors(new MySimpleLoggerAdvisor())//添加日志拦截器
//.defaultAdvisors(new SimpleLoggerAdvisor())//内置日志拦截器
.build(); // 构建ChatClient对象
}

@Bean
public ChatClient chatClient2(OllamaChatModel model){
return ChatClient
.builder(model) // 创建ChatClient对象,以及设置模型model
.defaultAdvisors(new MySimpleLoggerAdvisor())//添加日志拦截器
.build(); // 构建ChatClient实例
}

@Bean
public ChatClient chatClient3(OpenAiChatModel model){
// System Prompt 工程:清晰定义 AI 的角色、任务、约束和输出格式
//【系统提示词】
String systemPrompt = """
你是一个资深的 Java 技术顾问。
禁止回答任何非技术类问题,例如天气或娱乐八卦。
代码示例必须符合 Java 17+ 规范。
回答需要符合以下格式:首先一句话概括问题的核心,然后提供代码示例,最后补充注意事项。
如果自己不确定,可以说"关于这个问题,我目前没有确切的信息",禁止编造内容。
""";
return ChatClient
.builder(model) // 创建ChatClient对象,以及设置模型model
.defaultSystem(systemPrompt)
//.defaultAdvisors(new MySimpleLoggerAdvisor())//添加日志拦截器
.defaultAdvisors(new SimpleLoggerAdvisor())//内置日志拦截器
.build(); // 构建ChatClient对象
}


}

 

 

4、pojo

 

import java.util.List;

//使用 Java 16+ 的 Record 特性,编译器会自动生成构造器、equals/hashCode等方法
public record TopicBook(
String topic, // 主题
List<String> books // 推荐书籍
){}


// Java16+ Record 不可变实体,用于书籍评论结构化接收
public record BookReview(
String reviewerName, // 评价人
int rating, // 评分
String comment // 评价内容
){}

 

5、controller

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

@RestController
public class MyAiChatController {

@Autowired
private ChatClient chatClient;

@Autowired
private ChatClient chatClient2;

  @Autowired
  private ChatClient chatClient3;


@RequestMapping("/ai")
public String ai(String question){
return chatClient.prompt() // 创建 Prompt 对象,用于构建聊天请求
.user(question) // 设置用户输入
.call() // 调用模型,返回结果
.content(); // 获取结果内容
}

/**
* ollama
* @param question
* @return
*/
@RequestMapping("/ai2")
public String ai2(String question){
return chatClient2.prompt() // 创建 Prompt 对象,用于构建聊天请求
.user(question) // 设置用户输入
.call() // 调用模型,返回结果
.content(); // 获取结果内容
}

/**
* ollama
* @param question
* @return
*/
@RequestMapping(value = "/ai3",produces = "text/html;charset=UTF-8")
public Flux<String> ai3(String question){
return chatClient2.prompt() // 创建 Prompt 对象,用于构建聊天请求
.user(question) // 设置用户输入
.stream() // 流式响应输出
.content(); // 获取结果内容
}


/**
* 使用模板:一套代码应对所有场景
* @param topic
* @return
*/
@RequestMapping(value = "/ask", produces = "text/html;charset=UTF-8")
public Flux<String> ask(String topic){
PromptTemplate template = new PromptTemplate("介绍下{topic}");
Prompt prompt = template.create(Map.of("topic", topic));
return chatClient.prompt(prompt)
.stream() // 流式响应输出
.content(); // 获取结果内容
}

/**
* 使用ChatClient的流式 API 可以最快速地组装提示词
* @param topic
* @return
*/
@RequestMapping(value = "/ask2", produces = "text/html;charset=UTF-8")
public Flux<String> ask2(String topic){
return chatClient.prompt() // 创建 Prompt 构建器,用于构建聊天清求
.system("你是一个专业的书评助手") // 设置系统提示词
.user(u -> u.text("请给我推荐三本关于{topic}的书籍,只需要返回书名").param("topic", topic))
.stream() // 流式响应输出
.content(); // 获取结果内容
}

/**
* 【系统提示词】
* .defaultSystem(systemPrompt)
* @param question
* @return
*/
@RequestMapping("/ask3")
public String ask3(String question){
return chatClient3.prompt() // 创建 Prompt 对象,用于构建聊天请求
.user(question) // 设置用户输入
.call() // 调用模型,返回结果
.content(); // 获取结果内容
}




/**
* @param topic
* @return
*/
@RequestMapping("/ask4")
public String ask4(String topic){
// 链式调用,直接把模型结果转为TopicBook Record对象
TopicBook topicBook = chatClient.prompt()
.system("你是一个专业的书评助手") // 系统角色提示词
.user(u -> u.text("请给我推荐三本关于{topic}的书籍,只需要返回书名")
.param("topic", topic)) // 占位符参数赋值
.call()
.entity(TopicBook.class); // 结构化输出:自动JSON→Java实体

System.out.println(topicBook);
return "【TopicBook实体 】:"+topicBook.toString();
}

/**
* @return
*/
@RequestMapping("/ask5")
public String ask5(){
List<BookReview> bookReviews = chatClient.prompt()
.user(u -> u.text("请给{bookName}书籍三条评价信息")
.param("bookName", "深入理解Java虚拟机"))
.call()
// 通过ParameterizedTypeReference声明泛型List类型
.entity(new ParameterizedTypeReference<List<BookReview>>() {});

System.out.println(bookReviews);
return "【BookReview实体List】:"+bookReviews.toString();
}




}

 

 

6、访问

 

  6.1

http://localhost:18088/ask4?topic=java

image

 



 

   6.2

http://localhost:18088/ask5

image

 

 

image

 

 
posted on 2026-05-30 10:48  cn2025  阅读(4)  评论(0)    收藏  举报