第五节 消息注解

亮子 | 2026-04-07 13:56:39 | 36 | 0 | 0 | 0

接下来我们学习langchian4j中提供的消息注解,将来我们开发的项目叫做Ai志愿填报顾问,它只能回答志愿填报相关的问题,如果用户问其他的问题,则不予回答。比如你问它特朗普靠谱吗?它是不能回答你的。如果要实现这样的效果,我们就需要通过设定系统消息的方式来完成了。

1.SystemMessage

用于设置系统消息的,你可以直接在接口的方法上添加这个注解,在注解中书写系统消息即可。当然了, 如果我们的系统消息很长, 直接在代码中写不方便,它还提供了另外一种使用方式,通过fromResource属性,指定一个外部的文件。fromResource是从resources目录下查询文件的,注意文件的相对路径。

image.png

2.UserMessage

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

image.png

可以通过{{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.演示效果

image.png

image.png

image.png

源码仓库

https://gitee.com/ywbingchuan/server-ai-demo/tree/master/demo-ai-message