首页
看点啥
插画图片
首页 看点啥 一文讲透 Temperature 与 LangChain:从模型随机性控制到组装 AI 工作流

一文讲透 Temperature 与 LangChain:从模型随机性控制到组装 AI 工作流

2026-07-22 0

一文讲透 Temperature 与 LangChain:从控制模型随机性到组装 AI 工作流

今天上手跑通了第一个 LangChain 应用——用不同温度参数控制模型风格输出。这篇文章沿着我实际学习的路径,从"大模型为什么能随机说话"一直讲到"LangChain 怎么把 AI 工作流串成一条链"。

一文讲透 Temperature 与 LangChain:从控制模型随机性到组装 AI 工作流

先看文件全貌和它们的依赖关系:

 复制代码readme0721.md(参数理论:Temperature、Top-k、Top-p 是什么)
       ↓  理论落地
main.js(实践代码:双温度模型 + PromptTemplate + pipe 串联)
       ↓  框架展开
langchain-explained/readme.md(LangChain 全模块生态概览)

教学逻辑是 概念 → 落地 → 全景:先搞懂三大随机性参数怎么控制输出,再用 LangChain 把它们写进代码,最后俯瞰整个框架的能力边界。


一、大模型是怎么"随机"说话的?

大模型每生成一个词,本质是从一个概率分布里做一次"抽奖"。输入「你好」,模型会说:

 复制代码下一个词候选:
  「吗」35%   「啊」20%   「世界」15%   「我是AI」10%   「呀」7%   「哈哈」5%

从这个概率分布出发,有三个参数可以玩。

Temperature:马太效应的调节阀

底层公式很简单:

 复制代码调整后分数 = logits / Temperature
最终概率   = softmax(调整后分数)

Temperature < 1(低温)——除以一个小数放大差距,强者更强:

 复制代码T=0.3: 吗 72%   啊 18%   世界 6%   我是AI 3%
       ↑ 几乎锁死在「吗」

Temperature > 1(高温)——除以一个大数拉平差距,人人有机会:

 复制代码T=2.0: 吗 22%   啊 18%   世界 17%   我是AI 15%   呀 13%
       ↑ 百花齐放

不是——它只调整概率分布的"陡峭度",最终还是从新分布里随机采样。T=0.3 时「吗」占 72%,但依然有 28% 的概率抽到别的词。

结论:Temperature 是"马太效应调节阀"。写代码/合同设 0.2,搞文艺创作设 0.8。

Top-k 和 Top-p:砍掉垃圾的过滤器

Temperature 设高了之后,那些只占 1%-2% 的垃圾词也被一起拉高概率了——输出会不会崩?这就引出第二个参数 Top-k

Top-k 的做法非常粗暴:只保留概率最高的 k 个词,其余的全砍掉。

 复制代码用户输入「你好」:
原始 → 吗 35%  啊 20%  世界 15%  我是AI 10%  呀 7%  哈哈 5%  哦 4%...Top-k=4 → 只留:吗、啊、世界、我是AI,其他概率归零,永无出头之日

Top-p(核采样)换了一种砍法——从高到低累加概率,加到你指定的 p 值就停。p=0.7 时,35%+20%+15%=70%,刚好在「世界」这里停住,后面全砍。

一句话:Top-k 是"固定名额"(管你分布什么样都选 k 个),Top-p 是"动态名额"(候选数量弹性变化——分布集中时可能只留 2 个,分散时可能留 10 个)。

两个参数怎么配合?

实际用法是先砍再调:Top-k 画安全圈,Temperature 在圈里跳舞。

 复制代码原始概率 → ① Top-k 砍掉垃圾 → ② Temperature 调平/调陡 → ③ 随机采样

以 k=4, T=0.5 走一遍:

 复制代码原始:吗35%  啊20%  世界15%  我是AI10%  ...① Top-k=4 → 保留前4个,重新归一化:吗50%  啊29%  世界21%T=0.5   → 加剧分化的马太效应:吗78%  啊16%  世界6%
③ 随机采样 → 大概率输出「你好吗」

搭配原则:temperature 太高 + top-k 太小 = 池子里瞎搅和,输出要么千篇一律;temperature 太低 + top-k 太大 = 候选虽多但全都挤向同一个词,输出保守没有想象力。要根据业务场景调。


二、LangChain 实战:把参数落地成代码

为什么要用 LangChain?

直接调 OpenAI API 的话你得这么写:

 复制代码const prompt = '请写一篇散文,主题:' + theme + '...'  // 字符串拼接,换主题得改代码
const res = await fetch('...', { body: JSON.stringify({ model, temperature }) })
const data = await res.json()
const text = data.choices[0].message.content  // 手动剥好几层壳

Prompt 散落在代码各处,返回结果要手取 .content,步骤一多就成面条。LangChain 把这些都模块化了。

