zeus00456

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

AI | langchain4j - [底座项目]

依赖管理

<properties>
	<spring-boot.version>3.5.14</spring-boot.version>
	<langchain4j.version>1.15.1</langchain4j.version>
</properties>
<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-dependencies</artifactId>
			<version>${spring-boot.version}</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
		<!-- 加载bom 后,所有langchain4j引用不需要加版本号 -->
		<dependency>
			<groupId>dev.langchain4j</groupId>
			<artifactId>langchain4j-bom</artifactId>
			<version>${langchain4j.version}</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>

依赖

<!-- 集成openai,如果用其他集成,需要引用 langchain4j-xxx-spring-boot-starter -->
<dependency>
	<groupId>dev.langchain4j</groupId>
	<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
</dependency>
<dependency>
	<groupId>dev.langchain4j</groupId>
	<artifactId>langchain4j-spring-boot-starter</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
	<groupId>dev.langchain4j</groupId>
	<artifactId>langchain4j-reactor</artifactId>
</dependency>
<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<optional>true</optional>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-test</artifactId>
	<scope>test</scope>
</dependency>

配置

流式输出 + 正常chat + 监听器
需要根据不同场景使用不同模型,比如进行生图任务时可以使用 wan2.7-image 等

    @Bean
    public StreamingChatModel streaming(){
        return OpenAiStreamingChatModel.builder()
                .apiKey("sk-xxx")
                .modelName("deepseek-v4-flash")
                .baseUrl("https://api.deepseek.com")
                .sendThinking(false)
                .returnThinking(false)
                .logRequests(true)
                .logResponses(true)
                .timeout(Duration.ofSeconds(20))
                .build();
    }
    @Bean
    public ChatModel chat(){
        return OpenAiChatModel.builder()
                .apiKey("sk-xxx")
                .modelName("deepseek-v4-flash")
                .baseUrl("https://api.deepseek.com")
                .sendThinking(false)
                .returnThinking(false)
                .logRequests(true)
                .logResponses(true)
                .timeout(Duration.ofSeconds(20))
                .build();
    }

    @Bean
    ChatModelListener chatModelListener() {
        return new ChatModelListener() {
            @Override
            public void onRequest(ChatModelRequestContext requestContext) {
                log.info("onRequest(): {}", requestContext.chatRequest());
            }

            @Override
            public void onResponse(ChatModelResponseContext responseContext) {
                log.info("onResponse(): {}", responseContext.chatResponse());
            }

            @Override
            public void onError(ChatModelErrorContext errorContext) {
                log.info("onError(): {}", errorContext.error().getMessage());
            }
        };
    }

可以结合日志获取更多细节

langchain4j.open-ai.chat-model.log-requests = true
langchain4j.open-ai.chat-model.log-responses = true
logging.level.dev.langchain4j = DEBUG

流式输出时需要后端制定前端编码

server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
spring.webflux.encoding.charset=UTF-8

AI service

@AiService(wiringMode = EXPLICIT, streamingChatModel = "streaming",chatModel = "chat")
public interface ChatService {
    String chat(String prompt);

    @SystemMessage("你是一位资深二次元,只回答二次元相关的问题。输出限制:对于其他领域的问题禁止回答,直接返回'不好意思,你的问题不够变态'")
    @UserMessage("请回答以下二次元问题:{{question}}")
    String chat2(@V("question") String question);

    @SystemMessage("你是一位资深二次元,只回答二次元相关的问题。输出限制:对于其他领域的问题禁止回答,直接返回'不好意思,你的问题不够变态'")
    @UserMessage("请回答以下二次元问题:{{question}}")
    Flux<String> streamChat(@V("question") String question);
}

基础用例

@GetMapping(value = "/lcc/a")
public String assistant(@RequestParam("p") String p){
	return chatService.chat(p);
}

@GetMapping(value = "/lcc/a2")
public String assistant2(@RequestParam("p") String p){
	return chatService.chat2(p);
}


@GetMapping(value = "/lcc/s",  produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamChat(@RequestParam("p") String p) {
	Sinks.Many<String> sink = Sinks.many().multicast().onBackpressureBuffer();
	client.chat(p, new StreamingChatResponseHandler() {
		@Override
		public void onPartialResponse(String partialResponse) {
			sink.tryEmitNext(partialResponse);
		}
		@Override
		public void onCompleteResponse(ChatResponse chatResponse) { sink.tryEmitComplete();}
		@Override
		public void onError(Throwable throwable) { }
	});
	return sink.asFlux();
}

@GetMapping(value = "/lcc/ss",  produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamChat2(@RequestParam("p") String p) {
	return chatService.streamChat(p);
}
posted on 2026-06-14 17:17  问仙长何方蓬莱  阅读(4)  评论(0)    收藏  举报