前面,我们只是将用户的问题相关的内容保存在数据库了,但是LLM返回的结果我们是没有保存的,这个也需要保存。 1、对话开始时(ChatApplicationService#chat),创建一条Assistant消息:
String assistantMessageId = chatMessageService.saveAssistantMessage(chatParam.conversationId());
2、在模型返回后,更新消息,把LLM返回的内容更新进去:
Disposable disposable = knowEngineChatAiService.streamChat(chatParam.conversationId(), chatParam.content())
.doOnNext(token -> {
// 首个 token 到达时,如果之前没有发出"正在生成回答",则补发
// (正常情况下由 ProgressAwareContentAggregator 已发出,此处为兜底)
if (firstToken.compareAndSet(true, false)) {
// 标记已开始接收 token
}
contentBuilder.append(token);
})
.doOnComplete(() -> chatMessageService.updateContent(assistantMessageId, contentBuilder.toString()))
.subscribe(sink::next, sink::error, sink::complete);
// 取消时同步取消内部订阅
sink.onCancel(disposable::dispose);
在doOnNext中累计流式输出的结果,在doOnComplete中,完成更新操作。 引用文档的更新:
✅如何把引用文档内容返回给用户?
在RAG中,给问题回答增加参考来源是比较常见的做法,一方面可以增加回答的可信度,另外也能让用户直接查看完整文档,获取更多信息,如: 具体实现方式分两步,首先在分段时,需要在每一个分段中记录下来当前分段所属的文档的名称、以及对应的地址。 在 LLMentor 调用chatMessageService.updateRagReferences(chatMessageId, ragReferences);做更新。