获取 API 密钥

大模型 API 接口参数详解:从请求字段到响应字段

第一次看聊天补全接口的文档,往往会被一长串参数吓住。其实可以把一次调用想象成去餐厅点菜:messages 是你和服务员的对话记录,temperature 是你要厨师发挥多少,max_tokens 是这道菜最多上多少量,tools 则是允许厨师向后厨打电话问食材。这篇按这个思路,一张表一张表地把每个字段讲透。

更新于

要点

  • messages 由 system、user、assistant、tool 四种角色组成,模型没有记忆,历史要你自己带。
  • temperature 控制随机性,top_p 控制候选范围,两者作用相近,通常只调其一。
  • finish_reason 决定你该怎么处理结果:stop 是正常结束,length 是被截断,tool_calls 是要你去执行函数。
  • usage 字段是计费和预算的唯一可靠依据,每次都应该读取。

一次请求长什么样

接口地址是 POST https://api.apidamoxing.com/v1/chat/completions,鉴权头为 Authorization: Bearer <key>,请求体是 JSON,格式与 OpenAI 的聊天补全兼容。先看一个把常用字段都用上的完整请求:

curl https://api.apidamoxing.com/v1/chat/completions \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "uncensored",
    "messages": [
      {"role": "system", "content": "你是一位耐心的天文科普作者。"},
      {"role": "user", "content": "为什么月亮总是同一面朝向地球?"}
    ],
    "temperature": 0.7,
    "top_p": 0.9,
    "max_tokens": 400,
    "stop": ["###"]
  }'

注意这里的 model 只能填 uncensored,因为服务只有一个模型,没有可选项。可以用 GET /v1/models 确认。下面按字段逐个解释。

读完整篇你会发现,这些参数其实可以归成三类:决定“说什么”的(messages、tools),决定“怎么说”的(temperature、top_p),决定“说多少、何时停”的(max_tokens、stop、stream)。记住这个分类,以后遇到陌生字段,先判断它属于哪一类,大半就能猜出用途。

messages:这场对话的“记录本”

messages 是一个数组,每个元素有 role 和 content。想象它是一本逐页记录的会议纪要,模型每次都从头读一遍,然后写下一页。它自己不会记得上次读过什么,所以多轮对话时,历史必须由你完整带上。

role谁写的用途
system你(开发者)设定身份、规则、输出格式,通常放在最前面
user最终用户提问或指令
assistant模型(或你补写的历史)之前的回答,用于多轮上下文
tool你的程序函数调用的执行结果,需带 tool_call_id

一个常见的技巧:想让模型按某种口吻接着写,可以自己构造一条 assistant 消息放进历史里。要记住 prompt 和输出合计不能超过 100,000 token,历史越长越占空间。

举个具体的例子。你做了一个客服助手,system 写“只回答与订单有关的问题,回答不超过三句”。用户第一轮问发货时间,第二轮追问“那退货呢”。第二轮请求里,messages 要依次包含:system、第一轮的 user、第一轮模型的 assistant 回答、第二轮的 user。缺任何一条,模型都不知道“那”指的是什么。

采样参数:调“发挥空间”

模型生成每个字时,会先给所有候选字打概率分,再抽签。下面两个参数就是调整抽签规则的旋钮:

参数类比怎么理解常见取值
temperature厨师的创意度越低越保守、越稳定;越高越发散0 到 1.2,问答类取低,创作取高
top_p只在前几名里抽只从累计概率达到 p 的候选里抽签0.8 到 1,默认通常够用

两者都在管“随机多少”,只是角度不同。同时调很难判断效果来自哪个,所以建议一次只动一个。这些标准采样字段会原样透传,接口不会私自改写。

再用一个直观的数字例子:假设模型接下去最可能的三个字,概率分别是 60%、30%、10%。temperature 调低,会让 60% 的那个更占优势,输出更像每次都选第一名;调高则把三者拉近,冷门字更容易被抽中。top_p 取 0.9 的话,只保留累计到 90% 的前两个字,第三个直接出局。这些数字仅为说明原理的假设,并非真实概率。

控制长度与停止:max_tokens、stop、stream

参数作用要点
max_tokens限制本次最多生成多少 token默认 2048,单次最大 16,000;它与 prompt 合计不得超过 100,000
stop遇到指定字符串就停可传字符串数组,适合做分段、截断固定格式
stream是否流式返回设为 true 后用 SSE 逐块推送,最后自动追加一个带 usage 的数据块

max_tokens 就像一次上菜的盘子大小。盘子小了,菜没上完就被端走,这时 finish_reason 会是 length。stop 则像约定的暗号,厨师听到暗号就收手。stream 不改变内容,只改变交付方式:从“全部做好再端上来”变成“做好一口上一口”,用户感觉响应更快。

