4. 开发环境搭建
调用大模型接口,说白了就是往一个黑盒子里塞一段文本,然后等它吐出来另一段文本。但这个过程远比你想象的要精细。我刚开始接触 API 时,以为就是传个 prompt 就完事了,结果发现返回的内容要么太长、要么太短、要么格式完全不对。
嗯,这里的关键在于理解请求体里的那几个核心参数。它们就像控制大模型行为的旋钮,调对了,输出质量能上一个台阶。
4.1 Messages 与 Role:对话的骨架
大模型本身是无状态的,它不记得你上一轮说了什么。所以每次请求,你都得把整个对话历史打包发给它。这个历史就放在 messages 数组里。
每个 message 对象都有两个关键字段:role 和 content。
| Role | 含义 | 典型用途 |
|---|---|---|
system |
系统指令,设定模型的行为和人格 | “你是一个资深的 Python 工程师” |
user |
用户输入,即你提的问题或指令 | “请帮我写一个排序算法” |
assistant |
模型的回复,用于多轮对话 | 模型生成的代码或解释 |
我个人习惯把 system 消息放在数组最前面。它就像给模型戴上一个“角色面具”。比如我做一个客服机器人,system 消息里会写:“你是一个耐心、专业的售后客服,回答要简洁,不要超过 3 句话。” 这样模型就不会长篇大论地讲技术原理了。
多轮对话的构造其实很简单。每次模型回复后,你把它的 assistant 消息和你新的 user 消息一起追加到数组里,再发出去。我在项目中遇到过一个问题:如果对话轮次太多,messages 数组会变得非常大,导致 消耗激增。这时候就需要做截断或摘要。
4.2 Temperature:控制模型的“创造力”
Temperature 是我最喜欢调的参数。它控制模型输出文本的随机性。
- 低 Temperature(0 ~ 0.3):模型倾向于选择概率最高的词。输出稳定、可预测、重复性高。适合代码生成、事实性问答、翻译。
- 中 Temperature(0.5 ~ 0.7):平衡状态。有一定创造性,但不会太离谱。适合日常对话、文案写作。
- 高 Temperature(0.8 ~ 1.5):模型会选概率较低的词。输出多样、有创意,但也可能跑题或胡编。适合头脑风暴、诗歌生成。
我曾经在做一个代码补全功能时,把 Temperature 设成了 0.8。结果模型每次生成的代码都不一样,同一个函数名能给你写出五种实现。后来我把它降到 0.1,输出就稳定了。你想想看,如果让模型自由发挥去写生产代码,那后果不堪设想。
4.3 Max Tokens:给回复上个“紧箍咒”
Max Tokens 控制模型最多能输出多少个 。注意,是 ,不是汉字。一个 大约等于 0.75 个英文单词,或者 1 个汉字。
这个参数非常实用。我见过很多新手不设这个值,结果模型滔滔不绝地输出几千字,既浪费 又浪费时间。
- 短回复场景(如分类、打分):设 10 ~ 50。
- 中等回复场景(如摘要、问答):设 200 ~ 500。
- 长文本场景(如文章生成、代码生成):设 1000 ~ 4000。
我习惯在每次请求前先估算 prompt 的 数。很多 SDK 都提供了 num_tokens_from_messages() 这样的工具函数。这样可以避免请求被截断或失败。
4.4 Stop 序列:让模型在指定位置停下
Stop 序列是一个字符串或字符串数组。当模型生成的内容中出现这些字符串时,它会立即停止生成。
这个功能在结构化输出时特别好用。比如你想让模型生成一段 JSON,但模型有时候会在 JSON 后面加一句“以上是生成的 JSON”。你可以把 stop 设为 ["}"],这样模型生成完 JSON 对象后就会停。
再比如,你让模型列举几个要点,每个要点以换行符结尾。你可以把 stop 设为 ["\n\n"],这样模型生成完第一个要点后就会停,方便你逐步控制。
["User:"],想让模型在模拟用户输入时停下。结果模型在回复中自己生成了“User:”这个词,导致回复被截断。后来我改用更独特的标记,比如 ["<|im_end|>"],才解决了问题。
4.5 知识结构图:参数如何影响输出
下面这张图展示了请求参数与模型输出之间的核心关系。你可以看到,每个参数都像一个阀门,控制着输出的不同维度。
4.6 实战:一个完整的请求示例
说了这么多,不如直接看代码。下面是一个调用 兼容接口的 Python 示例,包含了我们刚才讲的所有参数。
import
response = .ChatCompletion.create(
model="-turbo",
messages=[
{"role": "system", "content": "你是一个简洁的代码助手。只输出代码,不要解释。"},
{"role": "user", "content": "用 Python 写一个快速排序函数"}
],
temperature=0.1, # 低温度,确保输出稳定
max_tokens=300, # 限制回复长度
stop=["\n\n"] # 遇到两个换行就停止
)
print(response.choices[0].message.content)
这个请求里,我设了 temperature=0.1,确保模型不会自由发挥;max_tokens=300,防止它写太多注释;stop=["\n\n"],让它写完函数体就停。这样返回的内容基本就是一段干净的代码。
stop 设为 ["}"],并在 system 消息里明确要求“只输出 JSON,不要其他内容”。这样返回的内容可以直接用 json.loads() 解析。
4.7 响应结构:你拿到的到底是什么
请求发出去后,你会收到一个响应对象。它的结构大致如下:
{
"id": "chatcmpl-xxx",
"object": "chat.completion",
"created": 1677652288,
"model": "-turbo",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "这是模型的回复内容"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 56,
"completion_tokens": 31,
"total_tokens": 87
}
}
几个关键字段:
- choices:数组,通常只有一个元素。里面包含模型回复的 message 和结束原因。
- finish_reason:
stop(正常结束)、length(达到 max_tokens)、content_filter(被内容过滤拦截)。 - usage: 消耗统计。这个字段对计费和优化非常重要。
我每次上线前都会检查 finish_reason。如果频繁出现 length,说明 max_tokens 设得太小了。如果出现 content_filter,说明 prompt 或回复触发了安全规则,需要调整。
choices[0].message.content。一定要检查 finish_reason。如果是因为 length 结束的,回复可能是不完整的。
好了,关于请求与响应结构,核心就是这些。记住:messages 是对话的骨架,temperature 是创造力的旋钮,max_tokens 是长度的缰绳,stop 序列是终止的信号。把这四个参数用好,你就能让大模型乖乖听话。