cd ../articles

AI/思考

LLM 是最后手段,不是默认手段

8 min read
一条流水线,绝大多数环节是朴素的齿轮和管道,只在最末端挂着一个发光的盒子。
一条流水线,绝大多数环节是朴素的齿轮和管道,只在最末端挂着一个发光的盒子。

这个项目最开始,我是打算整个交给 agent 跑的。

需求很清楚:把一批日文的短预告片找出来、下载、转成中文字幕、再分发出去。每一步——发现、判别、转录、翻译、写文案——在我脑子里都对应着一句「让模型去做」。2026 年了,活在 AI 时代,这不是天经地义的吗?我甚至没认真想过别的做法。

然后 Codex 那个 20 刀的套餐——我把它当成跑整条投稿流程的 agent,不是拿它写代码——没跑过几个视频就见底了。

我盯着那行额度用尽的提示看了很久。不是被金额吓到——20 刀能算什么。是被一种更难堪的东西噎住了:我精心设计的这套「全自动 agent 流水线」,在真实成本面前,连一个下午都活不过。

一个被订阅价养出来的错觉

我后来才想明白,我那套「LLM 能做一切」的世界观,是被订阅制喂出来的。

包月订阅给你的体验是:一个固定的、心理上约等于零的边际成本。你问它一百个问题和问一个问题,月底账单一模一样。久而久之,你会真的相信调用模型这件事不要钱——于是你设计系统时,会毫不犹豫地在每个环节都塞一次模型调用,因为「反正不要钱」。

可一旦你为了把它跑成一个真实在转的生产系统,从订阅换成 API token 按量计费,这个错觉就当场崩塌。

每一次调用都开始计价。每一个 token 都在跳表。你之前那种「哪儿不确定就再问一次模型」的奢侈,现在每一次都要从钱包里掏。更要命的是,生产系统是循环的:它一天要处理几十个视频,每个视频要走五六个阶段,每个阶段你都想「让模型判断一下」。把这些一乘起来,成本不是线性增长,是血崩

那一刻我才意识到:我设计的根本不是一套系统,是一套只有在我不付全价时才成立的系统

托给它的越多,心越滴血

被迫开始抠成本之后,我发现真正难受的,居然不是钱。

钱是能算的。难受的是心智负担,而且它是悄悄长上来的。

最典型的是译名。一开始,专有名词的翻译我是整个甩给千问的——一部动画的名字、人物名、专门术语,全丢进去让它译。它大部分时候译得也还行。但「大部分时候」在生产里是个陷阱:同一个名字,这个视频里它译成 A,下一个视频里它译成 B,跨视频一对就漂移了。观感很差,而我没有任何机制能保证它稳定。

于是我得回去给它写更长的提示词,喂例子、定规则、反复试。提示词越写越长,调一次的成本也越高,而我永远不知道下一个没见过的名字它会不会又自己发挥。

更深一层的负担是恐惧。一套全自动的、循环跑的 LLM 流水线,是一个你看不进去的黑盒。我天天提心吊胆:会不会哪个环节悄悄判错了,把一堆废片当好片处理下去?会不会哪个调用陷进了某种重试或自我对话的死循环,在我没盯着的时候一直烧钱?这种「我不知道它此刻在干嘛、也不知道它花了多少」的失控感,比账单本身更折磨人。每次想到它可能正在某个角落空转,心都在滴血。

一处一处把它请下神坛

想通这两笔账之后,方向就清楚了:凡是不必须用模型的地方,就把模型换掉,换成最无聊、最确定、最能让我睡着觉的东西——普通代码。

这个过程一点都不性感。它就是一处一处地,把「让模型判断」翻译回「写一段规则」。

拿译名来说。我不再让模型去「翻译」名字了,因为名字的正确答案不是生成出来的,是查出来的。我改成了一套死逻辑:把标题拆成 tag,去番组计划(Bangumi)那样的权威条目库里搜,命中了就直接拿它登记在册的官方中文名。这名字稳定、可复核、零漂移——而且查一次的成本,和让大模型生成一次比,几乎可以忽略。

判别也是。「这条视频是不是预告片」这种问题,我本来想每条都问模型。后来发现,一个关键词正则就能解决绝大多数,剩下的边界情况再单独兜。「这段字幕是不是模型幻觉出来的」也一样——与其再叫一个模型来审,不如写一道确定性的健康闸门:时间轴越界、整段高重复、文本退化成碎片,这些都是可以用规则判死的特征,根本不需要智能。

把这些改动摆在一起,是这么一张账:

原本想让 LLM 做的实际换成了什么换的理由
翻译专有名词拆 tag → 查权威条目库 → 拿官方译名名字是查出来的,不是生成的;零漂移
判断「是不是预告片」一段关键词正则 + 边界兜底一个正则解决,不必每条都问模型
判断「字幕是不是幻觉」确定性健康闸门(越界 / 高重复 / 碎片)这些都是规则可判死的特征,不需要智能
端到端「全自动决策」状态机 + 人在关键节点兜判断黑盒换成可看见、可复核的流程

