
1. 从“能跑通”到“敢上生产”知识库与 Agent 网关的优化起点做知识库和 Agent 网关这件事最坑的地方从来不是“搭不起来”而是“搭起来之后不敢用”。我见过太多团队Demo 阶段用几十份文档跑得飞起一上生产、文档量过万、并发上来、用户开始问刁钻问题整个系统就开始胡言乱语、超时、串味、答非所问。最近我花了两周时间把手上这套生产级知识库和 Agent 网关从头到尾捋了一遍重点不是加功能而是把“匹配度”和“稳定性”这两个要命的东西抠出来。先说清楚这套东西是什么。知识库说白了就是把企业内部的文档、Wiki、工单、产品手册这些非结构化内容经过切分、向量化之后存起来让大模型在回答问题时能“查资料”而不是“瞎编”。Agent 网关则是横在用户请求和底层模型、工具之间的那一层调度中枢负责路由、鉴权、限流、上下文拼装、工具调用编排。两者合在一起才构成一个能对外服务的智能问答或任务执行系统。这套东西适合谁看如果你正在用 Dify、RAGFlow、FastGPT 这类平台搭知识库或者自己用 LangChain、LlamaIndex 手搓 RAG 流水线又或者你正在为多个 Agent 做统一入口那这篇东西应该能帮你少踩几个坑。我不打算讲“什么是 RAG”这种入门内容直接进入优化现场讲我实际改了什么、为什么这么改、改完效果如何。2. 知识库检索质量优化匹配度上不去的根因拆解2.1 为什么你的知识库“答非所问”匹配度差九成以上的问题不在模型而在检索环节。我排查过的一个典型案例用户问“报销流程要几天”系统返回的是“差旅报销标准”那一段因为两段文本都包含“报销”这个词向量距离也接近但语义上一个是问时效、一个是讲金额标准。这就是典型的语义漂移。根因通常有三层。第一层是切分粒度不对。很多人图省事按固定 512 token 切结果一个完整的流程被切成三段每段都缺关键信息。第二层是 embedding 模型选型与业务语料不匹配通用模型对行业术语的区分度不够。第三层是只做了向量检索没有做关键词召回和重排导致“看起来像”但“实际不对”的结果排到了前面。我的处理方式是引入混合检索 重排。混合检索就是向量召回和 BM25 关键词召回并行各取 Top-K然后合并去重。重排则用一个 cross-encoder 模型对候选集重新打分。实测下来在同样 200 条测试 query 上纯向量检索的 Top-3 命中率是 61%加上 BM25 混合后到 74%再加重排能到 86%。这个提升是实打实的不是调参调出来的虚数。2.2 切分策略别让固定长度毁掉语义完整性切分这件事我的经验是按结构切不按长度切。Markdown 文档按标题层级切PDF 按段落和表格边界切代码文档按函数块切。如果文档本身没有结构那就用语义切分让模型判断句子之间的语义边界而不是硬性按 token 数截断。具体操作上我设置了一个滑动窗口重叠重叠比例控制在 15% 到 20%。比如一个 chunk 是 400 token那相邻 chunk 之间重叠 60 到 80 token。这样做的目的是防止关键信息刚好落在切分边界上被割裂。代价是存储量增加但相比答错的代价这点存储成本可以忽略。还有一个细节给每个 chunk 加上元数据。来源文档名、章节标题、更新时间、文档类型这些都要带上。检索时可以先按元数据过滤再做向量匹配。比如用户问的是“2025 年新政策”那 2023 年的文档就不该进候选集。这个过滤动作能把无效召回砍掉一大半。2.3 Embedding 模型选型别迷信榜单看你的语料选 embedding 模型我的原则是用业务语料做小规模评测不看公开榜单。公开榜单上的语料是通用领域的你的业务可能是农业、医疗、法律、制造分布完全不一样。我一般会从业务文档里抽 100 到 200 对“问题-正确段落”然后跑几个候选模型看 Recall5 和 MRR。国内环境下BGE 系列和 M3E 系列是比较稳的选择中文语义区分度好部署也方便。如果追求更高精度且资源允许可以用 bge-large 或 bge-m3后者支持多语言和长文本。但要注意模型越大推理越慢生产环境要权衡延迟。我现在的配置是检索用 bge-base 保证速度重排用 bge-reranker-large 保证精度两级分工效果和延迟都能接受。注意embedding 模型一旦确定后续所有文档的向量化都必须用同一个模型。中途换模型意味着全量重建索引这个成本要提前算进去。3. Agent 网关的核心设计路由、限流与上下文管理3.1 网关到底该管什么Agent 网关不是简单的反向代理。它要管的事情包括请求鉴权、模型路由、限流熔断、上下文拼装、工具调用编排、日志追踪。我见过有人把网关写成一个大 if-else根据用户 ID 硬编码走哪个模型这种写法在 Agent 数量超过五个之后基本没法维护。我的设计是配置驱动 插件化。路由规则写在配置里比如“知识库问答类请求走 RAG 链路代码生成类请求走代码模型翻译类请求走轻量模型”。每个链路是一个插件网关只负责按规则分发和收集结果。这样加一个新 Agent只需要加一份配置和一个插件不用动核心代码。限流这块我用的是令牌桶 并发信号量双保险。令牌桶控制 QPS信号量控制同时处理的请求数。为什么要两个因为有些请求虽然 QPS 不高但单个请求耗时长会把连接池占满。信号量能防止这种情况。实测下来单实例在 4 核 8G 的机器上稳定支撑 50 并发、200 QPS 没问题。3.2 上下文拼装别把整个知识库塞进 Prompt上下文拼装是网关最容易被忽视但最影响效果的部分。很多人检索出 10 个 chunk一股脑全塞进 Prompt结果模型被无关信息干扰反而答不好。我的做法是分级拼装Top-3 的 chunk 完整放入第 4 到第 6 的只放摘要或首句第 7 以后直接丢弃。同时我会在 Prompt 里明确标注每个 chunk 的来源和边界比如用[文档1报销制度第3节]这样的标记。这样模型在引用时能准确指向来源用户也能追溯。还有一个技巧把最相关的 chunk 放在 Prompt 的开头和结尾因为模型对首尾位置的注意力更强中间容易丢失。这个是我从多次 A/B 测试里总结出来的不是理论推导。3.3 工具调用的编排与容错Agent 网关经常要调用外部工具比如查数据库、调 API、执行代码。工具调用最大的风险是超时和失败。我的处理是每个工具调用都设超时默认 5 秒超时后走降级逻辑。降级不是简单报错而是返回一个“当前无法获取实时数据以下是基于知识库的回答”这样的兜底话术。另外工具调用的结果要做格式校验。我遇到过 API 返回了 HTML 错误页而不是 JSON结果整个链路崩掉。现在每个工具调用后都会校验返回结构不符合预期就当作失败处理。这个校验逻辑写在网关层不依赖上游工具自己保证。4. 生产环境实操从部署到调优的完整链路4.1 部署架构与资源规划我的部署架构是三层分离网关层、检索层、模型推理层。网关层无状态可以水平扩展检索层包含向量库和关键词索引用主从架构保证可用性模型推理层用 GPU 节点按需扩缩容。资源规划上向量库的内存占用是大头。以 100 万条 chunk、每条 768 维向量为例原始向量数据约 3GB加上索引开销实际内存占用在 6 到 8GB。如果 chunk 数量到 500 万内存需求就上到 30GB 以上。这个要提前算好别等 OOM 了才加内存。模型推理这边7B 级别的模型用一张 24G 显存的卡能跑但并发高了延迟会上去。我的经验是单卡并发控制在 8 到 12 路超过就排队。如果延迟要求严格就得多卡或者用更小的模型。4.2 索引构建与增量更新全量构建索引是个体力活。100 万条 chunk用 bge-base 做向量化单卡大概要 2 到 3 小时。这期间服务不能停所以我的做法是双索引切换新索引在后台构建构建完成后原子切换旧索引保留一段时间做回滚。增量更新更麻烦。文档改了对应的 chunk 要重新向量化旧向量要删除。我用的是软删除 定期压缩删除时只标记不立即物理删除等积累到一定量再统一压缩索引。这样避免频繁的索引重建性能更稳。提示增量更新时要注意 chunk ID 的生成规则。如果 ID 是基于内容哈希生成的内容一变 ID 就变旧记录就成了孤儿。建议用“文档ID 章节路径 序号”作为稳定 ID。4.3 监控指标与告警设置生产环境没有监控就是裸奔。我重点盯四个指标检索命中率、端到端延迟、工具调用失败率、模型输出异常率。检索命中率通过人工标注的测试集定期跑延迟和失败率实时监控输出异常率用规则加模型双重判断。告警阈值我设的是P99 延迟超过 8 秒告警工具调用失败率超过 5% 告警检索命中率周环比下降超过 10% 告警。这些阈值是根据业务容忍度定的不是拍脑袋。比如延迟用户能接受的最长等待大概是 10 秒超过就会关页面所以 8 秒是个合理的预警线。5. 常见问题与排查技巧实录5.1 检索相关高频问题问题现象可能原因排查方法解决方案返回结果与问题无关切分粒度过大或过小抽查 chunk 内容是否完整调整切分策略增加重叠相同问题每次答案不同检索结果不稳定检查是否有随机采样固定检索参数关闭随机性专业术语检索不到embedding 模型不匹配用术语做专项测试换模型或加关键词召回新文档检索不到索引未更新检查增量更新日志手动触发重建或修复更新链路5.2 Agent 网关高频问题网关这边最常见的是超时和串话。超时通常是下游模型或工具响应慢排查时先看是模型推理慢还是工具调用慢分别处理。串话则是上下文隔离没做好多个用户的请求混在一起。这个问题的根因往往是用了全局变量或者共享缓存没加用户隔离。我的做法是每个请求一个独立的上下文对象从入口传到出口不依赖任何全局状态。还有一个坑是流式输出的中断处理。用户关了页面但后端还在生成浪费资源。我在网关层加了连接状态检测客户端断开就取消下游任务。这个逻辑不难但很多人忘了做。5.3 独家避坑技巧第一个技巧给检索结果加“置信度”标记。如果 Top-1 和 Top-2 的分数差距很小说明检索结果不确定这时候应该让模型回答“我不确定”或者触发人工兜底而不是硬答。这个阈值我设的是分数差小于 0.05 就标记为低置信。第二个技巧定期做“对抗测试”。我每周会构造一批刁钻问题比如同义词替换、否定句、多跳推理看系统能不能扛住。这些问题不放进训练集纯粹用来发现薄弱环节。实测下来这个习惯帮我提前发现了至少三个重大缺陷。第三个技巧日志要记录完整链路。从用户 query 到检索结果、到 Prompt 拼装、到模型输出每一环都要留痕。出问题时能快速定位是哪一环出的错。我用的是一套 trace ID 贯穿全链路查起来很方便。6. 效果验证与持续迭代优化做完怎么验证效果我用的是离线评测 在线 A/B双轨。离线评测用标注好的测试集看命中率、准确率、召回率。在线 A/B 则是把新旧两套系统同时跑看用户的实际反馈比如追问率、点赞率、会话时长。实测数据上这轮优化后检索 Top-3 命中率从 61% 提到 86%端到端 P99 延迟从 12 秒降到 6.8 秒工具调用失败率从 8% 降到 2.3%。用户追问率下降了 35%说明一次答对的概率明显提升。迭代节奏上我保持每周一次小优化每月一次大版本。小优化就是调参数、补文档、修 bug大版本则是架构调整或模型替换。这个节奏既能持续改进又不会因为频繁变更导致系统不稳定。最后分享一个我在实际操作中的体会知识库和 Agent 网关的优化八成精力应该花在数据和检索上而不是模型上。我见过太多团队花大价钱换更大的模型结果检索出来的东西就是错的模型再强也救不回来。把切分做好、把混合检索做好、把重排做好用中等规模的模型就能达到很好的效果。这个顺序不能反。