
别把 LLM 当分类器,把它的判断当特征
让 LLM 直接输出标签,校准、阈值控制、对结构化数据的利用、可解释性全都会失控。把它的判断当成一个特征喂给逻辑回归,这些性质就都回来了;再叠上 LLM 抽取的特征和一批规则特征,讽刺识别任务的 Brier 分数从 0.259 降到 0.127,F1 从 0.747 提到 0.779。
原文来源:Minimally Sufficient — 与其让 LLM 直接吐标签,不如把它的判断当成特征交给逻辑回归:概率校准、阈值控制、结构化特征和可解释性都能拿回来,实测效果还超过了比赛冠军方案。
把 LLM 当分类器用——给一段上下文,让它返回一个标签——是很难用的一件事,麻烦的地方在于它往往表现得还不错。
先想想我们到底希望分类器具备什么性质,再看 LLM 直接输出标签能满足几条。
校准与阈值控制。 LLM 给出的通常是硬标签。你能拿到 token 的对数概率,但没有任何机制能说明这些概率是校准良好的;直接问模型「你有多确定」,同样没有理由认为那个数字可靠。随之而来的问题是:你很难用这些标签去有原则地权衡精确率和召回率。
用上所有可用信息。 LLM 处理非结构化文本很强,但我们手里常常还有干净的结构化数据。你可以把它塞进提示词,但 LLM 并不真的需要用它——哪怕是纯文本部分,我们也不知道模型到底用没用上。更麻烦的是,LLM 内部带着先验,这个先验未必匹配你的数据分布。比如它不知道我们是在正例稀少的样本上评估,还是在正例被刻意增多的样本上评估。你当然可以把这些背景写进提示词,但那意味着每换一个人群就要改一次提示词,而且和第一条一样,改了也不代表模型真的把它纳入了判断。
可解释性。 某种意义上提示词是高度可解释的——毕竟它是自然语言写成的。但我们也说不清模型内部到底发生了什么,提示词里哪些部分被正确执行、哪些根本没被理会。
这些失败不是 LLM 的锅:它本来就不是为分类任务设计的,也确实没有机制去实现上面这些事。但如果框架换一下,情况就不一样了。
把 LLM 判断当成一个特征
用一个合适的框架去发挥 LLM 的力量,就能同时拿到 LLM 的能力和传统机器学习算法的便利。先看一个最简单的做法:把 LLM 的判断包进逻辑回归:
p(y = 1 | x) = σ(α + β · LLM(x))
注意当 β → ∞ 时,这个模型基本就退化成了原来的 LLM 分类器。但这是个很蠢的参数选择策略。正确做法是照常规流程,用训练数据估计参数 α 和 β——问题会塌缩成两种情形,直接用经验估计:
p(y = k | LLM(x) = 1) = Σᵢ I(yᵢ = k 且 LLM(xᵢ) = 1) / Σᵢ I(LLM(xᵢ) = 1)
再回头检查那几条期望的性质:
- 校准与阈值控制:把 LLM 预测当特征用,会得到两个按经验比例给出的预测(因而在期望意义上是校准的)。随着特征增加,不同的点会越来越多,只要模型足够灵活,结果大致是校准的,而且我们还有办法继续改进。更重要的是,手上有了真正的概率,就可以按需要挑操作阈值来权衡精确率和召回率。
- 用上所有可用信息:这就是个逻辑回归,当然可以加其他协变量。要适配不同基线,逻辑回归会在训练集上拟合,从而自动适配那个基线的样本分布和协变量结构,甚至可以通过给样本重新加权去偏向其他分布。
- 可解释性:LLM 判断本身怎么解释仍然是个问题,但至少现在我们知道它对最终决策贡献了多少——尤其是在同时放进其他协变量的情况下。
想要的几条性质基本都回来了。还能再往前一步吗?
—— 广告 ——
更好的地方在于「优化路径」变了
假设模型效果不满意,应该怎么办?
在「LLM 当分类器」的路子里,唯一的办法是折腾提示词。这是门玄学,网上建议一大堆,真知灼见很少,祝你好运。
从机器学习的角度看,把模型变好的标准手段是这些:
收集更多数据。 这确实不够酷——LLM 分类器的诱人之处就在于免训练。所以「需要训练数据」听起来让人失望。但这点不方便其实比想象中轻:你总归要有一个测试集来评估性能(你打算量化性能的,对吧?),那再多准备一点训练数据又难到哪去。
把特征做得更好。 编辑自然语言写成的提示词时,「改进特征」很抽象,但至少可以筛特征:如果你相信某个特征出现就一定意味着正例,那可以经验性地验证这一点,不合适就调试。也可以把特征本身当成评估对象——把它设成次级目标,递归地去做一个更好的特征分类器。
创造更多特征。 你可以利用模型的残差来想该怎么改进,但不是去改措辞,而是考虑更广的特征集合。最直接的一个:把判断 token 的对数概率拿出来当特征;或者让分类器跑多次(如果判断前有推理过程,那些对数概率会趋于 0 或 1)。也可以让 LLM 输出更多东西——子判断、或其他维度上的特征。
改进模型结构。 这一步纯属即插即用。不喜欢逻辑回归?换成 xgboost 或神经网络。你想让 LLM 来实现一套基于规则的系统也行。都可以。
实测:讽刺识别
用一个具体例子把它做实。数据用 SemEval 2018 Task 3 数据集——4618 条由专家标注讽刺倾向的推文(3834 条训练 / 784 条测试)。讽刺识别很适合这个议题:这是一个 LLM 明显能提供真实信号的自然语言任务,而 LLM 内嵌的世界知识在这里正好有用。
提示词让模型做一个二分类判断,整批推文一次性跑完:
from typing import Literal
from pydantic import BaseModel, Field
MODEL = "gemini-3.1-flash-lite"
PROMPT_TEMPLATE = """\
Irony is when someone says one thing but means another, often for \
humorous or critical effect. It can be subtle: a tweet might read as \
sincere at first glance but carry an ironic tone through word choice, \
context, or contrast.
Consider the following tweet and label it as "Ironic" or "Not".
{tweet}"""
class Verdict(BaseModel):
reasoning: str = Field(
description="Brief reasoning: what language or context suggests irony or sincerity."
)
verdict: Literal["Ironic", "Not"] = Field(
description='Whether the tweet is ironic ("Ironic") or not ("Not").'
)
def build_request(row_id: int, tweet: str) -> dict:
return {
"contents": [
{"role": "user", "parts": [{"text": PROMPT_TEMPLATE.format(tweet=tweet)}]}
],
"metadata": {"id": str(row_id)},
"config": {
"response_mime_type": "application/json",
"response_schema": Verdict,
"temperature": 0,
},
}只用提示词的表现
| TPR | FNR | Brier 分数 | F1(阈值 0.5) |
|---|---|---|---|
| 0.965 | 0.035 | 0.259 | 0.747 |
一次性的零样本提示能做到这个程度相当惊人——你本来不会指望不训练就能实现这种效果,这正是 LLM 有意思的地方。当然也就那样:Brier 分数很差,因为完全没有校准(其实纯随机猜也能拿到 0.25 的 Brier 分数)。
加上逻辑回归
逻辑回归能把校准做好(注意它不改变排序,所以 F1 不变):
| LLM 判断 | 拟合出的 P(Ironic) |
|---|---|
| Ironic | 0.687 |
| Not | 0.188 |
| TPR | FNR | Brier 分数 | F1 |
|---|---|---|---|
| 0.965 | 0.035 | 0.175 | 0.747 |
再加特征
先看看分类错误的样本(两个模型错的是同一批),能明显看出问题在哪:有的推文反讽靠的是外部语境(「我不能呼吸」被选为年度名言),有的是习语翻新(「won't fit the crime」),有的是自嘲式的重复("loyalty vs. self protection" 反复念),单看文本确实难判。
于是把提示词改成多维度分析:先给出讽刺判断,再让模型回答 19 个问题,比如「是否想搞笑」「描述的是不是现实中可能发生的事」「是否需要用外部语境才能理解作者意图」「是不是在真诚地抱怨」「是否用正面语气描述负面处境」「是否自嘲」「是否有显式对比」「是否是反问」「是否是明褒实贬」「是否针对特定人物或机构」「抛开语气,描述的处境本身是否负面」「是否是字面意义的批评」「是否在赞同一个明显糟糕的结果」「是否对可预见的事假装惊讶」「是否是夸张的假热情」「是否是双关或文字游戏」「是否涉及政治」「是否涉及名人或体育」「是否关于日常琐事」。
同时手工加上一批确定性特征:
| 特征 | 含义 |
|---|---|
| is_reply | 推文以 @ 开头(回复) |
| has_url | 包含 URL |
| tweet_length | 字符长度 |
| n_hashtags | # 的数量 |
| n_exclamations | ! 的数量 |
| n_caps_words | 全大写单词数(长度 > 1) |
| has_ellipsis | 是否含省略号 |
| starts_with_quote | 是否以引号开头 |
| n_emoji | emoji 数量 |
三个嵌套模型的结果:
| 特征 | Brier | F1(测试集) |
|---|---|---|
| 只有判断 | 0.175 | 0.747 |
| + LLM 特征 | 0.131 | 0.768 |
| + 规则特征 | 0.127 | 0.779 |
每加一层特征都有明确收益,包括那些完全在 LLM 之外、靠规则算出来的确定性特征。可解释性这边也拿到了东西:逻辑回归的系数能直接看出模型在控制其他变量后真正依赖哪些特征。
和论文结果对比
| 系统 | F1 |
|---|---|
| 随机基线 | 0.373 |
| SVM + tf-idf(论文的 NRC 基线) | 0.589 |
| THU_NGN(比赛冠军) | 0.705 |
| NTUA-SLP(赛后方案,LSTM + 注意力) | 0.786 |
| LLM 硬标签(本文) | 0.747(0.712–0.778) |
| LLM + 逻辑回归 | 0.779(0.746–0.81) |
只靠提示词的 LLM 分类器轻松超过比赛冠军(0.747 对 0.705)。换成特征工程的思路之后,仅仅在 LLM 抽取的特征上叠一个逻辑回归,置信区间就已经和赛后最优方案重叠。
这门手艺值得认真对待
让 LLM 可靠地充当分类器是苦活,但潜在收益很大。现在越来越多研究依赖 LLM 做分类——比如分析 ChatGPT 使用方式的报告要用 LLM 给对话打标,Hugging Face 那次事件的「slop 调查」也是这样。我们需要从这些工具里拿到高质量的结果。好在支持这条思路的论文正在变多:
- Han 等,《Large Language Models Can Automatically Engineer Features for Few-Shot Tabular Learning》(ICML 2024)
- Balek 等,《LLM-based feature generation from text for interpretable machine learning》(2024)
- Malberg、Mosca 与 Groh,《FELIX: Automatic and Interpretable Feature Engineering Using LLMs》(ECML PKDD 2024)
作者本人更感兴趣的是「智能体式分类器」:不再固定特征集合,也不预先声明类别,而是让 LLM 自己去调查。它可以把调查过程本身的性质当特征用——相当于给调查的严谨程度和全面程度打分。只要有一个可靠的测试集,就能对结果做统计上有效的推断。
© 2026 四月
原文链接:https://www.aprilzz.com/tutorials/llm-classifier-feature-engineering
相关文章
OpenRouter 实战避坑:同一个模型,换个 Provider 就像换了另一个模型
同一个 DeepSeek V4 Flash,不同 Provider 的 TAU-Bench 成绩能差二十多个百分点。一位处理过 1800 万条消息的开发者,把用 OpenRouter 踩过的 10 个坑整理成了清单。
RAG 没那么复杂:6 个检索方案,从最小到完整
大多数人的 RAG 栈都过度设计了。这篇指南给出 6 种检索方案,从纯全文搜索到全量预 embedding,每个都有明确的适用条件、成本账和权衡。
llama.cpp 还是 vLLM?2026 年本地 LLM 推理引擎选型指南(附实测基准)
Red Hat 工程师用 Llama 3.1 8B 在单张 H200 上实测了两个主流推理引擎:64 并发下 vLLM 吞吐是 llama.cpp 的 44 倍,但 llama.cpp 在消费级硬件上依然是唯一选择。本文把量化、GGUF、PagedAttention、连续批处理讲清楚,附完整选型决策树。