KnoSphere遇到的bug
大模型输出格式错一、{queries: [...]}泄漏的根因后端 bug排查结论这是后端 bug不是前端 bug也不是思考被流式输出那么简单。完整链路doc_retrieval工具内部会调用一次嵌套 LLM 做Multi-Query 查询重写输出{queries: [...]}tools/retrieval/doc_retrieval.py的_generate_sub_queries。代码里虽有config{callbacks: []}想隔离但我实测发现它无效同步工具在ToolNode里经线程池执行嵌套 LLM 的 callbacks 仍会被 langgraph 的stream_modemessages捕获。后端api/chat.py原来把[chunk, meta]原样透传没有按节点过滤。前端只过滤type.includes(tool)而AIMessageChunk的 type 不含tool于是{queries: [...]}直接渲染到界面上。我用端到端脚本复现并确认该 JSON 在meta.langgraph_node tools的 chunk 里泄漏出来。输出设计核心是后端显式分类流帧而不是把模型输出原样透传StreamResponse带response_type字段thinking/answer/tool_call/tool_result/error等思考过程走独立通道reasoning_content→thinking帧thinking 工具{thought: ...}用jsonFieldExtractor提取后也发thinking帧思考结束时发done标记最终答案走 answer 通道前端按response_type分派思考进折叠面板deepThink.vue答案进 markdown 正文本次改造后端api/chat.pystream_mode[messages, custom]只透传langgraph_node agent的主模型文本为answer帧tools节点内部嵌套 LLM 输出一律丢弃修复泄漏工具上报的事件透传为thinking帧doc_retrieval.py工具新增runtime: ToolRuntime参数实测证明这是同步工具里唯一可靠的取流方式get_stream_writer()跨线程失效通过runtime.stream_writer上报两条思考子查询拆解与召回统计前端langgraph.tsstream_mode加customindex.vue消息模型加thinking/thinkingDone字段按帧type分派渲染新增仿deepThink的思考折叠块思考中展开实时可见出答案后自动收起可手动展开验证端到端脚本thinking 帧、answer 帧分通道正确{queries: [...]}泄漏 Falsepytest tests/24 个用例全部通过vue-tsc类型检查通过前端vite build构建成功效果现在提问后先看到思考过程折叠面板显示拆解出的检索子查询、检索到的片段数随后才是最终答案与 WeKnora 的交互一致。回答出现幻觉幻觉来自未选知识库时模型用公开常识作答增强对提示词的控制用知识库来检索文档严格控制边界。检索的内容不全增加父子分块策略指代不明时意图不清晰时仍进行了检索。根因在 查询理解 → 路由 这一环。意图clarification → 需要检索知识库这说明 LLM 把「这是什么」判成了clarification但系统仍然走了prefetch_retrieval。原因 1clarification被当成需要检索的意图query.pyLines 18-18RETRIEVAL_INTENTS: frozenset[str] frozenset({kb_search}) # 修复前含 clarification原先RETRIEVAL_INTENTS {kb_search, clarification}所以只要 intent 是clarificationneeds_retrieval()就返回True图就会路由到prefetch_retrieval。原因 2Prompt 定义有歧义原先写的是clarification问题含糊但可能需要检索LLM 很容易把「这是什么」标成clarification然后又被上面的规则拉去检索。原因 3「这是什么」本身不可检索没有实体、没有主题词向量/BM25 只能乱匹配简历、自我介绍等无关片段正确行为应是反问用户「您指的是什么」而不是检索改正后
