对话系统
大约 8 分钟
第七章:智能对话系统
7.1 简单聊天机器人
聊天机器人是AI应用中最常见的场景之一,Spring AI提供了强大的对话系统支持。
7.1.1 基础聊天机器人
@RestController
public class ChatbotController {
private final ChatClient chatClient;
public ChatbotController(ChatClient chatClient) {
this.chatClient = chatClient;
}
@GetMapping("/chatbot")
public String chat(@RequestParam String message) {
return chatClient.prompt()
.user(message)
.call()
.content();
}
}7.1.2 上下文感知聊天机器人
@RestController
public class ContextAwareChatbotController {
private final ChatClient chatClient;
public ContextAwareChatbotController(ChatClient chatClient) {
this.chatClient = chatClient;
}
@PostMapping("/chatbot/context")
public ChatResponse contextAwareChat(@RequestBody ChatMessage message) {
ChatPrompt chatPrompt = new ChatPrompt();
// 添加系统提示
chatPrompt.add(new SystemMessage("You are a helpful assistant"));
// 添加历史消息
for (Message historyMessage : message.getHistory()) {
chatPrompt.add(historyMessage);
}
// 添加当前消息
chatPrompt.add(new UserMessage(message.getCurrentMessage()));
return chatClient.prompt(chatPrompt).call();
}
}
public class ChatMessage {
private List<Message> history;
private String currentMessage;
// getters and setters
}7.1.3 主题限定聊天机器人
@RestController
public class TopicChatbotController {
private final ChatClient chatClient;
public TopicChatbotController(ChatClient chatClient) {
this.chatClient = chatClient;
}
@GetMapping("/chatbot/topic")
public String topicChatbot(
@RequestParam String topic,
@RequestParam String message) {
String systemPrompt = "You are a " + topic + " expert. Answer questions only about " + topic;
return chatClient.prompt()
.system(systemPrompt)
.user(message)
.call()
.content();
}
}7.2 上下文管理
7.2.1 对话历史管理
@Service
public class ConversationService {
private final ChatClient chatClient;
private final Map<String, Conversation> conversations = new ConcurrentHashMap<>();
public ConversationService(ChatClient chatClient) {
this.chatClient = chatClient;
}
public String sendMessage(String conversationId, String message) {
Conversation conversation = conversations.computeIfAbsent(
conversationId,
id -> new Conversation()
);
conversation.addMessage(new UserMessage(message));
ChatPrompt chatPrompt = new ChatPrompt();
chatPrompt.add(new SystemMessage(conversation.getSystemPrompt()));
for (Message msg : conversation.getMessages()) {
chatPrompt.add(msg);
}
ChatResponse response = chatClient.prompt(chatPrompt).call();
String content = response.getContent();
conversation.addMessage(new AssistantMessage(content));
return content;
}
public void clearConversation(String conversationId) {
conversations.remove(conversationId);
}
}
public class Conversation {
private String id;
private String systemPrompt;
private List<Message> messages;
// getters and setters
}7.2.2 对话状态管理
@Service
public class StatefulConversationService {
private final ChatClient chatClient;
private final Map<String, ConversationState> conversationStates = new ConcurrentHashMap<>();
public StatefulConversationService(ChatClient chatClient) {
this.chatClient = chatClient;
}
public String sendMessageWithState(
String conversationId,
String message,
Map<String, Object> state) {
ConversationState conversationState = conversationStates.computeIfAbsent(
conversationId,
id -> new ConversationState()
);
conversationState.setState(state);
String prompt = createPromptWithState(message, state);
String response = chatClient.prompt()
.user(prompt)
.call()
.content();
// 更新状态
updateStateFromResponse(response, conversationState);
return response;
}
private String createPromptWithState(String message, Map<String, Object> state) {
StringBuilder prompt = new StringBuilder(message + "\n\n");
prompt.append("Current state: ").append(state);
return prompt.toString();
}
private void updateStateFromResponse(String response, ConversationState state) {
// 从响应中提取状态信息
}
}
public class ConversationState {
private Map<String, Object> state;
// getters and setters
}7.2.3 对话持久化
@Repository
public class ConversationRepository {
private final Map<String, Conversation> conversations = new ConcurrentHashMap<>();
public Conversation save(Conversation conversation) {
conversations.put(conversation.getId(), conversation);
return conversation;
}
public Optional<Conversation> findById(String id) {
return Optional.ofNullable(conversations.get(id));
}
public void deleteById(String id) {
conversations.remove(id);
}
}7.3 多轮对话流程
7.3.1 对话流程定义
public class ConversationFlow {
private String id;
private List<ConversationStep> steps;
private int currentStep;
// getters and setters
}
public class ConversationStep {
private String prompt;
private Map<String, String> expectedResponses;
private String nextStep;
// getters and setters
}7.3.2 流程控制对话机器人
@RestController
public class FlowChatbotController {
private final ChatClient chatClient;
private final Map<String, ConversationFlow> flows = new ConcurrentHashMap<>();
public FlowChatbotController(ChatClient chatClient) {
this.chatClient = chatClient;
}
@PostMapping("/chatbot/flow")
public FlowResponse handleFlowMessage(
@RequestParam String flowId,
@RequestParam String message) {
ConversationFlow flow = flows.get(flowId);
if (flow == null) {
return new FlowResponse("Flow not found", null);
}
ConversationStep currentStep = flow.getSteps().get(flow.getCurrentStep());
String prompt = currentStep.getPrompt() + "\n\n" + message;
String response = chatClient.prompt()
.user(prompt)
.call()
.content();
// 检查响应是否符合预期
if (isExpectedResponse(response, currentStep)) {
flow.setCurrentStep(flow.getCurrentStep() + 1);
return new FlowResponse(response, flow.getCurrentStep());
}
return new FlowResponse(response, flow.getCurrentStep());
}
private boolean isExpectedResponse(String response, ConversationStep step) {
// 实现响应验证逻辑
return true;
}
}
public class FlowResponse {
private String response;
private Integer nextStep;
// getters and setters
}7.3.3 条件对话流程
@RestController
public class ConditionalFlowChatbotController {
private final ChatClient chatClient;
public ConditionalFlowChatbotController(ChatClient chatClient) {
this.chatClient = chatClient;
}
@PostMapping("/chatbot/conditional-flow")
public ConditionalFlowResponse handleConditionalFlow(
@RequestParam String flowId,
@RequestParam String message,
@RequestParam Map<String, String> context) {
// 根据上下文确定下一步
String nextStep = determineNextStep(context, message);
String prompt = "Based on the context, proceed to step: " + nextStep + "\n\n" + message;
String response = chatClient.prompt()
.user(prompt)
.call()
.content();
return new ConditionalFlowResponse(response, nextStep);
}
private String determineNextStep(Map<String, String> context, String message) {
// 实现条件判断逻辑
return "next_step";
}
}
public class ConditionalFlowResponse {
private String response;
private String nextStep;
// getters and setters
}7.4 对话状态管理
7.4.1 状态机对话系统
public enum ConversationState {
GREETING,
ASKING_QUESTIONS,
PROVIDING_ANSWERS,
CLOSING
}
@Service
public class StateMachineChatbot {
private final ChatClient chatClient;
private final Map<String, ConversationStateMachine> stateMachines = new ConcurrentHashMap<>();
public StateMachineChatbot(ChatClient chatClient) {
this.chatClient = chatClient;
}
public String handleMessage(String conversationId, String message) {
ConversationStateMachine stateMachine = stateMachines.computeIfAbsent(
conversationId,
id -> new ConversationStateMachine()
);
ConversationState currentState = stateMachine.getCurrentState();
String response = processMessageBasedOnState(currentState, message, stateMachine);
// 更新状态
updateStateBasedOnResponse(response, stateMachine);
return response;
}
private String processMessageBasedOnState(
ConversationState state,
String message,
ConversationStateMachine stateMachine) {
switch (state) {
case GREETING:
return handleGreeting(message, stateMachine);
case ASKING_QUESTIONS:
return handleQuestions(message, stateMachine);
case PROVIDING_ANSWERS:
return handleAnswers(message, stateMachine);
case CLOSING:
return handleClosing(message, stateMachine);
default:
return "I'm not sure how to respond to that.";
}
}
private String handleGreeting(String message, ConversationStateMachine stateMachine) {
// 处理问候消息
return "Hello! How can I help you today?";
}
// 其他状态处理方法...
}
public class ConversationStateMachine {
private ConversationState currentState;
private Map<String, Object> context;
// getters and setters
}7.4.2 对话意图识别
@RestController
public class IntentChatbotController {
private final ChatClient chatClient;
public IntentChatbotController(ChatClient chatClient) {
this.chatClient = chatClient;
}
@PostMapping("/chatbot/intent")
public IntentResponse handleIntent(@RequestBody ChatMessage message) {
String prompt = "Identify the intent of the following message and extract any entities:\n\n" + message.getCurrentMessage();
IntentAnalysis analysis = chatClient.prompt()
.user(prompt)
.call()
.entity(IntentAnalysis.class);
return new IntentResponse(analysis.getIntent(), analysis.getEntities());
}
}
public class IntentAnalysis {
private String intent;
private Map<String, String> entities;
// getters and setters
}
public class IntentResponse {
private String intent;
private Map<String, String> entities;
// getters and setters
}7.4.3 对话流程控制
@Service
public class DialogManager {
private final ChatClient chatClient;
public DialogManager(ChatClient chatClient) {
this.chatClient = chatClient;
}
public DialogResponse manageDialog(
String conversationId,
String message,
DialogContext context) {
// 根据上下文确定对话流程
DialogFlow flow = determineDialogFlow(context);
// 生成响应
String response = generateResponse(flow, message, context);
// 更新上下文
updateContext(response, context);
return new DialogResponse(response, context);
}
private DialogFlow determineDialogFlow(DialogContext context) {
// 实现对话流程确定逻辑
return new DialogFlow();
}
private String generateResponse(DialogFlow flow, String message, DialogContext context) {
// 实现响应生成逻辑
return "Response based on dialog flow";
}
private void updateContext(String response, DialogContext context) {
// 实现上下文更新逻辑
}
}
public class DialogContext {
private Map<String, Object> context;
// getters and setters
}
public class DialogFlow {
private List<DialogStep> steps;
// getters and setters
}
public class DialogStep {
private String prompt;
private List<String> expectedResponses;
// getters and setters
}7.5 高级对话功能
7.5.1 个性化对话
@RestController
public class PersonalizedChatbotController {
private final ChatClient chatClient;
public PersonalizedChatbotController(ChatClient chatClient) {
this.chatClient = chatClient;
}
@PostMapping("/chatbot/personalized")
public String personalizedChat(
@RequestParam String userId,
@RequestParam String message) {
UserPreferences preferences = getUserPreferences(userId);
String systemPrompt = createPersonalizedSystemPrompt(preferences);
return chatClient.prompt()
.system(systemPrompt)
.user(message)
.call()
.content();
}
private UserPreferences getUserPreferences(String userId) {
// 获取用户偏好设置
return new UserPreferences();
}
private String createPersonalizedSystemPrompt(UserPreferences preferences) {
// 创建个性化系统提示
return "You are a personalized assistant for this user";
}
}
public class UserPreferences {
private String language;
private String tone;
private List<String> interests;
// getters and setters
}7.5.2 多模态对话
@RestController
public class MultimodalChatbotController {
private final ChatClient chatClient;
private final ImageClient imageClient;
public MultimodalChatbotController(ChatClient chatClient, ImageClient imageClient) {
this.chatClient = chatClient;
this.imageClient = imageClient;
}
@PostMapping("/chatbot/multimodal")
public MultimodalResponse handleMultimodal(
@RequestParam String message,
@RequestParam MultipartFile image) {
// 处理文本消息
String textResponse = chatClient.prompt()
.user(message)
.call()
.content();
// 处理图像
ImagePrompt imagePrompt = new ImagePrompt(image, "Analyze this image");
ImageResponse imageResponse = imageClient.generate(imagePrompt);
return new MultimodalResponse(textResponse, imageResponse.getContent());
}
}
public class MultimodalResponse {
private String textResponse;
private String imageAnalysis;
// getters and setters
}7.6 实际应用示例
7.6.1 客服聊天机器人
@Service
public class CustomerServiceChatbot {
private final ChatClient chatClient;
public CustomerServiceChatbot(ChatClient chatClient) {
this.chatClient = chatClient;
}
public String handleCustomerQuery(String customerId, String query) {
String systemPrompt = "You are a customer service representative for an e-commerce platform";
return chatClient.prompt()
.system(systemPrompt)
.user(query)
.call()
.content();
}
}7.6.2 销售助手聊天机器人
@Service
public class SalesAssistantChatbot {
private final ChatClient chatClient;
public SalesAssistantChatbot(ChatClient chatClient) {
this.chatClient = chatClient;
}
public SalesResponse handleSalesInquiry(
String productId,
String customerProfile,
String inquiry) {
String prompt = "Product: " + productId + "\n" +
"Customer: " + customerProfile + "\n" +
"Inquiry: " + inquiry;
return chatClient.prompt()
.user(prompt)
.call()
.entity(SalesResponse.class);
}
}
public class SalesResponse {
private String recommendation;
private String pricing;
private String availability;
// getters and setters
}7.7 性能优化
7.7.1 对话缓存
@Configuration
@EnableCaching
public class DialogCacheConfig {
@Bean
public CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(Arrays.asList(
new ConcurrentMapCache("dialog-responses"),
new ConcurrentMapCache("conversation-context")
));
return cacheManager;
}
}7.7.2 异步对话处理
@RestController
public class AsyncDialogController {
private final ChatClient chatClient;
public AsyncDialogController(ChatClient chatClient) {
this.chatClient = chatClient;
}
@GetMapping("/dialog/async")
public CompletableFuture<String> asyncDialog(@RequestParam String message) {
return chatClient.prompt()
.user(message)
.callAsync()
.thenApply(ChatResponse::getContent);
}
}7.8 错误处理
7.8.1 对话异常处理
@RestControllerAdvice
public class DialogExceptionHandler {
@ExceptionHandler(DialogException.class)
public ResponseEntity<ErrorResponse> handleDialogError(DialogException ex) {
ErrorResponse error = new ErrorResponse(
"DIALOG_ERROR",
"对话处理失败: " + ex.getMessage()
);
return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}
}7.8.2 对话超时处理
@Service
public class TimeoutDialogService {
private final ChatClient chatClient;
public TimeoutDialogService(ChatClient chatClient) {
this.chatClient = chatClient;
}
public String handleDialogWithTimeout(String message) {
try {
return chatClient.prompt()
.user(message)
.call()
.content();
} catch (TimeoutException ex) {
return "Sorry, I couldn't process your request in time. Please try again.";
}
}
}7.9 监控与日志
7.9.1 对话监控
@RestController
public class DialogMetricsController {
private final MeterRegistry meterRegistry;
public DialogMetricsController(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
@GetMapping("/dialog/metrics")
public Map<String, Object> getMetrics() {
return Map.of(
"totalDialogs", meterRegistry.counter("dialog.total").count(),
"averageDuration", meterRegistry.timer("dialog.duration").mean(),
"errorRate", meterRegistry.counter("dialog.errors").count() /
(meterRegistry.counter("dialog.total").count() + 1.0)
);
}
}7.9.2 对话日志
@Configuration
public class DialogLogging {
@Bean
public ChatClient loggingChatClient(ChatClient chatClient) {
return new ChatClient() {
@Override
public ChatResponse call(Prompt prompt) {
long startTime = System.currentTimeMillis();
try {
ChatResponse response = chatClient.call(prompt);
long duration = System.currentTimeMillis() - startTime;
log.info("对话处理 - 耗时: {}ms, Prompt: {}", duration, prompt);
return response;
} catch (Exception ex) {
log.error("对话处理失败", ex);
throw ex;
}
}
// 实现其他方法...
};
}
}7.10 小结
本章详细介绍了智能对话系统的开发:
- 简单聊天机器人:掌握基础对话机器人的实现
- 上下文管理:学习对话历史和状态管理
- 多轮对话:了解对话流程和条件对话
- 对话状态:掌握状态机和意图识别
- 高级功能:学习个性化对话和多模态对话
- 实际应用:了解客服和销售助手等实际场景
- 性能优化:掌握对话缓存和异步处理
- 错误处理:了解对话异常和超时处理
- 监控日志:掌握对话监控和日志记录
在下一章中,我们将学习图像处理技术。 点击这里👇🏻获取:100万QPS短链系统、复杂的商城微服务系统、智能翻译助手AI Agent、SaaS点餐系统、刷题吧小程序、商城系统、秒杀系统、AI项目、代码生成神器、苏三demo项目、智能天气播报AI Agent、智能代码审查AI Agent等 10 个项目的:项目源代码、开发教程和技术答疑
