外观
Chat Completions 接口
约 1465 字大约 5 分钟
OpenAI、智谱和 DeepSeek 都通过 FrameAI 的 Chat Completions 接口调用。不同模型可能只支持公共字段的一部分;不确定的可选字段应省略,不要传空字符串或 null。
创建对话
POST https://mivsub.com/v1/chat/completions
Authorization: Bearer sk-frameai-xxxxxxxx
Content-Type: application/json请求示例
{
"model": "MODEL_NAME",
"messages": [
{
"role": "system",
"content": "你是专业助手。"
},
{
"role": "user",
"content": "请简要介绍这个模型的适用场景。"
}
],
"stream": false,
"max_tokens": 512,
"temperature": 0.7,
"top_p": 0.9
}请求字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | 是 | 使用 FrameAI 实际提供的模型名称,例如 gpt-5.4、glm5.2 或 deepseek-v4-pro。 |
messages | array<object> | 是 | 按顺序排列的对话消息。 |
messages[].role | string | 是 | 常用值为 system、user、assistant、tool。 |
messages[].content | string / array | 是 | 文本内容;多模态数组仅在目标模型支持时使用。 |
messages[].name | string | 否 | 消息发送者名称。 |
stream | boolean | 否 | true 使用 SSE 流式输出,false 返回完整 JSON。 |
stream_options | object | 否 | 流式选项;目标模型支持时可使用。 |
stream_options.include_usage | boolean | 否 | 是否在流式结束前返回用量块。 |
max_tokens | integer | 否 | 最大输出 Token 数。必须是非负整数并处于服务端上限内。 |
max_completion_tokens | integer | 否 | 新版最大输出 Token 字段;是否支持取决于目标模型。 |
temperature | number | 否 | 随机性参数,范围和效果由目标模型决定。 |
top_p | number | 否 | 核采样参数。通常与 temperature 二选一调整。 |
stop | string / array | 否 | 停止生成序列。 |
tools | array | 否 | 函数工具定义;仅在目标模型支持工具调用时使用。 |
tool_choice | string / object | 否 | 工具选择策略。 |
response_format | object | 否 | JSON Object 或 JSON Schema 输出约束;由目标模型决定是否支持。 |
reasoning_effort | string | 否 | 推理强度;只对支持该字段的模型有效。 |
非流式响应
{
"id": "chatcmpl-xxxxxxxx",
"object": "chat.completion",
"created": 1788487200,
"model": "MODEL_NAME",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "这是模型生成的文本。"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 32,
"completion_tokens": 18,
"total_tokens": 50
}
}响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 本次请求的响应 ID。 |
object | string | 通常为 chat.completion。 |
created | integer | Unix 秒时间戳。 |
model | string | 响应使用的模型名。 |
choices | array | 候选回答列表。 |
choices[].message.role | string | 返回消息角色,通常为 assistant。 |
choices[].message.content | string | 最终回答文本。 |
choices[].message.reasoning_content | string | 推理内容;仅推理模型返回时存在。 |
choices[].message.tool_calls | array | 模型发起的工具调用;仅使用工具时存在。 |
choices[].finish_reason | string | 常见值为 stop、length 或 tool_calls。 |
usage.prompt_tokens | integer | 输入用量。 |
usage.completion_tokens | integer | 输出用量。 |
usage.total_tokens | integer | 总用量。 |
实际响应可能包含模型提供方增加的扩展字段。客户端应读取所需字段,不要因为出现未知字段而拒绝整个响应。
流式调用
请求体设置:
{
"model": "MODEL_NAME",
"messages": [
{
"role": "user",
"content": "解释什么是事件流。"
}
],
"stream": true,
"stream_options": {
"include_usage": true
}
}响应类型为:
Content-Type: text/event-stream响应片段:
data: {"id":"chatcmpl-xxxxxxxx","choices":[{"index":0,"delta":{"role":"assistant","content":"事件"}}]}
data: {"id":"chatcmpl-xxxxxxxx","choices":[{"index":0,"delta":{"content":"流是一种持续传输数据的机制"}}]}
data: [DONE]客户端需要逐行读取 data:,收到 [DONE] 后结束。不要等待连接关闭后再一次性解析为 JSON。
工具调用示例
{
"model": "MODEL_NAME",
"messages": [
{
"role": "user",
"content": "北京今天的天气怎么样?"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "查询指定城市的天气",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
}
},
"required": ["city"]
}
}
}
],
"tool_choice": "auto"
}工具执行发生在客户端业务中:模型返回 tool_calls 后,客户端调用实际函数,再以 role: tool 把结果提交到下一轮对话。
Go 示例
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"time"
)
type chatResponse struct {
Choices []struct {
Message struct {
Content string `json:"content"`
} `json:"message"`
} `json:"choices"`
Msg string `json:"msg"`
Error *struct {
Message string `json:"message"`
} `json:"error"`
}
func main() {
requestBody := map[string]any{
"model": "MODEL_NAME",
"messages": []map[string]string{
{"role": "user", "content": "你好,请介绍一下自己。"},
},
"stream": false,
"max_tokens": 512,
}
body, err := json.Marshal(requestBody)
if err != nil {
log.Fatal(err)
}
req, err := http.NewRequest(
http.MethodPost,
"https://mivsub.com/v1/chat/completions",
bytes.NewReader(body),
)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer sk-frameai-xxxxxxxx")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 120 * time.Second}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
responseBody, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
var result chatResponse
if err := json.Unmarshal(responseBody, &result); err != nil {
log.Fatalf("解析响应失败: %v", err)
}
if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {
if result.Msg != "" {
log.Fatalf("请求失败: HTTP %d, %s", resp.StatusCode, result.Msg)
}
if result.Error != nil {
log.Fatalf("请求失败: HTTP %d, %s", resp.StatusCode, result.Error.Message)
}
log.Fatalf("请求失败: HTTP %d", resp.StatusCode)
}
if len(result.Choices) == 0 {
log.Fatal("响应中没有 choices")
}
fmt.Println(result.Choices[0].Message.Content)
}Python 示例
import requests
response = requests.post(
"https://mivsub.com/v1/chat/completions",
headers={
"Authorization": "Bearer sk-frameai-xxxxxxxx",
"Content-Type": "application/json",
},
json={
"model": "MODEL_NAME",
"messages": [
{"role": "user", "content": "你好,请介绍一下自己。"}
],
"stream": False,
"max_tokens": 512,
},
timeout=120,
)
response.raise_for_status()
print(response.json()["choices"][0]["message"]["content"])错误处理
无效 FrameAI API Key 返回 HTTP 401:
{
"code": "invalid_token",
"data": {},
"msg": "无效的令牌 (request id: REQUEST_ID)"
}其他请求校验或模型服务错误通常保持 OpenAI 兼容结构:
{
"error": {
"message": "错误详情 (request id: REQUEST_ID)",
"type": "new_api_error",
"param": "",
"code": "ERROR_CODE"
}
}| HTTP 状态码 | 常见原因 | 处理方式 |
|---|---|---|
400 | JSON 无效、字段类型错误、模型参数不合法 | 检查实际请求体和 Content-Type。 |
401 | FrameAI API Key 缺失、无效或过期 | 更新 Authorization。 |
403 | 当前 API Key 没有模型访问权限 | 检查账户和 API Key 的模型权限。 |
429 | 请求频率过高或服务繁忙 | 指数退避后重试。 |
500 | 本地处理或数据库异常 | 使用响应中的 request ID 查询日志。 |
502 | 模型服务暂时异常 | 稍后重试;持续出现时携带 request ID 联系管理员。 |
503 | 模型暂不可用或系统资源过载 | 稍后重试;持续出现时携带 request ID 联系管理员。 |
JSON 常见错误
错误:
{
"stream": flase,
"max\_tokens": 512
}正确:
{
"stream": false,
"max_tokens": 512
}JSON 只能使用普通空格、制表符、换行和回车作为空白字符。从富文本页面复制请求时,应避免混入不可断行空格 U+00A0。