新闻详情

新闻详情

首页 / 资讯中心 / 详情

用13张图讲透RAG:Spring AI从向量化到评测的落地实践

发布时间:2026/10/1 13:20:49来源:尧图网络
用13张图讲透RAG:Spring AI从向量化到评测的落地实践
RAG 这词这两年被聊烂了但真去落地过的朋友应该都有同感跑通一个 demo 不难难的是把效果调到“能用”。你问它一个问题它给你翻出来一堆风马牛不相及的片段你说它错吧它引用的内容确实来自你的知识库你说它对呢它回答的又不是人话。我前阵子帮朋友公司做企业知识库用的正是 Spring AI 这套技术栈从向量化、文档切片、检索链路到最终的评测体系每一步都实打实踩了一遍。这篇文章我想用 13 张图把这个链路里最关键的点一次讲透——从向量到底是个什么东西到 Spring AI 里怎么落地再到最后怎么用评测体系量化效果而不是靠感觉调参。这篇文章适合三类人看一是刚接触 RAG想搞清楚原理但被“向量”“Embedding”“召回率”这些词劝退的新手二是已经在用 LangChain4j 或 Spring AI 写 RAG但效果不理想、不知道怎么排查问题的开发者三是技术负责人想理解 RAG 项目到底该怎么评估、怎么验收。我不打算给你套现成的 LangChain 模板而是把底层逻辑拆开讲因为只有理解了每一环的工作原理出了问题你才找得到根因。1. 先看清这条链路RAG 不是“搜索加生成”这么简单1.1 RAG 解决的真实问题以及它和搜索引擎的本质区别我给你一个最直观的对比搜索引擎返回的是候选链接用户自己点开链接找答案RAG 是系统直接检索出候选内容再把这些内容当作参考材料喂给大语言模型由模型组织出一段完整的回复。也就是说RAG 的本质是“用私有知识约束大模型”让模型不再依赖训练时候的记忆而是依赖你给它的上下文。图 1 是 RAG 整体链路的全景图离线管道在左侧从文档加载开始经过切片、向量化、写入向量库在线管道在右侧用户问题进来后先做同样的向量化然后去向量库做相似度检索检索结果和原始问题拼成 Prompt交给大模型生成回答。这张图最容易被忽略的是中间那条线用户问题向量化和文档向量化必须走同一个 Embedding 模型。实际项目里我见过有人文档用 BGE 系列模型向量化查询时却用了 OpenAI 的 embedding 接口两边向量空间根本对不上检索结果自然一塌糊涂。这属于“不同模型向量空间不兼容”的典型问题——你让一个说中文的人去找一本英文书语言不通索引做得再好也没用。1.2 13 张图的分布逻辑在往下讲之前我把这 13 张图的主题先亮出来方便你对照阅读图序号主题属于链路环节图 1RAG 整体架构链路全景图 2向量的几何直觉原理图 3文本到向量的维度变化原理图 4余弦相似度的几何与计算原理图 5文档切片策略对比离线索引图 6切片参数对召回率的影响离线索引图 7向量数据库选型数据存储图 8Spring AI 索引管道实现代码实战图 9TopK 与阈值对检索的影响在线检索图 10检索上下文组装原理解析在线检索图 11Spring AI Advisor 链执行顺序代码实战图 12Naive RAG 与 Agentic RAG 对比架构演进图 13评测指标体系与调参矩阵评测体系基本上前面 4 张图是打地基中间 5 张图是核心代码链路的拆解后面 2 张图是架构升级最后 2 张图讲怎么量化验收。你按这个顺序读思路会非常清晰。2. 向量与 Embedding检索的地基没打牢后面全是豆腐渣工程很多开发者把 RAG 写成了“高级搜索”但一深究又说不清搜索背后的原理。向量是 RAG 的地基这一节我把向量怎么理解、文本怎么变成向量、相似度怎么计算讲透。2.1 向量的本质把“语义”塞进一串数字里图 2 画的是一张语义空间示意图假设我们把词映射到一个二维平面上“苹果”这个点落在水果区域“手机”这个点落在电子产品区域两个点的距离越近表示语义越接近。这个直觉就是向量思想的来源。一个文本向量本质上是一串浮点数比如[0.032, -0.124, 0.456, ...]长度通常是 384、768 甚至 1536。每一个数字翻译成人话就是这个文本在这个维度上的语义特征强度。想象一个 1536 维的空间你没法在脑子里画出图来但你要理解语义相近的文本在这个空间里的位置是相邻的这就是所有向量检索的根基。图 3 展示的是维度变化的示意一行文本经过 Embedding 模型输出一个固定长度的向量。这里有个关键点不管你的文本是一个词还是一整段话Embedding 模型输出的维度通常是固定的。对于同样的模型“吃饭了吗”和一篇 5000 字的技术文档向量维度一样但向量所承载的信息密度完全不同。这会导致一个现象短文本匹配长文档时检索效果往往不稳定因为短文本向量的大多数维度都不够“活跃”。2.2 三种相似度度量的几何直觉向量有了怎么判断两个向量是否相似图 4 画的是三种计算方式的几何对照和公式。第一种是欧氏距离直观理解为空间中两点间的直线距离。向量维度一高欧氏距离往往会大幅膨胀它对向量的模长也就是长度敏感。第二种是余弦相似度它只看两个向量的方向是否一致不看长度。打个比方一个文档向量模长是 10另一个是 1但它们指向同一个方向余弦相似度依然接近 1这在文本场景下更合理因为文档的长短差异会导致向量模长差异很大但语义方向可能相同。第三种是点积它是余弦相似度的分子部分对模长敏感适合在向量已经做了归一化处理的场景下使用计算速度更快。Spring AI 内置的 SimpleVectorStore 默认用的就是余弦相似度这也是大多数文本 RAG 场景的首选。如果你用的是 PGVector 或 Chroma注意在配置里把距离算法统一成 cosine否则不同算法算出来的分数没有可比性。2.3 Spring AI 里怎么把文本变成向量光讲理论没用我以 Spring AI 1.1.x 为例演示接入 Ollama 本地 Embedding 模型的完整配置。为什么要用 Ollama因为它在本地跑数据不出内网对于企业知识库这种敏感场景非常实用而且不需要外网调用费用。先加依赖dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-ollama-spring-boot-starter/artifactId version1.1.0/version /dependency再加配置spring: ai: ollama: base-url: http://localhost:11434 embedding: options: model: nomic-embed-text注意localhost:11434是 Ollama 的默认服务地址你在启动 Ollama 后要确认这个地址能通。然后注入 EmbeddingModelAutowired private EmbeddingModel embeddingModel; public void demo() { ListDouble vector embeddingModel.embed(Spring AI 是什么); System.out.println(向量维度: vector.size()); System.out.println(前 10 个分量: vector.subList(0, 10)); }跑一下就能看到这句话变成了一个 768 维的浮点数组。我之前犯过一个低级错误在 Docker 容器里部署服务base-url 写成了127.0.0.1:11434容器内访问不到宿主机的 Ollama结果向量化接口一直超时。排查了半个多小时才想起来容器里的 localhost 是容器自己不是宿主机。这个问题在本地开发时不会暴露一进容器就翻车。3. 文档切片数据这一侧决定 RAG 质量的上限我一直认为RAG 项目里文档切片比选哪个大模型更重要。模型错了可以换数据切错了检索出来的是碎片喂给什么模型都救不回来。3.1 两种切片策略以及我实际采用的方案图 5 对比了两种常见切片策略固定窗口切片和语义切片。固定窗口切片就是把文本按固定长度硬切比如每 500 个字符切一段相邻段之间重叠 50 个字符。它的优点是简单、稳定、可控缺点是容易把一句完整的话从中间截断导致切出来的片段语义不完整。语义切片是先把文档按段落、标题、章节结构分块再用模型判断每个块的边界是否合适。它的优点是对语义完整性更友好缺点是实现复杂处理大文档时耗时较长而且对于结构混乱的文档比如扫描版 PDF效果反而不如固定窗口。说句实在话我服务过的企业中90% 的知识库文档都是 Word、PDF、Markdown 混着来的很多 PDF 连目录都没有。在这种情况下语义切片是“理想丰满现实骨感”。我现在的做法是先按文档结构粗切再用固定窗口细切先解析出标题和段落以标题为边界切出大块每个大块超过一定长度就按固定窗口切小块并保留元数据来自哪个文档、哪个章节。3.2 chunk size 和 overlap 到底怎么定图 6 是我做过的一个实验曲线横轴是 chunk size纵轴是检索命中率。结论可能和你预想的不一样chunk size 太小比如 128 字符检索粒度碎正确上下文容易被切成两半chunk size 太大比如 2000 字符虽然上下文完整但引入了大量噪音向量表示被稀释检索相似度被无关内容拉低。在测试集上512 到 768 字符的区间往往效果最好。overlap 的作用则更直接它让相邻文本块之间共享一段内容避免语义边界正好落在切缝处导致的关键信息丢失。具体数值没有固定公式一般取 chunk size 的 10% 到 20%。这段代码用的是 Spring AI 的 TokenTextSplitter它比按字符切要聪明一些因为它尽量按句子的边界切TokenTextSplitter splitter TokenTextSplitter.builder() .withChunkSize(800) .withChunkOverlap(150) .build(); ListDocument chunks splitter.apply(List.of(document));注意这里两个参数的单位是 token 数不是字符数。如果你手上的文档里中文占了大头一个 token 大概对应 0.6 到 0.7 个汉字所以 800 token 的块大约能容纳 500 到 600 个汉字。3.3 向量数据库选型不是越重的越好图 7 是一张向量数据库选型象限图横轴是部署复杂度纵轴是数据规模。结论很简单数据量在几万条以内、单机应用直接上 Spring AI 内置的 SimpleVectorStore 或者 Chroma零部署成本有几百万条数据、高并发场景上 Milvus如果你不想额外引入一个中间件且已经用了 PostgreSQLPGVector 是最平滑的选择。我自己的经验是别一上来就上 Milvus。操作成本高运维复杂很多项目根本用不到那个数据量级。Chroma 这类嵌入式向量库可以直接依赖进 Spring Boot 应用里开发调试非常方便先拿它把链路验证通了再考虑迁移。4. Spring AI 索引管道与向量化写入4.1 管道装配从文档到向量库的完整流程图 8 展示的是 Spring AI 索引管道的落地实现读取文档、切块、灌入向量库。代码思路拆开如下每一步都比上一步要多一点“为什么”的考量Configuration public class IndexPipelineConfig { Bean public VectorStore vectorStore(EmbeddingModel embeddingModel) { return new SimpleVectorStore(embeddingModel); } Bean public TokenTextSplitter textSplitter() { return TokenTextSplitter.builder() .withChunkSize(800) .withChunkOverlap(150) .build(); } public void indexDocuments(String filePath, VectorStore vectorStore, TokenTextSplitter splitter) { // 读入文档这里以纯文本为例 Resource resource new FileSystemResource(filePath); Document document new Document(resource.getDescription()); // 切块 ListDocument chunks splitter.apply(List.of(document)); // 为每个块打上来源元数据 chunks.forEach(chunk - chunk.getMetadata().put(source, filePath)); // 向量化并写入 vectorStore.add(chunks); } }需要特别说明的是vectorStore.add(chunks)这行。Spring AI 的 VectorStore 接口内部会自动对每个 Document 调一次 EmbeddingModel所以这一步背后发生了两件事向量化和入库。我在测试时发现很多新手不知道这个细节会自己先调一遍embeddingModel.embed()再把向量手动写入结果导致重复向量化索引时间翻倍多花了不少无用功。4.2 向量化提交的批处理注意点如果你要索引的文档量大比如一个 10 万字的 PDF切分出来几百个 chunk一次性add()会非常慢。因为 SimpleVectorStore 默认是逐条调用 EmbeddingModel 接口的本地 Ollama 处理 768 维向量已经不算快几百条请求跑下来会让你怀疑人生。这时需要做批处理提交ListListDocument batches new ArrayList(); for (int i 0; i chunks.size(); i 50) { batches.add(chunks.subList(i, Math.min(i 50, chunks.size()))); } for (ListDocument batch : batches) { vectorStore.add(batch); }单批 50 条是我在本地 Ollama 上压出来的一个相对稳妥的值二十秒内能完成一批。批量太大Ollama 的 GPU 内存消耗陡增容易把内存打满批量太小网络请求的往返开销又占了大头。如果你用的是 API 形式的 Embedding 服务限制可能更严格需要优先看服务商的限额文档。4.3 分块元数据给每块文档打上身份标签这一小节容易被忽略但作用很大。检索结果被喂给大模型之后你通常需要在回答末尾标注“本回答来自哪份文档”这时如果每个 chunk 元数据里没有记录source字段就会非常尴尬——你无法追踪答案的来源也就无法校验其真实性。加元数据之后检索时就可以这样取出来用ListDocument docs vectorStore.similaritySearch( SearchRequest.builder() .query(Spring AI 的 RAG 原理) .topK(5) .build() ); docs.forEach(doc - { System.out.println(内容: doc.getText()); System.out.println(来源: doc.getMetadata().get(source)); });如果希望某些文档被检索时能按条件过滤比如只看某个月内更新的制度文件元数据字段还可以在检索时作为 filter 使用SearchRequest.builder() .query(员工休假制度) .topK(5) .filterExpression(source HR-2025-01.pdf) .build();这样检索范围瞬间缩小召回准确率通常也会提升因为不必要的语义干扰被滤掉了。5. 检索这一步TopK 与阈值的取舍5.1 官方说法合理但实际要自己调图 9 展示的是 TopK 值对检索效果的影响TopK 太小正确答案可能排在第 6 条而被漏掉TopK 太大虽然正确答案一定在里面但大量无关内容会稀释大模型的注意力生成质量反而下降。所以 TopK 不是越大越好。在短期记忆有限的场景下我一般先设 5如果发现命中率不达标优先看检索结果里正确答案的排名是多少再决定要不要加到 8 或 10。切记不要盲目调到 20因为大模型能处理的长上下文是有限的你把 20 个 chunk 全塞进 Prompt等于是喂了它 20 个噪声源。5.2 相似度阈值低分不代表错高分也不代表对向量检索返回的相似度分数是个相对值不同模型、不同向量库的分数分布完全不同。我发现用 nomic-embed-text 时相似度 0.65 以上算比较可靠但换了一个更激进的模型0.7 才勉强靠谱。所以阈值不能拍脑袋定要在你自己的数据集上看了分布后再定。有一种做法是先跑一批测试问题把检索结果的分数全部打印出来画个分布图。你会发现正确的上下文分数通常偏高错误的上文分数普遍偏低阈值就取两者分界的中间值。这个操作非常简单却能让检索质量提升一大截。5.3 从检索到生成上下文组装的一些细节图 10 展示的是上下文组装过程你虽然检索出 5 个 chunk但不需要把它们全部当作上下文可以只取分数最高的 3 个甚至可以在组装时拼接一个“来源清单”进去告诉模型“以下内容来自公司制度库请基于这些内容回答”。系统 Prompt 优化过的版本大概是这样的请你基于以下检索到的资料片段回答用户问题。 如果资料不足以回答问题请明确说你不知道不要编造。 资料片段 [1] 来源员工手册.pdf Spring AI 支持 RAG 链路开发核心组件包括 EmbeddingModel、VectorStore、QuestionAnswerAdvisor。 [2] 来源年度报告-2025.pdf 公司在 2025 年全面上线智能客服系统基于 Spring AI 与内部知识库。这个 Prompt 模板有两个关键约束一是“资料不足就承认不知道”可以有效降低模型幻觉二是“不要编造”这句话虽然朴素但实测确实能让模型更保守减少胡编乱造的概率。我在多个项目里验证过明确写了这两句之后生成内容的忠实度指标平均能提升 3% 到 5%。6. Spring AI 中检索生成链路的最简实现6.1 QuestionAnswerAdvisor 帮你把 RAG 接起来Spring AI 把检索生成封装成了 Advisor 模式用起来非常省事。图 11 展示的是 Advisor 链的执行顺序先检索再组装 Prompt最后调用模型。你不需要自己手动拼 Prompt只需要把这个 Advisor 挂到 ChatClient 上。Configuration public class RagChatConfig { Bean public ChatClient chatClient(ChatClient.Builder builder, VectorStore vectorStore) { return builder .defaultAdvisors(new QuestionAnswerAdvisor(vectorStore)) .build(); } }之后在 Controller 里直接用RestController public class RagController { private final ChatClient chatClient; public RagController(ChatClient chatClient) { this.chatClient chatClient; } PostMapping(/chat) public String chat(RequestBody QuestionRequest request) { return chatClient.prompt() .user(request.question()) .call() .content(); } }这个最简单的实现背后Spring AI 自动完成了这几件事把你的问题向量化、去 VectorStore 检索 TopK 个 chunk、把 chunk 和问题组装进系统 Prompt、调用 LLM 生成回答。整个链路大约二三十行代码从“写一个 RAG 接口”的角度说已经足够简单了。6.2 动态参数不同问题用不同 TopK不过这里有个容易被忽视的点Bean方式配置的 Advisor 是全局的所有请求的 TopK 都一样。我实测下来有些问题只需要检索 3 个 chunk 就能答好有些复杂问题则需要 6 个甚至更多。如果需求精度高可以改成动态控制return chatClient.prompt() .advisors(a - a.param(topK, request.topK())) .user(request.question()) .call() .content();你要在配置文件里把 Advisor 的默认参数先取消再在请求层注入动态值。这个方案适合产品需要针对不同用户展示不同详细度答案的场景。代价是你必须在业务层对问题进行简单分类比如判断是否涉及多个知识域的复合问题。如果不放心模型判断也可以用规则先兜底例如问题里包含“对比”“区别”“和”这类词的时候就把 TopK 调到 6。7. 从 Naive RAG 到 Agentic RAG复杂问题需要“思考后检索”7.1 一次性检索的局限图 12 对比了 Naive RAG 和 Agentic RAG 的流程差异。Naive RAG 是一次检索、一次生成问题来了就搜搜完就答。对于“公司年假制度是什么”这种单点问题足够了。但如果用户问“帮我对比一下公司新老两款产品的功能差异”Naive RAG 会把你的问题切成一个向量去检索八成搜到的都是笼统介绍很难恰好把两款产品各自的详细资料同时捞上来。Agentic RAG 的思路是让大模型参与检索策略的制定它先拆解用户问题分步骤检索必要时多次检索、汇总信息后再作答。举个例子模型会先解析出“需要检索产品 A 的详细功能”和“需要检索产品 B 的详细功能”两个子任务分别去向量库检索最后把两份结果综合成对比答案。7.2 基于 Spring AI 实现一个轻量 Agentic RAG我不建议一上来就上复杂框架可以先用一个最朴素的思路做先让大模型判断“当前问题是一次能答完还是要分多次检索”。public String agenticRag(String question) { String plan chatClient.prompt() .system(你是知识库检索规划器。如果问题需要从多个不同文档获取信息才能回答请列出需要检索的多个子问题否则仅回复无需拆分。) .user(question) .call() .content(); // 如果模型认为不需要拆分走普通 RAG if (无需拆分.equals(plan.trim())) { return simpleRag(question); } // 否则把子问题分别检索并汇总 ListString subAnswers new ArrayList(); for (String subQuestion : plan.split(\n)) { subAnswers.add(simpleRag(subQuestion)); } return chatClient.prompt() .system(请根据以下分部分检索结果综合回答原始问题。) .user(原始问题 question \n分部分结果 String.join(\n, subAnswers)) .call() .content(); }这个实现很粗糙但思路是对的而且它能帮你理解 Agentic RAG 的本质把问题拆解能力交给模型把检索执行能力留给自己。生产环境我会建议用一个更严格的状态机限定拆解步骤数量防止模型陷入无限循环的检索里同时给每一步加上超时和最大重试限制。7.3 Agentic RAG 的代价比你想象的高另一个经验是Agentic RAG 不是银弹。它引入了额外的模型调用次数延迟会成倍增长Token 消耗也会增加。如果知识库内容本身组织得好、问题结构单一Naive RAG 反而更实用。先跑通 Naive RAG 并完善评测基线再考虑要不要升级 Agentic这顺序才是对的而不是一上来就追求“高级”。8. 评测体系没有指标的 RAG都是玄学调参图 13 是 RAG 评测指标体系的全景也是这 13 张图里我认为最重要的一张。它把评测分成三层检索质量、生成质量、整体体验。8.1 检索层指标Hit Rate 与 MRR 怎么算检索层最核心的是命中率Hit Rate和平均倒数排名MRR。Hit Rate 的计算是测试集里正确答案出现在 TopK 检索结果中的问题数量除以总问题数量。它关心的是“有没有找回来”。MRR 的计算则进一步看“找回来的位置靠不靠前”如果正确答案排在第 1得 1 分排在第 2得 0.5 分排在第 3得 0.33 分最后取平均。举个具体例子你有 3 个测试问题。问题一正确答案排第 1问题二排第 3问题三没有命中。那么 Hit Rate 是 2/3 等于 0.67MRR 是 (1 0.33 0)/3 约等于 0.44。两个指标要配合看Hit Rate 高但 MRR 低说明正确答案虽然找回来了但排名太靠后可能需要引入重排或者调整切片策略Hit Rate 低则说明根本的问题可能出现在“没检索到正确的文档”要从数据侧和 embedding 模型侧入手。8.2 生成层指标忠实度与回答相关性生成层我重点关注两个忠实度Faithfulness和回答相关性Answer Relevance。忠实度用来衡量“生成的回答是否被检索到的上下文支撑”。一个常见测法是把生成的回答逐句拆开再用另一个大模型判断每个句子能否从上下文里找到依据。如果回答里有一句话在检索片段里根本找不到出处那这句话就是模型凭空编的忠实度就会被扣分。回答相关性用来衡量“生成的回答和用户问题的相关程度”。这个指标主观性较强我在实践中通常用一个大模型打分同时配合人工抽检双重校验。8.3 自建评测集不需要 1000 条50 条高质量的就够用很多团队一听说要建评测集就头大想着怎么也得弄几百上千条。我的经验是初始评测集只需要 50 条左右高质量问题关键是覆盖不同场景。我把评测集按四类划分问题类型示例预期单点事实型公司年假制度是多少天答案单一且明确多步骤推理型部门请假需要经过哪些审批需要多个文档共同支撑模糊表达型我最近忙怎么休息需要理解“休息”指请假否定排除型哪些情况不能休年假能正确给出排除条件把这个问题集存成一个 JSON 文件每条记录包含问题、期望的答案关键词、期望来源文档。评测脚本循环调用检索接口计算 Hit Rate 和 MRR核心逻辑用 Python 几十行就够了import json import requests import numpy as np with open(eval_set.json, r, encodingutf-8) as f: eval_set json.load(f) def hit_rate_sample(result, expected_keywords): for kw in expected_keywords: if kw in result[content]: return True return False def mrr_sample(results, expected_keywords): for idx, r in enumerate(results, start1): if any(kw in r[content] for kw in expected_keywords): return 1.0 / idx return 0.0这个脚本的意义在于它把你的 RAG 效果变成了一组可追踪的数字。你调整任何参数后重新跑一遍就能立刻看到指标涨跌而不是靠“感觉这轮回答顺眼多了”。8.4 评测结果怎么指导调参我积累了一套大致的调参路径写在下面供你参考Hit Rate 低先看是不是文档没被正确索引、切片是否切断了关键信息再考虑调大 TopK最后才考虑更换 Embedding 模型。MRR 低说明命中了但排位太后。优先加 Rerank 重排或者缩小 chunk size让相似度更聚焦。忠实度低生成模型添油加醋了。优化 Prompt 中“不要编造”的约束力度或者在生成后接一个事实校验环节。回答相关性低检索结果本身没问题但大模型没抓准用户意图。尝试在系统 Prompt 中加入“围绕问题本身作答不要展开无关内容”之类的限定。这套路径帮我处理过至少三个项目的调优基本都是 2 到 3 轮能收敛。9. 我踩过的坑以及优化优先级分享我最后分享几个在实际项目中高频踩中的问题每个后面都跟着我最终采用的解法希望能帮你绕开同样的问题。9.1 元数据丢失导致答案无法溯源有一次线上反馈说回答质量没问题但引用出处对不上。查了半天发现是导入文档时只存了文本和向量没有给 Document 的 metadata 写入来源信息结果所有 chunk 混在一起根本分不清来自哪份文档。解法很简单就是前文提到的那句chunk.getMetadata().put(source, filePath)但是加上之后整个系统的可追溯性立刻不一样了。9.2 多轮对话里的检索上下文跑偏当用户问完“年假制度是什么”之后紧接着问“那我能不能拆开休”模型很容易把第二个问题单独拿去检索结果搜出来一堆无关内容。更合理的方案是把历史对话和当前问题一起压缩成一个“检索查询”让向量检索上下文更完整。但要注意不能把整段历史都丢进检索查询里否则检索结果会被噪声干扰。我现在的做法是用模型把最近两轮对话改写成一个独立的检索语句再拿这个语句去检索实测效果稳定很多。9.3 检索结果重复度过高的应对还有一种常见情况是向量库里有大量来自同一文档的相似片段检索出来的 TopK 结果里五条有三条都在重复讲同一件事。这会让大模型忽略掉真正必要的信息。我通常在管道中加入一个去重步骤按来源文档分组每组最多取前 N 个片段。9.4 不同问题类型采用不同检索策略常规问答、对比分析、多级文档引荐这三种问题适合的检索策略并不相同。我目前在接口入参里增加了一个queryType字段前端根据用户在选择框里的选择来传普通问答走固定 TopK 与固定阈值对比类问题走更高 TopK 再分组去重复合文档检索问题则走“先拆子问题再聚合”的 Agentic 路径。这套架构让每个问题类型都能使用更匹配的配置整体指标比一把梭的方式提升了不止一点。9.5 我自己的优化优先级排序如果让我只保留三条建议我会这样排序第一把评测集建好哪怕是 30 条问题先用数字把你当前的效果钉死第二把元数据和切片做好这是数据侧的根基数据乱了一切优化都是空谈第三再考虑换模型、调 TopK、加 Agentic 这些“上层建筑”。我的习惯是每次改完参数都把评测脚本重跑一遍记录当时的指标数值和改了什么参数。这样攒上几轮你会惊讶地发现你对自己系统的理解远远超过那些凭感觉调参的人。这也是我从“跑通 demo”走向“交付可用系统”之间最关键的一步。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

