该功能于4.13实现
一、功能目标:
1.用户能连接大模型进行问答,且对话可自动生成标题
2.用户要能够专门依据此页典籍进行大模型问答,同时也可以实现对鼠标选中语段进行问答,
3.该对话功能还要能实现新建对话,查询往期对话,自动生成对话标题,
4.实现若用户对大模型回答不满意可以重新生成,可以让用户选择哪个对他来说回答更好。
本次主要实现了3.4两个功能
二、功能实现
1.架构设计全景图
graph TD
A[HTTP请求] --> B[API网关]
B --> C{业务路由}
C -->|会话管理| D[SessionController]
C -->|回答优化| E[MessageController]
D --> F[SessionService]
E --> G[MessageService]
F --> H[SessionRepository]
G --> I[MessageRepository]
G --> J[AIService]
2.智能对话管理
// 创建对话(带智能标题生成)
@Transactional
public QaSession createSessionWithTitle(Long userId, Long classicId, String firstQuestion) {
// 1. 基础会话创建
QaSession session = new QaSession();
session.setUserId(userId);
session.setClassic(classicRepository.getReferenceById(classicId));
// 2. 动态标题生成策略
String titlePrompt = String.format(
"基于以下对话初始问题生成简洁标题(15字内):\n" +
"问题:%s\n" +
"相关典籍:《%s》\n" +
"要求:包含核心问题关键词,格式示例:'XX问题探讨'",
firstQuestion,
session.getClassic().getTitle()
);
String generatedTitle = aiService.generateCompactResponse(titlePrompt session.setTitle(StringUtils.abbreviate(generatedTitle, 50));
// 3. 初始化会话状态
session.setCreatedAt(Instant.now());
session.setActive(true);
return sessionRepository.save(session);
}// 历史对话查询(带分页与排序)
public Page<SessionDTO> getHistoricalSessions(Long userId, Long classicId, Pageable pageable) {
// 安全校验
securityService.validateUserAccess(userId);
return sessionRepository.findByUserIdAndClassicId(userId, classicId, pageable)
.map(session -> new SessionDTO(
session.getId(),
session.getTitle(),
session.getCreatedAt(),
// 显示最后活跃时间
session.getQaMessages().stream()
.map(QaMessage::getCreatedAt)
.max(Instant::compareTo)
.orElse(session.getCreatedAt())
));
}
3.回答优化系统
// MessageService.java 核心代码片段
// 重新生成回答
@Transactional
public QaMessage regenerateAnswer(Long messageId) {
// 1. 获取原始消息
QaMessage original = messageRepository.findById(messageId)
.orElseThrow(() -> new MessageNotFoundException("原始消息不存在"));
// 2. 标记旧回答失效
original.setIsCurrent(false);
messageRepository.save(original);
// 3. 生成改进回答
String improvedContent = aiService.getEnhancedResponse(original.getContent());
// 4. 创建新版本消息
QaMessage newMessage = new QaMessage();
newMessage.setSession(original.getSession());
newMessage.setParent(original);
newMessage.setRole("assistant");
newMessage.setContent(improvedContent);
newMessage.setIsCurrent(true);
return messageRepository.save(newMessage);
}// 回答反馈处理
@Transactional
public void processFeedback(Long messageId, String feedbackType) {
QaMessage message = messageRepository.findById(messageId)
.orElseThrow(() -> new MessageNotFoundException("消息不存在"));
// 反馈类型验证
if (!List.of("helpful", "neutral", "unhelpful").contains(feedbackType)) {
throw new InvalidFeedbackException("无效反馈类型");
}
// 更新反馈统计
message.setFeedback(feedbackType);
messageRepository.save(message);
// 若为优质回答,提升其可见性
if ("helpful".equals(feedbackType)) {
message.getParent().ifPresent(parent -> {
parent.setIsCurrent(false); // 确保只保留最优回答
});
message.setIsCurrent(true);
}
}
4.回答优化流程
sequenceDiagram
participant 用户
participant 前端
participant MessageController
participant MessageService
participant AI服务
用户->>前端: 点击"重新生成"
前端->>MessageController: POST /regenerate {messageId}
MessageController->>MessageService: regenerateAnswer()
MessageService->>MessageRepository: 标记旧回答失效
MessageService->>AI服务: 获取改进回答
AI服务-->>MessageService: 返回新内容
MessageService->>MessageRepository: 保存新回答
MessageController-->>前端: 返回新消息ID
前端->>用户: 展示改进回答
用户->>前端: 选择"有帮助"
前端->>MessageController: POST /feedback {messageId, type}
MessageController->>MessageService: processFeedback()
MessageService->>MessageRepository: 更新反馈状态