1. 从“Jev 爆火”说起为什么我要把 System One 判断下沉搬进自己的 AI AgentJev 那套东西火起来的时候我正蹲在自己写的 AI Agent 项目里调一个让人头大的问题工具调用链路一长模型就开始“想太多”。明明只是查个天气它非要先规划三步、再反思两轮、最后还给自己加个总结延迟直接飙到十几秒。Jev 的爆火让我重新审视了一个被很多人忽略的点——不是所有判断都值得交给大模型。所谓“System One 判断下沉”说白了就是把那些高频、低复杂度、规则明确的判断从大模型的推理链路里拿出来下沉到代码层、规则层甚至本地小模型层去处理。System One 这个词借的是认知科学里的概念指的是人类那种快速、直觉、几乎不费力的判断对应的 System Two 则是慢速、理性、需要专注的深度思考。放到 AI Agent 里大模型就是那个 System Two而我们要做的是把一部分 System One 的活儿从它手里抢回来。我自己的开源 AI Agent 项目原本是个典型的“全交给模型”架构用户输入进来先过一遍意图识别再让模型决定调哪个工具工具返回后再让模型总结。这套东西 demo 阶段很惊艳一旦并发上来、任务变杂问题就全暴露了。Jev 的思路给了我一个很实在的启发判断下沉不是降级而是分层。把简单判断放在便宜、快、稳的地方把复杂推理留给真正需要它的场景。这篇文章我会完整拆解我是怎么把这套思想落地到自己项目里的包括架构怎么改、判断怎么分层、代码怎么写、并发怎么扛、踩了哪些坑。适合正在搭 AI Agent、被延迟和成本折磨、或者单纯想让自己项目更“扛造”的开发者参考。不管你是用 LangChain、Spring AI 还是自己手搓这套分层判断的思路都能直接抄。2. 判断下沉到底在解决什么问题先看清 AI Agent 的真实瓶颈2.1 全交给大模型的三个致命伤我最初的项目架构特别“纯粹”所有决策都走大模型。用户说“帮我看看明天北京天气”流程是这样的——模型先判断这是天气查询意图再决定调用天气工具工具返回 JSON 后模型再组织语言输出。听起来很合理但实测下来有三个问题躲不掉。第一是延迟不可控。一次完整的工具调用链路模型至少要跑两轮一轮决策、一轮总结。每轮按 2 到 5 秒算加上工具本身的网络耗时单次请求轻松突破 8 秒。用户等 8 秒查个天气体验直接崩了。第二是成本线性上涨。每一轮模型调用都是真金白银意图识别这种本该几毫秒搞定的事非要塞几千 token 的上下文进去让模型“思考”纯属浪费。并发一上来账单涨得比用户还快。第三是稳定性差。模型输出有随机性同样的输入今天判断对、明天可能就抽风。意图识别这种确定性极强的任务交给概率模型本身就是错配。2.2 System One 与 System Two 的分工逻辑判断下沉的核心是承认一件事Agent 的判断天然分两层。一层是快判断比如“这句话是不是在问天气”“这个参数是不是数字”“用户是不是在打招呼”另一层是慢判断比如“用户这句话背后真正想要什么”“这个多步骤任务该怎么拆解”“工具返回结果矛盾时该信谁”。快判断的特征是规则明确、输入输出可枚举、容错率低但复杂度低。这类判断下沉到代码层用 if-else、正则、关键词匹配、本地小模型就能搞定耗时从秒级降到毫秒级。慢判断才留给大模型让它专注做它真正擅长的事。我做过一个粗略统计在我项目的真实请求里大约65% 的判断属于 System One 级别。也就是说只要把这部分下沉整体延迟和成本能直接砍掉一大半。这个比例因项目而异但只要你做的是面向真实用户的 Agent快判断占比一定不低。2.3 下沉不等于阉割边界在哪里这里必须说清楚一个误区判断下沉不是把所有判断都写成硬编码规则。那样做出来的东西是“伪 Agent”稍微超出规则就废了。下沉的边界在于——只下沉那些确定性强、可枚举、错了代价可控的判断。举个例子“用户是不是在问天气”可以下沉因为关键词和句式相对固定但“用户问天气是想出门还是想吐槽”就不能下沉这需要理解语境和情绪。再比如“工具返回的 JSON 里 temperature 字段是不是数字”可以下沉“这个温度数据是否合理”就得看情况简单范围校验可以下沉异常归因就得交给模型。我给自己定的原则是能用规则覆盖 90% 以上情况的判断就下沉覆盖率低于 70% 的留给模型。这个阈值不是拍脑袋是实测出来的——覆盖率太低的下沉规则会频繁 fallback 到模型反而增加一次额外调用得不偿失。3. 我的分层判断架构从“全模型”到“三层漏斗”3.1 整体架构设计改造后的架构是一个三层漏斗请求从上游进来逐层过滤越往后越“重”。第一层是规则层纯代码实现处理关键词匹配、正则校验、参数格式检查这类确定性判断。耗时在毫秒级零模型成本。第二层是本地小模型层跑一个轻量级的分类模型处理规则覆盖不了的意图识别和简单分类。耗时几十毫秒成本几乎为零。第三层才是大模型层处理复杂推理、多步规划、结果总结这些真正需要“思考”的任务。请求进来先过规则层命中就直接返回或路由没命中进小模型层分类置信度够高就按分类结果走置信度低或者任务本身复杂才升级到大模型层。每一层都有明确的“升级条件”避免请求在某一层卡死或者被错误处理。这套架构的关键不是层数多而是每层的职责边界清晰。规则层只做它确定能做的事绝不越界小模型层只做分类不做生成大模型层拿到的是已经被“预处理”过的干净输入推理效率也更高。3.2 规则层把确定性判断压到毫秒级规则层是我花时间最多的地方因为它直接决定了整体性能上限。我的做法是把规则层拆成三个子模块意图关键词库、参数校验器、路由表。意图关键词库维护的是“什么词触发什么意图”的映射。比如“天气”“气温”“下雨”触发天气查询意图“汇率”“换算”“美元”触发汇率意图。这里有个技巧不要用单一关键词匹配要用关键词组合加权重。比如“北京 天气”权重高于单独的“天气”避免“天气真好”这种闲聊被误判成查询。参数校验器负责检查工具调用所需的参数是否齐全、格式是否正确。比如天气查询需要城市名如果用户输入里提取不到城市直接在这一层返回“请补充城市”不用惊动模型。这一步能挡掉大量无效请求。路由表则是把意图映射到具体工具或处理函数。命中意图后直接路由省掉模型决策环节。# 规则层核心逻辑示意 INTENT_RULES { weather: { keywords: [天气, 气温, 下雨, 温度], required_params: [city], handler: weather_tool }, exchange_rate: { keywords: [汇率, 换算, 美元, 人民币], required_params: [from_currency, to_currency], handler: exchange_tool } } def rule_layer(user_input: str): for intent, rule in INTENT_RULES.items(): hit_count sum(1 for kw in rule[keywords] if kw in user_input) if hit_count 1: params extract_params(user_input, rule[required_params]) if all(params.values()): return {intent: intent, params: params, layer: rule} return None # 未命中升级到下一层这段代码看着简单但实测能挡掉我项目里40% 左右的请求。关键是关键词库要持续维护把线上真实请求里高频的表达补进去。3.3 本地小模型层规则兜不住的交给它规则层没命中的请求进本地小模型层。我用的是一个蒸馏过的文本分类模型参数量控制在几千万级别跑在 CPU 上单次推理 30 到 50 毫秒。它的任务只有一个把用户输入分类到预定义的意图类别里并给出置信度。为什么不用大模型做这件事因为意图分类本质是个分类任务不是生成任务。分类任务用小模型完全够用而且小模型输出稳定、延迟低、成本几乎为零。我训练这个分类模型用的是项目积累的真实请求日志标注了十几个意图类别准确率能到 92% 左右。置信度阈值我设的是 0.85。高于这个值直接按分类结果路由低于这个值说明模型也不确定升级到大模型层。这个阈值调过几轮太低会导致误分类太高会导致大量请求升级最后定在 0.85 是个平衡点。def small_model_layer(user_input: str): intent, confidence classifier.predict(user_input) if confidence 0.85: return {intent: intent, confidence: confidence, layer: small_model} return None # 置信度不足升级到大模型这一层能再挡掉大约25% 的请求。加上规则层整体已经有 65% 的请求不用碰大模型了。3.4 大模型层只做真正需要“思考”的事剩下 35% 的请求进大模型层。这些请求要么是复杂多步任务要么是规则和小模型都拿不准的模糊输入。大模型层拿到的不再是原始用户输入而是经过前两层预处理的信息——已经知道大概意图、已经提取了部分参数模型只需要做它真正擅长的推理和生成。这个改动带来的效果很明显。以前模型要从零开始理解用户输入现在它拿到的是“半成品”推理步数少了输出也更稳定。我实测下来大模型层的平均响应时间从改造前的 6 秒降到了 3.5 秒左右因为模型不用再花时间做那些本该下沉的判断。更重要的是大模型层的调用量降了 65%成本直接砍掉一大半。并发能力也跟着上来了因为大部分请求在前两层就被消化了不会堆积到大模型层形成瓶颈。4. 实操落地从零改造一个 AI Agent 的完整过程4.1 第一步梳理你的判断清单改造之前我做的第一件事是把项目里所有的“判断点”列出来。所谓判断点就是代码里任何一处“根据输入决定下一步做什么”的地方。我列了大概三十多个然后逐个标注这个判断的输入是什么、输出是什么、复杂度如何、错了会怎样。列完之后你会发现真正需要大模型的判断其实没几个。大部分判断都是“这句话是不是在问 X”“这个参数是不是合法”“这个结果是不是空”这类确定性极强的事。把这些挑出来就是下沉的候选。我建议你用一个表格来管理这个清单字段包括判断名称、当前实现方式、复杂度评级、下沉可行性、下沉后预期收益。复杂度评级用高/中/低三档下沉可行性也用三档优先下沉“复杂度低可行性高”的判断。判断名称当前实现复杂度下沉可行性预期收益意图识别大模型中高延迟降 3s参数校验大模型低高成本降 30%结果总结大模型高低保留多步规划大模型高低保留空结果处理大模型低高延迟降 2s这张表是我改造的路线图按优先级逐个击破。4.2 第二步搭建规则层的关键词体系规则层的核心是关键词体系这东西没有捷径只能靠积累。我的做法是先从项目历史日志里挖高频表达用脚本统计每个意图下出现频率最高的词和短语然后人工筛选出真正有区分度的。这里有个坑要避开不要用太宽泛的词做关键词。比如“查”这个字几乎什么查询都能匹配放进去只会造成误判。关键词要选那些“出现即大概率是这个意图”的词。我一般要求单个关键词的意图区分度在 80% 以上才纳入。关键词体系建好后还要定期维护。用户表达是会变的新词、网络用语、缩写层出不穷。我设了个简单的机制每周看一次规则层未命中的请求把高频的新表达补进关键词库。这个维护成本不高但效果立竿见影。4.3 第三步训练本地小模型本地小模型这块如果你不想自己训练可以直接用现成的轻量级分类模型微调。我用的是 Hugging Face 上的一个中文小模型在自己标注的数据集上微调了几轮。数据集规模不用很大每个意图类别几百条样本就够关键是标注要准。训练的时候有个经验负样本很重要。所谓负样本就是那些“看起来像某个意图但其实不是”的输入。比如“天气真好”看起来像天气查询其实是闲聊。把这类样本标进去模型才能学会区分。我一开始没注意这点模型把大量闲聊误判成查询后来补了负样本才好转。模型训练完要评估重点看两个指标准确率和置信度分布。准确率决定它能不能用置信度分布决定阈值怎么设。如果模型在正确分类时置信度普遍很高阈值就可以设高一点减少升级到大模型的请求如果置信度普遍偏低说明模型不够自信阈值要相应调低。4.4 第四步设计升级与降级机制三层之间要有清晰的升级和降级机制。升级是指请求从低层往高层走降级是指高层处理不了时回退。我的设计是规则层未命中升级到小模型层小模型层置信度不足升级到大模型层大模型层如果判断这个请求其实很简单可以记录日志用于后续优化规则。升级机制的关键是避免无限循环。我见过有人设计成“大模型判断不了就回退到规则层”结果请求在层间来回跳延迟爆炸。正确做法是单向升级大模型层是终点它处理不了就返回兜底回复不再往下传。降级机制主要用于容错。比如小模型服务挂了请求直接跳过它进大模型层保证服务可用。这种降级要有监控告警不能默默降级没人知道。4.5 第五步压测与调优改造完成后必须压测。我用 Locust 模拟了 500 并发对比改造前后的数据。改造前平均响应时间 7.8 秒改造后降到 2.9 秒改造前大模型调用占比 100%改造后降到 34%改造前单请求平均成本 0.012 元改造后降到 0.004 元。压测的时候要重点看各层的分流比例。如果规则层分流比例远低于预期说明关键词体系没建好如果小模型层分流比例低说明置信度阈值设太高或者模型不够准。这些都要根据压测数据回头调。调优是个持续过程不是一次搞定。我上线后又根据真实流量调了两轮阈值和关键词分流比例才稳定下来。5. 并发场景下的判断下沉为什么这套架构更扛造5.1 并发瓶颈到底在哪一层AI Agent 扛并发瓶颈几乎永远在大模型层。大模型调用是网络 IO 加 GPU 计算单次耗时秒级并发一上来请求就排队。规则层和小模型层是本地计算耗时毫秒级并发能力比大模型层高几个数量级。所以扛并发的核心思路就是把请求尽量往前两层赶让大模型层只处理真正必要的请求。我改造后大模型层只承接 34% 的流量等于同样的 GPU 资源能扛三倍的并发。这个提升不是靠加机器是靠架构分层省出来的。5.2 各层的并发处理策略规则层是纯 CPU 计算无状态直接水平扩展就行。我把它做成无状态服务前面挂负载均衡加机器就能加并发。单机 QPS 能到几千完全不是瓶颈。小模型层稍微重一点但也是 CPU 推理单机 QPS 几百没问题。如果并发再高可以用批处理——把多个请求攒一小批一起推理吞吐能再提几倍。批处理窗口设 10 到 20 毫秒对延迟影响很小但吞吐提升明显。大模型层是瓶颈策略是限流加排队。我给它设了并发上限超过的请求进队列等待而不是直接打爆。队列要有超时等太久就返回兜底回复避免用户无限等待。同时监控队列长度持续过长就告警说明该扩容或者该优化前两层分流了。5.3 实测并发数据我用 500 并发压了 10 分钟改造前后的对比数据如下。指标改造前改造后平均响应时间7.8s2.9sP99 响应时间15.2s6.1s大模型调用占比100%34%单请求平均成本0.012 元0.004 元最大稳定 QPS45130最大稳定 QPS 从 45 提到 130接近三倍。这个数据是在同样硬件配置下测的提升完全来自架构优化。6. 踩过的坑与排查实录判断下沉不是银弹6.1 规则层误判关键词太宽泛的代价我最早的关键词库里有个词叫“查”本意是匹配查询类意图。结果上线后发现“我查过了”“查不到”这类表达全被误判成查询请求规则层分流比例虚高但准确率惨不忍睹。后来把“查”删掉换成更具体的组合词误判才降下来。这个坑的教训是关键词的区分度比覆盖率重要。宁可漏掉一些请求让它们升级到下一层也不要为了覆盖率塞进宽泛词造成误判。误判的代价比漏判高得多因为误判会直接给用户错误结果。6.2 小模型置信度虚高训练数据不均衡的锅小模型上线初期我发现它对某个意图的置信度总是特别高但准确率很低。排查后发现是训练数据不均衡——那个意图的样本特别多模型学会了“无脑猜这个意图”也能拿高置信度。解决办法是给样本少的类别做数据增强同时调整损失函数让模型不能靠猜多数类蒙混过关。6.3 升级机制死循环一次请求跑了三层有次线上出现极端情况一个请求在规则层没命中到小模型层置信度不够升级到大模型层大模型层判断这其实是个简单请求又建议回退到规则层处理。结果请求在层间来回跳延迟飙到几十秒。后来改成单向升级大模型层是终点才解决这个问题。6.4 常见问题速查表问题现象可能原因排查方向解决方法规则层分流比例低关键词覆盖不足看未命中请求的高频词补充关键词库规则层误判多关键词太宽泛看误判请求的共同特征删宽泛词加组合词小模型置信度虚高训练数据不均衡看各类别样本量数据增强调损失函数请求层间循环升级机制设计错误看请求在各层的流转日志改单向升级大模型层仍拥堵前两层分流不够看各层分流比例优化前两层或扩容7. 这套思路还能怎么扩展判断下沉这套东西落地之后我发现它的价值不止于降延迟和成本。它其实改变了整个 Agent 的设计哲学——从“让模型做所有事”变成“让合适的层做合适的事”。这个思路可以往几个方向继续延伸。一个方向是把下沉层做得更智能。现在规则层是硬编码的未来可以用规则挖掘算法从日志里自动发现规则减少人工维护。小模型层也可以持续用线上数据迭代越用越准。另一个方向是把下沉思想用到更多环节。不只是意图识别和参数校验工具选择、结果格式化、错误处理这些环节都可以分层。我现在正在把工具选择也下沉用规则加小模型先筛一遍候选工具再让大模型做最终决策。还有个方向是跨项目复用。这套分层架构其实是通用的任何 AI Agent 都能用。我打算把它抽成一个独立的库让其他项目直接接入。如果你也在做类似的事欢迎一起交流这块的坑我基本都踩过了。最后分享一个我自己的体会判断下沉最难的不是技术是克制。看到大模型什么都能做很容易什么都交给它。但真正做过线上项目就知道能下沉的判断不下沉就是在给自己埋雷。把简单的事交给简单的层把复杂的事留给模型这才是 Agent 该有的样子。