资讯动态

RAGless架构:把LLM调用从在线问答移到离线蒸馏,实现零推理成本

发布时间:2026/9/5 18:07:30 来源:尧图企业网站定制
大语言模型应用跑起来之后第一个震惊你的账单往往不是训练也不是微调而是每次用户提问都悄悄扣款的推理费用。做得越好的知识库问答被问得越频繁账单涨得越凶做得不好的知识库问答倒是省钱但答案基本没法用。RAG 架构把“检索”和“生成”绑在一起大模型主导了最后的答案生成LLM API 费用就像流水一样停不下来。RAGless 这个思路则完全不同它要做的事用一个判断就能说清楚——把“每次问答都在运行时花钱请大模型读文档”改成“在构建阶段就把文档里的知识消化好运行时只做确定性的查找和匹配”。这篇博客会从 RAGless 的设计动机、实现思路、适用边界、典型代码雏形、效果验证和工程化改造几个方面展开。核心结论我直接放在前面RAGless 真正省钱的不是因为它在技术上碾压 RAG而是它把成本发生的位置从每个用户请求的 hot path 上移到了知识更新的低频路径上。这不是一个万能替代它是“知识相对静态、答案确定性要求高、并发问答场景多”时更合理的架构选择。1. 这篇文章真正要解决的问题先给读者一个坐标系。你大概率见过下面这几类现象。第一类是 RAG 项目的“冷启动贵”。团队花大力气做文档切分、向量化、调 prompt好不容易上线了接着发现日志里每一个 query 都要带着几百上千 token 的上下文去找大模型要一个答案。先不说答案质量光是日活用户稍微涨一点按 token 计费的 API 成本就会线性上升。第二类是“知识更新一次代价极大”。常见 RAG 把文档切成 chunk入库时跑一次 embedding这步还好但真正烧钱的是每次文档更新后为了让大模型对同一段知识能给出稳定新答案需要反复做 prompt 调优和效果回归。文档一变可能整套链路都要重测。第三类是“答案质量不稳定”。同样一个问题用户上午问和下午问甚至连续问两次都可能因为大模型采样的随机性得到措辞不同、重点不同的回答。如果这个知识库面向企业内部制度、客服政策或售后话术这种不稳定非常致命。RAGless 的方案是什么它在索引阶段消化知识运行时不再调用 LLM。你可以暂时把它理解成一个极端版的“预计算 查表 确定性返回”。它想做的是既然知识库问答的终极目标是把“文档里已有的信息”准确、快速、低成本地给用户那为什么不把那些最核心的问答对或结论在构建阶段离线算好运行时只做文本匹配不过这里的判断也要保持清醒。RAGless 并不是要取代所有 RAG 场景。它对开放域理解、复杂推理、多轮对话、创造性归纳这类任务并不占优。最适合它的是信息密集、答案源固定、对一致性和成本敏感的场景。这也是为什么我认为“RAGless”更大的价值是逼着开发者重新想一个问题每一个用户问题真的都需要一次大模型生成吗还是说在你调 API 之前系统里已经躺着大部分答案2. RAG 与 RAGless核心概念与成本差异分析这部分不打算把 RAG 讲成百科词条。会用两个维度切架构流程上谁在做决策以及成本结构上谁在运行阶段买单。2.1 经典 RAG 的工作流程与成本模型RAGRetrieval-Augmented Generation最常见的技术路径是把文档切割成 chunkembedding 后存入向量库用户提问时先做向量检索召回 Top-K 相关内容再把用户 query 和召回内容拼进 prompt送给大模型生成自然语言答案。它的好处是泛化能力强能处理没见过的问法坏处是LLM 承担了所有“组织语言”的任务。每一次检索后都必须有一次生成。你可以优化 prompt 长度、可以换更便宜的模型但只要走的是“召回 生成”这个生成的费用就很难消灭。即便是把上下文从长文本砍到理想状态单次调用的 token 成本也不会变成零。从数据结构上看RAG 保存的其实是“知识片段”和“文档的离散向量”而不是“用户问题的最终答案”。知识片段的组织是碎片化的每次回答都需要重新组织一次。换句话说RAG 把一部分推理责任交给了运行时的大模型。2.2 RAGless 的核心思路与工作流程从标题里的 show 就能猜测RAGless 大概率是作者为了表达鲜明立场起的名字我不要运行时生成。既然我是没有官方文档的材料下面我只能基于设计与经验梳理出一个合理的 RAGless 原型流程。通常RAGless 会分成两个阶段离线构建阶段对已知文档和知识库进行分析抽取要点把文本归纳成问题答案或主题结论之类的结构化条目。每条后面可以接语义向量也可以只做文本归一化。在线问答阶段用户输入问题后系统执行确定性匹配也可以借助向量检索来召回但召回结果的排序和合并发生在本地从已有条目中找出最合适的答案然后直接返回。全程不调用大模型不生成新文本。也可以把 RAGless 理解为“知识蒸馏”加“近邻查询”的组合大模型只在文档更新时参与一次理解之后它就是一部可以按图索骥的静态“知识手册”。2.3 成本与延迟的直观对比把两者放到同一个表格里对比你很容易看出差异发生在哪个层面。对比维度经典 RAGRAGless 思路文档处理切 chunk、embedding文档更新时离线分析、抽取问答对运行时 LLM 调用每次 query 一次或多次无或极少兜底调用运行时成本随 query 数线性增长主要折算为基础设施与匹配计算答案稳定性依赖 prompt 与采样参数高答案来自固定条目开放性问答较强弱仅限已有条目能覆盖的范围知识更新周期更新 embedding 和 prompt需要重新执行离线构建定位召回 生成召回 查表返回RAGless 最大的门槛藏在“离线构建”阶段。如何从一段文档中准确抽出问答对或结论如何在庞大条目库里保证问题的归并和去重如何判断新问题在条目库里其实“没有标准答案”这些工作量并不小。如果文档属于强推理性内容比如“比较 A 方案和 B 方案并给出在不同前提下的建议”RAGless 往往会遇到一个边界它检索到的是相同主题的多个条目做不了跨条目的深度比较。这也是你在考虑这套思路时必须有的心理预期。3. RAGless 的适用场景与不适合的场景文章写一半最容易被追问的问题是你这个方案这么好为什么不是所有人都在用理性的回答是它对场景的挑选非常苛刻。它有明显的适用边界硬塞到错误场景会变成灾难下面把两类边界写清楚。3.1 适合 RAGless 的场景比较典型的场景有下面三类。企业内部规章制度问答。员工问“年假可以休几天”“报销金额超过多少需要总监审批”这些问题的答案在制度文档里是固定表述。你真正需要的是准确、一致、响应快。RAGless 可以把制度文档里的问答条目构建好运行时只要在条目库中匹配得到的答案和人工翻阅文档看到的高度一致。客服 FAQ 与售后知识库。大多数客服问题的问法虽然五花八门但核心语义都指向少量规范答案。传统 RAG 里模型可能用不同措辞反复解释同一件事RAGless 则可以把标准答复固化。对客服场景来说标准答复本身就是业务资产团队会不断维护这个答案库这正好匹配 RAGless 的运行模式。离线文档检索配套的结论查询。比如设备操作手册、产品规格说明、政策条款解释。用户问“最大支持并发数是多少”直接把条目中的答案取回来并给出原文所在章节远比让大模型现场总结更可信。在这些场景里还有一个容易被忽略的好处审计可控。由于返回答案来自固定的条目你可以直接追溯到文档来源。这在合规要求高的行业中非常受用。传统 RAG 中大模型生成的内容可能带推理痕迹很难逐句标出来源。3.2 不适合 RAGless 的场景不适合的场景更值得警惕。一是强综合推理类问答。比如“这几个产品相比哪个更适合我们团队”RAGless 只能返回每个产品的事实信息无法代替人去综合判断和给出定制建议。RAG 即便做得不够好至少在“现场组织推理”这件事上更灵活这种场景把两者放在一起是错位竞争。二是面向新知识快速过期的新闻或事件动态。如果知识库平均每几分钟就有新内容离线构建的条目很难保证实时性而 RAG 直接检索新向量内容的能力仍然不可替代。三是长尾开放式问题比例高的系统。如果用户总在问“这个东西怎么用的”“能不能结合我的情况分析一下”而标准问题集合覆盖不了他们RAGless 会频繁走进“查不到答案”的消极分支体验比 RAG 差很多。这种时候宁可用 RAG把成本和效果再调优也不要硬套 RAGless。3.3 判断是否切换到 RAGless 的三个标准实际项目中我会建议用三个问题快速筛选用户问题的最终答案是否都来自文档里“已经存在”的知识点用户能不能接受一个相对固定措辞的标准答案而不是每次重新生成的解释知识内容更新的频率是否显著低于用户查询的频率如果三个回答都是“是”RAGless 值得认真考虑。否则它可能只能作为一个低成本分流层承担其中一部分高频问题剩下的长尾继续走 RAG。这个“混合分流”的思路后面也会重点展开。4. RAGless 核心设计离线构建与运行时匹配前面几节已经在概念层用较大篇幅讲清了为什么。这一节进入工程视角把 RAGless 系统应该由哪些组件构成、每一步能踩什么坑讲透。4.1 整体架构拆解从架构上看我会把项目划分为四个核心模块文档解析与切分把 PDF、Word、Markdown、Wiki 页面解析成可处理的文本块。离线知识蒸馏选择 LLM 或其他自然语言模型把文本块总结成“问题—答案—来源段落”三元组这里是一次性成本。条目管理与索引构建去重、合并语义相近问题、为每个条目建立向量索引和文本索引。在线问答引擎接收 query - 做归一化与改写 - 检索匹配 - 返回答案与置信度 - 置信度低时触发兜底策略。4.2 每个环节的设计要点文档解析与切分。不是所有文档都是漂亮的 Markdown。PDF 里的表格、扫描件里的图表解析效果会直接影响后面的抽取质量。比起 RAG 中按固定 token 切 chunk 的粗放做法RAGless 更希望解析出“章节完整、上下文闭环”的文本块因为每一块文本都可能要被总结成问答对。如果切分太碎后面的离线蒸馏会丢失上下文。离线知识蒸馏。具体怎么执行取决于可用模型和能力限制。如果你的项目允许一次性调用商业模型 API这就是一次集中花费预算极紧的话本地部署小参数模型也能做到不错的效果。不要跳过“清洗答案”的步骤。模型给出的第一个答案通常是整段话你需要二次规则提示让它输出 JSON 结构化结果比如{ question: 带薪年假的天数如何确定, answer: 累计工作满1年不满10年的年休假5天满10年不满20年的年休假10天满20年的年休假15天。, source: 考勤管理制度-第三章-年假 }不建议一次性把上百个文本块的蒸馏工作交给一次巨大的 LLM 调用运行风险高。稳妥的做法是按文本块逐块或小批量处理失败重试结果落盘。问题归并去重。一个文档里经常有两段话描述同一件事比如“报销流程”在前言里提了一次在操作指南里又详细描述一次。离线蒸馏后会生成重复问题。这时需要做一层相似度归并把相同意图的问题合并到同一个标准答案上。这个环节通常也可以使用向量相似度把问题向量两两比较相似度超过阈值的放入一组人工或规则决定保留哪一个标准问法。在线匹配。到了运行时用户问题可能比较长、夹带语气词或错别字。所以先做 query 归一化小写化、去除停用词、保留关键词。然后采用两路召回:一是关键词或 BM25 类文本检索可以快速找到字面相似的问题二是向量检索用来捕获同义改写。两路结果合并后按得分排序如果最高分超过预设置信度阈值返回对应答案如果没超过则进入兜底。这里对“回答不上来”的处理比 RAG 更敏感。RAGless 没有大模型现场编内容的兜底因此必须显式设计“无法回答”时的用户话术。4.3 与 RAG 对比的回滚成本工程上同样要重视方案的“可回退性”。从 RAG 切到 RAGless不是一个配置开关而是一套新的知识管理习惯。最棘手的问题不是索引构建而是“运营人员的思维转变”。原先大家习惯了文档更新后直接把文件传上去RAG 链路会自动重新切分 embeddingRAGless 则需要额外的蒸馏和问答对审核流程。如果团队没有内容运营角色这套流程容易卡在文档更新这一环节上。建议在落地时把“文档变更 - 重新解析 - 生成候选问答 - 业务方确认 - 发布”这条流水线做成固定步骤而不是靠人来临时手动操作。5. 从零搭建 RAGless 原型完整示例这里给一个可运行、可扩展的最小示例。选择 Python演示核心链路读取 Markdown 文档、用本地离线逻辑生成问答条目、保存为 JSON、运行时做文本相似度匹配并返回答案。为避免依赖不明确的大模型厂商库我会先把“离线蒸馏”阶段抽象成一个接口并写一个规则版实现。这样你可以直接替换成自己的模型调用。5.1 项目结构规划先把目录列出来。这个结构很小但组件边界清晰后面替换模型时不会伤筋动骨。ragless-demo/ ├── data/ │ └── policies.md ├── src/ │ ├── ingest.py │ ├── distill.py │ ├── matcher.py │ └── server.py ├── output/ │ └── qa_store.json └── requirements.txt5.2 准备文档创建data/policies.md内容是两份简化版制度片段# 员工考勤管理制度 ## 年假说明 员工连续工作满1年不满10年的每年享有5天带薪年假满10年不满20年的享有10天满20年的享有15天。带薪年假可在自然年度内分段使用。 ## 病假说明 员工请病假需在当日10点前提交申请病假超过3天需提交医院开具的证明。病假期间工资按本市最低工资标准的80%发放。 # 费用报销管理制度 ## 报销时限 员工应在费用发生后30天内提交报销申请逾期需填写特殊审批单并说明原因。 ## 审批规则 单笔金额500元以下的报销由部门主管审批500元至5000元需部门总监审批超过5000元需总经理审批。5.3 配置依赖创建requirements.txt只保留最通用的文本处理库方便跑通numpy1.26.4 scikit-learn1.5.1如果系统里 Python 版本较高也可以把上述版本放宽到兼容版本例如numpy1.24、scikit-learn1.3。5.4 文档解析模块创建src/ingest.py解析 Markdown提取标题与段落。# src/ingest.py import re from pathlib import Path from dataclasses import dataclass dataclass class TextChunk: title: str section: str content: str property def full_text(self) - str: return f{self.title} - {self.section}: {self.content} def parse_markdown(file_path: str) - list[TextChunk]: path Path(file_path) lines path.read_text(encodingutf-8).splitlines() chunks: list[TextChunk] [] current_title current_section paragraph_buf: list[str] [] def flush(): nonlocal paragraph_buf text .join(paragraph_buf).strip() if text and current_title and current_section: chunks.append( TextChunk( titlecurrent_title, sectioncurrent_section, contenttext, ) ) paragraph_buf [] for line in lines: line line.rstrip() if line.startswith(# ): flush() current_title line.lstrip(# ).strip() current_section elif line.startswith(## ): flush() current_section line.lstrip(# ).strip() elif line.strip(): paragraph_buf.append(line.strip()) else: flush() flush() return chunks if __name__ __main__: for chunk in parse_markdown(data/policies.md): print(chunk.full_text)这里的切分逻辑是“标题 小节 连续纯文本段落”并不适合所有文档但它能让人清晰理解 RAGless 对输入文档结构化程度的要求输入越结构化后续蒸馏难度越低。5.5 离线蒸馏模块在真实项目中这一层通常调用一次 LLM API要求它把文本块摘要成 JSON 条目。在原型里我会写一个可替换的distill_chunk函数并内置一个简单的规则蒸馏实现供测试。# src/distill.py import json import re from typing import Callable from .ingest import TextChunk # 定义蒸馏器类型输入一个文本块输出问答条目列表 Distiller Callable[[TextChunk], list[dict]] def rule_based_distill(chunk: TextChunk) - list[dict]: 演示用规则蒸馏从纯文本里抓取出现“多少/是否/需/天”等模式的关键句。 真实项目中建议替换为一次结构化 LLM 调用。 candidates [] content chunk.content # 简易切分按句号、分号切句子 sentences re.split(r[。;], content) for sent in sentences: sent sent.strip() if not sent: continue if any(keyword in sent for keyword in (多少, 天, 元, 需, 要求, 规定, 审批)): candidates.append({ question: f{chunk.section}里关于{sent[:12]}的规定是什么?, answer: sent, source: f{chunk.title}-{chunk.section}, }) return candidates def generate_qa_store( chunks: list[TextChunk], distill: Distiller rule_based_distill, ) - list[dict]: qa_list [] for chunk in chunks: entries distill(chunk) for entry in entries: entry.setdefault(title, chunk.title) entry.setdefault(section, chunk.section) qa_list.append(entry) return qa_list def save_qa_store(qa_list: list[dict], output_path: str) - None: with open(output_path, w, encodingutf-8) as f: json.dump(qa_list, f, ensure_asciiFalse, indent2) if __name__ __main__: from .ingest import parse_markdown chunks parse_markdown(data/policies.md) qa_list generate_qa_store(chunks) save_qa_store(qa_list, output/qa_store.json) print(f生成 {len(qa_list)} 条问答条目)这段代码刻意做得简易主要为了让你跑通流程。真正到项目里建议把rule_based_distill换成类似“把文本发送给工具函数要求只输出合法 JSON”的实现。要注意给模型的蒸馏 prompt 需要固定 JSON Schema并做好解析失败的容错与重试。5.6 构建匹配器在线问答阶段我们采用“TF-IDF 余弦相似度”做检索。这只是一种轻量手段你完全可以换成句子嵌入向量。为了不引入太重的模型依赖先跑通。# src/matcher.py import json import re from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity import numpy as np class QAMatcher: def __init__(self, qa_store_path: str): with open(qa_store_path, r, encodingutf-8) as f: self.qa_list json.load(f) self.questions [item[question] for item in self.qa_list] self.vectorizer TfidfVectorizer(analyzerchar_wb, ngram_range(1, 2)) self.question_matrix self.vectorizer.fit_transform(self.questions) def normalize_query(self, query: str) - str: # 简单归一化去空格、统一符号 query re.sub(r\s, , query) query query.replace(, ).replace(?, ) return query.strip() def match(self, query: str, top_k: int 1, threshold: float 0.15): normalized self.normalize_query(query) q_vec self.vectorizer.transform([normalized]) scores cosine_similarity(q_vec, self.question_matrix)[0] top_indices np.argsort(scores)[::-1][:top_k] result [] for idx in top_indices: score float(scores[idx]) result.append({ question: self.qa_list[idx][question], answer: self.qa_list[idx][answer], source: self.qa_list[idx].get(source, ), score: score, }) return result这里没有用通用开源大模型做 embedding。RAGless 在线阶段如果不调用任何模型匹配器就会退化到传统文本检索。如果用本地向量模型做匹配这部分并不算“LLM API 成本”因为推理发生在你自己的环境里但需要额外考虑 CPU/内存占用。匹配阈值的选取是个工程细节。阈值太松会返回不相关答案置信度标注失真阈值太紧会把大量问题推向兜底牺牲覆盖率。建议收集一批真实用户 query离线统计阈值分布让业务方决定哪些属于 “可以答错也能接受”哪些属于“无法回答比给错答案更好”。5.7 提供问答服务创建一个极简命令行入口方便先体验效果# src/server.py from .matcher import QAMatcher def main(): matcher QAMatcher(output/qa_store.json) print(RAGless Demo 已启动输入 exit 退出。) while True: query input(\n请输入问题: ).strip() if query.lower() exit: break results matcher.match(query) if not results or results[0][score] 0.15: print(抱歉当前知识库中暂无匹配答案请换个问法或联系人工。) continue top results[0] print(f\n答案: {top[answer]}) print(f来源: {top[source]}) print(f相似度: {top[score]:.3f}) if __name__ __main__: main()再看一遍整体链路你会发现核心特征很明显加载的文档经过解析、蒸馏、生成固定问答对最后在线服务只读索引全程没有外部模型被打扰。这就是题目里 $0 runtime LLM API cost 的含义。6. 运行与验证如何判断这套流程真的可用很多项目在跑通 demo 后会天然陷入“结果好像还行”的舒适区。RAGless 本质上是一个检索系统它的验证方法非常接近搜索系统的验证方法绝不能只看一两个 query 回答得漂亮。6.1 运行命令与预期输出进入项目目录按顺序执行cd ragless-demo python -m src.ingest python -m src.distill python -m src.server前两步正确的话会输出类似内容生成 8 条问答条目第三条进入交互问答后输入“年假可以休几天”预期输出应该包含类似下面的结果答案: 员工连续工作满1年不满10年的每年享有5天带薪年假满10年不满20年的享有10天满20年的享有15天。带薪年假可在自然年度内分段使用。 来源: 员工考勤管理制度-年假说明 相似度: 0.xxx输出并不需要追求很高的相似度但要能命中答案并且来源正确。这里需要提醒在 demo 里如果输入的是“我两年年假多少天”因为文本相似度的原因可能匹配不到标准问题。这不是 bug而是 RAGless 在线匹配的能力边界。生产中这类同义改写依赖更好的向量模型或 query 理解模块。6.2 用评测集验证替代主观手感至少准备一份离线评测集包含问题、标准答案 id、是否应该能回答。然后把所有 query 批量跑一遍不要通过命令行手动一问一答否则你不会真正理解系统的覆盖率。一个最小化的评测脚本示例如下# eval_qa.py import json from src.matcher import QAMatcher test_cases [ {query: 年假可以休几天, expected_source: 员工考勤管理制度-年假说明}, {query: 病假超过几天需要证明, expected_source: 员工考勤管理制度-病假说明}, {query: 报销时限是多少, expected_source: 费用报销管理制度-报销时限}, {query: 单笔9000元报销要谁审批, expected_source: 费用报销管理制度-审批规则}, ] matcher QAMatcher(output/qa_store.json) hit 0 for case in test_cases: results matcher.match(case[query], top_k1, threshold0.0) if not results: print(fFAIL | {case[query]} - 未命中) continue top results[0] source top[source] ok source case[expected_source] hit int(ok) print(f{PASS if ok else FAIL} | {case[query]} - {source} | score{top[score]:.3f}) print(f\n命中率: {hit}/{len(test_cases)})不要只用准确率一个指标。我建议至少看三个维度覆盖率多少真实用户问题可以被回答、准确率回答的答案是否与人工标注一致、低置信率多少问题被系统主动归入无法回答。RAGless 的最大优点之一就是它对不确定性有显式表达。如果低置信率太高不是调整阈值就能解决的而是知识蒸馏阶段生成的问答对没有覆盖用户真实问法。6.3 失败排查顺序系统跑不起来或效果很差第一步不要乱试。按下面顺序排查看文档解析阶段是否成功分离标题与小节。如果 parse_markdown 后 chunks 为空后面所有步骤都不会有结果。看 QA store 条目的 question 是否合理。如果蒸馏器抽出来的问题本身没有语义自然不能指望匹配阶段回答好。用一条黄金 query 逐个环节打日志定位相似度得分走低是发生在归一化、向量化还是最终排序。如果是真实模型调用失败去看超时配置、prompt schema 和重试逻辑。7. RAGless 常见问题与排查思路这一节整理实际转化过程中大概率会遇到的卡点按表格列出方便直接对照。问题现象可能原因排查方式解决方案离线蒸馏产出大量重复问题没有执行语义去重把 QA 条目用向量相似度两两跑一遍观察聚类引入相似问题归并流程保留一个标准问法在线问答经常返回“无法回答”原文档蒸馏出的问答对不覆盖用户问法对比用户真实 query 与 QA 入口问题收集真实 query 反馈反向补蒸馏相近问题答错概率高匹配只靠字面相似度查看相似度得分和坏例换成语义 embedding或增加同义词表文档更新后老答案长期在线没有建立发布审核流程检查最近一次文档变更流程建立“变更-蒸馏-人工审核-发布-缓存淘汰”流水线用户问“如果是应届生呢”这类个性化问题问答对只有通用答案日志看是否大量涌入兜底将复杂个案人工接管或在知识库中补充条件分支条目API 调用只在离线构建期存在但成本仍然偏高每次文档版本文本块变化触发全量蒸馏观察离线构建任务的 token 消耗做增量蒸馏只蒸馏发生变化的文本块答案给出来但引用来源错误蒸馏时 source 字段没有正确绑定标题抽查 QA 条目 JSON 的 source修正蒸馏器让 source 从文档层级结构继承8. 从 RAG 到 RAGless混合架构与工程落地的进阶建议如果把架构选型理解成一道单选题那就太浪费 RAGless 带来的启发。更符合实际的视角是RAGless 可以作为整套问答系统里一个高性能、低成本的前置分流层RAG 作为长尾复杂问题的兜底。把两条链路组合在一起往往是成本与效果的次优解。8.1 设计一个双路径问答系统前端接入用户问题后先走 RAGless 的匹配层如果匹配分高于高置信阈值直接返回固定答案附上来源耗时极短费用为 0如果匹配分在中低位区间进入 RAG 链路让大模型参照检索片段生成答案如果匹配分极低说明知识库覆盖不到进入人工处理或转人工客服。这套设计能在大多数高频问题上省下所有 token 费用同时不让系统的长尾体验崩塌。每次 RAGless 没命中但 RAG 答对了都是一个可以沉淀为新问答对标的数据样本反过来RAG 答错但 RAGless 根本没参与的内容可以测试新的生成策略。这样就形成了成本监控与知识迭代的正反馈。8.2 从哪些层面评估上线后的效果成本指标最直接的是每千次查询的 LLM API 费用。对比引入 RAGless 分流前后观察只走 RAG 的命中率变化。这里容易出现把低成本、低价值混为一谈的情况。如果两个方案的答案准确率接近低成本的更优如果 RAGless 命中时准确率明显低于 RAG那么这个分流层反而是在靠牺牲质量省钱不能上线。延迟指标。运行时为什么快因为远端 LLM 调用被换成本地检索少了一次网络 RTT还少了生成时间。如果匹配层用的是本地向量模型也要把推理耗时算进去。运营指标。知识文档平均更新周期、QA 条目审核时长、人工处理量变化。RAGless 非常依赖“知识运营”这件事如果文档更新频繁而审核跟不上整个问答系统很快就会过时。质量指标。不能只测单条答案。把历史真实 query 沉淀成一个回归集每次知识库或代码变更都要全量跑一遍。这里可以借用常规的检索评测流程比如 hit rate、MRR 等指标。注意不要编造具体阈值不同业务差异很大。8.3 生产环境的工程细节离线蒸馏要做成带版本管理的任务。每条 QA 条目记录生成时间、文档版本、审核人。不要把问答对直接生成到线上库而没有任何变更记录。建议格式里至少包含doc_version、distill_model、reviewed_by等字段。在线匹配对性能要求高的把 QA 条目全部加载到内存。数据量超过单机内存时再考虑引入向量数据库或专门的检索引擎。这属于工程扩展和 RAGless 的核心思路不冲突你的目标是运行时少调外部模型不是禁止使用检索基础设施。安全方面要注意答案源实际上是一份先审核过的“可发布知识”。相比动态生成内容的 RAGRAGless 在这块天然更稳。但风险转移到了离线蒸馏与审核阶段如果审核不严格坏答案会稳定地、低成本地交付给所有用户风险会成倍放大。因此审核机制只能加强不能削弱。8.4 几个容易踩的认知误区第一个误区是“RAGless 完全不使用大模型”。事实上它的离线构建通常是模型能力的重头戏。与其说它消灭大模型不如说它把模型从“在线服务员”变成“离线知识编辑”。第二个误区是“匹配很弱效果太差”。匹配弱的原因往往在于 QA 条目的问题覆盖不够而不是方法本身有缺陷。真实系统中应该把 query 理解为“入口表达”一个标准答案需要挂载许多同义问法。匹配优化是持续建设的内容资产不是一次性算法调参。第三个误区是“如果文档经常变动RAGless 就不行”。实时性确实有挑战但可以考虑分主题更新时间线。高频变动文档走 RAG相对稳定的制度类、产品手册类文档走 RAGless。没有谁说整个知识库只能选择一种架构。9. 总结与下一步实践路径把全文的脉络收束一下。RAGless 的灵感起点很简单也非常务实RAG 把“生成”放到运行时带来的成本与延迟问题在很多固定知识问答场景里其实是多余的。RAGless 选择把知识总结成结构化条目在线阶段只做检索和返回所以运行时的 LLM API 费用可以压到 0。它并不适合所有知识库项目。适合它的是答案来源固定、一致性要求高、查询频率远高于知识更新频率的场景不适合它的是强推理、个性化、实时动态信息类问答。对你而言最有价值的动作不是立刻把所有 RAG 链路重写成 RAGless而是做一次架构审视现在系统里哪些 query 每天占了 80% 的调用量其中又有多少是雷同的标准问法能不能先抽出一部分高频问题做成固定问答对在线分流返回当你从账单里看到 tok 数字下降的时候才会真正理解 RAGless 这个思路背后的价值。你可以把这篇文章当成一个脚手架下一步做三件事一是拿自己业务里最高频的 50 个问题构建第一批标准问答条目二是写一个简单的低置信兜底逻辑让系统能优雅回答不上来三是搭建日志和评测闭环把每次 RAG 兜底回答的内容沉淀为新的 QA 候选。跑完这三步你会重新理解知识库问答的成本结构——原来最合理的成本优化不是把模型换成更便宜的版本而是尽量不把模型请到每一次问答的现场。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价