SA 问答对话 - 设计实现偏差问题说明(现状 vs 产品预期)
状态:待评审 | 范围:对话端(Chatbot)问答对话(QA Chat) | 关联:QA_闲聊对话_Agent设计、QA_G-Cite_Dify平台功能设计、知识库元数据标签体系设计、Web Search 工具选型报告、输入侧安全护栏设计 | 问题定位:
问答工作流.yml相对设计文档存在 1 处断链缺陷、1 处待实测验证项,另有 2 处设计取舍/缺失待评估
0. 问题清单总览
等级说明:由强哥手动维护优先级,P0(阻断/必须本期解决)> P1(本期应解决)> P2(后续版本/需求点)。未定级时留空。
| # | 问题 | 等级 | 定性 | 处理建议 |
|---|---|---|---|---|
| 1 | 历史会话断链:merge_chat 未注入任何下游节点,多轮上下文未生效 | P0 | 断链缺陷 | 修复(见 §5.1) |
| 2 | access_roles 权限过滤仅支持单角色匹配(Dify 限制,功能已通过) | 已知限制 | 已记录 PRD,暂不整改 | |
| 3 | 多源"来源优先级"规则被删除 + 寒暄/弱信息输入会引用检索片段 | P1 | 设计取舍/增强项 | 可选增强(行业优先级 + 寒暄规则) |
| 4 | 敏感话题拦截缺失(政治/暴力/色情/隐私) | P2 | 安全类·跨 Agent 共性 | 评估统一护栏方案(见 §3.4) |
| 5 | 知识库 score 阈值开关未开启(知识库侧预制设置) | P2 | 提示项 | 后续定阈值 |
1. 问题一句话
QA Chatflow 相对 G-Cite 设计在"多轮历史注入"上存在断链缺陷(历史合并结果未接入 LLM),权限过滤已确认单角色限制(Dify 限制,功能通过),另有多源来源说明删除(取舍一致)、敏感话题拦截缺失、score 阈值未开启三处需评审确认。
2. 产品预期(PRD 汇总)
按设计文档的原始定义:
- 多轮对话历史(QA Agent 设计 §6.1):同一会话内保留最近 5 轮对话历史,由 QA_Chat 的 Chat History 负责;跨 Agent 记忆由 Master Agent 负责。
- 上下文组织(主智能体 编排):Master 将
history_text+roles经 Chatflow Invokerinputs_json传入 QA Chatflow(keep_conversation=false无状态调用,历史依赖入参)。 - 权限过滤(元数据标签体系 §2.2):用户角色 ∩
access_roles≠ ∅ 则可见;空access_roles表示无限制、对所有人可见。 - 多源检索(G-Cite §2.2/§3):RAG + Web 双源并行 → 合并 → 单一 LLM,LLM 一次性看到全部片段自主选择引用。
- 幻觉控制(QA Agent 设计 §7.3):KB 未命中(Score < 0.6)不得编造楼宇信息。
- 安全边界(QA Agent 设计 §7.1/§7.2):敏感话题拒答 + 业务越权引导。
3. 现状实现与偏差定性
3.1 历史会话断链(真缺陷)
QA Chatflow 内 合并历史会话和当前会话 节点产出 merge_chat(历史会话:{chathistory} 当前提问:{query}),但该输出没有任何下游边引用:
| 消费方 | 实际使用的输入 | 是否消费 merge_chat |
|---|---|---|
| 知识检索(迭代内) | sys.query | ❌ |
| 百度搜索 | sys.query | ❌ |
| LLM 用户提示词 | {{#sys.query#}} | ❌ |
Master 侧确认:构建问答inputs 已把 history_text(近 3 轮,MAX_SESSION_TURNS=3)传入 QA 的 Start 输入 chathistory,且 keep_conversation=false 说明历史本就依赖入参透传——断链完全在 QA 工作流内部,传进来的历史被丢弃,LLM 看不到任何多轮上下文。
补充:QA 工作流 Start 的
chathistory实际类型是字符串(Master 传入history_text文本),而合并历史会话节点的 docstring 按数组设计,但运行逻辑对字符串同样可拼接,不影响断链结论。
3.2 access_roles 权限过滤:单角色匹配(已知限制,功能已通过)
实现方式:迭代遍历 roles_list(每角色一次知识检索),过滤条件为 access_roles is {{当前角色}} OR access_roles is empty。
- ✅ 已落地能力:单角色过滤;无角色限制文档(
is empty)对所有人可见;多角色用户逐角色命中任一即召回。功能已测试通过。 - ⚠️ 已知限制(已更新 PRD):Dify 无法对
access_roles(JSON 数组字符串)做元素级交集匹配,仅支持单角色精确匹配。文档打标时access_roles需按单角色值填写(或留空表示无限制);若存多角色 JSON 数组则无法被is命中。多角色交集检索暂不可行,后续按需评估。
3.3 多源"来源优先级"规则被删除 + 寒暄/弱信息引用检索(增强项)
设计 §5.2 系统提示词含"检索片段来源说明(多源时启用)"段(知识库/公网来源介绍 + "涉及楼宇流程优先标注知识库来源 / 涉及通用知识优先标注公网来源")。实际实现整段删除。
寒暄/弱信息现状:当前"无脑双通道"对所有输入(含"你好""hello"等纯寒暄)都跑 RAG + Web 检索,LLM 面对不相关片段可能引用其中内容作答——寒暄话题拉检索很蠢,应直接自然回应。
判定(来源优先级删除):删除与设计 §5.2 末尾注释的取舍一致("LLM System Prompt 不告诉 LLM 源类型,避免干扰,差异化由前端体现");且设计原文"两种来源同等重要"与"优先标注"规则自相矛盾。故不算缺陷,作为可选增强处理。
可选增强(P1,合并为一段系统提示词增强):
- 寒暄/弱信息规则:对纯寒暄、无信息量输入直接回应,不引用检索片段(修复寒暄拉检索的"弱智问题");
- 行业知识优先级:结合公司业务定位(《苏高新数科营销话术》——泛建筑/园区数字化,建筑操作系统覆盖智能化、机电、运维、运营四大模块,行业覆盖企业园区/产业园区/医院/文旅场馆/城市综合体/酒店/公建/低碳),强化本楼/本园区权威性。
建议文本合并见 §5.3。
3.4 敏感话题拦截缺失(P2,待评估)
设计 §7.1 要求政治敏感/暴力色情/人身攻击/个人隐私四类拒答。实际系统提示词能力边界只覆盖业务越权(不能控设备/订会议/查能耗),无敏感话题规则,依赖模型层对齐兜底。
定性补充(2026-09-17 评审):本项与「提示词注入/引导犯错」同属输入侧安全护栏缺失,且在多个 Subagent 均可能存在——属跨 Agent 共性问题,不适合在各 Subagent 分别补丁。统一护栏方案已另行成文,见 输入侧安全护栏设计,本文档不再承载。
3.5 知识库 score 阈值未开启(提示项)
知识检索节点 score_threshold: null。设计 §7.3 建议 Score<0.6 不采用。用户反馈知识库侧存在预制阈值设置但未开启——属知识库配置项,非 Dify 工作流修复点,阈值取值后续评估。
4. 测试用例(实测清单)
4.1 历史会话断链验证(P0,先复现)
| ID | 输入 | 前置条件 | 设计预期 | 现状预期 | 判定 |
|---|---|---|---|---|---|
| T-HIS-01 | 轮1:"会议室怎么预约";轮2:"那需要提前多久" | 同一会话连续两问 | 轮2 理解"那"指会议室预约,延续话题 | 轮2 被当作独立问题,无历史上下文 | 复现断链 |
| T-HIS-02 | 轮1:"订会议室带投影";轮2:"访客怎么登记" | 跨主题切换 | 正常回答访客问题(历史不干扰) | 正常回答(历史本就没注入,无法判断干扰) | 对照基线 |
验证方式:在 QA Chatflow 调试页连续发两问,观察轮 2 的 LLM 输入是否含"历史会话:"前缀(调试面板查看 LLM 节点输入),无则确认断链。
4.2 权限过滤(已确认,无需补测)
功能已测试通过(单角色过滤、无限制文档召回、多角色用户逐角色命中均正常),本期不再补测。
已同步 PRD:access_roles 仅支持单角色精确匹配(Dify 无法对 JSON 数组做元素匹配),文档打标时按单角色值填写或留空表示无限制(见 知识库元数据标签体系 §2.2)。
4.3 score 阈值(提示项)
| ID | 输入 | 前置条件 | 设计预期 | 现状预期 | 判定 |
|---|---|---|---|---|---|
| T-SCORE-01 | 问一个知识库无相关内容的问题 | 知识库存在低相似度片段(如 0.3) | 低分片段不进入回答依据 | 全部进入上下文,靠 LLM 规则自行判断 | 记录,后续定阈值 |
5. 整改方向(供评审)
- 历史会话断链:二选一——(a) 将
merge_chat接入 LLM 用户提示词(替换{{#sys.query#}}为{{#...merge_chat#}});(b) 移除冗余合并节点,LLM 用户提示词直接引用 Start 输入chathistory。推荐 (b),更简。 - 权限过滤:已确认单角色限制并同步 PRD;后续若需多角色交集检索,再评估替代方案(如物理库隔离、外部统一检索服务)。
- 行业知识优先级 + 寒暄规则(可选增强,P1):在系统提示词"回答规则"之后新增一段(合并寒暄/弱信息处理与行业优先级,结合泛建筑/园区行业定位):
# 寒暄/弱信息处理
对纯寒暄、无实质内容的输入(如"你好""hello""谢谢""再见"等问候),直接自然回应即可,
不引用任何检索片段,也不添加任何 [C:N]。
# 行业知识优先级
1. 本楼/本园区的内部信息(规章制度、服务流程、会议室与设备使用、楼层设施、访客/停车指引)
以知识库为准,公网信息仅作参考,二者冲突时以知识库为准。
2. 泛建筑/园区数字化概念(建筑操作系统、智能化、机电、能源管理、绿色低碳、招商运营、运维工单等)
回答时优先结合本楼实际落地场景,避免泛泛而谈。
3. 涉及本楼具体设备(空调/新风/照明/门禁/电梯/消防/给排水/变配电/监控等)的参数与操作,
必须以知识库为准,公网内容不得替代。
4. 当知识库与公网信息矛盾时,以知识库(本楼权威)为准,可补充说明"该信息以本楼实际为准"。- 敏感话题拦截(P2,转专项):归入跨 Agent 输入侧安全护栏统一评估(含提示词注入/敏感话题两类),本项不在 QA 单点整改。方案见 输入侧安全护栏设计。
- score 阈值:评估在知识库侧开启预制阈值,定值后再验证 Golden Set 命中率变化。
6. 已决策 / 不纳入项(评审确认后冻结)
| 项 | 决策 | 依据 |
|---|---|---|
| 多源"来源优先级"规则删除 | 不算问题,保持现状 | 与 G-Cite 设计取舍一致(不告知源类型、避免干扰);设计原文自相矛盾 |
Web 结果截断为 2 条(MAX_WEB_RESULTS=2) | 不算问题,保持现状 | Dify 百度搜索 Top-K Bug 的已知妥协(G-Cite 附录 A 已记载) |
| RAG top_k=4 vs 设计示例 5 | 不算问题 | 参数级差异,可按实测效果调整 |
| 前端相关(citations trailer 机制、半屏渲染、idMap) | 不纳入本次走查 | 属端侧实现,另行走查 |
| access_roles 仅支持单角色匹配 | 不算问题,保持现状 | Dify 元数据过滤无法做数组交集;功能测试通过,限制已写入 PRD |
7. 例外说明
本问题不影响单轮问答主链路:RAG + Web 双源并行、UnifiedChunk 合并、[C:N] 引用归因均正常。
百度 AI Search 选型、副标题降级链、RAG 优先排序等已落地能力不在本次问题范围。
