Spring AI:提示词工程 - Prompt 角色分类(系统角色与用户角色)

Spring AI 之前的文章列表

Spring AI:对接DeepSeek实战
Spring AI:对接官方 DeepSeek-R1 模型 ------ 实现推理效果
Spring AI:ChatClient实现对话效果
Spring AI:使用 Advisor 组件 - 打印请求大模型出入参日志
Spring AI:ChatMemory 实现聊天记忆功能
Spring AI:本地安装 Ollama 并运行 Qwen3 模型
Spring AI:提示词工程

Prompt 角色分类

Prompt(提示词)

目前,我们知道通过 ChatModel 的 call() 方法 ,或则 steam() 方法,调用 AI 大模型,该方法入参接收一个 Prompt 实例,并返回 ChatResponse 响应。

Prompt 类可以看做一个容器,用于组织一系列 Message 消息对象和可选的 ChatOptions 请求配置。

以下是 Prompt 类的源码简化版(省略了构造器和工具方法):

java 复制代码
public class Prompt implements ModelRequest<List<Message>> {
    private final List<Message> messages; // 消息列表
    private ChatOptions chatOptions;      // 聊天配置选项
}

每个 Message 消息,在提示词中扮演不同的角色,其作用各不相同,涵盖用户消息、AI 生成的响应等等。这种结构支持与 AI 模型进行复杂精细的交互,因为提示词由多条消息构建而成,每条消息在对话中被赋予特定功能。

Message(消息)

查看 Message 消息接口源码,它封装了提示词的文本内容、元数据属性集合以及分类标识 MessageType。

接口定义如下:

java 复制代码
// 内容接口
public interface Content {
    String getContent();                 // 获取文本内容
    Map<String, Object> getMetadata();   // 获取元数据
}

// 消息接口
public interface Message extends Content {
    MessageType getMessageType();        // 获取消息类型,如用户消息、系统消息、AI 回复等
}

另外,对于多模态消息类型 (指模型支持多种类型的数据输入或输出,如文本,图片等等),Spring AI 额外定义了 MediaContent 接口,提供媒体内容对象列表:

java 复制代码
public interface MediaContent extends Content {
    Collection<Media> getMedia();        // 支持图像/音频/视频等多媒体内容
}

Message 接口的多种实现,对应着 AI 模型可处理的不同类别的消息。

角色分类 (Roles)

每条消息都被赋予一个特定的角色 (role)。这些角色用于对消息进行分类,向 AI 大模型阐明在提示词中,每个部分的上下文和目的。这种结构化的方法增强了与 AI 沟通的细微差别和有效性,因为提示词中的每个部分,在交互中都扮演着独特且定义明确的角色。

主要角色包括:

  • 系统角色 (System Role): 指导 AI 的行为和响应风格,设定 AI 如何解释和回复输入的参数或规则,比如让 AI 大模型扮演一个客服。类似于在开始对话之前,向 AI 大模型提供指令。

  • 用户角色 (User Role): 即用户的输入------ 如向 AI 提出的问题、发出的命令或陈述。这个角色是基础性的,因为它构成了 AI 响应的依据。

  • 助手角色 (Assistant Role):

    即 AI 大模型对用户输入的响应。

    它不仅仅是一个回答,对于维持对话的流畅性至关重要。通过跟踪 AI 之前的响应(即其 '助手角色' 消息),系统确保聊天是连贯的。

  • 工具/函数角色 (Tool/Function Role): 调用外部服务,比如获取天气数据、查询数据库等等。这里仅做了解,后面会单独学习这块。

在 Spring AI 中,以上角色通过 MessageType 枚举类型来表示,源码如下:

java 复制代码
public enum MessageType {

    USER("user"), // 用户消息
    ASSISTANT("assistant"), // 助手消息
    SYSTEM("system"), // 系统消息
    TOOL("tool"); // 工具/函数消息
}

ChatClient 指定系统角色消息

接下来,我们在代码中,实际感受一下,如何对消息设定角色。其实,在之前的文章中,就体验过,在初始化 ChatClient 对象时,为其指定一个系统角色,如下:

除了上面这种以 "全局" 的方式,设置系统角色外,也可以在接口中,动态、更灵活的指定系统角色消息,如下图所示:

java 复制代码
@RestController
@RequestMapping("/v2/ai")
public class ChatClientController {

    @Resource
    private ChatClient chatClient;

    // 省略...

    /**
     * 流式对话
     * @param message
     * @return
     */
    @GetMapping(value = "/generateStream", produces = "text/html;charset=utf-8")
    public Flux<String> generateStream(@RequestParam(value = "message", defaultValue = "你是谁?") String message,
                                       @RequestParam(value = "chatId") String chatId
    ) {

        // 流式输出
        return chatClient.prompt()
                .system("请你扮演一个智能客服")
                .user(message) // 提示词
                .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, chatId))
                .stream()
                .content();

    }

}

ChatModel 指定系统角色、用户角色消息

那么,如果是通过 ChatModel 这种方式来调用 AI 大模型,要如何指定 "系统角色" 的消息呢?也很简单,代码如下:

java 复制代码
@RestController
@RequestMapping("/v6/ai")
public class PController {

    @Resource
    private DeepSeekChatModel chatModel;

	// 省略...

    /**
     * 流式对话
     * @param message
     * @return
     */
    @GetMapping(value = "/generateStream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<AIResponse> generateStream(@RequestParam(value = "message", defaultValue = "你是谁?") String message) {
        // 系统角色消息
        SystemMessage systemMessage = new SystemMessage("请你扮演一个智能客服");
        // 用户角色消息
        UserMessage userMessage = new UserMessage(message);
        // 构建提示词
        Prompt prompt = new Prompt(Arrays.asList(systemMessage, userMessage));

        // 流式输出
        return chatModel.stream(prompt)
                .mapNotNull(chatResponse -> {
                    Generation generation = chatResponse.getResult();
                    String text = generation.getOutput().getText();
                    return AIResponse.builder().v(text).build();
                });

    }

}

解释一下上面的代码:

  • new SystemMessag() : 设置一个系统角色的消息,如指定 AI 大模型扮演一个客服;
  • new UserMessage() : 初始化一个用户角色消息,设置用户提出的问题;
  • Prompt 作为一个容器,将这些消息包装一下,扔给 AI 大模型;
相关推荐
Ttang231 小时前
【AI学习1】了解开源大模型
人工智能·学习·开源
小马爱打代码1 小时前
Spring AI:多模态 AI 大模型
java·人工智能·spring
johnny2331 小时前
蚂蚁百灵研发助手CodeFuse介绍
人工智能
paopao_wu1 小时前
阿里通义实验室开源Z-Image:6B参数的AI图像生成
人工智能·ai·开源
Swizard1 小时前
Claude Opus 4.5 深度解构:当 AI 学会了“拒绝道歉”与“痛恨列表”
ai·llm·prompt·claude
sg_knight1 小时前
SSE 技术实现前后端实时数据同步
java·前端·spring boot·spring·web·sse·数据同步
haing20191 小时前
三次 B 样条曲线基于曲率极值的限速速度规划方法
人工智能·b样条·曲率极值限速
AutumnorLiuu1 小时前
【红外小目标检测实战 四】使用风车卷积和Neck多层融合改进
人工智能·目标检测·计算机视觉
亿林-智企AI2 小时前
AI数字人技术浪潮:亿林数据引领人机交互新范式
人工智能·人机交互·智能客服·ai数字人·ai智能体·算力一体机