接下来我们学习langchian4j中提供的消息注解,将来我们开发的项目叫做Ai志愿填报顾问,它只能回答志愿填报相关的问题,如果用户问其他的问题,则不予回答。比如你问它特朗普靠谱吗?它是不能回答你的。如果要实现这样的效果,我们就需要通过设定系统消息的方式来完成了。
1.SystemMessage
用于设置系统消息的,你可以直接在接口的方法上添加这个注解,在注解中书写系统消息即可。当然了, 如果我们的系统消息很长, 直接在代码中写不方便,它还提供了另外一种使用方式,通过fromResource属性,指定一个外部的文件。fromResource是从resources目录下查询文件的,注意文件的相对路径。

2.UserMessage
假设现在没有SystemMessage,那么我们可以借助于UserMessage注解完成同样的效果,我们可以在用户消息前后,拼接提前预设的内容。

可以通过{{it}}的方式, 动态的获取到用户传递的消息,然后再往它的前后拼接上预设的内容即可,想拼什么拼什么。
这里有一点需要说明,这个花括号内的it是固定的,不能随便写。假设你不想使用it这个名字,langchain4j提供了一个V注解,用于解决这个问题。我们在参数前面通过V注解给这个参数起一个名字,然后在花括号内写上同样的名字就能获取到了
这个时候发送的是role为user的用户信息,而不是系统消息。
3.完整接口定义
package com.shenma.service;
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
import dev.langchain4j.service.spring.AiService;
import dev.langchain4j.service.spring.AiServiceWiringMode;
import reactor.core.publisher.Flux;
/**
* @author 军哥
* @version 1.0
* @description: TODO
* @date 2026/4/7 13:38
*/
@AiService(
wiringMode = AiServiceWiringMode.EXPLICIT,
chatModel = "openAiChatModel",
streamingChatModel = "openAiStreamingChatModel"
)
public interface ConsultantService {
@SystemMessage("你是军哥的助理小月月,温柔貌美又多金")
public Flux<String> chat1(String message);
@SystemMessage(fromResource = "system.txt")
public Flux<String> chat2(String message);
@UserMessage("你是东哥的助手小乐乐,温柔貌美又多金。{{it}}")
public Flux<String> chat3(String message);
@UserMessage("你是东哥的助手小青青,温柔貌美又多金。{{msg}}")
public Flux<String> chat4(@V("msg") String message);
}
4.完整controller定义
package com.shenma.controller;
import com.shenma.service.ConsultantService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
/**
* @author 军哥
* @version 1.0
* @description: TODO
* @date 2026/4/7 13:45
*/
@RestController
public class ChatController {
@Autowired
private ConsultantService consultantService;
//produces:响应的数据编码类型
@PostMapping(value = "/chat1", produces = "text/html;charset=utf-8")
public Flux<String> chat1(@RequestParam("message") String message) {
Flux<String> result = consultantService.chat1(message);
return result;
}
@PostMapping(value = "/chat2", produces = "text/html;charset=utf-8")
public Flux<String> chat2(@RequestParam("message") String message) {
Flux<String> result = consultantService.chat2(message);
return result;
}
@PostMapping(value = "/chat3", produces = "text/html;charset=utf-8")
public Flux<String> chat3(@RequestParam("message") String message) {
Flux<String> result = consultantService.chat3(message);
return result;
}
@PostMapping(value = "/chat4", produces = "text/html;charset=utf-8")
public Flux<String> chat4(@RequestParam("message") String message) {
Flux<String> result = consultantService.chat4(message);
return result;
}
}
5.演示效果



源码仓库
https://gitee.com/ywbingchuan/server-ai-demo/tree/master/demo-ai-message