典籍知识问答重新生成逻辑修改
1.需求
希望点击重新生成后就在原回答上进行修改,不要再生成新的回答
2.后端代码修改
//QAService
// 修改 regenerateResponse 方法
@Transactional
public QaMessage regenerateResponse(Long messageId) {
QaMessage original = messageRepository.findById(messageId)
.orElseThrow(() -> new RuntimeException("Message not found"));
// 验证:只能重新生成AI消息
if (!"assistant".equals(original.getRole())) {
throw new IllegalArgumentException("只能重新生成AI消息");
}
// 生成新的回复
String improvedContent = aiService.getEnhancedResponse(original);
// 更新原消息内容
original.setContent(improvedContent);
// 重置反馈状态
original.setFeedback(null);
// 删除所有后续消息(子消息)
deleteChildrenMessages(original);
return messageRepository.save(original);
}
// 新增辅助方法:递归删除子消息
private void deleteChildrenMessages(QaMessage message) {
List<QaMessage> children = message.getQaMessages();
for (QaMessage child : children) {
deleteChildrenMessages(child);
messageRepository.delete(child);
}
message.getQaMessages().clear();
}
// 修改 streamRegenerateResponse 方法
public void streamRegenerateResponse(Long messageId, SseEmitter emitter) {
try {
QaMessage original = messageRepository.findById(messageId)
.orElseThrow(() -> new RuntimeException("Message not found"));
// 验证:只能重新生成AI消息
if (!"assistant".equals(original.getRole())) {
throw new IllegalArgumentException("只能重新生成AI消息");
}
// 删除所有后续消息
deleteChildrenMessages(original);
// 重置原消息内容
original.setContent("");
original.setFeedback(null);
messageRepository.save(original);
// 生成改进提示(使用原消息的父消息)
QaMessage parentMessage = original.getParent();
String prompt = parentMessage != null ? parentMessage.getContent() : original.getContent();
aiService.streamAIResponse(prompt, new AIService.StreamCallback() {
final StringBuilder fullContent = new StringBuilder();
@Override
public void onStart() throws IOException {
// 发送原消息ID
emitter.send(SseEmitter.event().name("START").data(original.getId()));
}
@Override
public void onContent(String token) throws IOException {
fullContent.append(token);
original.setContent(fullContent.toString());
emitter.send(SseEmitter.event().data(token));
}
@Override
public void onComplete() throws IOException {
original.setContent(fullContent.toString());
messageRepository.save(original);
emitter.send(SseEmitter.event().name("COMPLETE"));
emitter.complete();
}
@Override
public void onError(Exception e) {
original.setContent("重新生成失败: " + e.getMessage());
messageRepository.save(original);
emitter.completeWithError(e);
}
});
} catch (Exception e) {
emitter.completeWithError(e);
}
}
3.前端修改
//qa-stores
const regenerate = async (messageId) => {
try {
loadingMessage.value[messageId] = true;
// 找到原消息
const originalMsgIndex = currentMessages.value.findIndex(msg => msg.id === messageId);
if (originalMsgIndex === -1) {
throw new Error('消息未找到');
}
// 重置原消息状态
currentMessages.value[originalMsgIndex].content = '';
currentMessages.value[originalMsgIndex].streaming = true;
currentMessages.value[originalMsgIndex].error = false;
const response = await fetch(`/api/qa/stream-regenerate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ messageId })
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
let currentEvent = null;
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split('\n');
buffer = lines.pop() || '';
for (const line of lines) {
if (line.startsWith('event:')) {
currentEvent = line.replace('event:', '').trim();
continue;
}
if (line.startsWith('data:')) {
const data = line.replace('data:', '').trim();
// START 事件 - 确认原消息ID
if (currentEvent === 'START') {
if (data !== messageId.toString()) {
console.warn('消息ID不匹配', data, messageId);
}
currentEvent = null;
continue;
}
// 普通内容 - 更新原消息
if (currentEvent === null) {
currentMessages.value[originalMsgIndex].content += data;
}
// 完成事件
if (currentEvent === 'COMPLETE') {
currentMessages.value[originalMsgIndex].streaming = false;
}
}
}
}
// 确保结束状态
currentMessages.value[originalMsgIndex].streaming = false;
await fetchSessions(classic.value.id);
} catch (error) {
console.error('重新生成失败:', error);
const originalMsgIndex = currentMessages.value.findIndex(msg => msg.id === messageId);
if (originalMsgIndex !== -1) {
currentMessages.value[originalMsgIndex].content = '重新生成失败: ' + error.message;
currentMessages.value[originalMsgIndex].streaming = false;
currentMessages.value[originalMsgIndex].error = true;
}
} finally {
loadingMessage.value[messageId] = false;
}
};