Message 类型与多轮对话
约 640 字大约 2 分钟
布欧-Lewyon
2026-05-15
首页 › Spring AI › ChatClient 与 Prompt 工程
Message 类型
Spring AI 定义了多种 Message 类型对应不同的对话角色:
| Message 类型 | 对应角色 | 用途 |
|---|---|---|
SystemMessage | System | 设定 AI 的行为和角色 |
UserMessage | User | 用户输入的问题或指令 |
AssistantMessage | Assistant | AI 的回复 |
ToolResponseMessage | Tool | 工具调用的返回结果 |
// 构建多轮对话 Prompt
Prompt prompt = new Prompt(List.of(
new SystemMessage("You are a helpful assistant specialized in Java"),
new UserMessage("What is the difference between List and Set?"),
new AssistantMessage("List allows duplicates and maintains order..."),
new UserMessage("Can you show me a code example?") // 追问
));多轮对话管理
AI 模型本身是无状态的,每次调用都是独立的。要实现多轮对话,需要手动维护历史消息。
ChatMemory
Spring AI 的 ChatMemory 接口抽象了对话历史的存储:
// 内存实现(开发/测试使用)
ChatMemory chatMemory = new InMemoryChatMemory();
// 保存消息
chatMemory.add("session-123", new UserMessage("Hello"));
chatMemory.add("session-123", new AssistantMessage("Hi! How can I help?"));
// 获取历史
List<Message> history = chatMemory.get("session-123", 10);
// 清空
chatMemory.clear("session-123");MessageChatMemoryAdvisor
Spring AI 提供了 Advisor 机制自动管理对话历史:
@RestController
public class ChatWithMemoryController {
private final ChatClient chatClient;
public ChatWithMemoryController(ChatClient.Builder builder) {
this.chatClient = builder
.defaultSystem("You are a helpful assistant.")
.build();
}
@GetMapping("/chat/memory")
public String chatWithMemory(
@RequestParam String sessionId,
@RequestParam String message) {
return chatClient.call(
new Prompt(new UserMessage(message)),
new ToolContext(Map.of("sessionId", sessionId))
).getResult().getOutput().getContent();
}
}使用 Advisor 自动管理
@Bean
public ChatClient chatClientWithMemory(
ChatClient.Builder builder,
ChatMemory chatMemory) {
return builder
.defaultSystem("You are a helpful assistant")
.defaultAdvisors(
new MessageChatMemoryAdvisor(
chatMemory, // ChatMemory 实现
"sessionId", // 会话 ID 参数名
10 // 保留最近 10 轮对话
)
)
.build();
}// 控制器侧 - 只需传递 sessionId
@GetMapping("/chat/advisor")
public String chatWithAdvisor(
@RequestParam String sessionId,
@RequestParam String message) {
return chatClient.call(new Prompt(new UserMessage(message)))
.getResult().getOutput().getContent();
}自定义 ChatMemory 实现
@Component
public class RedisChatMemory implements ChatMemory {
private final StringRedisTemplate redis;
public RedisChatMemory(StringRedisTemplate redis) {
this.redis = redis;
}
@Override
public void add(String conversationId, List<Message> messages) {
String key = "chat:history:" + conversationId;
messages.forEach(msg -> {
SerializedMessage serialized = new SerializedMessage(
msg.getMessageType(), msg.getContent());
redis.opsForList().rightPush(key, serialized.toJson());
});
redis.opsForList().trim(key, 0, 19); // 最多保留 20 条
}
@Override
public List<Message> get(String conversationId, int lastN) {
String key = "chat:history:" + conversationId;
List<String> jsonList = redis.opsForList().range(key, -lastN, -1);
if (jsonList == null) return List.of();
return jsonList.stream()
.map(SerializedMessage::fromJson)
.collect(Collectors.toList());
}
@Override
public void clear(String conversationId) {
redis.delete("chat:history:" + conversationId);
}
}小结
- Message 类型:System(角色设定)、User(用户输入)、Assistant(AI 回复)、Tool(工具结果)。
- AI 模型无状态,多轮对话需手动维护历史消息。
InMemoryChatMemory适合开发测试;生产推荐 Redis/MongoDB 持久化。MessageChatMemoryAdvisor自动管理对话历史,只需传递 sessionId。- 直接调用时通过
add("sessionId", message)和get("sessionId", lastN)手动管理。
