在当今 AI 开发领域,Spring AI 框架与阿里巴巴推出的 DashScope 大模型服务平台深度集成,为开发者带来高效、便捷的开发体验。本文将深入剖析 基于Spring AI 框架,使用DashScope的大模型,实现灵活调用大模型及参数配置的自由对话功能的实现细节,并结合单元测试,演示如何基于 DashScope 平台自主配置 Chat 应用。
一、项目核心组件解析
DashScopeChatModelController
:作为 Spring AI 框架核心控制器,承担与 DashScope 平台交互重任。依托ChatModel
接口调用 DashScope API,解锁简单聊天、流式聊天及自定义参数聊天功能。
java
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.cloud.ai.example.chat.dashscope.controller;
import com.alibaba.cloud.ai.dashscope.api.DashScopeApi;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
import jakarta.servlet.http.HttpServletResponse;
import reactor.core.publisher.Flux;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@RestController
@RequestMapping("/dashscope/chat-model")
public class DashScopeChatModelController {
private static final Logger logger = LoggerFactory.getLogger(DashScopeChatModelController.class);
private static final String DEFAULT_PROMPT = "你好,介绍下你自己吧。";
private final ChatModel dashScopeChatModel;
public DashScopeChatModelController(ChatModel chatModel) {
this.dashScopeChatModel = chatModel;
}
/**
* 最简单的使用方式,没有任何 LLMs 参数注入。
* @return String types.
*/
@GetMapping("/simple/chat")
public String simpleChat() {
logger.info("Executing simpleChat method with default prompt.");
return dashScopeChatModel.call(new Prompt(DEFAULT_PROMPT, DashScopeChatOptions
.builder()
.withModel(DashScopeApi.ChatModel.QWEN_PLUS.getModel())
.build())).getResult().getOutput().getText();
}
/**
* Stream 流式调用。可以使大模型的输出信息实现打字机效果。
* @return Flux<String> types.
*/
@GetMapping("/stream/chat")
public Flux<String> streamChat(HttpServletResponse response) {
logger.info("Executing streamChat method with default prompt.");
response.setCharacterEncoding("UTF-8");
Flux<ChatResponse> stream = dashScopeChatModel.stream(new Prompt(DEFAULT_PROMPT, DashScopeChatOptions
.builder()
.withModel(DashScopeApi.ChatModel.QWEN_PLUS.getModel())
.build()));
return stream.map(resp -> resp.getResult().getOutput().getText());
}
/**
* 使用编程方式自定义 LLMs ChatOptions 参数, {@link com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions}
* 优先级高于在 application.yml 中配置的 LLMs 参数!
*/
@GetMapping("/custom/chat")
public String customChat() {
logger.info("Executing customChat method with customized options.");
DashScopeChatOptions customOptions = DashScopeChatOptions.builder()
.withTopP(0.7)
.withTopK(50)
.withTemperature(0.8)
.build();
return dashScopeChatModel.call(new Prompt(DEFAULT_PROMPT, customOptions)).getResult().getOutput().getText();
}
}
application.yml
:在此配置文件中,DashScope 平台 API 密钥(api-key
)被明确定义,成为访问平台服务的关键凭证。
yaml
server:
port: 10000
spring:
application:
name: spring-ai-alibaba-dashscope-chat-model-example
ai:
dashscope:
api-key: ${AI_DASHSCOPE_API_KEY:sk-XXSSDSFSDSDSDSD}
- 单元测试类
DashScopeChatModelControllerTest
:借助 Mockito 模拟ChatModel
行为,精准验证控制器方法的正确性,为代码质量保驾护航。
二、核心控制器深度剖析
构造函数与依赖注入
java
private static final String DEFAULT_PROMPT = "你好,介绍下你自己吧。";
private final ChatModel dashScopeChatModel;
public DashScopeChatModelController(ChatModel chatModel) {
this.dashScopeChatModel = chatModel;
}
优势 :依赖注入的运用,巧妙解耦控制器与具体实现细节,为单元测试与后续拓展提供极大便利。
简单聊天接口
java
@GetMapping("/simple/chat")
public String simpleChat() {
logger.info("Executing simpleChat method with default prompt.");
return dashScopeChatModel.call(new Prompt(DEFAULT_PROMPT, DashScopeChatOptions
.builder()
.withModel(DashScopeApi.ChatModel.QWEN_PLUS.getModel())
.build())).getResult().getOutput().getText();
}
要点 :凭借默认提示词(DEFAULT_PROMPT
)与 DashScopeChatOptions
配置的QWEN_PLUS
模型,轻松实现基础聊天功能。日志记录的嵌入,便于随时调试与监控。
流式聊天接口
java
@GetMapping("/stream/chat")
public Flux<String> streamChat(HttpServletResponse response) {
logger.info("Executing streamChat method with default prompt.");
response.setCharacterEncoding("UTF-8");
Flux<ChatResponse> stream = dashScopeChatModel.stream(new Prompt(DEFAULT_PROMPT, DashScopeChatOptions
.builder()
.withModel(DashScopeApi.ChatModel.QWEN_PLUS.getModel())
.build()));
return stream.map(resp -> resp.getResult().getOutput().getText());
}
亮点 :基于 Reactor 框架响应式编程模型,采用 Flux<ChatResponse>
支持异步流式处理,搭配 UTF-8 编码设置,完美适配需实时反馈的场景,如在线客服、实时翻译等。
自定义聊天接口
java
@GetMapping("/custom/chat")
public String customChat() {
logger.info("Executing customChat method with customized options.");
DashScopeChatOptions customOptions = DashScopeChatOptions.builder()
.withTopP(0.7)
.withTopK(50)
.withTemperature(0.8)
.build();
return dashScopeChatModel.call(new Prompt(DEFAULT_PROMPT, customOptions)).getResult().getOutput().getText();
}
特色 :开发者可编程自定义 LLMs 参数,覆盖 application.yml
默认配置。参数如 withTopP(0.7)
控制文本多样性、withTopK(50)
影响文本质量、withTemperature(0.8)
调整文本随机性,赋予开发者灵活掌控对话风格的能力。
三、单元测试成效与解读
测试用例 1:testSimpleChat
java
@Test
void testSimpleChat() {
Mockito.when(mockChatModel.call(any(Prompt.class))).thenReturn(createMockChatResponse("Hello"));
String result = controller.simpleChat();
assertEquals("Hello", result);
}
结论 :测试顺利通过,有力证实 simpleChat
方法精准调用 ChatModel
的 call
方法,返回预期结果,交互逻辑无误。
测试用例 2:testStreamChat
java
@Test
void testStreamChat() {
Mockito.when(mockChatModel.stream(any(Prompt.class))).thenReturn(Flux.just(createMockChatResponse("Hello")));
Flux<String> result = controller.streamChat(null);
assertEquals("Hello", result.blockFirst());
}
结论 :测试成功,彰显 streamChat
方法可靠处理流式数据,精准把控流式数据处理流程。
测试用例 3:testCustomChat
java
@Test
void testCustomChat() {
Mockito.when(mockChatModel.call(any(Prompt.class))).thenReturn(createMockChatResponse("Custom Hello"));
String result = controller.customChat();
assertEquals("Custom Hello", result);
}
结论 :测试通关,印证 customChat
方法妥善处理自定义参数,灵活运用 LLMs 参数的特性得以验证。
四、结语
综上,本文全方位拆解基于 DashScope 平台的 Spring AI Chat 应用,深入解读 DashScopeChatModelController
核心功能与参数配置。单元测试的加持,全方位验证控制器可靠性与稳定性,为开发者呈上详尽开发指南与实用范例,助力高效、优质 Chat 应用开发。