Prompt源码刨析
目前,我们知道通过 ChatModel 的 call() 方法 ,或则 steam() 方法,调用 AI 大模型,该方法入参接收一个 Prompt 实例,并返回 ChatResponse 响应。
Prompt 类可以看做一个容器,用于组织一系列 Message 消息对象和可选的 ChatOptions 请求配置。以下是Prompt部分源码
public class Prompt implements ModelRequest<List<Message>> {
private final List<Message> messages;//消息列表
@Nullable
private ChatOptions chatOptions;//聊天配置选项
而这个Message内部也封装了文本内容、元数据属性集合以及分类标识 MessageType
public interface Message extends Content {
/**
* Get the message type.
* @return the message type
*/
MessageType getMessageType();
对于多模态消息类型 (指模型支持多种类型的数据输入或输出,如文本,图片等等),Spring AI 额外定义了 MediaContent 接口,提供媒体内容对象列表:
public interface MediaContent extends Content {
Collection getMedia(); // 支持图像/音频/视频等多媒体内容
}
角色的分类
每条消息都被赋予一个特定的角色 (role)。这些角色用于对消息进行分类,向 AI 大模型阐明在提示词中,每个部分的上下文和目的。这种结构化的方法增强了与 AI 沟通的细微差别和有效性,因为提示词中的每个部分,在交互中都扮演着独特且定义明确的角色。
主要角色包括:
- 系统角色 (System Role): 指导 AI 的行为和响应风格,设定 AI 如何解释和回复输入的参数或规则,比如让 AI 大模型扮演一个客服。类似于在开始对话之前,向 AI 大模型提供指令。
- 用户角色 (User Role): 即用户的输入—— 如向 AI 提出的问题、发出的命令或陈述。这个角色是基础性的,因为它构成了 AI 响应的依据。
- 助手角色 (Assistant Role):
- 即 AI 大模型对用户输入的响应。
- 它不仅仅是一个回答,对于维持对话的流畅性至关重要。通过跟踪 AI 之前的响应(即其 '助手角色' 消息),系统确保聊天是连贯的。
- 工具/函数角色 (Tool/Function Role): 调用外部服务,比如获取天气数据、查询数据库等等。
在 Spring AI 中,以上角色通过 MessageType 枚举类型来表示,源码如下:
package org.springframework.ai.chat.messages;
/**
* Enumeration representing types of {@link Message Messages} in a chat application. It
* can be one of the following: USER, ASSISTANT, SYSTEM, FUNCTION.
*/
public enum MessageType {
/**
* A {@link Message} of type {@literal user}, having the user role and originating
* from an end-user or developer.
* @see UserMessage
*/
USER("user"),
/**
* A {@link Message} of type {@literal assistant} passed in subsequent input
* {@link Message Messages} as the {@link Message} generated in response to the user.
* @see AssistantMessage
*/
ASSISTANT("assistant"),
/**
* A {@link Message} of type {@literal system} passed as input {@link Message
* Messages} containing high-level instructions for the conversation, such as behave
* like a certain character or provide answers in a specific format.
* @see SystemMessage
*/
SYSTEM("system"),
/**
* A {@link Message} of type {@literal function} passed as input {@link Message
* Messages} with function content in a chat application.
* @see ToolResponseMessage
*/
TOOL("tool");
private final String value;
MessageType(String value) {
this.value = value;
}
public static MessageType fromValue(String value) {
for (MessageType messageType : MessageType.values()) {
if (messageType.getValue().equals(value)) {
return messageType;
}
}
throw new IllegalArgumentException("Invalid MessageType value: " + value);
}
public String getValue() {
return this.value;
}
}
之前其实已经用过chatClent的方式来声明过系统角色

ChatModel 指定系统角色、用户角色消息
而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();
});
}

Comments NOTHING