RAGate:面向多轮对话的自适应RAG调控框架
1. 项目概述当RAG不再“一刀切”对话AI才真正开始理解上下文RAGate这个名字乍一听像某个开源工具的代号但拆开来看“RAG”是Retrieval-Augmented Generation的缩写而“-ate”这个后缀在英文里常表示“使…化”或“具备某种能力”比如“activate”激活、“orchestrate”编排。所以RAGate直译就是“让RAG活起来”——不是把检索和生成简单拼在一起而是让整个RAG流程能根据当前对话状态、用户提问意图、历史交互质量动态调整检索策略、文档切片方式、重排序强度甚至决定要不要启用RAG。这背后解决的是当前 Conversational AI 领域一个被反复吐槽却少有系统性解法的痛点固定RAG流水线在多轮对话中越来越“迟钝”。你有没有遇到过这样的情况第一轮问“公司Q3财报核心数据有哪些”RAG精准召回年报PDF第12页表格回答干净利落第二轮紧跟着问“那相比Q2营收增长主要来自哪个业务线”模型却开始胡扯或者干脆复述Q3数据而不做跨文档对比——因为默认RAG还是去搜“Q2财报”而不是意识到用户其实在要求“Q3 vs Q2”的差异分析。RAGate要干的事就是让系统自己判断这一轮该搜什么、搜多深、用哪类文档、要不要跳过RAG直接靠模型记忆回答。它不替换LLM也不重写检索器而是在LLM和检索器之间加了一层轻量但高感知的“对话认知层”。适合正在落地客服对话机器人、技术文档问答助手、企业知识库智能坐席的工程师和产品经理也适合想深入理解RAG工程瓶颈、不愿再被“召回率/准确率”静态指标困住的研究者。它不是又一个benchmark刷分模型而是一套可插拔、可监控、可解释的RAG运行时调控框架。2. 核心设计思路为什么必须放弃“静态RAG流水线”2.1 传统RAG的三大刚性缺陷直接导致多轮对话失焦我们先看一个真实产线问题某金融客户部署的投研问答Bot单轮问答准确率92%但进入三轮以上深度追问时准确率断崖式跌到57%。日志分析发现83%的失败案例都卡在同一个环节——检索阶段的“语义漂移”。比如用户首轮问“科创板IPO审核周期平均多久”RAG从监管问答库召回《科创板发行上市审核规则》第28条第二轮问“那北交所呢”系统照例检索“北交所审核周期”结果召回一堆新闻稿而非正式规则因为新闻稿里“北交所”和“审核周期”共现频率远高于规则文档。这不是模型能力问题而是RAG架构本身的刚性缺陷检索目标刚性传统RAG对每一轮用户输入都做独立语义向量化完全忽略对话历史。它不知道第二轮的“北交所”是和首轮“科创板”做平行对比还是单纯切换话题。向量空间里“科创板审核周期”和“北交所审核周期”的距离可能比“北交所上市门槛”更远——因为前者在文本中极少并列出现。文档处理刚性所有文档无论类型PDF法规/Excel表格/Markdown会议纪要都用同一套chunk size如512 token和overlap如128 token切分。结果是法规条文被硬生生切成“第28条……”和“……审核时限为……”两段关键主谓宾被割裂而会议纪要里一句“张总说Q3重点推A产品”却被塞进包含10个议题的超长chunk检索时权重被稀释。决策逻辑刚性是否启用RAG、检索多少文档、用哪些字段重排序全靠人工预设阈值如“query长度15字则启用RAG”。当用户输入“嗯”“好的”“还有吗”这类对话管理语句时系统仍会傻乎乎地检索既浪费资源又污染上下文。RAGate的设计起点就是把这三重刚性全部软化。它不追求“一次检索打遍天下”而是承认对话是状态机RAG必须是状态感知的。2.2 RAGate的三层自适应架构从“被动响应”到“主动编排”RAGate不是单个模块而是一个嵌入在标准RAG pipeline中的轻量调控层结构上分为三层每层解决一类刚性问题对话状态感知层State Perception Layer这是RAGate的“眼睛”。它不分析原始query而是接收LLM上一轮的输出、用户本轮输入、以及二者之间的对话行为标记如“澄清请求”“对比追问”“确认指令”。我们用一个极简的Finite State MachineFSM建模对话流初始态Init、信息获取态InfoSeek、比较分析态Compare、操作执行态Action、结束态End。状态转移由一组规则引擎驱动例如当上一轮LLM回复含“根据XX文件第X条”且本轮query含“vs”“对比”“差异”等词则触发Compare态。实测表明仅用5条正则规则1个小型分类器3M参数状态识别准确率达94.7%远超端到端大模型微调方案——因为对话行为模式本身高度结构化。检索策略编排层Retrieval Orchestration Layer这是RAGate的“手”。它根据当前状态动态生成检索指令。在Compare态下指令不是“搜北交所审核周期”而是“检索与‘科创板审核周期’语义相近的文档片段同时强制包含‘北交所’实体且文档类型监管规则发布时间2023-01-01”。这个指令会被翻译成混合查询向量检索主干语义 关键词增强“北交所”AND“审核” 元数据过滤typerule, date2023。更关键的是它能控制检索粒度对法规类文档启用“条款级切分”按标题/编号切对会议纪要启用“发言者级切分”每人每次发言为一chunk对表格类文档则跳过切分直接用OCR结构化提取后的cell-level embedding检索。响应可信度调控层Response Calibration Layer这是RAGate的“大脑”。它不直接生成答案而是评估本次RAG响应的可信度并决定最终输出路径。评估维度包括检索文档与query的语义匹配分Cross-Encoder打分、文档间一致性多文档答案是否冲突、LLM生成答案与检索证据的支撑度用self-check prompt量化。当可信度0.65时触发“降级策略”若处于Init态返回通用欢迎语若处于Compare态则生成追问“您希望对比科创板与北交所在审核周期、信息披露要求还是上市标准方面”把模糊需求显性化。这个阈值不是拍脑袋定的——我们用历史bad case回溯标注找到使F1-score最优的0.65分界点。这三层不是黑盒堆叠而是全程可观测每轮对话都会输出一个JSON诊断报告包含state_id、retrieval_intent、confidence_score、fallback_reason。运维人员一眼就能看出是状态识别错了还是检索策略没生效或是可信度模型过于保守。2.3 为什么选“轻量调控层”而非重训大模型工程落地的现实权衡看到这里你可能会问既然要状态感知为什么不直接finetune一个对话专用的RAG模型比如用Qwen2-7B加对话历史微调我们做过对照实验在相同硬件A10G*2上微调方案推理延迟均值2.8s/轮而RAGate调控层仅增加0.17s延迟纯CPU计算。更重要的是稳定性——微调模型在未见过的对话模式如突然插入英文术语下状态识别错误率飙升至31%而RAGate的规则小模型组合在同样场景下错误率仅8.2%。根本原因在于对话行为模式是离散、有限、可枚举的而语言生成是连续、高维、难约束的。强行用生成模型学状态就像让厨师同时负责菜单设计和炒菜——专业分工才能稳。RAGate的哲学是把确定性高的事状态识别、策略编排交给确定性高的方法规则小模型把不确定性高的事答案生成留给LLM专注处理。这种“分而治之”思想在我们交付的7个企业项目中平均将RAG相关故障定位时间从4.2小时缩短到18分钟。它不追求学术SOTA只解决产线里那些让工程师半夜爬起来改配置的“具体问题”。3. 核心细节解析如何让RAG真正读懂对话的“潜台词”3.1 对话状态机的构建5个状态如何覆盖99%的企业对话场景RAGate的状态机不是理论玩具而是从237小时真实客服对话录音、14万条内部知识库问答日志中抽象出来的。我们摒弃了学术论文里常见的12状态复杂模型聚焦企业场景最频发的5个核心状态每个状态都对应明确的RAG行为策略状态ID状态名称触发条件典型信号RAG行为策略实际效果S0Init初始态用户首条消息或上轮LLM明确结束对话如“祝您愉快”启用基础检索chunk_size256仅向量检索禁用元数据过滤避免首轮过度检索降低冷启动延迟S1InfoSeek信息获取态query含疑问词什么/哪里/如何/为什么或上轮LLM回复含“根据XX文件”启用增强检索chunk_size512向量关键词混合按文档类型动态切分提升单点事实检索精度减少“答非所问”S2Compare比较分析态query含对比词vs/对比/差异/相同/哪个更好或上轮LLM提供单一答案本轮追问“那XX呢”启用双焦点检索主query向量检索 强制实体共现约束文档类型限定为同类如均为监管规则解决跨文档对比失效问题准确率提升37%S3Action操作执行态query含动词宾语“生成合同模板”“导出Q3数据”或含明确格式要求“用表格列出”“分三点说明”检索范围收缩至操作指南类文档启用“步骤级切分”每步操作为一chunk确保操作指令有据可依避免LLM幻觉步骤S4Clarify澄清态query为短句/疑问代词“这个”“哪几个”“前面说的”或上轮LLM回复含不确定表述“可能”“通常”“建议确认”暂停检索基于上轮检索文档做局部重排若文档不足3份则触发追问减少无效检索将澄清成本前置关键细节在于状态转移的防抖机制。比如用户连续发两条“嗯”不能从S1跳到S4再跳回S1。我们在FSM中加入3秒时间窗口和最小编辑距离校验只有当新query与上轮query的Levenshtein距离0.3且间隔3秒才允许状态变更。这避免了因网络延迟、用户误触导致的状态震荡。另一个实战技巧S2Compare态的实体共现约束我们不用布尔AND太严格而是用“soft co-occurrence”——要求两个实体在同一个文档内且距离500字符。这样既能捕获“科创板审核周期为X北交所为Y”的并列句式也能覆盖“对比科创板与北交所的审核要求”这类概括性表述。3.2 动态切分策略为什么“一刀切”的chunk size是RAG精度的最大敌人几乎所有RAG教程都告诉你“用512 token切分文档”。但当你真把一份《民法典》PDF丢进去就会发现第1042条“禁止包办、买卖婚姻和其他干涉婚姻自由的行为”被切成两半前半句在chunk A后半句在chunk B而chunk A里还混着第1041条的结尾和第1043条的开头。用户搜“包办婚姻”召回的chunk可能只含“禁止包办”却漏掉“干涉婚姻自由”这个关键定性。RAGate的解决方案是按文档语义结构切分而非机械按token数。我们为常见文档类型预设了切分策略模板法规/标准类PDF/DOCX识别标题层级H1/H2/H3、条款编号“第X条”“Article X”、章节分隔符。切分单元为“完整条款”即从“第X条”开始到下一个“第Y条”或文档结束为止。实测《GB/T 19001-2016 质量管理体系要求》用此策略条款级召回准确率从68%提升至91%。会议纪要/访谈记录TXT/MD按发言者切分。每段以“【张三】”“Q:”“A:”等标记开头到下一个标记或空行结束。避免把不同人的观点混在同一chunk。对技术评审会纪要这种切分使“风险点讨论”相关问答准确率提升52%。表格类XLSX/PDF表格跳过文本切分直接用Tabular Data Embedding。我们用LayoutParser检测PDF表格区域用Pandas读取Excel将每行数据转为“字段名值”字符串如“供应商名称ABC科技合同金额120万元签约日期2023-05-20”再向量化。用户搜“2023年签约的供应商”不再需要猜表格哪列是日期。代码文档MD/HTML按函数/类定义切分。识别def func_name(、class ClassName(、/// summary等标记确保每个chunk包含完整函数签名注释示例。开发者搜“如何初始化数据库连接”不再召回半截代码。这些策略不是硬编码在代码里而是存在YAML配置文件中运维可随时热更新。比如某客户新增了“专利说明书”类型只需添加一条配置patent_doc: type: patent split_by: section_title # 按“背景技术”“发明内容”“权利要求”等标题切 min_chunk_size: 128 max_chunk_size: 1024无需重启服务RAGate自动加载。这种设计让RAG从“文档处理工具”升级为“知识结构理解引擎”。3.3 可信度调控的量化逻辑如何用0.65这个数字堵住90%的幻觉漏洞RAGate的可信度调控不是玄学打分而是三个可解释、可审计的子分数组成的加权和语义匹配分SM-Score用tiny-bert-base110M参数对query和top-k检索文档做cross-encoding输出0~1分。关键优化是不单独打分而是计算query与所有文档的相似度分布熵值。如果top3文档得分分别是0.82、0.79、0.31熵值低集中说明有明确答案如果得分是0.65、0.63、0.61熵值高分散说明证据模糊。我们给高熵情况额外扣0.15分。证据支撑分ES-Score让LLM自己验证答案。在生成答案前插入prompt“请基于以下检索证据判断答案‘[ANSWER]’是否得到充分支持。证据[EVIDENCE_1]...[EVIDENCE_k]。仅输出‘是’或‘否’。” 实测显示LLM对自身答案的支撑度判断准确率89%且比人类标注快100倍。这个“自我审查”步骤增加约0.3s延迟但将幻觉率从22%压到6%。文档一致性分DC-Score当检索到多份文档时检查它们对同一事实的陈述是否冲突。例如文档A说“科创板审核时限为6个月”文档B说“原则上不超过6个月”我们视作一致但若文档C说“3个月”则触发冲突标记DC-Score归零。一致性检查用规则引擎实现正则匹配数值单位修饰词不依赖LLM毫秒级完成。最终可信度 0.4×SM-Score 0.35×ES-Score 0.25×DC-Score。0.65阈值的确定过程很务实我们在验证集上画出“阈值-准确率”曲线发现0.65是准确率87.3%和召回率76.1%的帕累托最优交点。低于此值大量正确答案被拦截高于此值幻觉答案开始涌入。这个数字不是理论推导而是产线数据喂出来的“安全边界”。4. 实操过程详解从零部署RAGate的完整工作流4.1 环境准备与依赖安装为什么坚持用Python 3.9和PyTorch 2.0RAGate对环境的要求看似宽松但几个关键依赖版本有强约束这是踩过坑后定下的铁律Python 3.9必须≥3.9因为我们要用graphlib.TopologicalSorter做状态机依赖解析S2状态需S1先发生这个模块在3.8及以下不存在。曾有客户坚持用3.8我们被迫手写拓扑排序结果在循环依赖检测上出错导致状态机死锁。PyTorch 2.0tiny-bert的cross-encoder需要TorchScript编译加速。2.0的torch.compile()比1.13的JIT提速2.3倍且内存占用降40%。测试中1.13版本在A10G上跑SM-Score会OOM2.0则稳定在3.2GB显存。核心依赖清单requirements.txt节选# 必须精确版本避免兼容问题 torch2.0.1cu118 # CUDA 11.8适配A10G transformers4.35.2 # tiny-bert支持最佳 sentence-transformers2.2.2 # embedding模型管理 layoutparser[layoutmodels]0.3.4 # PDF表格检测 pandas1.5.3 # 表格处理稳定版 # 可选但强烈推荐 vllm0.2.7 # LLM推理加速比transformers快4倍安装命令不是简单的pip install -r requirements.txt。我们要求分步验证# 1. 先装CUDA toolkitA10G需11.8 wget https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda_11.8.0_520.61.05_linux.run sudo sh cuda_11.8.0_520.61.05_linux.run --silent --override # 2. 创建隔离环境避免污染系统Python python3.9 -m venv ragate_env source ragate_env/bin/activate # 3. 安装PyTorch必须指定CUDA版本 pip3 install torch2.0.1cu118 torchvision0.15.2cu118 --extra-index-url https://download.pytorch.org/whl/cu118 # 4. 最后装其他依赖 pip install -r requirements.txt # 5. 关键验证运行健康检查脚本 python -m ragate.health_check # 输出应为✅ PyTorch CUDA可用 | ✅ Cross-encoder加载成功 | ✅ LayoutParser PDF检测正常这个流程看似繁琐但省去了后续90%的“环境不一致”故障排查。我们服务过的客户里73%的首次部署失败源于Python或PyTorch版本不匹配。4.2 配置文件详解5个YAML文件如何定义你的RAGate行为RAGate的核心是配置驱动而非代码修改。所有业务逻辑通过5个YAML文件定义放在config/目录下state_machine.yaml定义5个状态的转移规则。关键字段states: S2: # Compare态 triggers: - type: regex pattern: vs|对比|差异|相同|哪个.*更好|孰优 - type: llm_output_contains keywords: [相比之下, 相较而言, 前者...后者] fallback_threshold: 0.65 # 此状态下可信度阈值可单独设retrieval_policies.yaml为每个状态绑定检索策略。重点看hybrid_query字段policies: S2: hybrid_query: vector_weight: 0.6 # 向量检索占60%权重 keyword_boost: # 关键词增强非简单AND terms: [科创板, 北交所] proximity: 500 # 两词距离500字符才计分 metadata_filters: - key: doc_type value: regulation # 强制同类文档chunking_rules.yaml文档类型切分规则。min_chunk_size和max_chunk_size防止极端情况rules: regulation: split_by: clause_number # 按“第X条”切 min_chunk_size: 64 # 条款太短如“第1条目的”则合并到下一条 max_chunk_size: 2048 # 条款太长如附则则按句号二次切分confidence_weights.yaml三个子分的权重分配。可根据业务调优weights: semantic_match: 0.40 # 语义匹配最重要 evidence_support: 0.35 # 自我审查次之 doc_consistency: 0.25 # 一致性最后fallback_strategies.yaml降级策略。这是用户体验的关键strategies: low_confidence: S2: # Compare态下可信度低 action: ask_for_clarification prompt: 您希望对比科创板与北交所在审核周期、信息披露要求还是上市标准方面请明确方向。 default: action: return_generic_response response: 我暂时无法确定请换一种方式描述您的问题。配置不是一次写完就完事。我们要求客户用ragate config validate命令校验# 检查语法和逻辑 ragate config validate --config-dir ./config/ # 检查配置与实际文档库的兼容性如指定doc_type是否存在 ragate config validate --config-dir ./config/ --doc-db-path ./data/这个步骤能提前发现80%的配置错误比如在retrieval_policies.yaml里写了doc_type: whitepaper但文档库里根本没有whitepaper类型。4.3 文档入库与索引构建如何让RAGate“吃透”你的知识库RAGate的文档处理不是简单扔进向量库而是三阶段流水线阶段1文档解析与元数据注入from ragate.document_processor import DocumentProcessor processor DocumentProcessor( config_path./config/chunking_rules.yaml ) # 自动识别PDF/DOCX/XLSX等格式提取文本元数据 docs processor.parse_directory(./knowledge_base/) # docs是Document对象列表每个含 # - content: 原始文本 # - metadata: {source: xxx.pdf, doc_type: regulation, page: 12, section: 第三章}阶段2动态切分与结构化from ragate.chunker import AdaptiveChunker chunker AdaptiveChunker(config_path./config/chunking_rules.yaml) chunks chunker.split_documents(docs) # chunks是Chunk对象列表每个含 # - text: 切分后文本如“第28条科创板发行上市审核时限为六个月。” # - metadata: 继承自Document新增{chunk_id: xxx_28, split_by: clause_number}阶段3多模态索引构建from ragate.indexer import MultiModalIndexer indexer MultiModalIndexer( vector_modelall-MiniLM-L6-v2, # 主向量模型 table_modellayoutlmv3-base, # 表格结构模型 code_modelcodebert-base # 代码模型 ) # 构建混合索引向量表格代码 indexer.build_index( chunkschunks, output_path./vector_store/, batch_size128 )关键细节索引不是单一FAISS库而是三个子索引的组合vector_store/faiss/标准向量索引vector_store/table/表格cell的embedding索引用LayoutLMv3vector_store/code/代码函数的embedding索引用CodeBERT查询时RAGate根据query类型检测到“表格”“代码”等词自动路由到对应子索引。这种设计让RAGate在处理混合知识库时检索准确率比单一向量索引高29%。4.4 对话服务启动与API调用如何集成到现有系统RAGate提供两种集成方式推荐从FastAPI服务开始启动服务# 启动RAGate核心服务监听8000端口 ragate serve \ --config-dir ./config/ \ --vector-store ./vector_store/ \ --llm-model Qwen2-7B-Instruct \ --host 0.0.0.0 \ --port 8000 # 输出 RAGate server started at http://0.0.0.0:8000/docs # 自动提供Swagger UI可直接测试API标准API调用curl示例curl -X POST http://localhost:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { messages: [ {role: user, content: 科创板IPO审核周期平均多久}, {role: assistant, content: 根据《科创板发行上市审核规则》第28条审核时限为六个月。}, {role: user, content: 那北交所呢} ], stream: false }响应体关键字段{ response: 根据《北京证券交易所向不特定合格投资者公开发行股票并上市审核规则》第25条北交所审核时限为两个月。, diagnostics: { state: S2, retrieval_intent: compare: 科创板 vs 北交所, doc_typeregulation, confidence_score: 0.82, evidence: [ {doc_id: bjse_rule_25, text: 第25条北交所发行上市审核时限为两个月。, score: 0.91} ] } }diagnostics字段是调试神器。当答案出错时运维直接看retrieval_intent就知道是状态识别错了还是检索策略没生效。我们禁止生产环境关闭这个字段——它不是性能负担JSON序列化开销2ms而是故障定位的黄金线索。5. 常见问题与排查技巧实录那些文档里不会写的血泪经验5.1 “状态机总在S0和S1之间跳变根本进不了S2”——时间窗口与编辑距离的实战调优这是客户反馈最多的问题。现象用户连续问“科创板审核周期”“北交所呢”日志显示状态在S0→S1→S0→S1循环。根本原因不是规则写错而是时间窗口和编辑距离阈值没调准。我们的默认配置是# config/state_machine.yaml debounce: time_window: 3.0 # 3秒内重复状态不变更 min_edit_distance: 0.3 # 编辑距离0.3才认为是新query但客户的真实对话中用户打字慢两条消息间隔常达5-8秒且“北交所呢”和“科创板审核周期”的编辑距离算出来只有0.22因为“北交所”和“科创板”都是3字专有名词。解决方案是按业务场景微调而非全局修改。在state_machine.yaml中为S1→S2转移单独设宽松阈值states: S1: transitions: to_S2: time_window: 10.0 # 允许更长等待 min_edit_distance: 0.15 # 对比词敏感度提高 triggers: - type: regex pattern: vs|对比|差异|哪个.*更好|孰优|那.*呢这个改动让状态机在客服场景下S2触发率从31%升至89%。记住状态机不是越“智能”越好而是越贴合你的用户行为越好。5.2 “检索总是召回无关文档比如搜‘合同模板’却返回员工手册”——元数据过滤的强制生效技巧问题根源客户在retrieval_policies.yaml里写了metadata_filters但文档入库时没注入doc_type元数据导致过滤失效。RAGate的元数据过滤是“硬过滤”——如果文档没有doc_type字段它会被直接排除哪怕向量匹配分再高。排查步骤检查文档解析日志grep doc_type ./logs/parse.log确认是否每份文档都有doc_type。如果没有修改document_processor.py在解析后强制注入if doc_type not in doc.metadata: # 根据文件扩展名和路径智能推测 if doc.source.endswith(.docx) and contract in doc.source.lower(): doc.metadata[doc_type] contract_template elif doc.source.endswith(.pdf) and employee in doc.source.lower(): doc.metadata[doc_type] handbook重建索引ragate indexer rebuild --config-dir ./config/更彻底的方案是在chunking_rules.yaml中为每种文档类型设default_metadatarules: contract_template: default_metadata: doc_type: contract_template priority: high # 后续可用来排序这样即使原始文档没元数据RAGate也会自动补全。5.3 “可信度分数忽高忽低0.65阈值根本不好用”——子分项权重的业务定制法客户抱怨财务问答场景下ES-Score自我审查经常偏低因为LLM对数字敏感看到“6个月”和“六个月”就判不一致。但实际这是同一事实。解决方案不是调低阈值而是调整子分权重让SM-Score语义匹配主导# config/confidence_weights.yaml weights: semantic_match: 0.60 # 提高到60%因财务文档语义稳定 evidence_support: 0.25 # 降到25%容忍LLM对格式的苛刻 doc_consistency: 0.15 # 降到15%财务数据冲突少同时在state_machine.yaml中为财务问答设专属状态S5绑定此权重配置。我们服务的3家金融机构都采用了此方案F1-score提升12%且工程师不再需要半夜调阈值。5.4 “A10G显存爆了SM-Score计算失败”——Cross-Encoder的降级保底策略tiny-bert-base在A10G24GB显存上跑SM-Score本该绰绰有余但客户遇到OOM。查日志发现他们上传了一份1200页的PDF解析后生成了8700个chunkSM-Score要对query和全部8700个chunk做cross-encoding显存峰值达26GB。紧急修复方案无需改代码# config/retrieval_policies.yaml policies: S1: max_chunks_for_sm: 200 # SM-Score只算top200 chunk fallback_to_vector_score: true # 若chunk200用向量相似度代替SM-Score这个配置让RAGate在超大文档场景下自动降级用向量分虽精度略低保证服务不挂。长期方案是在文档入库时用chunk_filter预筛——对法规类文档只保留含“第X条”“Article X”的chunk剔除纯标题页、页眉页脚。我们提供ragate chunk filter --rule has_clause_number命令一键执行。提示所有配置变更后必须运行ragate config validate再重启服务。我们见过太多客户改了