
1. 从“什么都问大模型”说起Agent 设计的核心误区做 Agent 开发的人几乎都经历过一个阶段手里有了一个能力还不错的大模型就恨不得把所有的判断、决策、执行都塞进 prompt 里让模型一次性搞定。我最早做 Agent 项目的时候也是这样一个请求进来先让模型理解意图再让模型规划步骤再让模型决定调哪个工具再让模型解析工具返回结果最后让模型生成回复。整条链路下来一次用户交互可能要调用五六次大模型延迟高得离谱成本也压不住而且稳定性极差——模型稍微“发挥”一下整个流程就崩了。这个问题的本质其实不是模型不够强而是我们把不该交给大模型的事情也交给了它。大模型擅长的是语义理解、模糊匹配、自然语言生成这类“软”任务但 Agent 系统里还有大量“硬”任务——状态管理、流程控制、条件分支、重试逻辑、参数校验——这些东西用代码写只需要几行交给模型反而变得不确定。Jev 这个项目给出的新答案核心思路就是把 System One Model 和 LLM 的职责分开让该确定的地方确定该灵活的地方灵活。这篇文章适合正在做 Agent 开发、被大模型调用链路折磨过的工程师也适合刚开始接触 Agent 框架、想搞清楚“到底什么该交给模型、什么不该”的初学者。我会从设计思路、核心机制、实操落地、问题排查几个维度把 Jev 这套方案拆开讲清楚尽量让你看完就能在自己的项目里用起来。2. Agent 架构的核心矛盾确定性 vs 灵活性2.1 为什么“全交给大模型”一定会出问题先说一个我踩过的真实坑。之前做一个客服 Agent用户输入“帮我查一下上周的订单如果还没发货就取消”。这个需求拆开看有三步查订单、判断发货状态、条件取消。我当时的做法是把这三步全部写进 system prompt让模型自己规划。结果测试的时候发现模型有时候会跳过“判断发货状态”直接取消有时候会把“上周”理解成“最近七天”而不是“上一个自然周”还有时候工具返回了错误码它却当成成功继续往下走。这些问题的根源在于大模型的输出是概率性的而 Agent 的流程控制需要确定性。你让模型做语义理解没问题它确实比正则表达式强但你让模型做“如果 A 则 B 否则 C”这种逻辑判断它每次都可能给你不同的答案。更麻烦的是当工具调用失败时模型不一定能正确识别错误并重试它可能会编一个结果继续往下走。Jev 的思路很直接把 Agent 的执行过程拆成两层一层是确定性的编排层一层是模型驱动的决策层。编排层用代码写死流程、状态、重试、校验决策层只在真正需要语义理解的地方调用 LLM。这样既保留了模型的灵活性又保证了系统的稳定性。2.2 System One Model 到底解决什么问题Jev 里提到的 System One Model名字借用了认知科学里“系统一”的概念——快速、直觉、自动化的思考方式。在 Agent 语境下它指的是一个轻量级的、专门负责快速决策的模型或规则引擎用来处理那些不需要深度推理的任务。举个例子用户说“帮我订明天去北京的机票”。传统做法是把这句话丢给大模型让它解析出意图、时间、目的地、动作。但 Jev 的做法是先用 System One Model 做一层快速匹配——识别出“订机票”这个意图提取“明天”“北京”这两个槽位然后直接走预设的订票流程。只有当用户说“帮我安排一下下周的行程顺便看看有没有合适的航班”这种模糊表达时才把请求交给 LLM 做深度理解。这样做的好处很明显大部分常见请求走快速通道延迟从几秒降到几百毫秒成本从几分钱降到几乎为零。只有真正复杂的、模糊的请求才走大模型整体资源消耗大幅下降。而且因为快速通道是确定性的不会出现“模型今天心情不好就理解错了”的情况。2.3 两层架构的职责边界怎么划划边界的原则其实就一句话能用规则解决的问题不要用模型能用小模型解决的问题不要用大模型只有必须用大模型的地方才用大模型。具体来说下面这些任务适合放在 System One Model 层意图分类用户这句话是要查订单、退款、还是咨询槽位提取时间、地点、数量、金额这些结构化信息流程路由根据意图直接跳转到对应的处理流程参数校验检查必填字段是否齐全、格式是否正确状态管理当前处于流程的哪一步、下一步该做什么而下面这些任务才需要交给 LLM模糊语义理解用户表达不完整、有歧义、带隐喻多轮对话中的上下文推理用户说“就那个”需要结合历史判断指代自然语言生成把结构化结果转成流畅的回复复杂规划需要多步推理、权衡取舍的决策异常处理遇到没见过的输入需要模型兜底这个边界不是一成不变的随着你的 System One Model 覆盖的场景越来越多需要调用 LLM 的比例会越来越低。Jev 的设计里这个比例是可以动态调整的这也是它比传统“全 LLM”方案更实用的地方。3. Jev 的核心机制拆解怎么做到“该省的省该花的花”3.1 快速通道规则引擎 轻量模型Jev 的快速通道不是简单的 if-else而是一个可配置的规则引擎加上一个轻量级的分类模型。规则引擎负责处理那些模式固定的请求比如“查订单”“退款”“改地址”这些高频意图直接用关键词匹配或者正则就能搞定。轻量模型负责处理规则覆盖不到的边缘情况比如用户换了一种说法但意思差不多。我实测下来一个训练得当的小模型参数量在百兆级别在意图分类任务上能做到 95% 以上的准确率而推理成本只有大模型的几十分之一。Jev 的做法是把这个小模型和规则引擎串起来先走规则规则命中就直接返回规则没命中走小模型小模型置信度低于阈值才升级到大模型。这个阈值怎么定我的经验是从 0.8 开始调。阈值太高大量请求会升级到大模型省不了钱阈值太低小模型误判率上升用户体验变差。你可以先跑一批真实数据画出准确率和覆盖率的曲线找到那个拐点。Jev 的配置里这个阈值是暴露出来的方便你根据业务场景调整。3.2 升级机制什么时候该把请求交给大模型升级机制是 Jev 里我觉得最巧妙的部分。它不是简单地“小模型搞不定就升级”而是有一套多级触发条件置信度触发小模型输出的概率低于阈值规则触发请求里包含特定关键词比如“投诉”“紧急”“人工”轮次触发多轮对话超过 N 轮还没解决异常触发工具调用返回错误、参数校验失败用户触发用户明确说“转人工”或者表达不满这些触发条件可以组合使用Jev 的配置里用的是一个优先级队列高优先级的条件先检查。比如用户说“转人工”不管小模型置信度多高直接升级。这样做的好处是既保证了效率又不会在关键时刻掉链子。我自己的项目里还加了一个“学习触发”每次大模型处理完一个请求把输入和输出存下来定期用来微调小模型。这样小模型的能力会越来越强升级到大模型的比例会越来越低。Jev 虽然没有内置这个功能但它的架构留了扩展点你可以自己接一个数据管道进去。3.3 状态管理Agent 的“记忆”不该放在 prompt 里很多 Agent 项目把对话历史、用户信息、流程状态全部塞进 prompt导致 prompt 越来越长成本越来越高而且模型还容易“忘记”前面的内容。Jev 的做法是把状态管理从 prompt 里抽出来放到独立的存储层。具体来说Jev 用一个状态机来管理流程。每个用户会话对应一个状态实例记录当前处于哪个节点、已经收集了哪些信息、下一步该做什么。当需要调用 LLM 时只把当前节点相关的上下文传进去而不是把整个历史都塞进去。这样 prompt 长度可控模型注意力集中输出质量也更稳定。这个设计的好处我在实际项目里深有体会。之前做一个多轮填单的 Agent用户要提供姓名、电话、地址、时间四个信息。传统做法是把所有历史对话都传给模型让它判断还缺什么。结果模型有时候会重复问已经填过的字段有时候会漏问。改成状态机之后缺什么字段代码里一清二楚直接问就行根本不需要模型判断。只有用户回答的内容需要解析时才调用模型提取槽位。3.4 工具调用的确定性编排工具调用是 Agent 最容易出问题的环节。模型可能调错工具、传错参数、或者对返回结果理解错误。Jev 的方案是把工具调用从模型决策改成编排层决策。具体怎么做在流程定义阶段每个节点就明确指定了“这一步该调哪个工具、参数从哪里来、返回结果怎么处理”。模型只负责在需要的时候提取参数值不负责决定调哪个工具。比如订机票流程里“查询航班”这个节点固定调用航班查询接口参数是出发地、目的地、日期这些参数从状态机里取不需要模型决定。这样做的好处是工具调用的成功率大幅提升。我实测下来确定性编排的工具调用成功率能到 99% 以上而模型自主决策的工具调用成功率通常只有 85% 到 90%。别小看这 10 个百分点的差距在真实业务里意味着每天少几百个失败请求。当然有些场景确实需要模型自主选择工具比如开放式问答或者复杂任务规划。Jev 也支持这种模式但它建议把自主决策限制在最小范围内能确定的地方尽量确定。4. 实操落地怎么在自己的项目里用这套思路4.1 从现有 Agent 里识别“不该交给模型”的部分如果你已经有一个跑着的 Agent 项目想改成 Jev 这套思路第一步是做一次调用链路审计。把每次用户请求涉及的大模型调用列出来逐个问三个问题这次调用是在做语义理解还是在做逻辑判断这次调用的输出空间是开放的还是有限的如果这次调用出错有没有代码层面的兜底如果答案是“逻辑判断”“输出有限”“没有兜底”那这次调用大概率可以改成确定性代码。我自己的项目审计下来发现大概 60% 的大模型调用是可以去掉的改成规则或者状态机之后整体延迟降了 70%成本降了 80%。Jev 的文档里给了一个更简单的判断标准如果你能用一段伪代码描述清楚这个决策的逻辑那它就不该交给模型。比如“如果用户说的是查订单就走订单查询流程”这种用代码写就是一行 if交给模型反而增加不确定性。4.2 搭建 System One Model 层的具体步骤搭建 System One Model 层不需要一开始就上模型可以分三步走第一步先用纯规则跑通流程。把高频意图和固定模式用关键词、正则、模板匹配覆盖掉。这一步不需要任何模型纯代码就能做。我建议先覆盖 Top 20 的意图这些通常能占到 80% 的请求量。第二步引入轻量分类模型。当规则覆盖不到的长尾请求多起来之后训练一个小模型来做意图分类和槽位提取。数据来源就是之前大模型处理过的请求日志标注好意图和槽位用几百到几千条数据就能训出一个可用的模型。Jev 支持接入 HuggingFace 上的小模型也可以用 ONNX 做本地推理延迟能控制在 50 毫秒以内。第三步建立升级机制。给小模型的输出加一个置信度阈值低于阈值就升级到大模型。同时加上前面说的那些触发条件保证特殊情况能及时升级。这一步的关键是阈值要可配置、可监控上线后根据实际数据持续调整。4.3 状态机的设计与实现要点状态机是 Jev 架构里的核心组件设计好坏直接影响系统稳定性。我总结几个实操要点状态粒度要适中。太粗会导致一个状态里做太多事模型调用次数增加太细会导致状态数量爆炸维护成本高。我的经验是一个状态对应一个用户可感知的步骤比如“询问出发地”“询问目的地”“确认订单”各是一个状态。状态转移条件要明确。每个状态到下一个状态的转移条件必须用代码写清楚不能依赖模型判断。比如“用户提供了有效日期”这个条件用正则校验就行不需要模型。状态数据要结构化。状态里存的数据用 JSON 或者数据库表字段明确。不要存自然语言文本否则后续处理还得再解析一遍。异常状态要单独处理。每个状态都要考虑“用户不按预期回答”的情况设置一个兜底转移比如重试三次后升级到大模型或者转人工。Jev 的状态机配置用的是 YAML 格式下面是一个简化示例states: ask_departure: prompt: 请问您从哪个城市出发 extract: field: departure method: city_parser next: ask_destination on_fail: ask_departure_retry max_retry: 3 ask_destination: prompt: 请问您要去哪个城市 extract: field: destination method: city_parser next: ask_date on_fail: ask_destination_retry max_retry: 3这种配置方式的好处是流程和代码分离产品经理也能看懂改流程不用改代码。4.4 大模型调用的“最小化”原则即使到了必须调用大模型的环节也要遵循最小化原则。具体来说只传必要上下文。不要把整个对话历史都塞进去只传当前状态相关的信息。比如用户在第 5 轮说“就那个”你只需要传第 4 轮的候选列表不需要传前 3 轮的内容。限制输出格式。让模型输出 JSON 而不是自由文本这样解析更稳定。Jev 的 prompt 模板里会强制要求模型按指定 schema 输出解析失败就重试。设置超时和重试上限。大模型调用可能超时必须设置超时时间和重试次数。我的经验是超时设 10 秒重试最多 2 次超过就降级处理。缓存高频请求。有些请求是重复的比如“你们几点上班”这种可以直接缓存答案不用每次都调模型。Jev 支持在编排层加缓存节点命中缓存直接返回。5. 常见问题与排查技巧实录5.1 小模型误判率太高怎么办这是最常见的问题。小模型误判通常有三个原因训练数据不够、类别不平衡、阈值设置不合理。训练数据不够的话先别急着标更多数据试试用大模型做数据增强。把已有的标注数据喂给大模型让它生成同义变体能快速扩充数据集。我试过用这个方法把 500 条数据扩到 3000 条小模型准确率从 82% 提到了 91%。类别不平衡的话给少数类别加权重或者在采样时做 oversampling。Jev 的训练脚本里支持配置 class weight直接改配置就行。阈值设置不合理的话别拍脑袋定跑一批验证数据画出 PR 曲线找到 F1 最高的那个点。如果业务上更怕误判就把阈值调高更怕漏判就调低。5.2 升级到大模型后响应太慢升级机制本身会增加延迟因为要先跑小模型再跑大模型。优化思路有两个并行化。小模型和大模型可以并行调用小模型先返回结果如果置信度够就直接用不够就用大模型的结果。这样大部分请求的延迟等于小模型延迟只有少数请求需要等大模型。预判升级。根据历史数据某些意图的升级率特别高比如“投诉”类请求 90% 都会升级。这种可以在请求进来时直接走大模型跳过小模型。Jev 的配置里支持给每个意图设置“直连大模型”的标记我建议把升级率超过 70% 的意图都标记上。5.3 状态机卡死或者死循环状态机卡死通常是转移条件写错了导致某个状态无法跳出。排查方法是在每个状态转移时打日志记录当前状态、输入、转移目标。跑一遍测试用例看日志就能定位问题。死循环的常见原因是重试逻辑没有上限。每个状态的重试次数必须设上限超过上限要强制转移到一个兜底状态。Jev 的配置里 max_retry 是必填项就是防止这个问题。还有一个隐蔽的坑状态数据被意外修改。比如某个状态里修改了全局变量导致后续状态判断出错。我的做法是状态数据只读需要修改时创建新副本避免副作用。5.4 工具调用返回结果解析失败工具返回的结果格式可能和预期不一致比如接口升级、字段缺失、编码问题。排查步骤先看原始返回确认是工具的问题还是解析的问题如果是工具的问题加一层适配器把不同格式统一成内部格式如果是解析的问题检查解析代码的容错性比如字段缺失时给默认值加监控告警工具调用失败率超过阈值时通知Jev 的工具调用层支持配置 schema 校验返回结果不符合 schema 时自动触发重试或者降级。这个功能很实用建议开启。5.5 常见问题速查表问题现象可能原因排查方法解决方案小模型误判率高训练数据不足看混淆矩阵数据增强或补充标注升级后延迟高串行调用看调用链路日志并行化或预判升级状态机卡死转移条件错误打状态转移日志修正条件或加重试上限工具解析失败返回格式变化看原始返回加适配器或 schema 校验成本居高不下大模型调用比例高统计升级率优化小模型或调整阈值多轮对话丢上下文状态未持久化检查状态存储用状态机管理上下文5.6 几个我踩过的坑坑一过度依赖模型的“常识”。有一次做地址解析我以为模型能自动识别“朝阳区”属于北京结果用户说“朝阳区”的时候模型有时候当成北京有时候当成其他城市。后来改成用行政区划表做匹配准确率直接到 100%。模型没有常识只有概率涉及事实性的东西一定要用数据源校验。坑二忽略冷启动问题。新业务上线时没有历史数据小模型训不出来只能全走大模型。这时候成本会很高要有心理准备。我的做法是先跑一段时间收集数据同时用规则兜底等数据够了再训小模型。坑三状态机设计得太复杂。一开始想把所有分支都覆盖结果状态数量爆炸维护成本极高。后来简化成“主流程 异常处理”两层主流程只覆盖正常路径异常统一走兜底维护成本降了一半。坑四忘记处理并发。同一个用户可能同时发起多个请求如果状态机没有并发控制会出现状态覆盖的问题。Jev 的状态存储支持加锁但需要你自己在配置里开启。我建议所有涉及状态修改的操作都加锁宁可慢一点也不要出错。6. 这套思路的适用边界与扩展方向Jev 这套“System One Model LLM”的架构不是万能的它有明确的适用边界。如果你的业务场景是高度开放的比如创意写作、复杂咨询、开放式问答那大模型的比例本来就该高强行拆解反而会降低体验。但如果你的业务是流程化的、意图相对固定的比如客服、订票、填单、查询那这套架构能带来数量级的效率提升。我自己的项目从全 LLM 架构改成这套之后平均响应时间从 4.2 秒降到 0.8 秒单次对话成本从 0.15 元降到 0.02 元用户满意度反而上升了因为响应快了、出错少了。这个投入产出比是值得的。扩展方向上我觉得有几个点可以继续挖一是用小模型做槽位提取不只是意图分类这样能进一步减少大模型调用二是把状态机可视化让非技术人员也能配置流程三是接入强化学习根据用户反馈自动优化升级阈值。Jev 的架构留了这些扩展点但需要自己实现。最后分享一个我常用的判断标准当你发现自己在 prompt 里写“如果……就……”的时候就该停下来想想这个逻辑是不是该用代码写。大模型是拿来处理模糊性的不是拿来替代 if-else 的。把这个边界划清楚Agent 的稳定性和效率都会有质的提升。