stop 有个很实用的用法:你让模型按“问题:……答案:……###”的固定格式输出,再把 ### 设为 stop,生成到分隔符就自动停止,既省 token,也避免它后面多说废话。注意 stop 命中时 finish_reason 同样是 stop,如果你要区分,需要自己检查内容。

tools 与 tool_choice:让模型“打电话”问你

模型本身查不到实时数据。function calling 的做法是:你先告诉模型有哪些函数可用,模型判断需要时,不直接回答,而是返回“请调用某函数,参数是……”,你的程序执行后把结果交回,模型再据此组织答案。格式与 OpenAI 一致。

参数取值说明
tools函数描述数组每个含 name、description 和 JSON Schema 形式的 parameters
tool_choice"auto" / "none" / 指定函数auto 由模型决定,none 禁止调用,指定函数则强制调用它
import json
import os
from openai import OpenAI

client = OpenAI(base_url="https://api.apidamoxing.com/v1", api_key=os.environ["API_KEY"])

tools = [{
    "type": "function",
    "function": {
        "name": "get_tide_time",
        "description": "查询某港口今天的高潮时刻",
        "parameters": {
            "type": "object",
            "properties": {"port": {"type": "string", "description": "港口名称"}},
            "required": ["port"],
        },
    },
}]

messages = [{"role": "user", "content": "青岛今天几点涨潮?"}]
first = client.chat.completions.create(
    model="uncensored", messages=messages, tools=tools, tool_choice="auto"
)
msg = first.choices[0].message

if msg.tool_calls:
    call = msg.tool_calls[0]
    args = json.loads(call.function.arguments)
    result = {"port": args["port"], "high_tide": "14:20"}   # 这里换成你自己的查询
    messages.append(msg)
    messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result, ensure_ascii=False)})
    final = client.chat.completions.create(model="uncensored", messages=messages, tools=tools)
    print(final.choices[0].message.content)
else:
    print(msg.content)

流程是两轮:第一轮拿到 tool_calls,第二轮把 role 为 tool 的结果追加后再请求。description 写得越具体,模型越知道什么时候该调。参数是 JSON 字符串,务必用 json.loads 解析并做校验,别直接信任。

响应字段:读懂返回的“收据”

一次成功响应大致如下,字段是固定的:

{
  "id": "chatcmpl-xxxx",
  "object": "chat.completion",
  "model": "uncensored",
  "choices": [
    {
      "index": 0,
      "message": {"role": "assistant", "content": "因为潮汐锁定……"},
      "finish_reason": "stop"
    }
  ],
  "usage": {"prompt_tokens": 38, "completion_tokens": 212, "total_tokens": 250}
}
字段含义
choices结果数组,通常只有一项,正文在 choices[0].message.content
finish_reason结束原因:stop 正常结束;length 触达 max_tokens 被截断;tool_calls 模型请求调用函数
usage.prompt_tokens输入消耗的 token
usage.completion_tokens输出消耗的 token
usage.total_tokens两者之和

代码里应该先看 finish_reason:是 length 就提示用户内容被截断或者自动续写;是 tool_calls 就走函数执行分支。usage 的作用在token 与计费那篇里有更详细的预算方法。

几个最容易踩的参数误区

  • 把 max_tokens 当成“输入上限”。它只管输出,输入由你控制。
  • 以为模型记得上一次请求。每次请求都是独立的,历史自己带。
  • temperature 设 0 就以为每次结果完全相同。会更稳定,但不应当假设逐字一致。
  • 流式模式下直接读 choices[0].message。流式的块里字段是 delta,要自己拼接。
  • tool 调用后忘记追加 assistant 那条带 tool_calls 的消息,导致第二轮报错。

错误码含义和重试策略可在文档中查看。想看一个把这些参数串起来的完整例子,参考聊天机器人搭建一篇。

常见问题

可以同时设置 temperature 和 top_p 吗?

可以,但效果难以拆分判断。多数场景只调 temperature 即可,需要精细控制候选范围时再动 top_p。

finish_reason 是 length 该怎么办?

说明输出触达 max_tokens 被截断。可以调大 max_tokens,上限 16,000,或者让模型分段生成。

tools 的格式和 OpenAI 一样吗?

是的,使用 OpenAI 格式的 tools 与 tool_choice,响应里的 tool_calls 也是同样的结构。

流式响应里怎么拿到用量?

开启 stream 后,最后会自动追加一个包含 usage 的数据块,读取它即可,无需额外参数。

只需填写表单即可获取密钥

创建账户,复制密钥,修改 Base URL。配置就是这么简单。

获取 API 密钥