第一步:创建两个不同温度的大模型

 复制代码// 创意型:高温 + 小 Top-k = 发散但不跑偏
const creativeModel = new ChatOpenAI({
  model: 'deepseek-v4-flash',   // 轻量、速度快
  temperature: 0.8,             // 高温 → 更多可能性
  topK: 4,                      // 只从概率前4的词汇里采样
  maxToken: 600,
})// 严谨型:低温 + 中 Top-k = 准确且完整
const preciseModel = new ChatOpenAI({
  model: 'deepseek-v4-pro',     // 更强模型,质量优先
  temperature: 0.2,             // 低温 → 确定性输出
  topK: 8,                      // 更大的候选池,保证信息完整性
  maxToken: 600,
})

代码里的 temperaturetopK 和前面的理论一一对应:creative 是"高温小池",precise 是"低温大池"。

第二步:用 PromptTemplate 把提示词变成模板

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

字符串拼接时,prompt 的结构逻辑和业务数据混在一起,换个主题就得改代码。PromptTemplate 把**不变的结构(模板)可变的数据(变量)**拆开——同一个模板,换不同的 {theme} 就直接复用。Agent 应用里,同一套 AI 逻辑换不同用户身份(诗人 vs 律师),变的只是参数,代码完全不动——这就是模板化的价值。

第三步:用 OutputParser 自动剥壳

 复制代码const outputParser = new StringOutputParser()
// 内部等价于:result.content ?? result.toString()

单独用确实不值。但当你把它挂在 chain 末尾时,价值就出来了——链条外面拿到手直接就是干净的字符串,不用再 .content。管道里的最后一道工序。

第四步:用 .pipe() 组装传送带

 复制代码const creativeChain = storyPrompt     // 1️⃣ 填入 {theme},产出完整 prompt 字符串
  .pipe(creativeModel)                // 2️⃣ LLM 推理,产出消息对象
  .pipe(outputParser)                 // 3️⃣ 剥出 content,产出纯字符串const preciseChain = storyPrompt
  .pipe(preciseModel)
  .pipe(outputParser)

pipe 做的事非常简单——上一个 .invoke() 的输出,自动变成下一个 .invoke() 的输入,省掉你手动从中间环节取结果再传递。执行顺序就是顺着代码从上到下、从左到右:

 复制代码{ theme: '秋日山野晚风' }
    → ① storyPrompt.invoke() → 完整 prompt 字符串
    → ② creativeModel.invoke() → { content: "晚风轻拂...", ... }
    → ③ outputParser.invoke() → "晚风轻拂..."

你最后只需一句 creativeChain.invoke({ theme }),整条链自动流转。

第五步:启动流水线

 复制代码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))

顶层 .catch() 兜住一切——API Key 没配、网络超时、{theme} 忘传——避免 Node 直接崩出 UnhandledPromiseRejection。


三、LangChain 还能做什么?

走完最简工作流,整个框架的全景也就清晰了:

模块职责一句话
Prompts模板化提示词结构变数分离,复用不重写
Messages标准化对话格式System / Human / AI 三类,所有 LLM 通用
Output Parsers解析返回内容String / JSON / Structured 三种解析器
Tools给模型挂外部能力模型自己决定调用工具(查天气、搜资料)
Vector Stores向量化存储+搜索RAG 核心——让模型"读取"海量文档
Document Loaders加载各类文件PDF、TXT、CSV → 统一文档对象
Text Splitters切分长文本按 chunkSize 切块,overlap 保留上下文

Agent 就是这些模块的组合:Messages 管理对话历史 → Tools 提供外部能力 → PromptTemplate 设定人设 → 模型自主规划什么时候调用什么工具。而我们今天走通的最简链——PromptTemplate → LLM → OutputParser——正是这一切的基础。


学习回顾

今天按"概念 → 落地 → 全景"的顺序覆盖了:

  1. Temperature(概率分布缩放)、Top-k(固定名额裁剪)、Top-p(动态阈值裁剪)及三者搭配
  2. ChatOpenAI 构造函数里 temperature / topK 的实际配置
  3. 为什么需要 LangChain——从手动拼字符串到模块化工作流
  4. PromptTemplate 把"结构"和"数据"分离
  5. StringOutputParser 自动取 .content
  6. .pipe() 管道串联——自动传递,代码即流水线
  7. 同一模板 + 不同温度 → 不同风格的 AI 输出
  8. LangChain 全模块:从 Prompts 到 Agent 的生态全景

下一步可以沿 Tools → Agent 方向深入自主决策型应用,或走 RAG 路线做私有知识库问答。

#LLM #LangChain #Temperature #Node.js #学习笔记

喜欢(0)

上一篇

反硬凑契约:当 AI 自信输出 130 行废话时

反硬凑契约:当 AI 自信输出 130 行废话时

下一篇

供电瓶颈限制美国AI数据中心建设

供电瓶颈限制美国AI数据中心建设
猜你喜欢