
工单打标这活儿以前是真·体力活。团队里两三个运营天天守着工单后台一条条看用户反馈然后挪到不同的分类目录里。量大一点就扛不住分错还特别正常——支付问题被标成产品咨询用户多等两轮满意度蹭蹭往下掉。后来大家都开始尝试用大语言模型的API来做自动打标确实快但真踩进去会发现里面门道不少方式有好几种各有各的脾气选错路子费钱又费时间。这篇文章我把自己试过的和身边同行用过的5种主流方式整理出来顺便聊聊目前争议最大的几个点给准备上手或者正在纠结方案的你一个参照。先说清楚这事的适用读者如果你正在做客服工单系统、用户反馈分类、需求标签聚合或者任何文本进来、标签出去的事情这篇都值得看完。如果你只是好奇LLM API能干嘛前面的原理部分也能帮你建立起基本判断。1. 工单打标这件事为什么值得用LLM重做一遍在聊5种方式之前先把为什么说透。因为很多团队上来就问用哪个模型好但其实连打标的目标都没理清——是给客服看还是给产品经理看是粗粒度分五大类还是细粒度给几十个标签这两个问题直接决定后面的技术路线。1.1 传统关键词规则的死穴以前做工单打标最常用的方案是关键词规则写一大堆正则表达式什么退款匹配售后多久发货匹配物流。这套东西看着简单用起来全是泪。一方面用户表达五花八门同一个意思能给你写出十种说法钱没到账、} 到账 、支付成功但没提示……关键词根本列不全。另一方面规则之间还会打架优先级设置错了一条工单同时命中两个分类系统就傻眼。最痛苦的是维护成本规则越写越多后期改一条规则可能牵出一串连锁反应负责维护的人想骂人。1.2 LLM API打标真正带来的是什么LLM API做打标本质上是把让机器理解语义这件事从规则工程师手里解放出来。它不需要你穷举所有表达方式模型本身对自然语言有理解能力你只告诉它根据用户描述判断属于哪个类别它就能处理那些你根本没想到的变体表达。这一点是质变不是量变。实际用下来还有一个隐性的好处打标规则变得可维护了。以前改分类口径要改代码、改参数现在改分类口径只需要改Prompt里的描述文本。运营同学自己都能上手调整不用每次排队等开发。这一点对业务迭代快的团队来说价值甚至超过准确率本身。1.3 适合谁、什么时候上这套方案我的判断是工单量日均超过200条或者现有规则分类准确率已经明显低于人工水平就值得考虑用LLM API。如果每天只有几十条工单人工分一分也就半小时没必要为了技术而技术徒增成本。另外还有一种情况也适合上你的工单标签体系本身还在快速变动比如新产品上线期间用户咨询方向随时可能出现新类别传统规则完全跟不上这时候LLM的灵活性就是压倒性优势。2. 5大主流方式的拆解与选型现在进入正题。我按实际使用中由浅入深的顺序把这5种方式逐个拆开讲它们各自怎么运作、适合什么场景、成本表现如何、踩坑点在哪里。2.1 方式一Prompt直出分类Zero-shot模式这是最直接的一种做法把工单内容拼接好在Prompt里写上分类说明让模型直接输出类别名称。比如请判断以下工单内容属于哪个类别{售后问题、物流问题、支付问题、产品咨询、其他建议} 工单内容我刚下单怎么还显示未支付 直接输出类别名称不要解释。这种方式的好处是零门槛照着上面这个格式抄就能跑。实测下来对于大类目5到10个标签的粗分类不少模型的准确率能到85%以上已经优于很多关键词规则的命中率。而且改动灵活类别变了改Prompt就行。但坑也很明显第一输出格式不稳定。模型可能多输出一句解释或者把类别名写变形导致下游程序不好解析。第二对类别描述敏感。如果你在Prompt里只写售后问题四个字模型理解得比较泛你写上包括退货退款、维修换货、发票相关反而准确率明显提升。第三上下文理解受限。工单通常很短但如果用户在一条工单里接连吐槽了三个问题Zero-shot模式经常只覆盖最后一个前面两个就被漏了。这一点我们在后面核心争议里还会细聊。2.2 方式二Few-shot示例增强Zero-shot不够稳时大多数人第一步会想到在Prompt里塞几个例子这就是Few-shot。实际操作方式是在分类说明后面加上两三条已经分好的样例格式如下请判断以下工单内容属于哪个类别{售后问题、物流问题、支付问题、产品咨询、其他建议} 参考示例 工单内容快递三天没动了什么时候能到 类别物流问题 工单内容买的东西有瑕疵想退货怎么操作 类别售后问题 工单内容电池能用多久 类别产品咨询只要这几条示例选得够典型准确率可以在Zero-shot的基础上往上涨3到8个百分点。原理不难理解模型不需要凭空推理你的分类口径了它从示例里直接学到原来你这套体系把这种情况归到这类。但需要留意的是Few-shot不是随意加例子就生效。示例本身要有代表性最好覆盖容易混淆的边界情况。比如你在售后问题和产品咨询之间经常分不清那么示例里就该放一两个这类型的边界案例让模型看清楚你希望的切割线在哪里。另外每次请求都带上这些示例会额外吃掉token对成本有一定压力。2.3 方式三函数调用/结构化输出这是我认为工程上最稳妥的一种方式也是我个人项目里目前的主力方案。所谓函数调用就是让模型不是输出一行随意文本而是输出一个严格符合JSON结构的对象。大部分主流LLM供应商的API都内置了Function Calling能力前端给它一个函数描述它就知道把结果包装成固定Schema。你定义这样一个输出结构{ category: 售后问题, confidence: 0.92, summary: 用户反馈商品有质量问题需要退货 }然后在请求里声明这个结构作为可用函数模型就会严格按这个格式吐数据不再出现直接输出类别名称但模型偏要解释两句的情况。confidence这个字段我建议一定要有它可以在下游做置信度过滤——低置信度的工单不进自动分类队列转人工处理这是控制整体准确率的关键。这种方式很大程度上解决了方式一和方式二输出不规范的痛点也让批处理流水线写起来干净很多。代价是需要多写一点代码对技术团队来说通常不算门槛对完全不懂的运营同学来说则是需要开发配合的一步。2.4 方式四Embedding 语义相似度分类很多团队在尝试这条路先不用LLM的内容生成能力而是把工单文本和每个类别的代表描述都转成向量然后计算余弦相似度相似度最高的那个就是预测类别。做法是先准备好每个类别对应的中心向量。怎么得到把历史已分类工单按类别分组分别调用Embedding API生成向量取平均作为该类的中心。新工单来了同样转成向量算它跟每个中心的相似度最高者胜出。这种方式的优点很突出速度快、成本低、结果可解释性强你能清楚看到它为什么分到某个类。实测中最适合大类目不多的场景如果类别在10个以内稳定性其实不错。缺点是对每个类别中心向量的描述敏感类别语义本身比较模糊时会互相打架多标签场景也麻烦——一个工单对应多个类别时相似度计算的方式会变得复杂。还有一种变化玩法是不靠历史工单取平均值而是每个类别用一句话描述作为代表文本再转向量。这种方式更灵活但稳定性不如历史工单平均对描述语句的选择比较挑剔。选哪条路建议根据你们已有数据的质量来定。2.5 方式五微调专用分类模型最后一种是重武器用历史工单数据微调一个专用于你们分类体系的模型。这种方式适合数据量足够大、标签体系足够稳定的团队。所谓足够大我的经验是至少要有一两万条已经标好的工单且分类均衡太少的话微调收益不明显反而容易过拟合。微调在效果上的优势是上限最高因为模型见过大量你们自己的真实工单对特定领域的表达方式、黑话、你们家特殊的业务逻辑都了然于心。实测在一些垂直领域微调模型的准确率可以明显超过前面所有Prompt方案属于那种一劳永逸把效果做上去的路子。但代价也最大需要数据清洗、标注一致性检查、训练周期、GPU费用或API微调费用、后续标签变动时重训模型……整套流程下来少说几个星期。如果你今天标签体系三天两头在动微调就是驴唇不对马嘴。2.6 五种方式的横向对比方式上手成本准确率上限延后维护适用标签数量每次调用成本Zero-shot Prompt极低中等偏高极低5-10个为宜最低仅文本分类说明Few-shot Prompt低高低5-15个中需带示例tokenFunction Calling中高中5-20个中高输出结构token占用较多Embedding相似度中中高中15个以内更稳低向量调用便宜新工单无Prompt输出微调专用模型高最高高20个以上也能扛部署后按量计费与标准API相当这张表格不是我闭门造车写的而是把我们自己的项目数据和几个同行交流的结果汇总出来的。它代表一种普遍性判断但具体选型一定要结合你们工单的形态是长文本还是短文本是客单式多人对话还是单次提交标签之间是互斥还是允许重叠这些都会影响效果。3. 实操用Function Calling跑通一个完整打标流水线光讲原理太虚我拿一个模拟项目来走一遍完整流程。项目背景就是一个电商平台需要给用户反馈工单打标标签体系先定为{售后问题、物流问题、支付问题、产品咨询、其他建议}五大类。目标是在保证分类准确率的前提下实现每分钟处理几百条的批处理能力。3.1 数据准备与标签定义开跑前先做两件事。一是拉出过去两周两万条已人工分类的工单按类别均衡抽出一百条作为测试集注意不要污染到Prompt的示例集里否则评估结果虚高。二是把每个标签的说明写具体比如售后问题退货退款、换货、维修、质量问题、发票相关 物流问题快递配送超时、物流轨迹不更新、丢件破损、发货时间咨询 支付问题支付失败、扣款未到账、优惠券无法使用、退款进度 产品咨询功能使用、商品规格、使用方法、兼容性 其他建议无明确诉求的吐槽、改进建议、非以上四类的任何内容这一步骤千万不要省也不要嫌麻烦。标签描述写得细不细对效果影响非常大——测试下来描述泛泛的Prompt准确率很可能只有75%描述具体的能到88%以上。3.2 设计输出结构并写核心调用代码接下来用函数调用来约束输出格式。以某供应商API为例核心调用逻辑长这样import json from openai import OpenAI client OpenAI( # 自行配置密钥与模型参数 api_keyYOUR_API_KEY, ) functions [{ name: tag_ticket, description: 为工单打标并提取关键摘要, parameters: { type: object, properties: { category: { type: string, enum: [售后问题, 物流问题, 支付问题, 产品咨询, 其他建议] }, confidence: { type: number, description: 0到1之间的置信度分数 }, summary: { type: string, description: 一句话概括用户核心诉求 } }, required: [category, confidence, summary] } }] def tag_ticket(content): response client.chat.completions.create( modelyour-llm-model, messages[ {role: system, content: 你是一位工单分类助手只负责根据工单内容打标不回答无关问题。}, {role: user, content: f工单内容{content}} ], functionsfunctions, function_call{name: tag_ticket}, temperature0 ) args json.loads(response.choices[0].message.function_call.arguments) return args有几点值得展开说明。temperature0意味着每次输出基本唯一不会同一个工单这次分A下次分B这在工单流水线上是底线级要求。function_call参数显式指定必须调用这个函数可以防止模型东拉西扯输出废话。结构里的confidence先留着在下一步会派上大用场。3.3 置信度阈值与人工兜底设计置信度不是摆设它是我在工单系统里真正的安全阀。跑完上面这段你会拿到一批带有置信度的分类结果。这时候别急着直接入库先做一个分布统计通常情况下95%以上的工单置信度都在0.8以上其中绝大多数会是正确分类。剩下5%置信度偏低正好是系统拿不准、需要人工介入的部分。我个人的经验是把0.8作为阈值高于0.8自动打标入库低于0.8进入待人工确认队列由运营统一复核。这样设计有几个好处可以卡准确率——自动入库的部分准确率能拉到97%以上人工只需要处理很少量确实有争议的工单成本可控系统中还能始终保留一条人工兜底路径出问题时有退路。3.4 批量跑批的工程细节单条调用性能很有限真正干活要设计批量流水线。我采用的是并发控制在10路的朴素方式每分钟能跑五六百条对中小规模项目完全够用。更省成本的做法是走供应商的Batch API把当日工单拉成一个JSONL文件提交几小时内返回结果费用比单条并发便宜不少但延迟高很多适合隔天出结果的分析场景不适合实时分类。批量跑批时最常见的坑是超时和限流。LLM API并发高了容易被限流不要一上来就把并发拉到50路稳妥的是10路起观察响应延迟和报错率再逐步往上探。另外每条工单提交前要做截断处理超长工单截断到1000字以内既省token又避免模型被消极的长文带偏。4. 核心争议效果、成本、幻觉与工作流边界光有流程远远不够真正让团队头大的其实是下面这四类争议。我把它们单独拎出来聊是因为这些点不是技术参数能解决的每一个都涉及业务与技术的权衡。4.1 争议一准确率到底行不行——看跟谁比、怎么测LLM打标准确率超过人工这种说法我劝你直接无视。准确率是个依赖基数的概念你们的工单结构、标签体系、分类口径全都不同别人测出来的数字跟你没有半点可比性。更实际的做法是拿你们自己的历史工单建一个测试集然后跑一轮对比实验。但这里有个隐蔽的争议点怎么定义正确同一个工单在售后和产品咨询之间不同的人本身就有不同判断。我和几个团队共用过一批测试数据人工标注的一致率所谓Kappa值也只在0.85到0.92之间。所以先别急着逼模型做到100%先把你们内部人工标注的口径对齐再来谈模型的准确率。模型分错的工单有时不是它错了而是标注标准本身互相打架。4.2 争议二成本到底贵不贵——别只算单次调用很多人算成本只看调一次API多少钱这是典型的算账误区。完整成本的构成应该是单次调用token费用 重试成本 Prompt调试时间成本 模型选错后返工成本。其中Prompt调试的时间成本最容易被忽视几个人折腾两周换来的准确率提升折合的人力成本可能已经超过API费用的十倍。另一个争议是要不要为了省成本用Embedding方案而放弃LLM直出我的观点是看业务对错误率的容忍度。工单打标错误会让用户多等一轮体验受损但如果只是给内部分析做个粗维度错几个并不致命。不同的容忍度配上不同方案没有放之四海而皆准的最优解。4.3 争议三幻觉与多标签漏标问题幻觉放在工单打标里比想象中更隐蔽。最常见的幻觉不是凭空编造而是在多标签工单里只挑一个标签输出。用户写支付扣款了但东西没发货申请退款这条实际上同时涉及支付问题、物流问题和售后问题。模型即使支持结构化输出也只按你给的schema吐一个category其他两个就那样被吞掉了。解决多标签有两种路线。一种是在schema里把category改成数组让模型输出一至多个标签但这对模型的指令遵循能力有更高要求标签多了容易乱。另一种路线是先判定再拆分第一步先判断是否复合问题是的话现场切分成多个子工单再分别调一次分类接口。后者更稳但成本翻倍。我们目前的做法是先尝试让模型输出数组标签同时用置信度做保护一旦信心中位数偏低自动降级到拆分路径。权衡下来准确率和成本勉强能接受。4.4 争议四LLM打标会不会取代规则与小模型这是团队内经常吵的事。支持派觉得LLM语义理解碾压规则反对派觉得规则逻辑透明、完全可预期、零成本。我的真实感受是它们不该是取代关系而是分层关系。一条工单进来先走硬规则快速通道——命中某些强关键词的直接打标一分钱不花不符合规则的再走LLM分类低置信度的进入人工。这样90%的常见工单被规则低价拦截LLM真正专注处理那些需要语义判断的长尾内容。这种分层模型也回应了成本贵的争议不是所有流量都需要LLM只有最值得的那部分才值得花钱。我看到很多团队一上来就All in LLM把全部工单都走一遍API经费烧得飞快其实大可不必。5. 常见拦路问题与排查实录最后这部分全是干货我把实操中大概率会撞上的问题统一列出来每条都给出排查思路和解决办法。5.1 输出格式飘忽不定即使加了Function Calling偶尔还会出现参数缺失或抛错的情况。排查思路是分三步走先看模型返回的原始JSON长什么样确认到底是字段名变了还是结构坏了其次在函数定义里把所有可能的值都放入enum减少模型自由发挥的余地最后还是不行换一个命令遵循能力更强的模型版本很多供应商的标准版和加强版在这方面差距明显。5.2 标签定义改了一版效果反而变差这种情况我听好几个团队抱怨过。多半原因是改动的标签描述语义过宽或互相重叠。比如把产品问题和售后问题的说明里都写了质量问题模型就会经常拿不准。解决办法是明确标签之间的排他边界在Prompt里加一句如果同时命中两个领域以用户主要诉求为准。5.3 工单内容是对话型文本分类被上下文带偏你们的工单如果是客服和用户一来一回的对话体直接整段丢给模型它很容易被中间内容干扰。保险做法是只取用户发送的最近一条最初反馈两段作为输入去掉客服回复部分。如果你做不到自动切分可以先把全部文本拼接后再让模型先做用户诉求提取这一步再基于提取结果做分类两步走虽贵但稳。5.4 长内容工单把分类重点稀释了工单太长时最相关的信息往往埋在中后段模型的注意力会被大量无关词带跑。有时候用户在开头先说了一大段背景最后才轻描淡写说了真正的问题。针对这种情况我试过几种办法最有效的是截取文本时不要用固定长度而是按句号切前几句和后几句组合成摘要块再丢给模型。优先保留用户最后的明确诉求句。5.5 批次结果里出现分布异常已经跑通的流水线某天突然发现支付问题数量暴增先别急着怀疑模型抽风。排查顺序是先看输入数据样本是不是某个渠道或某类设备产生了大量同类问题再检查标签定义是否改过最后看供应商API版本有没有被平台侧悄悄切换。有一回我们的异常就是平台侧把模型路由到了低配版本误打误撞定位半天才发现。5.6 打标系统上线后运营认可度低怎么办这个问题比技术问题更致命。即使准确率数字好看运营每天还是要处理几十条复查工单他们就会觉得帮我干活还是给我添活。我的建议是上线初期把复查界面做轻——让运营在一屏内完成确认/修改标签两个动作顺手看一眼前一次分类的置信度。等到他们确认质量稳定了逐步把低置信度队列缩窄信任感才会建立起来。6. 一条贯穿始终的实操底线最后分享一个贯穿整个项目的经验无论选哪种方式都一定要在交付前把评估测试集和置信度日志铺好。这两个东西一个是标尺一个是体检表缺任何一个后续的优化都是在黑箱里瞎猜。我见过太多团队热血澎湃地上了LLM API打标结果用了几周又开始悄悄加回关键词规则原因就是没有把这次改动让准确率提升了多少这个数字量化出来一遇到运营抱怨就慌慌就退回到老路。准确率、成本、人工复核占比这三个数字每周拉一次长期盯住你才能心安理得地用LLM替代传统方案也才能在老板问效果怎么样时不慌不忙地甩出数据而不是感觉。工单打标只是LLM API在企业落地中最不起眼的一个场景但把这个流程打磨顺了你收获的远不只是省几个人力——你会建立起一套如何用语言模型与业务数据协作的方法论。这套东西才是真正能用很久的资产。