最近在打磨一个AI原生应用,越做越发现一个尴尬的事:你让大模型直接面对所有问题,它确实能聊、能写,但一碰到精确计算、规则校验、多步状态跟踪,就开始一本正经地胡说八道。混合推理技术就是冲着这个痛点去的,思路很直接:别让大模型包办一切,把语义理解和逻辑计算拆开,让各自擅长的地方各自干活。这篇文章我会把我实际踩过的坑、搭过的链路、调过的参数都摊开讲,适合正在做AI应用落地、但又对纯提示词方案不太满意的开发者参考。
1. 先算一笔账:纯LLM推理在AI原生应用里的软肋到底在哪
1.1 统计推理的天花板:它不是计算器,也不是数据库
我见过太多项目组的开场白是"我们直接用大模型处理所有逻辑",结果上线两周就发现几个非常规律的问题。第一个是算术和精确映射:你问它"某商品原价1299元,满300减50,两件再打九五折,最后多少钱",它能给你列出步骤,但三步之后开始出现进位错误。这不是偶发,而是必然,因为LLM的底层机制是"根据前文预测下一个最可能的token",它在做概率采样,不是真的在按规则做四则运算。
第二个是时效性和事实性。大模型的参数知识是训练时冻结的,它不知道今天股票收盘价,不知道某仓库此刻的实时库存。你让它基于"当前库存量"做决策,它只能猜,猜完还非常自信。第三个隐藏问题是状态一致性:多轮对话里,它容易忘记前面已经确认过的条件,或者把规则A和规则B混在一起。你可以靠提示词反复强调,但token上下文一长,注意力就被稀释了。
我打个比方:纯LLM像一个博览群书但心算极差的助手,你让它复述知识、概括大意,它一流;你让它一口报出996×897等于多少,它大概率给你一个漂亮但错误的答案。混合推理要做的事,就是给这个助手配一个计算器和一本最新的手册。
1.2 提示词工程边际收益递减:为什么堆Prompt解决不了问题
很多人第一反应是"那我写更详细的提示词不就行了",这条路我走过,开头有效,后面越走越窄。当任务只有两三步时,你把步骤写清楚,模型基本能跟住。但当业务链路变成"理解意图→查库存→算优惠→检查优惠券是否可用→生成回复",你再把所有规则塞进一段提示词,问题就来了:模型开始顾此失彼,有时候跳过校验直接算,有时候把优惠券规则张冠李戴,而且每次出问题你都不知道该改哪一句Prompt。
还有一个被低估的问题:成本。提示词越长,每次请求的token消耗越大,在高并发场景下这不是小数。更关键的是,提示词写得再细,它仍然是"建议性"的,模型对规则的理解本质上是语义层面的近似,而不是逻辑层面的强制执行。你要的不是"它大概记得规则",而是"规则必须被严格执行"——这就必须引入确定性的代码路径、规则引擎或约束求解器。
所以说,混合推理不是"加个新功能",而是换一种架构思路:把LLM当作系统里的一个组件,而不是系统本身。这是我后来做所有AI应用设计时的第一原则。
2. 混合推理到底混什么:快慢结合的架构拆解
2.1 快思考交给LLM,慢思考交给确定性模块
有一个很好用的理解框架,就是卡尼曼的快慢系统。快思考是直觉、联想、模式识别,对应LLM的强项:理解自然语言、提炼意图、生成表达、做开放性创意;慢思考是逻辑推演、精确计算、规则执行,对应的是传统程序、计算器、规则引擎、知识图谱这类确定性组件。混合推理AI原生应用的核心,就是在这两者之间架一座调度桥,让快思考负责"理解世界",让慢思考负责"算出结果"。
举个例子。用户说:"我要查一下上个月的电费,看看是不是被多收了。"快思考部分识别出这是"账单查询+费用校验"的复合意图,并提取出关键实体(上个月、电费、多收的怀疑);慢思考部分去账单数据库取实际读数,拉取计费规则,算一遍标准价格,再跟实收金额对比。整个计算、比对、阈值判断都不该让LLM来做,而是由代码完成。
我一开始犯过相反的错:让LLM去判断"实收是否合理"。它当然能给你一段分析,但同样的输入,它有时候说有误,有时候说没问题,你根本没法对用户交代。换成熟练的确定性校验逻辑之后,结果百分之百可复现,用户不满意的点只会集中在数据源,而不是模型随机性。
2.2 三种常见混合范式:工具调用、把推理写成代码、符号约束
我梳理一下目前项目里最常用的三种混合模式,你可以把它们当积木用。
第一种是"工具调用式",这是最直觉的:LLM理解意图后,生成一个工具调用的请求,比如查天气、搜文档、查数据库,然后系统去执行工具,把结构化结果放回上下文,LLM再基于结果组织回复。这里LLM本质是个调度员和发言人,真正的事实获取由工具完成。需要注意的是,工具返回的结果越结构化,LLM的最终回复越不容易跑偏;相反,你给一堆混乱日志让它"总结一下",它就可能开始脑补。
第二种是"代码推理式",适用于数学、逻辑推导类任务。思路是让LLM把问题翻译成一段可执行的程序或表达式,然后由解释器跑出精确答案,而不是让LLM直接输出答案。我做过一个Demo,用户输入任何复杂计算问题,系统生成一段Python代码,执行后返回结果,准确率从纯文本答案的七成提升到接近满格。关键细节在于,LLM只负责"写代码",不负责"跑代码",跑代码的过程天然带有校验,出错就是异常,可以捕获重试。
第三种是"符号约束式",适用于强规则、强合规场景。比如优惠券叠加规则、排班约束、库存分配策略,这些规则用自然语言描述给LLM,怎么都有模糊空间,但用规则引擎或约束求解器表达,就变成铁律。LLM在其中负责把用户需求转化成约束条件,再由求解器找到可行解。这种模式可解释性最强,出了问题你能明确说是哪条规则冲突。
2.3 怎么选:给不同任务匹配不同的推理路径
没有包打天下的混合策略,我自己会按任务的四个特征来分派:是否需要精确性、是否需要外部事实、是否需要状态跟踪、是否需要可解释审计。
如果答案是"需要精确性",走代码推理;"需要外部事实",走工具调用;"需要状态跟踪",就用工作流加显式状态变量;"需要可解释审计",走符号约束。如果一个任务四者都占,那就分层:LLM负责拆解和调度,中间层跑代码和工具,最底层挂规则引擎。项目里我习惯在代码里写一个简单的路由函数,先根据意图分类结果决定走哪条通道,而不是让单个LLM调用从头管到尾。这样每条链路都短,调试起来非常爽。
3. 落地实操:一个AI原生订单处理应用的混合推理设计
3.1 业务场景与整体链路设计
我用一个我自己做过的模拟项目来演示完整方案,项目名就叫"某订单助手",需求是这样的:用户在对话框里提出订单相关问题,系统需要识别意图,返回真实订单数据,执行优惠计算与价格校验,最后生成自然语言回复。这个问题看起来很普通,但纯Prompt方案很容易在价格计算和优惠规则上翻车,非常适合做混合推理的练兵场。
整体架构分四层。第一层是入口层,接收用户消息;第二层是意图识别与实体抽取,我用LLM配合结构化JSON输出,让模型返回意图标签和关键实体;第三层是推理调度,根据意图标签路由到不同处理器;第四层是执行层,包含订单查询服务、优惠规则引擎、价格计算器,最后由生成模块把执行结果转成自然语言。整个链路里,LLM出现两次:一次在入口做语义解析,一次在出口做文案组织,中间的业务逻辑全部由确定性代码完成。
很多人会问:为什么不直接让LLM工作流自动调工具?我试过,但发现让LLM自己决定"什么时候调工具、调哪个工具、传什么参数",在复杂场景下不可控。显式的路由和分层反而更稳,因为规则是死的,模型的选择空间被限制在固定选项里,出错概率大幅下降。
3.2 核心实现:推理路由与工具调用
推理路由是整个系统的心脏。我采用的是"意图分类+参数校验+分支执行"三步结构。意图分类由LLM完成,返回一个固定枚举值,比如query_order、calc_price、check_refund、other。然后一个纯Python函数根据意图枚举决定走哪个处理器,这就是我说的显式调度。
def route_request(intent: str, entities: dict) -> dict: routes = { "query_order": handle_query_order, "calc_price": handle_calc_price, "check_refund": handle_check_refund, "other": handle_fallback } handler = routes.get(intent, handle_fallback) return handler(entities)LLM部分我用结构化输出约束,提示词里明确要求只返回JSON,例如:
{"intent": "calc_price", "entities": {"sku_id": "A1023", "quantity": 2, "coupon_code": "SAVE50"}}收到JSON后,代码先做参数校验,检查必填字段是否完整、枚举值是否合法,不合法就直接进入澄清追问流程,而不是让下游去猜。
我建议所有实体都做一层类型转换和范围校验。比如quantity字段,模型可能返回"两件"也可能返回"2",字符串处理和类型强转这步必须放在确定性层,不要依赖模型自己格式化好。
3.3 关键参数选择与背后的理由
在调节这套系统时,有几个参数我反复调过,直接把结论分享给你。
温度(temperature)参数:意图识别和实体抽取的任务,我固定在0到0.2之间。这个环节要求稳定和可复现,温度太高会让同样的输入偶尔给出不同意图,虽然听起来只是"偶尔",但线上就是不可接受的波动。生成最终回复时可以调到0.4到0.7之间,这时候需要一点自然语言多样性。
重试机制:当LLM返回的JSON解析失败,或者参数校验不过,我采用了最多三次重试策略,每次重试重新调用一次解析模型。三次是最优解:一次太少,偶发格式错误直接让用户体验断裂;五次以上收益为零,因为反复失败大概率是提示词本身有歧义,而不是运气问题,此时应该降级到人工澄清话术。
置信度阈值:如果意图分类器附带置信度分数,我会区分硬路由和软路由。置信度高于0.85,直接按意图走;在0.6到0.85之间,进入确认式对话,跟用户做一次轻量澄清;低于0.6,直接转兜底。这个阈值不是拍脑袋定的,我用一批真实用户问题做回归测试,画出准确率和召回率的曲线后选的拐点。
3.4 用"决策护栏"防止模型越权
我强烈建议,凡是涉及用户资产、金额、退款的操作,必须在确定性层加一道"决策护栏"。比如价格计算器返回优惠后的金额后,再让规则引擎检查一遍优惠叠加条件是否满足,全部通过之后才允许生成回复。这个设计本质上不让LLM"决定"结果,只让它"表达"结果。
护栏还有一个容易被忽略的用途:可解释性。系统里每一步都会产生审计日志,比如"意图=price_calc,规则=满减300减50,计算入口=折扣计算器,校验=通过"。将来用户质疑账单,运维可以直接查看这段日志链路,而不是翻聊天记录去猜模型当时怎么想的。这个能力在纯LLM方案里几乎做不到,也是我后来向其他项目组推荐混合推理时最强调的卖点。
4. 混合推理常见问题排查与避坑实录
4.1 工具调用不准:模型不按Schema传参
这是全项目里最让我头疼的问题。症状是模型明明应该传coupon_code,它却传成了coupon_type;或者一个数组参数,它只传了一个字符串。这种问题有几个常见原因:第一个是数据结构设计得太复杂,嵌套JSON的大模型解析效果天然差;第二个是提示词里缺少足够清晰的字段示例,尤其是枚举值的取值范围;第三个是模型把历史对话里的字段跟当前接口搞混了。
我的解决方案分三层:第一层简化Schema,能用平铺字段就绝不嵌套,字段控制在五六个以内;第二层在提示词里给一个"几乎完全相似的示例",包括它该忽略的无关字段;第三层在代码里做字段级校验,识别到字段缺失或类型错误时,不是直接抛给用户,而是把错误信息作为上下文给LLM再补一轮修正。经过这三层,工具调用成功率基本稳定在九成以上。剩下的失败,就靠重试和澄清兜底,不能再往下压了,收益不够。
4.2 路由误判、死循环与降级策略
路由误判最常见的情况是用户说了一句模棱两可的话,比如"我的订单到底怎么回事",它既可能是查物流,也可能是查退款进度。我最初的方案是只做单意图分类,效果很差。后来改成"主意图+备选意图"双输出:主意图走主链路,如果执行过程中发现数据异常,自动切到备选链路去查;如果两条链路都查不到,直接转人工话术。
死循环问题则发生在"LLM→工具→结果异常→再问LLM→再调工具"的链路上,如果代码没设上限,一次异常查询可能引发好几轮内部循环,既浪费钱又拖慢响应。我的做法是给整个推理链路设定最大迭代次数,默认三次,超过之后不再尝试推理,走兜底回复。这个兜底回复也要设计得有用,比如"我暂时没查到,请您提供订单号后再试",而不是干巴巴的"系统错误"。
4.3 性能与成本:混合推理会不会更慢更贵
刚上手混合推理时,直观反应是"又多调了好几次模型",成本岂不是更高?其实不一定。关键看你把模型调用花在什么地方。纯Prompt方案里,你要把所有规则和历史塞进上下文,每次都很贵;混合推理方案里,意图识别和实体抽取的输入很短,输出是结构化JSON,token开销小得多,同时精确计算由代码完成,不用反复喂给模型试错。
我做的实际优化有三个:一是用小模型做意图识别,我实测过不少场景下90%的意图分类用小参数模型足够,只有复杂实体抽取才上大模型;二是给常用查询做缓存,同一个用户问同一种订单状态,直接命中缓存结果,既不调LLM也不查数据库,响应延迟直接降到毫秒级;三是把工具调用结果写进短时记忆,同一轮对话后续问题直接引用,避免重复查询。
4.4 混合推理问题排查速查表
| 现象 | 可能原因 | 排查顺序 | 解决方案 |
|---|---|---|---|
| 工具参数频繁传错 | Schema设计复杂、示例不足 | 1.查看原始返回 2.检查Schema层级 | 简化字段、增加相似示例、加字段级校验 |
| 同一问题答案不稳定 | 温度过高、上下文有噪音 | 1.检查温度 2.检查历史拼接 | 决策类请求温度降到0.2以下,裁剪冗余上下文 |
| 路由总是误判 | 意图枚举太粗、提示词歧义 | 1.跑一批真实语句看分布 | 加备选意图、增加澄清对话、调整置信阈值 |
| 内部循环很久才返回 | 缺少迭代上限、降级策略缺失 | 1.看审计日志循环次数 | 设置最大迭代次数为3,超限走兜底 |
| 费用高得离谱 | 大模型被频繁调用、长上下文反复发送 | 1.看调用次数 2.看token分布 | 换小模型做分类、加缓存、压缩对话历史 |
| 审计对不上账 | 缺少链路日志 | 1.检查日志埋点 | 在路由和护栏位置埋结构化日志,记录意图和校验结果 |
这张表是我每次复盘项目时必对照的,新人在接手这类系统时,我也会先让他们拿这张表走一遍排查流程,比自己瞎试效率高得多。
5. 从项目里沉淀的几点个人体会
最后说几点只有自己动手踩过坑才会有的体会。第一,混合推理不是越复杂越好,别一上来就堆知识图谱、规则引擎、求解器一大堆,我见过好几个项目死于过度设计。先从一条最痛的业务链路下手,把"LLM理解+确定性计算"这套骨架跑通,确认收益后再横向扩展,这样每一步都有真实数据支撑。第二,日志和可解释性不是加分项,而是混合推理系统的生命线,没有审计日志,你根本没法判断是模型的问题、规则的问题还是数据的问题,凡是没有日志的推理调用,我都视为无效调用。第三,模型能力的边界要摸清楚,我定期用一批固定难度的回归题测试当前模型,一旦发现某个任务频繁失手,就果断把它移出LLM职责,交给代码处理。这种"能力审计"应该每个月做一次,而不是等到线上出事故再补救。
再分享一个小技巧:把所有涉及金额计算的请求,无论模型给出什么结果,都被要求在确定性计算层跑两遍,第一遍用浮点,第二遍用整数分单位计算,两次结果一致才放行。这个小成本操作帮我拦住过好几轮"差一分钱"级别的用户投诉。混合推理这条路,本质上是让AI原生应用学会"有所为有所不为",想明白什么话该让模型说、什么数该让代码算,你的应用才真正从"能聊"变成"靠谱"。