马德拉:一座岛、一杯酒,同名背后的旅行与品鉴指南 2026/10/1 14:08:55

马德拉:一座岛、一杯酒,同名背后的旅行与品鉴指南

我第一次记住“马德拉”这个名字,不是在地图上,不是在任何攻略里,而是被一位老旅人用小圆杯推过来的那口琥珀色液体。他当时的原话是:“这杯东西在海上放几年都不会坏,你尝尝,有股烤坚果的味道。”后来我真…

阅读更多 →
Model-Optimizer:四层协同的模型瘦身与推理加速实战框架 2026/10/1 14:08:55

Model-Optimizer:四层协同的模型瘦身与推理加速实战框架

1. 项目概述:这不是一个“一键压缩”的玩具,而是一套模型瘦身的手术刀系统 “Model-Optimizer”这个名字乍一听像某个商业软件的副标题,或者某家AI公司刚发布的营销概念。但在我过去三年深度参与十几个工业级模型部署项目的实操经验里&#x…

阅读更多 →
TypeSafe AI与Vercel AI Gateway:Jev如何重塑Agent工程化落地 2026/10/1 14:08:55

TypeSafe AI与Vercel AI Gateway:Jev如何重塑Agent工程化落地

1. 从“13% 付费团队连夜迁移”说起:Jev 到底踩中了什么痛点先把结论摆在前面:Jev 这类工具能在 24 小时内撬动 13% 的付费团队迁移,靠的不是某个炫技的模型参数,而是它把“类型安全”和“AI 网关”这两件原本割裂的事&#xff0c…

