LLM改造日志路由器失败记:从智能升级到紧急回退的教训
如果你也在考虑让 LLMs 接管基础设施里某个默默无闻的组件我建议你先听完我这周的遭遇。我给我们团队的 log router 接上了一个大模型想让它变得聪明一点结果上线不到三天就紧急回退。标题那句话是我回退后的真心话LLMs 太大了而我的日志路由器根本不需要登台献唱。这次实验最大的价值不是“验证了 LLM 能做什么”而是让我彻底想明白了日志路由这类组件到底需要什么。它不是表演舞台不是内容生成器而是流水线上一个必须准时准点、永不掉链子的分拣员。把这篇文章写出来是想给所有正在考虑“用 AI 重构基础设施”的同行提个醒有些组件值得用 LLM 增强有些组件接入 LLM 等于给自己埋雷。1. 一次被“智能升级”四个字推进坑里的实验1.1 最初的需求其实很朴素我们团队的日志路由器是一条流式处理管道负责把来自几十个服务的日志统一收进来解析出时间、级别、服务名然后按团队和子系统分发到对应存储同时把错误日志送到告警侧。这套东西运行了大半年痛点一直都有日志格式变来变去正则维护起来确实烦第三方推送的行格式五花八门很多匹配不上的日志落到 unknown 桶里还得手工去捞。就在这时有人提了一句“LLM 不是能理解语义吗让它做路由肯定比正则强。”这个提议听起来太合理了。语义理解确实能解决“格式多变”的问题只要它真的理解。我当时最心动的地方在于它可以根据上下文判断一条日志到底属于哪个子系统天然抗格式变化。这正好戳中了我们维护正则的痛处。于是我带着这个假设开始搭验证环境。1.2 验证阶段它表现得过于聪明我写了个 POC把一周的抽样日志跑了一遍。给模型设计了一个 prompt读一条日志输出 JSON字段包括 route_to、confidence、reason目标值限制在几个团队已经约定好的类别里。几千条样本跑下来识别准确率肉眼看着相当不错连那些正则完全对不上的第三方日志都能给出合理归属。印象最深的一条日志“ERROR payment timeout from order 123”模型给出的输出是{ route_to: payment_alert, confidence: 0.93, reason: 支付超时直接影响用户下单应进入支付团队告警链路 }连 reason 都写得像模像样旁边围观的人啧啧称奇。那几天我甚至开始规划用 LLM 替换掉一半规则代码以后日志路由器就属于“智能基础设施”了。现在回头看这个判断错得很典型——我把“抽样样本上的演示效果”当成了“生产环境里的系统能力”。1.3 掌声还没落生产环境先给了我一巴掌POC 通过后我花了两天把 LLM 接入正式链路做一个前置的路由决策服务日志进来先调模型拿到 route_to再按结果转发。架构看起来很干净。结果上线之后问题在头几个小时就开始冒泡。最初是延迟后来是成本更麻烦的是行为不可控——这些我在下面按条展开讲。2. 上线不到三天我算完了这笔不划算的账2.1 吞吐和延迟日志流的节奏LLM 根本跟不上我们线上的日志峰值大约每秒 5000 条这在很多公司里根本不算大流量但对转发链路来说是个常态量级。普通日志路由器单实例做解析和转发每秒跑几十万条是常态。而一次 LLM 推理哪怕是很轻量的模型也要几百毫秒。简单算一笔账就知道不对就算单条日志一个请求5000 条/秒的流量意味着要维持 5000 个并发推理如果用外部 API还要叠加网络开销、限流、超时和 token 上限。日志路由器不允许制造反压因为一旦处理不过来就只能丢日志而日志丢了业务排查时就没有证据。这是可观测性系统里最不能接受的事情之一。我还试过本地自托管一个小模型来降低成本但服务器上多跑一个模型实例之后CPU 和内存直接顶到警戒线反而把原服务的吞吐拖下来了。日志管道本来可以跑在普通服务器上为了“智能”硬生生变成了高算力消耗大户这个方向从一开始就是歪的。2.2 成本账每秒百万 token 的单价有多痛“智能”不是免费的但这次的价格离谱到了让我在周会上说不出话的程度。粗略估算一下假设每秒 5000 条日志平均每条日志进 LLM 之前被截断到 200 token那么每秒要处理约 100 万个 token。哪怕按一个非常便宜的接口价格来算比如每千 token 0.003 元每秒就是 3 元一小时 10800 元一天接近 26 万元。这还只是“路由决策”这一项没有算重试、没有算模型偶尔输出格式错误后重新解析的成本也没有算为了容量高峰提前预留的预算。更残酷的是如果换能力更强的模型成本直接翻几倍。一个基础设施模块每秒钟花在决策上的钱比业务功能本身还多这个事实本身就是最响的报警。我当时把这个表格贴在了群里提议用 LLM 的同事沉默了半分钟然后说“那还是回归则吧。”2.3 不确定性路由是秩序问题秩序不接受抽卡日志路由的第一原则是确定性同样一条日志今天应该去 A明天也去 A规则代码不会因为心情变化改变判断。正则做不到就匹配不到但能匹配的一定稳定。LLM 做不到这种确定性。温度调到 0输出也不保证 100% 一致换一次模型版本行为可能整体漂移同一句话换一种表述方式模型就可能给出不同的路由结论。更危险的是幻觉问题。遇到完全没见过的新日志格式LLM 不会像正则一样乖乖报“无法匹配”而是会自信地给出一个看起来合理但错误的目的地。我们后来复盘时发现过一个真实案例一条“connection reset by peer”日志被模型归到了“网络噪音”类别没有进入告警通道而值班同学其实需要看到所有 error 级别日志。模型认为它不需要告警但它没有资格替人做这个决定。日志一旦被路由到错误的地方就几乎等于丢了。你不会每天都去翻检目的存储里是否混进了不该出现的内容。可观测性工具自己不可观测、不可解释这是最要命的。2.4 最讽刺的发现喂给 LLM 的预处理本身就是路由逻辑要把日志稳定地喂给模型你得做一串工作截断超长日志、分段处理堆栈信息、注入 service 和 level 字段、脱敏敏感数据、校验输出 schema、处理超时重试。等这一圈做下来我发现自己已经实现了一个大半个路由器和解析器。经过这些预处理模型需要做的只剩“从几个候选标签里选一个”——这本质上就是一个封闭式分类问题。既然预处理已经把问题收敛成决策表那我为什么还要让模型来选直接维护一张可审计、可测试的路由表效果更可控成本还低几个数量级。这个发现几乎让我笑出来我以为自己是在用 LLM 替代路由逻辑实际上只是先把路由逻辑做完了再雇了一个昂贵的分类器来做最后一跳。3. 日志路由的本质是确定性分发不是语义理解3.1 把“路由”拆开过滤、分流、富化在日志系统的语境里路由就是三个操作过滤这条日志要不要收、分流送到哪个目标存储或队列、富化打上哪些标签。这三个操作没有一个是开放式的语义问题。在一个具体团队里合法目标集合永远是可枚举的归类标准也是可以用语言描述清楚的——总不可能今天把支付日志送到存储 A明天送到存储 B而且理由说不清。既然问题可枚举就能用规则表覆盖。规则表当然有维护成本但这是我们真正要去解决的问题。之前正则维护痛苦不是因为“规则”这个思路错了而是因为规则散落在各种配置文件里没有组织、没有测试、没有审查流程。把烂摊子归罪于“正则不够智能”其实是找错了病因。3.2 “语义理解”在路由场景是毒药这句话我要说得重一点在转发链路上语义理解不是多了个优点而是多了个不确定源。规则引擎的失败是显式的匹配不上就走 fallback链路逻辑可追踪、可回滚。模型路由的失败是隐式的它给了一个看起来很合理的答案但你不知道依据是什么也不知道这次和上次为什么会不一样。你无法在凌晨三点把模型叫起来对质“你凭什么把这条日志送到降级桶”事故复盘时任何一句“模型今天状态不好”都无法让下游团队接受。参与者要的是可复现的结论而 LLM 天生就不擅长给出可复现结论。这里不是否定 LLM 的能力只是它被放在了错误的位置。正则的脆弱性被抱怨最多但正则的好处也被严重低估了它是一段可测试、可审查、可继承的文本。真正要补的课是测试和组织规则而不是用模型掩盖规则缺失。3.3 LLM 的合理位置在事后分析不在转发链路同样的模型如果放在“日志分析”这一侧完全是另一回事。离线、批量、非实时允许模型生成自然语言摘要允许用户用自然语言提问“过去一小时支付失败为什么增多”它可以直接当查询引擎用。这个场景对延迟不敏感对成本有预算预期而且输出错了也不致命——用户可以追问、纠正、重新查询。日志路由在写路径上应该保持安静、稳定和廉价日志理解在读路径上可以聪明、灵活和昂贵。这两个位置对延迟、成本、确定性的要求完全不同。把它们调换过来把最重的模型放到吞吐量最大的转发路径上就等于让一个歌唱家去当搬运工还要求他不喘气、不跑调。这不是能力问题是岗位匹配问题。4. 回退之后我用三层方案接住了所有日志4.1 第一层基于解析字段的静态路由回退的第一个动作是重建规则库但我不打算按以前的方式再散落一次。先把日志做结构化解析用正则或 JSON 解析器把关键字段提取出来然后基于字段组合做路由比如“service 为 payment-api 且 level 为 ERROR”送告警主题“path 以 /api/pay 开头”进支付链路分析。以下是简化后的路由配置示意表达的是思路而不是某个特定工具的完整语法# 简化示意基于字段的路由 route: - name: payment_alert when: service payment-api level ERROR to: alert_topic - name: payment_debug when: service payment-api level DEBUG to: debug_bucket - name: unknown when: otherwise to: unknown_bucket字段级路由比全文正则稳定得多因为匹配意图更明确。解析器虽然也要正则但它的职责被压缩到“从已知结构里提取字段”而不是“判断整条日志的归属”维护面小了很多。这条经验让我意识到路由规则的关键是结构而不是智能。4.2 第二层频率统计和滑动窗口很多真正的问题是“错误次数增多”不是“某个关键词出现”。我在路由器里加了一个计数器以时间窗口为单位统计每个服务的 error 数量超过阈值才把日志流转到外部告警通道。这个逻辑 LLM 反而做不好因为它没有全局时钟也没有跨样本状态。滑动窗口是天然的流式处理设计几千年前统计员就会用放在日志链路里依然不过时。# 伪代码滑动窗口错误计数 import time from redis import Redis r Redis() WINDOW 60 LIMIT 20 for log in logs: key ferr:{log.service}:{log.level}:{time.time() // WINDOW} count r.incr(key) r.expire(key, WINDOW * 2) if log.level ERROR and count LIMIT: route_to_alert(log)这套逻辑上线之后效果立竿见影错误风暴发生时告警不依赖单条日志内容而是依赖整体趋势噪音量大幅下降。这是传统方案完胜模型方案的一个典型场景。4.3 第三层轻量分类器加规则兜底如果确有一些日志格式无法用规则覆盖我会加一个很小的文本分类模型比如 FastText几百 MB 以下推理是毫秒级吞吐可以到几十万条/秒。它也有不准的时候所以输出必须带标签概率低于阈值就送 unknown 桶。这和 LLM 的根本区别在于它的行为可以被锁死在固定版本里可复现而且模型很小可以跑在路由服务进程内不产生额外的网络往返和成本黑洞。import fasttext model fasttext.load_model(router_model.bin) labels, probs model.predict(ERROR payment timeout from order 123) print(labels, probs) # (__label__payment_alert, 0.86)轻量模型不是必须项只有当规则库已经覆盖了 90% 以上的流量、剩下的 10% 确实没有明显规律时我才建议引入。而且它必须挂在规则兜底之后不能反过来让模型当主决策。4.4 兜底思路unknown 桶不是失败而是闭环回退后最好用的设计其实是未知桶。所有没匹配上的日志进一个低优先级的观察队列每天花几分钟看一眼把高频出现的新模式补进规则库。这不是偷懒而是一个反馈闭环。规则库越用越完整因为每个新格式最终都会变成规则的输入而不是被某个模型悄悄“消化”掉。之前用 LLM 时看起来没有 unknown实际是模型把所有未知都幻觉到了某个已知标签里。问题没有消失只是看不见了。规则方案反而让未知变得可见、可治理这是这个方案比模型方案更健康的地方。5. 回退路上踩过的坑以及我现在怎么判断5.1 从模型行为反推规则库是一条死路我试过把 LLM 在抽样集上的分类结果直接当标注数据用来自动生成规则。效果很差。模型分类边界是模糊的同样的日志因为上下文里的微小变化可能被分成不同类别导致学出来的规则互相冲突。比如那条支付超时日志模型有时分类到 payment_alert有时分类到 payment_debug理由是“超时可能影响用户体验也可能只是网络抖动”。这样的数据训练出来的规则比人写的还难维护。最后我还是人工重新标注了一千条有代表性的样本完全按业务语义来定义类别再从样本里提炼规则。这段路没有捷径但值得走因为每一条规则背后的业务意图都是清楚的。5.2 规则库要像代码一样维护回退之后我把路由规则从一个散落在配置文件里的正则集合重构成有结构的路由表每条规则包含名称、说明、匹配表达式、测试样例。每加一条规则必须带上对应的测试日志跑 CI。这个习惯救了我很多次上游日志格式一改测试立刻报警而不是半夜用户来告诉我日志丢了。规则不是技术债没有维护结构的规则才是。给规则建测试就像给函数写单测是投入产出比极高的事。一个跑了半年都没有出过一次路由事故的规则库让我比原来那个“智能路由”安心得多。5.3 判断“这里要不要用 LLM”的四道题以后再有人提议用 LLM 改造某个模块我会先问四个问题。这四个问题不是拍脑袋而是这次翻车经历换来的。问题指向“不要用 LLM”的信号指向“可以考虑 LLM”的信号需求是否能清晰描述成输入-输出映射能说明规则可以覆盖不能说明问题太开放输出错误后的代价是什么不可重试、不可逆可容忍、可人工审查流量和延迟约束是否允许模型推理每秒成千上万条、要求毫秒级低流量、非实时样本和标注体系能否长期维护没有稳定评估集有专门团队维护数据如果四个问题里有任何一个指向“不行”就不该上 LLM。日志路由在这四个问题上全部踩线所以它被判死刑一点都不冤。5.4 一点个人体会这次实验给我最大的收获不是“LLM 没用”而是“在正确的位置使用它”。日志路由器继续做它擅长的事安静、确定、快速地分发。而我把 LLM 放到了它真正擅长的位置——做了一个小的日志摘要助手值班同学可以用自然语言问它“过去一小时支付失败为什么增多”它会读取指标和日志生成一段可读的摘要。那个助手每天被用几十次成本在一个可接受的预算范围内。同一个模型换一个位置从“灾难”变成“赠品”。这就是我最后想说的不是所有组件都需要唱歌更不是所有组件都有资格登台。先把分发干好再谈聪明不迟。