本文记录我设计并实现商户运营知识库问答系统的过程。项目面向商户运营、客服、销售、数据分析和新员工,将入驻审核、门店信息维护、推广分析、指标口径与服务升级规范沉淀为可检索知识。
系统的数据模型和知识内容均按演示环境设计,知识库使用脱敏合成的商户运营样例,不包含真实商户信息、客户联系方式、内部文档或生产日志。
一、要解决什么问题
商户运营类问题通常不是“有没有答案”,而是答案分散且有版本:入驻资料不全怎么办、门店信息更新后何时生效、曝光下降先看什么、一次推广活动如何复盘、哪些问题必须升级人工处理。
如果只做普通聊天机器人,模型很容易把经验性推测说成平台规则;如果只做关键词搜索,又难以把业务问题和对应 SOP 组织起来。因此,这个项目把目标收敛为三件事:
- 高频标准问题优先返回稳定答案,避免每次都调用模型。
- 非标准问题基于当前知识库检索,再生成可追溯的回答。
- 知识不足、规则冲突或涉及敏感业务时明确提示人工核对,而不是编造结论。
二、系统主流程
用户问题 -> Greeting Rule -> FAQ: MySQL + BM25 + Redis cache -> 未命中进入 RAG -> Metadata source filter -> Milvus dense/sparse hybrid search -> BGE reranker -> MaaS OpenAI-compatible streaming answer + source citation这里最重要的取舍是:FAQ 分流与 RAG 检索不是同一个环节。FAQ 负责用标准答案快速解决高置信问题;只有未命中或低置信问题,才进入向量检索和重排。这样既降低高频问答的延迟,也让检索链路处理真正需要上下文的问题。
三、知识范围与数据隔离
| 领域 | 覆盖内容 |
|---|---|
| onboarding | 商户入驻与审核规范 |
| profile | 门店名称、地址、电话、营业时间和图片维护 |
| promotion | 地图曝光、点击、导航、到店和推广活动分析 |
| analytics | 客流指标口径与运营报告 |
| service | 商户服务、隐私与问题升级规范 |
当前演示数据包括 35 条 FAQ、5 份 Runbook、40 条查询分类样本、10 条评估问题和 5 个 Bad Case。它们用于验证流程和边界,不用于宣称生产准确率或业务效果。
为保证不同环境的数据互不干扰,项目使用独立命名空间:
MySQL: merchant_ops_kbRedis: DB 2Milvus: merchant_ops / merchant_ops_v1四、FAQ 为什么要放在 RAG 前面
并非每个问题都适合交给大模型。比如“商户入驻审核失败先检查什么?”属于口径明确、重复率高的标准问题,直接使用 FAQ 答案更稳定,也更容易审核。
FAQ 存储在 MySQL 中,应用层用 BM25 计算相似度,并通过相对分数与绝对分数两个阈值做高置信分流。精确匹配还会先规范化首尾空白、大小写和中英文标点,所以同一个问题有没有中文问号,不会改变它进入 FAQ 的结果。
当 FAQ 未命中时,系统再进入 RAG。这个分层避免了把所有查询都变成“先检索、再生成”,也让标准业务规则保持可控。
五、RAG 检索如何做到可追溯
Runbook 文档在入库时会写入知识领域、文档标题、版本、生效日期和相对路径等 Metadata。查询时先根据问题所属领域做 source filter,再进行 dense/sparse hybrid search,最后由 BGE reranker 对候选片段排序。
问题: 门店曝光下降应该先分析什么? -> 领域过滤: promotion -> 混合检索召回推广运营 Runbook 片段 -> Reranker 排序 -> 依据命中片段生成回答 -> 返回文档标题、版本和生效日期来源信息不是只在页面上展示的装饰。评估集为每个问题保留expected_source,用于检查 Metadata 过滤是否命中预期领域。若同一领域出现多个版本,系统会提示人工核对当前生效规则,而不是擅自选择一份旧文档。
六、接口与运行状态
应用基于 FastAPI 提供 HTTP 与 WebSocket 两种交互入口。除了问答接口,项目还保留了几个只读接口,帮助区分“服务在运行”与“服务真正可用”。
GET /health 进程存活检查GET /ready 依赖和本地模型就绪检查GET /api/diagnostics MySQL、Redis、Milvus 与模型状态GET /api/knowledge-documents 知识文档版本和生效状态GET /api/assessment 评估集与领域覆盖检查POST /api/query 单次问答WebSocket /api/stream 流式问答POST /api/feedback 答案反馈/health只说明进程存活;/ready会在 MySQL、Redis、Milvus 或本地模型未就绪时返回503。诊断接口也只返回可达性和配置状态,不返回密码、API Key 或绝对路径。
七、为了可维护性做的边界处理
- 输入校验:HTTP 与 WebSocket 共用规则,问题不能为空、长度不超过 1000 字符,领域过滤只能来自白名单。
- 拒答边界:上下文不足、版本冲突或需要人工判断时,不把推测包装成平台规则。
- 模型复用:embedding 与 reranker 通过本地 Junction 复用已有模型目录,不复制大模型文件。
- 配置隔离:凭据仅从本地环境变量读取,代码、日志、文档和评估集均不记录密钥或真实业务数据。
- 最小化架构:当前 MVP 不堆叠多 Agent、MCP、GraphRAG 或微调,把重心放在检索质量、来源和业务边界。
八、验证结果与当前限制
项目已完成 Python 编译、数据格式、配置与 Prompt 格式、来源过滤、前端领域、FAQ 标点路由和评估数据覆盖检查。页面、/health、/ready、/api/sources、/api/knowledge-documents、/api/diagnostics与/api/assessment均已完成本地验证;五个知识领域的 FAQ 与检索流程可进入对应业务链路。
目前真实生成依赖外部 MaaS 模型服务。本机网络受限时,系统会返回统一的“模型服务暂时不可用”兜底与确定性来源列表。因此,本文不把真实生成质量或模型效果写成已完成的结论,后续仍需在网络与轮换后的凭据可用时继续验证。
九、面试时如何说明这个项目
- 业务问题:运营规范分散、重复咨询多、规则版本容易混用。
- 技术路线:FAQ 解决标准问题,未命中问题走 Metadata 过滤、混合检索和重排。
- 核心取舍:不追求堆叠技术名词,优先保证来源可追溯、边界可控、知识可更新。
- 风险处理:文档版本冲突、知识不足和敏感业务问题必须提示人工核对。
这个项目的价值不在于把 RAG 包装成万能问答,而在于把一个可解释、可维护的知识库主流程落到具体业务领域中。后续会继续补充 Bad Case 的阈值调整记录,以及文档版本的人工确认流程。