项目仓库

@AiService注解

  • 和starter依赖配置使用,starter会自动扫描yml配置文件生成对应bean供AiService使用
  • 分为自动分配和手动分配
  • 放置在接口上面
  • 直接在Controller直接使用即可
package org.dxy.ai.service;

import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.spring.AiService;
import dev.langchain4j.service.spring.AiServiceWiringMode;
import reactor.core.publisher.Flux;

//@AiService(
//        wiringMode = AiServiceWiringMode.EXPLICIT,  // 显式注入模式:所有依赖(如模型、记忆)都必须在注解中显式指定 Bean 名称
//        chatModel = "ollamaChatModel",              // 指定使用的对话模型 Bean 名称,对应你在配置中声明的 OllamaChatModel(普通同步对话模型)
//        streamingChatModel = "ollamaStreamChatModel"  // 指定使用的流式对话模型 Bean 名称(支持逐字生成响应)
////        chatMemory = "chatMemory"                   // 指定对话记忆组件 Bean 名称,用于保存上下文历史,实现连续对话
//)


@AiService(
        wiringMode = AiServiceWiringMode.EXPLICIT,  // 显式注入模式:所有依赖(如模型、记忆)都必须在注解中显式指定 Bean 名称
        chatModel = "openAiChatModel",              // 指定使用的对话模型 Bean 名称,对应你在配置中声明的 OllamaChatModel(普通同步对话模型)
        streamingChatModel = "openAiStreamingChatModel",  // 指定使用的流式对话模型 Bean 名称(支持逐字生成响应)
        chatMemoryProvider = "chatMemoryProvider",
        contentRetriever = "contentRetriever",
        tools = "factoryTool"
)
public interface Assistant {

    /**
     * 使用同步方式与 AI 交互。
     * 等待完整响应后一次性返回。
     *
     * @param message 用户输入的消息
     * @return 完整的 AI 回复
     */
    String chatSync(String message);

    /**
     * 使用流式输出与 AI 交互。
     * 返回内容会分段发送,适合实时输出场景(如 SSE)。
     * @param memoryId 用户会话id
     * @param message 用户输入的消息
     * @return 分段的响应流
     */
//    @SystemMessage(fromResource = "prompts/mes-ddd-prompt.txt")
    Flux<String> chatStream(@MemoryId String memoryId, @UserMessage String message);


}



    @PostMapping(value = "/askStream", produces = MediaType.TEXT_XML_VALUE)
    public Flux<String> ask(@RequestBody ChatRequest request) {
        log.info("收到聊天请求: {}", request.toString());
//        return assistant.chatStream(request.getMemoryId(), request.getMessage());

        // 1️⃣ 将阻塞调用放到 boundedElastic(防止异步返回变为阻塞)
        return Mono.fromCallable(() -> assistant.chatStream(request.getMemoryId(), request.getMessage()))
                .subscribeOn(Schedulers.boundedElastic()) // ✅ 切换线程池
                // 2️⃣ 转为 Flux 流
                .flatMapMany(flux -> flux);
    }

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