logprobs 是什么?模型每写一个字前的心理活动,置信度、候选概率一次讲明白(2026入门)

你问模型「1+1 等于几」,它回答「2」。你有没有想过,这个「2」是从哪来的?

模型内部其实给词表里每个 token 都打了一次分,每个分数对应一个概率。「2」被选中,是因为它在那一轮概率最高。但第二名的候选是什么?概率差多少?默认情况下你看不到,模型只把最终答案递出来。

这套打分机制叫 logprobs,对数概率。它能告诉你这个回答模型自己有多「确定」,也能告诉你每一次落笔时还有哪些备选、各有多大胜算。名字听起来唬人,东西本身不难,今天就把它讲明白。

先从分数到概率说起

大模型每生成一个 token 之前,都要算一遍整个词表的概率分布。词表通常有十几万个 token,每个位置一个分数,这些分数叫 logits,原始得分,没有归一化,直接看没有「概率」的含义。你在 temperature 和 top_p 那篇里调的采样参数,动的就是这份分布。

logits 经过 softmax 函数归一化,变成一组加起来等于 1 的概率(softmax 本身在 softmax 入门篇里已经拆过)。比如「2」0.82,「20」0.09,「二」0.05,剩下十几万个 token 分掉最后一点。

问题来了。概率经常是特别小的数,0.00037 这种。乘起来更麻烦,生成 100 个 token 要把 100 个小数连乘,数值会小到浮点数都存不下。

工程上的做法是取对数,把连乘变成连加。概率 0.82 取对数大约是 -0.2,概率 0.00037 取对数大约是 -8。这就是「对数概率」名字的由来:内容还是那个概率,只是换了个好存的写法。

所以当你从 API 里看到一个 logprob 等于 -2.3,它的含义是:这个 token 的真实概率是 e 的 -2.3 次方,大约 10%。数值越接近 0,模型越笃定;越往负无穷走,模型越觉得不太对劲。

API 里怎么开

主流 API 都是同一个开关思路:请求里加参数,响应里多一个字段(还不熟 API 基本盘的话,先看这篇 Kimi K3 API 上手)。

以 Kimi API 为例,请求里加两个参数。第一个是 logprobs,布尔值,设成 true 才会在响应的 message 里返回每个输出 token 的对数概率。第二个是 top_logprobs,指定每个位置返回概率最高的候选 token 数量,范围 0 到 20,用这个参数时必须把 logprobs 设成 true。

代码不用整段贴,三行就够:

from openai import OpenAI

client = OpenAI(
    api_key="你的密钥",
    base_url="https://api.moonshot.cn/v1",
)
resp = client.chat.completions.create(
    model="kimi-k2.7-code",
    messages=[{"role": "user", "content": "用一句话介绍你自己"}],
    logprobs=True,
    top_logprobs=3,
)

响应里多出来的部分长这样(示意):

content: "我是 Kimi。"
token_logprobs:
  - token: "我",  logprob: -0.09, top_logprobs: [我 -0.09, 我叫 -2.8, 您 -3.1]
  - token: "是",  logprob: -0.01, top_logprobs: [是 -0.01, 叫 -4.6, 叫做 -5.3]
  - token: " Kimi", logprob: -0.35, top_logprobs: [Kimi -0.35, 一名 -1.9, AI -2.2]

每一步都有账。模型写「我是」的时候几乎不犹豫,logprob 接近 0;写到「 Kimi」时给出 -0.35,还有「一名」和「 AI」两个备选在后面追。

OpenAI 的响应结构完全同构,它的官方 SDK 类型定义里写得明明白白:每个位置一个 token、一个 logprob,外加一个 top_logprobs 列表。列表里有一处细节值得单独说:如果一个候选 token 已经排在 20 名开外,它的 logprob 会被填成 -9999.0。这个数不是真实的概率,是一个哨兵值,表示「太靠后了,没记录」,看到就当它不存在,别拿去做算术。

logprob 怎么读:四个区间

拿到数值之后,最常见的问题是:多少算好?经验上可以分四个区间:

  • 接近 0 到 -0.3:模型非常确定,基本是条件反射。
  • -0.3 到 -1:比较顺手,有小纠结但不影响走向。
  • -1 到 -3:明显犹豫,几个候选都在认真竞争。幻觉和胡编经常从这里开始。
  • -3 以下:模型自己都不信,这种 token 出现得越多,回答越可疑。

同样一句话,有的位置模型闭着眼都能写对,有的位置它在几个选项之间反复横跳。犹豫点就是你该盯着看的地方。

