Spring-ai-Alibaba integration QwQ_32b

Keep up with the trend of AI technology and quickly adapt to Alibaba's new model QwQ-32b.
Core content:
1. Introduction to Alibaba's new model QwQ-32b
2. Integration method of Spring-ai and Spring Cloud Alibaba AI
3. Detailed configuration steps for creating SCA AI applications
DeepSeek is the leader in large models in China, and Alibaba has just released qwq-32b. But it doesn’t matter. If you use spring-ai (or Spring Cloud Alibaba AI ), you can adapt it by changing the configuration (warm reminder: qwq-32b does not support function-call like deepseek-r1)
Spring Cloud Alibaba AI
Spring Cloud Alibaba AI is a springboot-stater specially designed by Alibaba to allow Java programmers to access the large model of the Bailian platform. It is based on Spring AI and is updated synchronously with SpringAi.
Quick Experience
Creating SCA AI Applications
Introduce the following dependency configuration in pom.xml:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-ai</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- Because Spring AI has not been officially released to the Maven repository, the Maven repository needs to be false before adding this configuration project.
issue: https://github.com/spring-projects/spring-ai/issues/537
-->
<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>
api-key configuration
Get API Key
- Hover your mouse over theicon and click API-KEY in the drop-down menu .
- In the left navigation bar, select All API-KEYs or My API-KEYs , and then create (position ① in the figure) or view (position ② in the figure) an API Key.
Of course, you can also configure it through the application.yml configuration item:
In order to prevent the api-key from being exposed in the code, the environment variable ${ALI_AI_KEY} is read:
spring:
ai:
dashscope:
api-key: ${ALI_AI_KEY}
model: qwq-32b
Chat Conversation Experience
public class ChatService {
// Chat client
private final ChatClient chatClient;
// stream streaming client
private final StreamingChatClient streamingChatClient;
@Autowired
public ChatService(ChatClient chatClient, StreamingChatClient streamingChatClient) {
this.chatClient = chatClient;
this.streamingChatClient = streamingChatClient;
}
@Override
public String normalCompletion(String message) {
Prompt prompt = new Prompt(new UserMessage(message));
return chatClient.call(prompt).getResult().getOutput().getContent();
}
@Override
public Map<String, String> streamCompletion(String message) {
StringBuilder fullContent = new StringBuilder();
streamingChatClient.stream(new Prompt(message))
.flatMap(chatResponse -> Flux.fromIterable(chatResponse.getResults()))
.map(content -> content.getOutput().getContent())
.doOnNext(fullContent::append)
.last()
.map(lastContent -> Map.of(message, fullContent.toString()))
.block();
return Map.of(message, fullContent.toString());
}
}
After that, create a controller interface to call the service:
@Autowired
private ChatService chatService;
@GetMapping("/example")
public String completion(
@RequestParam(value = "message", defaultValue = "Tell me a joke")
String message
) {
return chatService.completion(message);
}
@GetMapping("/stream")
public Map<String, String> streamCompletion(
@RequestParam(value = "message", defaultValue = "Please tell me how to make beef brisket stewed with tomatoes?")
String message
) {
return chatService.streamCompletion(message);
}
The following is the interface test:
Wenshengtu Experience
/*
* 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.model;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.ai.image.ImageModel;
import org.springframework.ai.image.ImageOptions;
import org.springframework.ai.image.ImageOptionsBuilder;
import org.springframework.ai.image.ImagePrompt;
import org.springframework.ai.image.ImageResponse;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/ai")
public class ImageModelController {
private final ImageModel imageModel;
ImageModelController(ImageModel imageModel) {
this.imageModel = imageModel;
}
@GetMapping("/image/{input}")
public void image(@PathVariable("input") String input, HttpServletResponse response) {
ImageOptions options = ImageOptionsBuilder.builder()
.model("wanx-v1")
.build();
ImagePrompt imagePrompt = new ImagePrompt(input, options);
ImageResponse imageResponse = imageModel.call(imagePrompt);
String imageUrl = imageResponse.getResult().getOutput().getUrl();
try {
URL url = new URL(imageUrl);
InputStream in = url.openStream();
response.setHeader("Content-Type", MediaType.IMAGE_PNG_VALUE);
response.getOutputStream().write(in.readAllBytes());
response.getOutputStream().flush();
} catch (IOException e) {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
}
Interface calling experience:
Terminal window
http://localhost:8080/ai/image/Beauty
Click on the address and we can see the following generated beauty pictures:
For more configuration items, please refer to: https://help.aliyun.com/zh/dashscope/developer-reference/api-details.
Example code: https://gitee.com/xscodeit/spring-cloud-alibaba-ai-example