Spring Cloud Alibaba AI DEMO

73 阅读1分钟

初始化后端项目

  • 引入相关依赖

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.5.5</version>
        <relativePath/>
    </parent>

    <properties>
        <java.version>17</java.version>
        <spring-ai.version>1.0.1</spring-ai.version>
    </properties>

    <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>

    <dependencies>
        <!-- Spring Boot Web Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Spring AI PDF Document Reader -->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-pdf-document-reader</artifactId>
        </dependency>

        <!-- Spring AI Tika Document Reader -->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-tika-document-reader</artifactId>
        </dependency>

        <!-- Alibaba Dashboard Starter -->
        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
            <version>1.0.0.2</version>
        </dependency>

        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
  • 配置API-KEY
spring:
  ai:
    dashscope:
      agent:
        app-id: ${APP_ID} # 大模型应用ID,如未配置环境变量,请在这里替换为实际的值
      api-key: ${DASHSCOPE_API_KEY}

编写代码

@RestController
@RequestMapping("/chat")
@RequiredArgsConstructor
public class AiChatController {

    private final ChatService chatService;

    /**
     * ChatClient 简单调用
     */
    @PostMapping("/simple")
    public CommonResponse<ChatResponse> simpleChat(@RequestBody ChatRequest chatRequest) {
        return CommonResponse.success(chatService.chat(chatRequest));
    }
}

----

@Slf4j
@Service
@RequiredArgsConstructor
public class ChatService {
    private final ChatClient dashScopeChatClient;
    private final ChatSessionService chatSessionService;

    public ChatResponse chat(ChatRequest chatRequest) {
        String text = chatRequest.getText();
        String sessionId = chatRequest.getSessionId();
        CustomUserDetails userDetails = (CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (StringUtils.isBlank(sessionId)) {
            sessionId = UUID.randomUUID().toString();
            chatSessionService.createChatSessionRecord(sessionId, userDetails.getUserId());
        }
        String content = dashScopeChatClient.prompt().user(text).call().content();
        String finalSessionId = sessionId;
        CompletableFuture.runAsync(() -> {
            chatSessionService.createSessionDetail(finalSessionId, SubjectType.USER.name(), text);
            chatSessionService.createSessionDetail(finalSessionId, SubjectType.ROBOT.name(), content);
        });
        return new ChatResponse(finalSessionId, content);
    }
}
    @PostMapping
    public SseEmitter streamChat(@RequestBody ChatRequest chatRequest) throws Exception {
        return chatService.streamChat(chatRequest);
    }

  // service 代码
    public SseEmitter streamChat(ChatRequest chatRequest) throws Exception {
        SseEmitter finalSseEmitter = new SseEmitter(5l * 60 * 1000);
        dashScopeChatClient
                .prompt()
                .user(chatRequest.getText())
                .stream()
                .chatClientResponse()
                .subscribe(it -> {
                            String text = it.chatResponse().getResult().getOutput().getText();
                            log.info("sessionId: {}, text: {}", sessionId, text);
                            try {
                                finalSseEmitter.send(text, MediaType.TEXT_EVENT_STREAM);
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                        },
                        e -> {
                            log.info("session id: {}, occur error", sessionId, e);
                        },
                        finalSseEmitter::complete
                );
        return sseEmitter;
    }

效果展示

  • 同步接口

  • 流式输出