Browse Source

fix(app): 修复切换会话后用户提问被查询重写结果覆盖

RAG 查询重写(REWRITE 等策略)的润色产物被当作用户消息落库到
chat_message 会话记忆表,导致 ChatSDK 切换角色/对话后前端拉取
历史显示的是润色版而非原始提问。

ChatPipeline 在 RAG 分支将 finalMessage 由 rag.rewrittenQuery()
改为 ctx.message(),使查询重写仅服务于检索,用户消息(传给模型、
落库、前端展示)统一为原始提问。
Spring-AI-1.1.2
wanghanlin 1 month ago
parent
commit
081758128c
  1. 6
      src/main/java/com/wok/supportbot/app/ChatPipeline.java
  2. 2
      src/main/java/com/wok/supportbot/app/ChatRequest.java
  3. 4
      src/main/java/com/wok/supportbot/rag/RagContext.java

6
src/main/java/com/wok/supportbot/app/ChatPipeline.java

@ -66,7 +66,7 @@ public class ChatPipeline {
* <li>未启用 RAG(普通对话 / 严格隔离下 KB 拒绝)→ 用原始 message、基础 system</li>
* <li>寒暄/闲聊(IntentRouter 或寒暄词命中)→ 同上,跳过 KB 检索</li>
* <li>FAQ 命中 → 直接返回标准答案,不调用 ChatClient</li>
* <li>RAG 生成 → 资料块注入 system,重写后查询作为 user 消息</li>
* <li>RAG 生成 → 资料块注入 system,原始 message 作为 user 消息(重写查询仅用于检索)</li>
* </ul>
*
* @param ctx 对话上下文
@ -128,9 +128,9 @@ public class ChatPipeline {
globalPrompt, null, null, "FAQ", null, null, rag.faqMatchResult());
}
// RAG 生成:资料块注入 system,重写后查询作为 user 消息
// RAG 生成:资料块注入 system,原始 message 作为 user 消息(重写查询仅用于检索)
String finalSystem = baseSystem + ragPipeline.buildRagContextBlock(rag.contextText());
return new ChatRequest(ctx, rag.rewrittenQuery(), finalSystem, Optional.empty(),
return new ChatRequest(ctx, ctx.message(), finalSystem, Optional.empty(),
globalPrompt, rag.contextText(), rag.documents() != null ? rag.documents().size() : 0, "RAG",
rag.searchMode(), rag.documents(), null);
}

2
src/main/java/com/wok/supportbot/app/ChatRequest.java

@ -15,7 +15,7 @@ import java.util.Optional;
* 字段含义:
* <ul>
* <li>{@link #faqAnswer()}:FAQ 命中时直接返回标准答案,跳过 ChatClient 调用</li>
* <li>{@link #finalMessage()}:传给模型的用户消息(RAG 场景为重写后的查询,否则为原始 message)</li>
* <li>{@link #finalMessage()}:传给模型的用户消息(始终为原始 message,查询重写仅用于检索)</li>
* <li>{@link #finalSystemPrompt()}:传给模型的系统提示词(角色人设 + RAG 资料块),可为空</li>
* <li>{@link #globalPrompt()}:全局提示词快照(来自 system_config.ai_system_prompt),可为空</li>
* <li>{@link #ragContextText()}:RAG 资料块文本(未注入时为空/null)</li>

4
src/main/java/com/wok/supportbot/rag/RagContext.java

@ -13,13 +13,13 @@ import java.util.Optional;
* <ul>
* <li>{@link #faqAnswer()} 命中 → 直接返回标准答案,跳过生成</li>
* <li>未命中 → 用 {@link #documents()} 展示引用来源,用 {@link #contextText()} 注入系统提示词,
* 用 {@link #rewrittenQuery()} 作为传给模型的用户消息</li>
* {@link #rewrittenQuery()} 仅用于检索,不作为传给模型的用户消息</li>
* </ul>
*
* @param faqAnswer FAQ 命中的标准答案;未命中为 {@link Optional#empty()}
* @param documents 检索命中的知识库片段(含 metadata),可为空
* @param contextText 拼接后的资料文本(用 {@code "\n\n---\n\n"} 分隔);无资料时为空串
* @param rewrittenQuery 传给模型的用户消息:MULTI_QUERY 为原始 message,其余策略为重写后的查询
* @param rewrittenQuery 检索用的改写查询(MULTI_QUERY 为原始 message,其余策略为重写后的查询),仅用于检索,不作为用户消息
* @param searchMode 真实检索模式(VECTOR / KEYWORD / HYBRID),当前主管道固定为 VECTOR
* @param faqMatchResult FAQ 命中详情(含 matchType/score);未命中为 null
*/

Loading…
Cancel
Save