每换掉一处,我的账单就轻一点,更重要的是,我的就轻一点——因为我又收回了一小块「我能看懂、能复核、不会半夜偷偷烧钱」的地盘。

反例:要的是专精,不是更大的 LLM

但如果这篇文章读到这里,结论变成了「所以别用 AI、用代码就行」,那我就把它写歪了。

因为同一个项目里,我做了一件完全相反的事:为了一个环节,我专门去搭了一台跑模型的服务器。

问题出在转录。预告片里的台词经常被背景音乐压住,直接做语音识别,模型会大段大段地幻觉——把没有人说话的地方,脑补出一句根本不存在的台词。这种错最阴险,因为它看起来像正常字幕,不仔细核对发现不了。

一个本能的解法是:上更大、更强的多模态模型,指望它「听」得更准。但我算了笔账就放弃了——多模态本来就更贵,而且效果不稳,一次识别砸了,那份钱就白烧了,很肉疼。更大的通用模型,是用更高的成本去赌一个不确定的效果。

我最后选的,是一条完全不同的路:先用一个专精的人声分离模型(Mel-Band RoFormer),把人声从背景音乐里抠出来,再喂给转录。这个模型什么别的都不会,它只干一件事——分离人声——但它把这件脏活干得比任何通用大模型都好。前置这一步之后,原本满屏幻觉的片子,能干干净净地转出真实台词。

这一步也不是没有代价——人声分离加在线 Whisper,这套组合并不是「零成本」(现在用付费的在线转录,纯粹是因为本地没有显卡;等有了卡,这块成本几乎能整个省掉)。但关键从来不是「免费」,是性价比对不对:花一份专精模型的小钱,换一份稳定的、可预期的结果,这笔账划算得多。

所以你看,我反的从来不是 AI。我反的是「有需求就无脑上通用大模型」这个默认姿势。

那它到底该待在哪

兜了这么一圈,LLM 在我的系统里最后留在了哪儿?

留在了最末端,做它唯一不可替代的那件事:把已经确定好的信息,翻译成一句自然、地道的中文。

这里值得说清楚一个层次。翻译这件事,本身确实还是得靠 LLM——规则代码写不出有语感的句子。但我没有再把一整个翻译任务扔给它。我是先用前面那些死逻辑,把所有最容易出错的硬骨头都替它啃掉了:权威译名查好了、专有名词钉死了、明显的废片和幻觉在更早的闸门就拦掉了。等轮到模型时,它面对的不再是一道开放的、容易自由发挥的难题,而是一道已经被确定性流程收窄到很小的题——它只需要在给定的事实之上,把话说漂亮。

结果是返工骤降。把名字钉死再让它翻,和把整件事甩给它,准确率差着一大截。

flowchart LR
  A["发现 / 下载"] --> B["查权威译名<br/>(死逻辑)"]
  B --> C["健康闸门<br/>(规则判废)"]
  C --> D["人声分离 + 转录<br/>(专精模型)"]
  D --> E["翻译润色<br/>(LLM 收尾)"]
  E --> F["分发"]
  style E fill:#6366f1,color:#fff

整条流水线里,真正交给通用大模型的,就剩末端那一个发光的盒子。前面所有又长又笨的环节,都是为了让那个盒子面对的问题足够小、足够确定。

但我不敢说这是真理

写到这儿,我本该收一个漂亮的结论:你看,确定性脊柱加 LLM 收尾,这才是正确的工程姿势。

可我收不下去。因为有个问题我没法对自己撒谎:这套东西,会不会只是穷的形状?

我做这一切优化的起点,从头到尾都是成本。要是我不差钱,要是我用的还是那个边际成本约等于零的订阅,我大概率根本不会去抠这些。我会像最开始那样,痛痛快快地把每个环节都交给 agent,享受那种「一句话就让模型搞定一切」的顺滑,压根不会去写什么查表的死逻辑、搭什么人声分离的服务器。那些被我赞美成「对症」「可控」「可复核」的设计,会不会换个不缺钱的人来看,只是一堆为了省钱而背上的、本不必要的工程负担

我诚实地讲:我分不清。

我分不清「LLM 是最后手段」这条信念里,有多少是真正的工程判断,有多少只是我钱包的形状投射上去的影子。「有需求就上 agent」是一种高效的做法,我并不真的反对它(这笔效率账,我在 AI Coding 到底有没有提效 里也单独算过一篇)——也许我只是因为付不起那个高效的代价,才被迫走到了这条更笨、更便宜的路上,然后顺手把这条路美化成了一种原则。

成本逼我上了路,路上我确实撞见了一些真东西——查出来的名字比生成的稳,专精的模型比通用的对症,被收窄过的问题比开放的问题可靠。这些不像是假的。

但它们是不是非得用我这种穷办法才能换来,我说不准。我把这个问号原样留在这儿,不去强行抹平它——至少它提醒我,下一次再想张口说「这是对的工程姿势」之前,先摸一摸,那到底是判断,还是只是兜里的形状。

// related

作者头像
yen@harvey:~$ exit 0