LLM 的"严谨"与"胡说":temperature、Top K + LangChain 工作流

摘要:LLM是概率引擎,每个词都是从概率分布中抽出来的。temperature控制发散度,TopK限制候选池,两者配合决定输出是严谨还是创意。本文用LangChain搭双链条同一主题两套参数,直观对比真实效果。


目录

  1. [LLM 怎么"随机"说话?](#LLM 怎么"随机"说话? "#%E4%B8%80llm-%E6%80%8E%E4%B9%88%E9%9A%8F%E6%9C%BA%E8%AF%B4%E8%AF%9D")
  2. [temperature:从 0 到 1 的发散控制](#temperature:从 0 到 1 的发散控制 "#%E4%BA%8Ctemperature%E4%BB%8E-0-%E5%88%B0-1-%E7%9A%84%E5%8F%91%E6%95%A3%E6%8E%A7%E5%88%B6")
  3. [Top K:给候选池圈个范围](#Top K:给候选池圈个范围 "#%E4%B8%89top-k%E7%BB%99%E5%80%99%E9%80%89%E6%B1%A0%E5%9C%88%E4%B8%AA%E8%8C%83%E5%9B%B4")
  4. [实战:用 LangChain 搭建双链条对比](#实战:用 LangChain 搭建双链条对比 "#%E5%9B%9B%E5%AE%9E%E6%88%98%E7%94%A8-langchain-%E6%90%AD%E5%BB%BA%E5%8F%8C%E9%93%BE%E6%9D%A1%E5%AF%B9%E6%AF%94")
  5. 总结

一、LLM 怎么"随机"说话?

LLM 的工作方式本质上是"根据上文预测下一个词"。给定前文"你好",模型会输出一张概率分布表

python 复制代码
"你好" 之后下一个词的概率分布:
────────────────────────────
吗   0.60  ████████████████████████████████
啊   0.15  ████████
呀   0.10  █████
美   0.05  ██
坏   0.05  ██
...  (词表中有数万个候选词,都分配了微小的概率)

问题是:模型每次都选概率最高的"吗"吗?如果是这样,所有对话都将千篇一律。但如果纯随机抽,又可能抽到"坏"让对话跑偏。

真实答案是:每次生成都从概率分布中采样,但通过两个参数控制采样的"纪律"。 这就是 temperature 和 Top K 的用武之地。

flowchart LR A[上文: 你好] --> B[LLM 计算<br/>下一个词概率分布] B --> C[Top K<br/>只保留前 K 个候选] C --> D[temperature<br/>调整概率分布陡峭度] D --> E[随机采样<br/>抽出下一个词] E --> F{是否结束?} F -->|否| A F -->|是| G[输出完整文本]

二、temperature:从 0 到 1 的发散控制

temperature 的值在 0 到 1 之间,它调整的是概率分布的"陡峭度":

temperature 效果 概率分布形态 适用场景
0.2 低随机,高概率词被极度放大 陡峭------"吗"几乎稳中 代码生成、法律合同、翻译
0.8 高随机,中低概率词被拉起来 平缓------"呀"也有机会 散文创作、AI 漫剧、头脑风暴

数学上,temperature 作用在 softmax 之前:将 logits 除以 temperature。当 T < 1 时,高概率词被放大,分布变陡;当 T → 1 时,分布趋近原始形态。

同一个"你好",不同 temperature 下的实际表现:

ini 复制代码
temperature = 0.2 →  "你好吗?最近怎么样?"      (安全、常见)
temperature = 0.8 →  "你好呀,今天的风吹得人很舒服" (发散、有画面感)

三、Top K:给候选池圈个范围

Top K 是第二道闸门:只保留概率最高的前 K 个候选词,其余的全部清零。

Top K 效果 适用场景
K = 4 只从概率前 4 的词里抽,限制跑偏 需要一定创意但不想失控
K = 8 候选池更大,信息更完整 需要保证表达丰富性的严谨写作

Top K 和 temperature 是一个先过滤、再调整的两阶段流程:

css 复制代码
原始概率分布(数万个词)
    ↓ Top K:只保留前 K 个得分最高的候选
缩小后的候选池(K 个词)
    ↓ temperature:调节这 K 个词的分布陡峭度
最终采样分布 → 随机抽一个 → 输出

黄金组合

两个参数不可能都太大(那等于完全随机),也不可能都太小(那等于退化到最大概率选择,丧失多样性)。最佳实践:

组合 temperature Top K 效果
精准 + 完整 低(0.2) 高(8) 准确且不失信息丰富性,适合正式写作
创意 + 靠谱 高(0.8) 低(4) 有创意但不跑偏,适合文学创作

四、实战:用 LangChain 搭建双链条对比

理论讲完,用代码让效果一目了然。LangChain 提供了一套将 LLM、Prompt、输出解析器串联成**工作链(Chain)**的抽象。

两条模型,两套参数

javascript 复制代码
import { ChatOpenAI } from '@langchain/openai';
import { StringOutputParser } from '@langchain/core/output_parsers';
import { PromptTemplate } from '@langchain/core/prompts';

// 创意写作模型:高发散 + 小候选池
const creativeModel = new ChatOpenAI({
    model: 'deepseek-v4-pro',
    temperature: 0.8,   // 增强创意发散
    topK: 4,            // 仅从前4候选抽,防止彻底跑偏
    maxToken: 600,
    apiKey: process.env.DEEPSEEK_API_KEY,
    configuration: { baseURL: 'https://api.deepseek.com' }
});

// 严谨写实模型:低发散 + 大候选池
const preciseModel = new ChatOpenAI({
    model: 'deepseek-v4-pro',
    temperature: 0.2,   // 保守严谨
    topK: 8,            // 更大候选池,保证表达丰富
    maxToken: 600,
    apiKey: process.env.DEEPSEEK_API_KEY,
    configuration: { baseURL: 'https://api.deepseek.com' }
});

可复用的 Prompt 模板

LangChain 的 PromptTemplate 将 Prompt 从硬编码字符串变为可复用、可传参的模板

javascript 复制代码
const storyPrompt = PromptTemplate.fromTemplate(`
请写一篇短篇散文,主题{theme}
风格温柔治愈,篇幅200字左右,不要分段,文字细腻有画面感。
`);

同一个模板,传入不同的 theme 就能生成不同主题的散文------Prompt 不再散落在代码各处,而是集中管理、按需调用。

链条组装:.pipe() 串联一切

javascript 复制代码
const outputParser = new StringOutputParser();

// 创意链条
const creativeChain = storyPrompt
    .pipe(creativeModel)      // PromptTemplate → LLM
    .pipe(outputParser);      // LLM 输出 → 纯文本

// 严谨链条
const preciseChain = storyPrompt
    .pipe(preciseModel)
    .pipe(outputParser);
flowchart LR A[PromptTemplate<br/>主题=秋日山野晚风] --> B{分支} B -->|creativeChain| C[temperature 0.8<br/>TopK 4] B -->|preciseChain| D[temperature 0.2<br/>TopK 8] C --> E[StringOutputParser<br/>提取纯文本] D --> E E --> F[两段完全不同的散文]

同一主题,两种文风

javascript 复制代码
async function runWriteDemo() {
    const theme = '秋日山野晚风';

    console.log('创意写作模式');
    const creativeText = await creativeChain.invoke({ theme });
    console.log(creativeText);
    // 可能输出:夕阳把山野染成了橘色,晚风在林间跳着自由的舞...

    console.log('严谨写实模式');
    const preciseText = await preciseChain.invoke({ theme });
    console.log(preciseText);
    // 可能输出:秋天的山野笼罩在暮色中,晚风拂过灌木丛,发出沙沙的响声...
}

runWriteDemo().catch(err => console.error(err));

同一个主题 {theme: '秋日山野晚风'},同一个 Prompt 模板,唯一区别是 temperature 和 Top K 的参数不同------输出就是两篇风格截然不同的散文。创意链的句子更长更跳跃,用词更大胆;严谨链的表达更工整,逻辑更连贯。

chain.invoke({theme}) 是整个工作流的启动点------把参数塞进链条,PromptTemplate 自动填充模板,发给 LLM 生成结果,StringOutputParser 提取出纯文本,一条龙完成。

为什么需要 Chain?

不用 Chain 用 Chain
Prompt 管理 硬编码在代码各处 PromptTemplate 集中管理,变量参数化
输出处理 手动从 response 中取 choices[0].message.content StringOutputParser 自动提取纯文本
可复用性 换一个模型要改多处代码 .pipe() 链式组装,换模型只改一个节点
可维护性 业务逻辑和调用代码杂糅 每个节点职责单一,链条清晰可追踪

AI 应用开发的核心矛盾是"既要可控又要有创意"。Chain 的价值就是把"不可控的生成过程"封装进"可控的工作流"------temperature 和 Top K 让你知道它在怎么随机,PromptTemplate 让你知道它收到了什么指令,链条结构让你知道数据是怎么流转的。黑盒变成了透明的流水线。


五、总结

  1. LLM 的概率本质:每个词都是从概率分布中采样出来的。默认选择最高概率词会让输出千篇一律,纯随机又会让内容失控。
  2. temperature 是发散旋钮:0.2 放大高概率词(严谨),0.8 拉平分布(创意)。底层原理是 softmax 前的 logits 缩放。
  3. Top K 是候选围栏:只保留前 K 个得分最高的候选,其余清零。和 temperature 是两步流水线------先过滤、再调节。
  4. 黄金组合:温度低 + K 高 = 精准且丰富(正式写作);温度高 + K 低 = 创意不跑偏(文学创作)。
  5. LangChain 三步搭链条PromptTemplate 管输入、带参数的 model 管生成、StringOutputParser 管输出。.pipe() 串联所有节点。
  6. 同一主题两套参数 = 两篇不同文章:想控制 LLM 的"胡说"程度,就调 temperature 和 Top K 两个旋钮。

------ LLM 的随机是可控的,钥匙就在 temperature 和 Top K 两个旋钮上。

相关推荐
元直数字电路验证1 小时前
深入理解 AI Agent:从模型能力到生产级系统的完整路线图
人工智能·langchain·aigc·agent·智能体
带刺的坐椅2 小时前
Solon AI:Tool 与 Talent 怎么选?从函数到领域专家
java·ai·llm·agent·solon
白执落2 小时前
使用 Python + LangChain + Vue3 构建 LLM 聊天应用
人工智能·python·langchain
AINative软件工程2 小时前
LLM 账单来了,却不知道哪个功能在烧钱:Cost Attribution 工程实践
llm·ai编程
不好听6133 小时前
LLM 是怎么"随机"说话的 —— Temperature、Top-K、Top-P 详解
llm
一起努力啊~3 小时前
DataWhale组队学习笔记--llm-algo-leetcode(五)
笔记·学习·llm
To_OC11 小时前
大模型蒸馏是啥?说白了就是大厨带徒弟的学问
人工智能·llm·agent
陳陈陳11 小时前
从“胡说八道”到“妙笔生花”:我用LangChain手搓了一个可控AI写作流(Temperature+TopK调参指南)
langchain·llm