你有没有想过一个问题:同样一个AI,同样一个问题,为什么有时候回答得规规矩矩,有时候却脑洞大开、胡说八道?
今天我们就来彻底搞懂------大模型是怎么"随机说话"的 ,以及作为开发者,怎么控制它的随机性。
一、先搞懂大模型是怎么"想"的
要理解随机性,得先理解大模型生成文本的基本逻辑。
大模型(比如你用的DeepSeek、ChatGPT)本质上是一个 "下一个词预测器" 。它不会像人一样先构思好一整句话再开口,而是一个词一个词往外蹦。
举个例子。你输入"你好",模型要预测下一个词是什么。这时候,模型内部会计算出一个概率分布------简单说,就是给词典里每一个可能的词打一个分,表示"我觉得下一个词是这个"的可能性有多大。
大概长这样:
| 下一个词 | 概率 |
|---|---|
| 吗 | 0.60 |
| 啊 | 0.15 |
| 呀 | 0.10 |
| 美 | 0.05 |
| 坏 | 0.01 |
| ... | ... |
概率最高的词是"吗"(60%),其次是"啊"(15%),依此类推。
关键问题来了:模型一定要选概率最高的"吗"吗?
答案是:不一定。这就是"随机性"的入口。
如果每次都选概率最高的词,那模型就变成了确定性模型------同样的输入永远输出同样的结果。这样虽然稳定,但也很无聊,写不出有创意的故事,也做不出多样化的回答。
所以,大模型引入了一个机制:按照概率分布去"抽签" 。概率高的词被抽中的概率大,但概率低的词也有机会被选中。这就是"随机采样"。
但问题又来了:随机到什么程度? 这就引出了我们今天要讲的两个核心参数------Temperature(温度) 和 Top K。
二、Temperature:控制"抽签"的胆量
Temperature的取值通常在0到1之间 (有些模型支持到2)。它的作用听起来很抽象------改变概率分布的"锐度" 。
别怕,我用最直白的方式解释给你听。
当 Temperature 很低(比如 0.2)
概率分布会被"压扁"?不对,说反了------低温度会让高概率的词更高,低概率的词更低。
还是上面那个例子:
- 原来"吗"是60%,"啊"是15%
- 温度调到0.2后,"吗"可能变成85%,"啊"变成5%
- 差距被拉大了
这时候抽签,几乎每次都会抽到"吗"。结果就是:输出非常稳定、保守、可预测。
适合的场景:写代码、写法律合同、写公司制度文档------这些场景需要准确,不需要创意。
当 Temperature 很高(比如 0.8)
效果正好相反------概率分布被"抹平"了:
- "吗"从60%降到40%
- "啊"从15%升到20%
- 那些本来几乎不可能的词(比如"美"0.05%)也有机会被选中
这时候抽签,结果就五花八门。模型可能说出一些意料之外的话,有时候惊艳,有时候翻车。
适合的场景:写小说、写诗歌、做创意文案------需要发散性思维的地方。
三、Top K:给模型划一个"候选圈"
Temperature管的是"怎么抽",而Top K管的是"从谁里面抽" 。
Top K的逻辑很简单:把所有候选词按概率从高到低排序,只保留前K个,剩下的直接淘汰 。
举个例子。假设K=3:
| 排名 | 词 | 概率 |
|---|---|---|
| 1 | 吗 | 60% |
| 2 | 啊 | 15% |
| 3 | 呀 | 10% |
| 4 | 美 | 5% |
| 5 | 坏 | 1% |
Top K=3 意味着:只从"吗、啊、呀"这三个里面选,"美"和"坏"连参赛资格都没有。
如果K=1,那就是每次都选概率最高的那个词------相当于完全关闭了随机性。
如果K很大(比如默认的8),那候选范围就宽,更多词有机会被选中。
四、Temperature 和 Top K 怎么搭配?
这两个参数不是独立工作的,它们是配合使用的。
我打个比方你可能更好理解:
- Top K 像是海选------先划一个圈子,只有圈子里的人能进入下一轮
- Temperature 像是决赛的评委------在圈子里决定谁最终胜出,评委越随意(温度高),结果越不可预测
所以搭配的策略很讲究:
方案一:Temperature 小 + Top K 大
- 温度低 → 输出稳定、准确
- Top K大 → 候选范围广,信息完整
- 效果:准确但有艺术性,适合需要高质量文本的场景
- 比如:写产品文案、做内容摘要
方案二:Temperature 大 + Top K 小
- 温度高 → 输出有创意、发散
- Top K小 → 候选范围窄,不容易跑太偏
- 效果:靠谱的创意,既不会太无聊也不会太离谱
- 比如:写故事、做头脑风暴
不建议两个都调得很大 ------那输出就太随机了,基本没法用。也不建议两个都很小------那跟确定性模型没啥区别,浪费了大模型的多样性。
五、来写点代码:用 LangChain 搭建两条"生产线"
理论讲完了,我们上手写代码。
我们用 LangChain 来搭建两条不同的"AI写作生产线"------一条负责创意写作(温度高),一条负责严谨写作(温度低)。
第一步:安装和引入
javascript
javascript
import 'dotenv/config'
import { ChatOpenAI } from '@langchain/openai'
这里我们用 dotenv 来管理 API Key,用 ChatOpenAI 来连接大模型(DeepSeek 兼容 OpenAI 的接口)。
第二步:创建两个模型实例
一个走创意路线,一个走严谨路线:
javascript
php
// 创意模型 ------ 温度高,Top K 小
const creativeModel = new ChatOpenAI({
model: 'deepseek-v4-pro',
temperature: 0.8, // 高温度,增强创意发散性
topK: 4, // 小 Top K,限制候选范围,防止跑偏
maxToken: 600,
apiKey: process.env.DEEPSEEK_API_KEY,
configuration: {
baseURL: 'https://api.deepseek.com',
}
})
// 严谨模型 ------ 温度低,Top K 大
const preciseModel = new ChatOpenAI({
model: 'deepseek-v4-pro',
temperature: 0.2, // 低温度,输出保守稳定
topK: 8, // 大 Top K,保证信息完整性
maxToken: 600,
apiKey: process.env.DEEPSEEK_API_KEY,
configuration: {
baseURL: 'https://api.deepseek.com',
}
})
看到区别了吗?
- 创意模型:temperature 0.8 + topK 4 → 敢于创新但不会太离谱
- 严谨模型:temperature 0.2 + topK 8 → 稳定准确且信息全面
这就是前面说的"搭配策略"在代码里的具体体现。
第三步:定义提示词模板
以前我们写提示词都是硬编码在代码里,改一次要翻代码、重新部署,很麻烦。
LangChain 提供了 PromptTemplate,把提示词抽出来单独管理:
javascript
javascript
import { PromptTemplate } from '@langchain/core/prompts';
const storyPrompt = PromptTemplate.fromTemplate(
`
请写一篇短篇故事,主题:{theme}
风格温柔治愈,篇幅200字左右,要分段,文字细腻有画面感。
`
)
注意里面的 {theme} ------ 这是一个变量占位符。使用时我们可以动态传入不同的值(比如"霸总"、"科幻"、"校园"),而不需要修改模板本身。
这样做的好处是:提示词可以复用、可以集中管理、可以随时调整。
第四步:添加输出解析器
大模型返回的数据通常是一个复杂的对象,不只是纯文本。但我们很多时候只想要最终的文字内容。
这时候用 StringOutputParser 帮我们自动提取纯文本:
javascript
javascript
import { StringOutputParser } from '@langchain/core/output_parsers';
const outputParser = new StringOutputParser();
第五步:用管道组装"生产线"
这是 LangChain 最精彩的部分 ------ 用管道(pipe)把各个环节串起来:
javascript
scss
// 创意写作流水线
const creativeChain = storyPrompt
.pipe(creativeModel)
.pipe(outputParser)
// 严谨写作流水线
const preciseChain = storyPrompt
.pipe(preciseModel)
.pipe(outputParser)
这两条流水线做的事情完全一样,只是中间用的模型不同:
text
提示词模板 → 大模型(创意/严谨) → 输出解析器 → 纯文本结果
这就像工厂里的两条生产线,原料(提示词和主题)一样,但用的机器(模型参数)不同,产出的产品(文章风格)就完全不同。
第六步:跑起来看看效果
javascript
javascript
async function runWriteDemo() {
const theme = "霸总";
console.log('创意写作模式');
const creativeText = await creativeChain.invoke({ theme });
console.log(creativeText);
console.log('\n-----------------');
console.log('严谨写实模式');
const preciseText = await preciseChain.invoke({ theme });
console.log(preciseText);
}
runWriteDemo().catch(err => console.error(err));
invoke({ theme }) 就是把 { theme: "霸总" } 这个变量值传进提示词模板,替换掉 {theme} 占位符,然后启动整条流水线。
运行后你会发现:
- 创意模式写出来的霸总故事:文笔飘逸、情感丰富、可能有点出人意料的转折
- 严谨模式写出来的霸总故事:结构规整、用词准确、逻辑严密但可能少了一点惊喜
两条流水线,同样的主题,完全不同的风格。
六、为什么需要 LangChain?
你可能会问:我直接调用API不也能实现吗?为什么要多此一举用LangChain?
好问题。我直接说三个核心原因:
1. 开发更快
有了 PromptTemplate,提示词可以单独维护、版本管理、随时调整,不需要动代码。
有了 StringOutputParser,不用每次手动解析返回结果。
有了 pipe(),搭一条工作流就像搭积木。
2. 工作流可复用
你可以把 creativeChain 和 preciseChain 分别用在不同的业务场景里:
- 创意链 → AI写小说、写营销文案
- 严谨链 → AI写代码注释、写技术文档
甚至可以把它们组合成更复杂的链------先让创意链生成初稿,再让严谨链修改润色。
3. 应对大模型的"黑盒"特性
大模型本质上是概率模型,输出有一定的不确定性。有时候你觉得它太笨(输出太简单),有时候又觉得它太聪明(不知道怎么做到的)。
LangChain 的链式结构把每一步都显式化了:提示词是什么 → 用什么模型 → 参数怎么设置 → 输出怎么解析。每一步都可控、可追溯、可调试。
七、总结:一张图看懂全部
回顾一下今天的内容:
大模型生成文本的本质:根据概率分布"抽签"选下一个词。
Temperature(温度) :控制抽签的随机程度
- 低 → 稳定保守(写代码、合同)
- 高 → 创意发散(写故事、文案)
Top K:控制候选词的范围
- 小 → 只从最可能的几个词里选
- 大 → 从更多词里选
搭配策略:
- 温度低 + Top K大 → 准确又全面
- 温度高 + Top K小 → 靠谱的创意
LangChain 工作流:
text
scss
PromptTemplate(提示词模板)
↓ .pipe()
大模型(带着 temperature 和 topK 参数)
↓ .pipe()
StringOutputParser(输出解析器)
↓
纯文本结果
有了这套工具,你就能精准控制大模型"说话"的风格------想要它老实巴交还是天马行空,全看你参数怎么调。
下次再用AI写东西的时候,不妨试试调一下 temperature 和 Top K,看看同样的提示词能变出多少种不同的花样来。