ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

RAGless:去掉运行时生成,实现知识库问答近零Token成本

RAGless:去掉运行时生成,实现知识库问答近零Token成本 先给结论RAGless 这个项目的核心卖点是把 RAG 这条链路里的“运行时生成”去掉让知识库问答在运行阶段不调用 LLM API因此 token 费用趋近于零。它仍然要建索引、要做检索也需要回答用户问题但它不再像常规 RAG 那样每次提问都把一堆资料塞进 Prompt 里让大模型重新组织语言。适合的场景很明确FAQ、产品文档、操作手册、规范条目这类“答案本来就写在某段原文里”的知识库问答。不适合的场景也同样明确需要跨文档归纳、改写、翻译、多轮综合的开放问答让它硬做会非常勉强。这篇文章会从 RAG 的成本构成讲起拆清楚 RAGless 到底省掉的是哪部分钱再把落地时需要处理的数据、索引、查询、评测和边界问题逐个说一遍。如果你手上正好有一个文档问答需求但预算又很紧这篇文章值得完整看完。1. RAGless 不是去掉检索而是去掉运行时的“生成”1.1 RAG 的钱主要花在哪一步要理解 RAGless得先理解 RAG 的成本发生在哪个环节。常规 RAG 在处理一次用户问题时通常是这样走的用户输入一个问题。系统把问题转成向量或者做关键词召回。从知识库中检索出若干相关片段。把“用户问题 检索到的片段 系统提示词”拼成一段长文本。调 LLM API 生成最终回答。第 2 步和第 5 步都可能产生 API 费用。第 2 步如果使用远端 embedding 模型也需要按 token 计费。但大头其实在第 5 步因为你要发给模型的 Prompt 不只是用户那一句话还包括检索出来的文档片段和提示词模板。文档片段越长、top-k 数量越多单次请求消耗的 token 就越高。如果用户再追问几轮历史消息也要重新拼进去费用会进一步上升。所以很多团队在做 RAG 原型时发现单个问题看起来没多少钱但一天几千次查询后账单增长很快。更隐蔽的是部分回答质量不高需要加长上下文、提高召回数量来缓解这又会反过来推高成本。RAG 的 API 费用不是固定值而是和你的文档长度、召回数量、并发规模强相关。1.2 RAGless 的取舍索引期做重活运行期只做检索和展示RAGless 的核心变化是把成本尽量挪到索引构建阶段而不是每次用户提问时都付一次推理费用。具体来说它在离线阶段同样要做文本清洗、分块、向量化或关键词索引这些操作即使使用本地开源模型或传统分词算法也只需要承担服务器资源成本不需要按次调用云端 LLM API。到了运行阶段用户提问之后系统只做检索、排序、按阈值截断、返回原文片段或者用前端模板把命中片段拼成一个可读的问答结果。整个过程没有大模型生成这一步所以 LLM API 费用是零。它和 RAG“相似”的地方在于它依然沿用“问题 → 召回 → 排序 → 返回相关内容”的框架甚至很多分块策略、向量索引方案、Top-K 参数设计都是通用的。区别在于最后一步RAG 是让模型“看着资料说人话”RAGless 是直接把资料里的原句返回或者让前端把几段原句拼成答案卡。这种取舍换来的是明确的工程优势每次查询成本可控接近 0。响应延迟低因为没有大模型排队和推理耗时。回答可追溯用户能看到答案来自哪篇文档、哪一个段落。不存在大模型幻觉因为根本不让模型自由发挥。代价是回答的自然语言组织能力弱同义改写能力弱复杂问题只有先靠检索命中才能解决。1.3 两种方案适合的内容形态不同RAGless 适合的是“答案能从原文里直接截取”的知识库。例如企业内部 FAQ报销流程是什么、假期怎么申请、密码多久改一次。产品操作手册某个按钮在哪里、某个报错怎么处理、某项配置如何开启。政策规范类文档某一条规定原文是怎么写的、截止时间是哪天。标准答案类业务库常见问题对应的标准回复模板。传统 RAG 则更适合“需要综合后再表达”的场景比如多份合同的关键风险归纳、多篇论文的研究方法对比、开放式的资料问答。这种需求即使把相关段落都检索出来直接堆给用户也读不出完整结论必须有一层生成能力做组织。因此 RAG 和 RAGless 不是替代关系而是成本、效果和场景不同的两条路。给一个直观对比对比项传统 RAGRAGless运行时是否调用 LLM API是否单次查询 token 费用与上下文长度正相关接近 0回答形态模型生成的连贯文本原文片段、命中段落、模板拼接响应速度受 LLM 推理影响主要取决于检索引擎可解释性可给引用但回答本身是生成的天然可追溯到原文跨文档综合能力强弱最佳内容类型开放问答、总结、对比、分析FAQ、文档查询、标准条目2. 运行前先做三件事数据清洗、索引构建、成本重新定位2.1 先接受“零 API 成本不等于零部署成本”“$0 LLM API costs at runtime”这句话要正确理解。它说的是运行阶段不按次付 LLM 费用不代表整个系统不需要花钱。索引构建需要计算资源全文检索或向量检索服务需要内存和 CPU如果使用本地 embedding 模型做向量化还需要额外的机器资源。文档越多索引越大内存占用也会上升。所以在选型前先做一个简单判断你的查询量到底有多大如果每天只有几十次问答传统 RAG 也许花费并不高没必要为了省 API 费用引入一套自建索引和检索体系。如果每天有几千上万次查询或者你希望知识库问答直接暴露给终端用户那 RAGless 的价值就很明显API 费用的边际成本可以压到接近零。另外还要考虑团队维护成本。自建检索服务需要处理文档更新、索引重建、并发查询和监控告警这些虽然是工程上常见的工作但确实需要有人持续维护。2.2 数据准备分块和清洗决定效果的上限RAGless 不生成内容因此它的回答效果几乎完全依赖于“索引里有没有相关文本”以及“检索能不能把这段文本找出来”。第一步是清洗。网页正文要抽取出来PDF 里的表格要尽量转成可检索的结构化文本Markdown 里的代码块和目录要按需求决定是否保留。如果原始文档里混杂大量页眉、页脚、导航文字这些噪声会成为检索时的干扰项。第二步是分块。分块是 RAG 类系统最重要的前置步骤之一。块太大检索命中后返回内容很泛用户看不出针对性块太小语义不完整有时一句话被截断在中间返回结果难以理解。常见做法是让分块尽量覆盖一个完整的语义单元比如按“标题 若干段落”来切而不是死板地按固定字符数切。关于分块下面的参数可以作为起点但一定要结合自己的文档类型调整参数常规起始值判断依据chunk_size300 到 800 字文档段落长短、问题答案通常落在多长的片段内overlap50 到 100 字避免关键词分布在分块边界时被切断分块单位标题、段落、列表项优先保持一个完整语义节点是否保留元数据是文档名、章节路径、更新时间要随块保存我看过很多检索效果差的项目最后定位下来都不是模型问题而是源文档本身没清洗干净或者分块策略完全不匹配实际问答长度。比如一份报销制度文档如果每个条目只有两行你却按 800 字分块一个块会混入多个不同主题用户问“差旅住宿上限是多少”时召回结果里混着一堆无关差旅内容回答体验自然很差。2.3 索引方案的选择关键词召回还是向量召回RAGless 的索引层可以有两种选择。第一种是关键词检索也就是传统的倒排索引。它对“专有名词、编号、操作步骤”这类强标识内容非常有效。比如用户问“SSH 连接超时怎么办”倒排索引能直接根据“SSH”和“超时”精确定位到相关文档段。优点是部署简单、资源占用低、可解释性强不用考虑 embedding 模型的选型问题。第二种是向量检索也就是把文本通过 embedding 模型转成向量再通过余弦相似度或内积做召回。它的优势是能匹配同义表达例如用户问“连不上服务器怎么排查”即使原文写的是“远程连接失败”向量检索也有机会命中。缺点是构建索引时需要额外的 embedding 计算可能是调用远端 embedding API也可能是本地跑开源模型查询时也需要为每一条 query 做向量化。更稳妥的做法是混合召回先用关键词召回和向量召回各取一批候选再做结果合并和重排。这样既保留了精确关键词的命中率也增加了语义模糊查询的召回范围。RAGless 项目不一定每条查询都能命中所以召回策略做得越稳可用性越高。如果你刚开始尝试建议先用纯关键词方案跑通流程。用 30 到 100 条高频问题测试一遍如果关键词召回的效果已经能满足大多数问题就不必急着引入向量检索。只有当用户提问方式和文档原文差异很大、关键词命中率明显不足时再补上向量召回。3. 最小可用流程从一份 FAQ 跑通 RAGless3.1 第一步定义问题和答案的原始格式无论最终用什么框架实现我都建议先从一个非常小的知识库开始比如 20 到 30 条常见问题。这样能快速验证方案是否可行也方便人工检查每一条检索结果。先整理一个结构化的源文件最简单的是 Markdown 或者 JSON。每条内容至少包含三部分问题或主题答案或对应原文来源标识如果内容来自文档则应该把文档路径、章节标题、段落内容一起存下来。这里给一个示意不用照抄格式但思路可以参考[ { id: faq-001, title: SSH 登录提示 Permission denied 怎么办, content: 先检查用户名和密钥路径是否正确……, source: docs/remote-login.md }, { id: faq-002, title: 如何修改默认端口, content: 修改配置文件中的 port 字段……, source: docs/server-config.md } ]对 FAQ 类内容标题本身往往就是最好的检索字段。对长文档类内容需要先把文档清洗、分块、生成小块文本再把每个块和它的来源章节一起写入索引。3.2 第二步建立索引这里的索引策略取决于你选的是关键词检索还是向量检索。关键词检索可以用常见的全文检索引擎或纯内存倒排向量检索则需要一个向量数据库或者把向量写到本地文件中用近邻搜索库加载。具体用哪个工具取决于你的技术栈和部署环境但流程是通用的# 示例流程不是某个工具的固定命令 python build_index.py \ --input data/faq.json \ --index-dir output/index \ --chunk-size 500 \ --chunk-overlap 50 \ --embedding-model your-embedding-model如果走纯关键词路线embedding 部分可以省略如果走向量路线需要预先确定 embedding 模型。这里有一个关键判断embedding 模型的选择会影响召回效果但不会影响运行时是否调用 LLM API只要你在索引构建时用本地模型即可。索引构建完成后应该单独存一份文件或目录供查询服务启动时加载。生产环境下还需要考虑增量更新问题新文档加入后不能只重建全量索引尤其是文档量达到几千份以上时增量索引和定时重建要一起做。3.3 第三步写一个最简查询接口查询接口的逻辑比 RAG 简单很多。用户输入问题后经过一次检索从索引中找出与问题最相关的前若干条文本然后直接返回。不同的落地方案可以有不同的输出形态返回命中文档标题和片段。返回 FAQ 的标准答案。返回原文加高亮。将命中的多条片段交给前端按模板渲染。如果整个链路不用 LLM 生成那这一步通常就写成类似下面的伪代码def answer(query: str, top_k: int 5) - list[dict]: hits search(query, top_ktop_k) result [] for hit in hits: if hit.score threshold: continue result.append({ title: hit.title, snippet: hit.snippet, source: hit.source, score: hit.score }) return result如果知识库内容是 FAQ且每条 FAQ 本身有标准答案那返回结果应该直接带 answer 字段。如果知识库内容是文档那返回内容可以是一段原文前端负责把多段原文拼接成答案区域并在底部展示来源链接。这里不建议用一个固定 threshold 值直接过滤所有数据。不同文档、不同索引算法的分数分布差异很大我一般先跑一批人工标注的问题观察命中结果的分数区间再来定阈值。更稳的办法是如果 top-1 的相似度很低直接返回“未找到相关内容”不要硬凑答案。硬凑会让用户觉得系统在瞎答。4. 验证质量RAGless 的效果要从“检索命中”开始看4.1 单条用例的检查清单RAGless 没有生成阶段因此人工验证一条回答是否合格和传统 RAG 的验证方式不太一样。重点不是“回答是否通顺”而是“检索结果是否准确覆盖了用户问题的答案范围”。我建议每一条测试用例都按下面的清单检查用户问“如何找回邮箱密码”返回的第一条是否真的包含找回密码的步骤返回内容里是否有来源和章节信息如果问题需要查看某一步的截图或配置返回文本是否能说明位置如果用户使用同义词发问比如把“怎么改端口”写成“更换监听地址”索引还能不能找到对应文档完全没有相关内容时系统是否给出兜底提示而不是返回垃圾片段单条用例不是看一次就够的。同一个问题换几种表达方式再测比如把“怎么办”换成“处理方式”把缩写换成全称才能看到检索的鲁棒性。4.2 离线评测指标要量化和持续改进 RAGless 的效果手工测试几条远远不够应该造一份离线评测集。评测集的结构可以非常简单每一行包含一个用户问题、一个期望命中的知识库内容 ID也可以额外标注一个期望命中的来源文档路径。[ { question: SSH 登录出现 Permission denied 通常要检查什么, expected_ids: [faq-001] }, { question: 数据库连接池大小怎么配置, expected_ids: [faq-002, manual-003] } ]有了这样的评测集就可以计算几个简单指标Recallk最相关的那条内容是否出现在前 k 条召回结果里。MRR正确结果的排序位置有多靠前位置越靠前越好。无答案率样本里有大量查询无法命中任何合理内容说明索引或分块有问题。这些指标虽然传统但在 RAGless 这种依赖检索的系统里非常有用。因为它们能直接告诉你“检索层的工作是否合格”不掺入生成模型的干扰。如果 MRR 很低说明不是回答模板的问题而是召回阶段根本拉不出正确内容。我自己一般会先人工标 50 条到 100 条高频问题按季度或文档更新节奏做一轮回归。把指标记录下来改完分块、调整完索引策略后重新跑用数据判断是否真的变好了。4.3 在线运行要看什么日志系统上线后还需要观察真实用户问题与预期是否一致。传统 RAG 可以通过日志记录用户问题和大模型回答RAGless 同样可以记录但记录的重点要换成“检索命中日志”。需要记录的信息包括用户原始查询。召回的前几名内容 ID。Top-1 相似度分数。是否落入无答案兜底。用户是否点击了来源文档。如果“无答案”比例过高常见原因是用户提问方式和文档用词差异太大说明需要加强召回策略或者补充同义词。如果用户频繁点击某一条来源文档说明这条内容高频有用可以考虑把它抽成标准答案模板。如果某份文档长期被检索但从没被点击则要考虑是不是文档位置靠前误导了用户。这些日志不需要依赖任何 LLM API也能形成一套完整的数据优化闭环。5. 边界和常见问题别把 RAGless 当万能问答5.1 它是怎么丢分的同义改写、指代和多文档综合RAGless 在测试时最容易出现的问题是问法一变命中结果就飘了。比如文档里写的是“异地备份”用户却问“容灾机房在哪儿”如果索引层没有同义扩展或语义召回靠纯关键词搜索很难命中。另一个问题是指代。RAGless 通常只能处理单轮独立问题因为多轮对话需要理解“它”“刚才那个问题”这些指代关系而它没有大模型理解上下文的能力。如果把多轮语义理解任务硬交给 RAGless你只能自己维护一个轻量的改写模块比如把上一轮的命名实体、关键短语带入当前问题再触发检索。如果用户问题需要综合三份文档才能回答每条被召回的片段都只说了一部分那么 RAGless 的表现就很差。这已经不是“加一个模板”能解决的问题综合归纳本身需要生成能力。因此RAGless 的适用范围必须限定在“答案能在单条记录或单段文本中闭合”的问题上。5.2 文档更新后索引不同步的问题这是工程落地时最容易踩的坑。文档更新了但索引还是旧的于是用户查到的永远是最早那一版内容时间一长就会丧失信任。解决办法可以按数据量大小分档数据量小定时全量重建比如每晚重建一次。数据量中等依赖文档变更事件单独更新变更内容的块。数据量大建立版本号机制每个块带着源文档版本查询时只返回最新版本。如果源文件是数据库里的记录那更新的触发点就更明确记录变更时同时更新索引里的对应条目。总之索引和源数据之间必须有一条明确同步链路否则检索系统上线三个月后很多内容会变成过期答案。5.3 排查顺序先看分块再看召回最后看返回模板RAGless 出了问题不要第一反应是换模型或者调 threshold按下面顺序排查更快看返回是否命中了不应命中的文本块。如果是先检查这个文本块是不是包含了太杂的主题。看正确内容是否压根没出现在召回结果里。如果没出现要检查索引里是否真的存在这条内容以及问题用词和原文用词差异有多大。看正确内容出现在召回结果里但排序不靠前。这时候再调 Threshold、调 Top-K或者加一条重排规则。看正确内容命中了但用户反馈看不懂。问题多半出在返回模板而不是检索。也就是说先判断“检索阶段是否拿到正确答案”再判断“展示阶段是否把它讲清楚”。很多表面上像检索能力不够的问题实际是分块粒度把正确文本切碎了或者跟一堆无关内容混在了一个块里。5.4 适用与不适用清单RAGless 更合适高频重复的 FAQ。标准操作流程。版本固定的产品文档。政策、制度、规范原文查询。对成本和响应速度极其敏感的对外问答场景。RAGless 不合适需要跨文档归纳总结的问题。需要判断用户情绪或意图的客服对话。没有固定标准答案需要生成解析的问题。资料本身没有结构化每篇文档都是一大段故事性文本的场景。如果你发现你的业务场景里用户问题的答案几乎都不是原文档中的某一段落而更多是综合理解后的结果那 RAGless 很难做为主方案。6. 什么时候该上 RAGless什么时候还得走 RAG6.1 一个更现实的成本模型选型不应该只盯着“LLM API 费用是 0”这一个点而要看整体成本结构。RAGless 省的是每次查询的 token 费用但会新增索引维护成本、检索服务部署成本、数据清洗成本和评测集的长期维护成本。一个更现实的判断方式是这样的查询量低、答案又需要较多生成能力直接走传统 RAG简单直接。查询量高、文档答案相对固定RAGless 可以显著降低边际成本。查询量高、但一部分问题确实需要生成总结就采用 RAGless 优先、LLM 兜底的混合方案。混合方案的策略并不复杂先用 RAGless 检索并判断命中分数。如果 Top-1 命中得分很高答案原文已经足够直接回答就直接返回文档片段完全不调用 LLM。如果得分偏低说明纯检索可能满足不了用户这时候才进入降级路径把检索片段交给 LLM由模型组织生成回答。这种“先检索后判断再按需生成”的做法在日常真实业务里会比纯 RAG 或纯 RAGless 都稳。既保住了大部分查询的低成本也给真正复杂的查询留了出口。6.2 从运营角度看使用成本RAGless 不只是节省 API 费用还大大降低了排障时的外部依赖。传统 RAG 如果回答质量差你很难判断是召回问题还是 Prompt 问题还是模型问题。RAGless 没有模型生成层回答质量只取决于数据质量和检索质量定位问题会更快。同时因为每一次回答都能直接给出原文来源用户也能自行判断结果是否可信。企业内部的合规类知识库、客服标准答案库这类场景会非常看重这一点。如果准备长期采用这种架构一定要在前期预留几个能力模块一个评测集维护机制用来做索引更新后的回归验证。一个查询日志服务用来观察无答案率和高频问题变化。一个人工兜底反馈入口让用户找不到答案时可以提交工单。一个可选的 LLM 降级调用开关避免业务复杂后方案完全锁死。6.3 落地建议和验收标准如果你想把这套方案真正落到自己的项目里我建议按阶段推进第一阶段先选一个范围很小的知识库比如 30 条高频 FAQ用关键词检索跑通端到端流程。验收标准是高频问题都能在结果中命中正确内容且无答案兜底提示能正常出现。第二阶段把数据量扩到几百份文档加入向量召回或混合召回。验收标准是新增评测集里的 Recall1 有明显提升用户提问表达方式变化后结果依然稳定。第三阶段再把 RAGless 作为主入口接入真实业务保留日志和人工兜底。验收标准不是看“回答是否像真人”而是看“有多少比例的问题能不经 LLM 直接解决”这个数字越高说明 RAGless 承担的有效查询量越多省下的成本也越明显。从我自己的经验看真正决定 RAGless 方案成败的往往不是“检索算法选得够不够新”而是数据清洗、分块粒度、评测集质量和文档更新机制是否扎实。把这几件事做好哪怕只用最基础的关键词检索也能解决相当一部分高频问答需求。相反如果源文档一团乱、分块没有逻辑、也没有评测方法就算把向量模型换得再好用户依然会觉得这个知识库“什么都搜不到”。
返回列表