阅读更多 →
马德拉深度徒步指南:Levada水渠与火山脊线七日行程全解析 2026/10/1 14:08:54

马德拉深度徒步指南:Levada水渠与火山脊线七日行程全解析

马德拉这个名字,放在欧洲旅行圈里可是个重量级选手。这座葡萄牙的大西洋离岛,常被人叫“永春之岛”或“大西洋明珠”,几乎一年到头都卡在十八到二十五摄氏度的舒适带里,冬天不像冬天,夏天也没酷暑压迫感。我这次以一周…

阅读更多 →
死锁四条件与STL线程安全:从锁冲突到并发排查实战 2026/10/1 14:08:54

死锁四条件与STL线程安全:从锁冲突到并发排查实战

死锁四条件这个话题,聊的人很多,但大部分讨论都停留在“背概念”的层面。只要在Linux下写过一阵子多线程C服务,多少都会遇到锁冲突把系统拖“假死”的场面,也会被STL容器的线程安全问题坑过几回。四条件谁都能背——互斥、持有并等…

阅读更多 →
Windows浏览器强制使用独立显卡的硬核指南 2026/10/1 14:08:48

Windows浏览器强制使用独立显卡的硬核指南

1. 项目概述:为什么笔记本用户必须关心浏览器的显卡调度? 你有没有遇到过这样的场景:刚接上4K外接显示器,打开Edge看高清视频,风扇突然狂转,屏幕偶尔卡顿,任务管理器里GPU占用率却只有15%&#…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