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 大模型;
相关推荐
m0_587383009 分钟前
深圳24小时自助健身房系统软件开发实战:架构设计与部署指南
人工智能·数据挖掘·系统架构·需求分析
Joy T10 分钟前
Spring AI 2.0 Agent 进阶:Memory、State 与 Context Engineering 常见技术全景
java·人工智能·后端·spring·agent入门·agent state
估值探索者11 分钟前
【Python量化系统工程化 #08】关了 SSH 就停?systemd 让脚本开机自启 + 异常自动拉起
java·c++·人工智能·分类·数据挖掘
西柚研究生12345613 分钟前
论文分析17:YOLOv11_UAVNet:无人机航拍图像专用目标检测算法
人工智能·python·深度学习·算法·目标检测
m4Rk_13 分钟前
【论文阅读】Agent 记忆机制(74):CompassMem——从相似度检索走向事件图上的记忆导航
论文阅读·人工智能·学习·开源·github
镭封17 分钟前
短剧多人对白怎么配?一人完成多角色配音的办法
人工智能·音视频·语音识别·媒体
昇腾知识体系29 分钟前
昇腾 torchrec_npu Docker 镜像选择:CANN/PyTorch/torchrec 版本矩阵与启动参数
人工智能·华为·知识图谱
VIP_CQCRE35 分钟前
用 Ace Data Cloud 一次接入 AI 视频生成:HappyHorse Videos API 实战指南
人工智能·api·ai视频·acedatacloud
去伪存真1 小时前
大模型的参数量为什么那么大?
前端·人工智能