整句还能算一个总账:把每个 token 的 logprob 加起来,就是整句的总对数概率。想要更直观的话除以 token 数再取指数,得到几何平均概率。比如全句平均 logprob 是 -0.5,对应大约 61% 的平均概率;平均 -2,对应大约 13.5%。这两个数可以当整段回答的「置信度」来用,批量评测的时候尤其顺手。

能用它做什么

拿它干活,常见路数有五种。

第一,扫描幻觉高发段。分类、抽取、判断这类任务,让模型只输出一个词或一个标签,然后看这个词的 logprob。置信度低的条目单独捞出来复核,比全量人工检查省力得多。长回答里也可以把 logprob 低于 -3 的 token 标出来,大概率就是胡编的位置。

第二,做分类任务的置信度输出。比如让模型从「正」「负」「中性」里选一个,top_logprobs 一开,三个候选各自的概率直接到手。你不需要模型输出「我有 80% 把握」,数字本来就在响应里。

第三,评测和改提示词。同一个任务跑 50 条样本,比较两组提示词的平均 logprob。哪个提示词让模型写标签写得更果断,一目了然。做模型选型时同理:两个模型跑同一批题,总 logprob 高的,在这个任务上更对胃口。算账口径可以参考 API 计费篇的 token 统计方法。

第四,给 Agent 设卡点。模型调用工具时,如果「选择工具」那一步的 logprob 很低,说明它自己也不确定该调哪个。可以在这种位置插一轮追问或者人工确认,而不是让错误一路传导下去。工具调用的完整流程看 Function Calling 入门。

第五,训练和蒸馏场景。用 top_logprobs 把候选概率导出来,就是现成的软标签数据。蒸馏里管这叫软目标,数值比只有对错的两类标签信息量大得多。自己跑开源模型的话,vLLM 的 SamplingParams 里也有对应参数,还能对输入部分的每个 token 打分,做数据筛选很方便,尤其是你想给某个垂直领域攒一批高质量训练样本、又付不起人工标注钱的时候。

几个容易踩的坑

坑一:logprobs 不是评分器。它是模型对「下一个 token 该是什么」的信念,不是对你任务答案的质量评分。问它「1+1 等于几」然后输出「7」,这个「7」的 logprob 也可能很高,因为模型真这么觉得。它度量的是确定度,不是正确度。这一点最容易被人误解。

坑二:探索性写作里低置信度是正常的。写小说、起标题这种发散任务,模型本来就该在多个方向上犹豫。低 logprob 不等于出错,别一刀切报警。确定度高的任务(分类、抽取)才是它发挥的地方。

坑三:候选列表有截断。top_logprobs 最多 20 个候选,20 名开外的候选拿不到真实概率(OpenAI 生态里填 -9999.0)。你想知道「模型认为某某说法的概率」,如果这个说法没进前 20,答案是查不到,不是 0。别把 -9999 当成「概率极小」,它只是个占位符。

坑四:各家参数形状不一样,用前查文档。OpenAI 和 Kimi 是「布尔开关 + 数量上限」的形状,vLLM 是「直接填数量」,位置、默认值、上限都有差异。本文只给了 Kimi 和 OpenAI 生态的形状,其他平台用之前去翻一遍参数文档,别照抄。

坑五:思考型模型的 logprobs 支持情况要单独确认。现在不少主流模型默认开启思考模式(原理见 思考模式入门),思考部分的 token 要不要计 logprobs、怎么计,各平台处理不一致,用前先查文档或者实测一下。

一个完整的判断流程

把上面的东西串起来,实践中可以用这样一个流程:

任务里哪些 token 的答案「只许对不许错」?先把这类输出圈出来。跑一批样本,统计这些位置的 logprob 分布,定一条线,比如低于 -2 的进复核队列。上线之后持续监控这条线的命中量。命中突然变多,说明提示词或者模型该查一查了。

这个流程没有高深的东西,我自己的用法也是这样:先圈重点,再定线,剩下交给监控。

logprobs 这个功能在 OpenAI 生态里已经存在很多年,不算新东西,但真正把它用起来的团队不多。它不需要额外花钱开会员,也没有复杂的接入流程,就一个请求参数。下次写提取和分类的代码时,顺手把它打开,你会对模型的「心理活动」有具体得多的判断。

下一篇预告:RAG 里查询效果差怎么办?查询改写的几个经典套路,包括多查询和 HyDE,下篇见。

发表评论