[{"data":1,"prerenderedAt":251},["ShallowReactive",2],{"note:\u002Fprojects\u002Frag-knowledge-base\u002F01-架构总览与阅读地图":3},{"id":4,"title":5,"body":6,"date":228,"description":229,"draft":230,"extension":231,"featured":230,"kind":232,"lastmod":228,"meta":233,"navigation":237,"path":238,"planned":239,"section":240,"seo":241,"source":242,"stem":243,"tags":244,"toc":237,"weight":249,"__hash__":250},"notes\u002Fprojects\u002Frag-knowledge-base\u002F01-架构总览与阅读地图.md","企业级 RAG 平台架构：一次提问背后的完整链路",{"type":7,"value":8,"toc":220},"minimark",[9,13,16,20,23,26,102,105,108,111,114,125,132,138,144,150,156,159,165,168,171,177,183,189,192],[10,11,12],"p",{},"大部分人写 RAG 都停在同一个位置：本地存一个向量库，similarity_search 拿 top3，\n塞进 prompt，让模型回答。Demo 阶段这没问题。但只要有人问一句\n「这个答案的依据是什么？」，或者「今天更新了制度，为什么明天才生效？」，\n这套代码就撑不住了。",[10,14,15],{},"这篇文章不讲原理，只讲一件事：一个敢上线的企业内部知识问答系统，\n一次提问背后到底跑通了哪些层。读完你应该能说清这个项目的骨架，\n也能对照检查自己的 RAG 项目缺了哪一块。",[17,18,19],"h2",{"id":19},"先给结论",[10,21,22],{},"能上线的 RAG = 数据契约 + 意图路由 + 混合检索 + 重排 + 置信度与引用 + 版本与隔离 + 门禁验收。",[10,24,25],{},"少任何一块，系统都能跑，但都会在某个具体场景下崩掉：",[27,28,29,42],"table",{},[30,31,32],"thead",{},[33,34,35,39],"tr",{},[36,37,38],"th",{},"缺失的层",[36,40,41],{},"什么时候崩",[43,44,45,54,62,70,78,86,94],"tbody",{},[33,46,47,51],{},[48,49,50],"td",{},"数据契约",[48,52,53],{},"有人往知识目录里丢了一个没有分类的 PDF，检索时分类过滤直接失效",[33,55,56,59],{},[48,57,58],{},"意图路由",[48,60,61],{},"用户问「你好」也被送进向量库，召回一堆无关文档，模型硬答",[33,63,64,67],{},[48,65,66],{},"混合检索",[48,68,69],{},"用户搜具体编号（如「报销单号 R-2024-001」），纯语义检索召不回",[33,71,72,75],{},[48,73,74],{},"重排",[48,76,77],{},"top20 里正确答案排在第 15 位，被 top_k=5 直接截断",[33,79,80,83],{},[48,81,82],{},"置信度与引用",[48,84,85],{},"知识库里没有答案，模型照样流畅编造",[33,87,88,91],{},[48,89,90],{},"版本与隔离",[48,92,93],{},"更新制度后新旧两版同时可召回，同一个人一天内听到两种说法",[33,95,96,99],{},[48,97,98],{},"门禁验收",[48,100,101],{},"改一行阈值，FAQ 准确率从 92% 掉到 71%，没人发现",[17,103,104],{"id":104},"一句话描述这个项目",[10,106,107],{},"SHUN RAG：面向企业内部知识问答的 LangChain + Milvus Hybrid + FastAPI 平台。\n业务已经收敛为单一场景 enterprise_knowledge，覆盖 HR 制度、IT 支持、账号安全和财务报销。",[10,109,110],{},"技术栈本身不新鲜，值得看的是它的分层方式。",[17,112,113],{"id":113},"四层架构",[115,116,122],"pre",{"className":117,"code":119,"language":120,"meta":121},[118],"language-text","第一层  用户入口        static\u002F         问答页 + 管理页 + 状态页\n第二层  FastAPI 路由    qa_core\u002Fapi\u002F    pages \u002F chat \u002F admin \u002F kb_versions\n第三层  核心引擎        qa_core\u002F        18 个子包：意图、检索、生成、缓存、治理、质量\n第四层  外部依赖        MySQL \u002F Redis \u002F etcd \u002F MinIO \u002F Milvus \u002F LLM 供应商\n","text","",[123,124,119],"code",{"__ignoreMap":121},[10,126,127,131],{},[128,129,130],"strong",{},"第一层刻意做得很薄。"," 前端是原生 HTML\u002FCSS\u002FJS（static\u002F），没有前端框架包袱，\n因为它不需要承担业务逻辑，只负责把 WebSocket 事件流渲染成对话。",[10,133,134,137],{},[128,135,136],{},"第二层只做接入。"," app.py 全文不到 150 行，只干四件事：建应用、配 CORS 与静态资源、\n启动预热、注册路由。意图识别、检索策略、Prompt 拼接、Milvus 查询一律不在这里出现。\n入口越薄，「系统里有没有旧链路、有没有技术降级旁路」这件事就越容易确认。",[10,139,140,143],{},[128,141,142],{},"第三层是全部内容所在。"," qa_core\u002F 下的子包各管一件事，\n其中主链路是 intent → retrieval → retrieval.strategy → pipeline → prompts：",[115,145,148],{"className":146,"code":147,"language":120,"meta":121},[118],"qa_core\u002F\n  api\u002F           HTTP \u002F WebSocket 入口\n  application\u002F   QAService 编排（API 与 pipeline 之间的唯一通道）\n  intent\u002F        规则 + BERT 模型 + 网关仲裁\n  retrieval\u002F     Milvus 混合检索、动态检索计划、重排、过滤\n  pipeline\u002F      主流程、步骤、置信度、引用、事件流\n  prompts\u002F       按意图与风险类别组织的 Prompt 档位\n  indexing\u002F      解析、归一化、切分、指纹、增量\n  quality\u002F       入库质量门禁与冲突检测\n  governance\u002F    知识库版本、数据域隔离\n  cache\u002F         L1 进程 + L2 Redis，namespace epoch 失效\n  memory\u002F        会话历史与反馈\n  graphrag\u002F      GraphRAG 扩展\n  observability\u002F LangSmith Trace\n",[123,149,147],{"__ignoreMap":121},[10,151,152,155],{},[128,153,154],{},"第四层是三个独立服务。"," MySQL 存控制面（版本、反馈、会话），Redis 做缓存，\nMilvus 存向量（依赖 etcd 做元数据、MinIO 做对象存储）。它们由 compose 统一编排，\n互相之间没有隐藏依赖。",[17,157,158],{"id":158},"一次提问经历了什么",[115,160,163],{"className":161,"code":162,"language":120,"meta":121},[118]," 1. 浏览器 WebSocket 连到 \u002Fapi\u002Fstream\n 2. API 层限流、校验参数\n 3. QAService 解析场景，做数据域隔离（tenant \u002F dataset \u002F visibility \u002F role）\n 4. 意图识别：先规则收口（问候、越界、直答直接返回），再判断 FAQ \u002F 知识查询 \u002F 追问\n 5. 检索计划：意图 + 短问题保护 + 规则分数 + 风险类别 → top_k、阈值、查哪些集合\n 6. 查询改写与变体生成（生成 1~3 个等价问法）\n 7. 命中 FAQ 快路径 → 精确匹配成功则直出\n 8. 文档混合检索：dense + sparse 双路召回，带元数据过滤\n 9. CrossEncoder 重排，选出最终上下文\n10. 三段置信度计算 + 强制引用来源；证据不足则拒答或提示人工确认\n11. LLM 流式生成，逐 token 推给前端\n12. 落库：会话历史、检索结果缓存\n",[123,164,162],{"__ignoreMap":121},[10,166,167],{},"第 4、5、10 步是这个项目和 toy 项目真正的分界线。",[17,169,170],{"id":170},"三个值得抄的设计决策",[10,172,173,176],{},[128,174,175],{},"一、业务先收敛，技术再展开。","\n项目原本是多场景模板，现在主动收敛成单场景 enterprise_knowledge。\nHR \u002F IT \u002F 财务只是场景内部的 source 分类，不是三套业务。\n收敛之后，规则、评测集、门禁阈值才有稳定的调参基准——\n多场景同时演进时，任何一次调参都是在拆东墙补西墙。",[10,178,179,182],{},[128,180,181],{},"二、启动失败是一种设计。","\nLLM Key、Milvus、MySQL、本地模型、场景配置、active 知识库版本，\n任何一项缺失，服务直接启动失败，而不是降级运行。\n同时 BERT、BGE、Reranker 和 Milvus collection 预热完成前不接收流量。\n宁可起不来，也不要「看起来能跑但答错」。",[10,184,185,188],{},[128,186,187],{},"三、检索分数不等于答案可信度。","\nMilvus 返回的 score 只说明候选和 query 的相关性排序，\n不说明答案是否被证据支撑。所以这里有生成前证据置信度、生成后支撑度、\n最终合并置信度三段计算，并且引用来源是强制校验的。",[10,190,191],{},"这个系列拆成 8 篇，跟着一次提问的路径走：",[193,194,195,199,202,205,208,211,214,217],"ol",{},[196,197,198],"li",{},"架构总览与阅读地图（本篇）",[196,200,201],{},"部署、前置校验与启动预热",[196,203,204],{},"知识入库：数据契约、切分与增量指纹",[196,206,207],{},"意图识别、网关仲裁与动态检索策略",[196,209,210],{},"Milvus 混合检索与 CrossEncoder 重排",[196,212,213],{},"主链路编排、置信度与「该拒答就拒答」",[196,215,216],{},"两级缓存、知识库版本与多租户隔离",[196,218,219],{},"质量门禁、评测闭环与交付验收\n下一篇从最实际的地方开始：怎么把这套东西在本地完整跑起来，\n以及那几个容器到底各自在负责什么。",{"title":121,"searchDepth":221,"depth":221,"links":222},2,[223,224,225,226,227],{"id":19,"depth":221,"text":19},{"id":104,"depth":221,"text":104},{"id":113,"depth":221,"text":113},{"id":158,"depth":221,"text":158},{"id":170,"depth":221,"text":170},"2026-05-29","从数据契约到评测门禁，梳理企业内部知识问答系统一次提问背后的完整工程链路。",false,"md","project-chapter",{"migration":234},{"generator":235,"sourceSha256":236},"nuxt-site\u002Fscripts\u002Fmigrate-content.mjs","e14cd168238f0c6682317a657f67a8393d0370adfd40fbc4d00f24c13b172074",true,"\u002Fprojects\u002Frag-knowledge-base\u002F01-架构总览与阅读地图",null,"projects",{"title":5,"description":229},"content\u002Fprojects\u002Frag-knowledge-base\u002F01-架构总览与阅读地图.md","projects\u002Frag-knowledge-base\u002F01-架构总览与阅读地图",[245,246,247,248],"RAG","LangChain","Milvus","FastAPI",31,"hIyRcUjI1Ugvfi_SzXP0xi5NQ5lvXaC_5fWxTsFx2SY",1791279145024]