外观
OpenAI
约 1414 字大约 5 分钟
OpenAI 模型通过 FrameAI 统一的 /v1/chat/completions 接口调用。客户端只需要使用 FrameAI API Key,并在请求体中填写实际可用的模型名称。
支持的模型
当前支持的 OpenAI 模型名称如下:
gpt-5.6-sol
gpt-5.6-terra
gpt-5.5
gpt-5.4
gpt-image-2
gpt-5.4-mini
codex-auto-review其中,gpt-5.6-sol、gpt-5.6-terra、gpt-5.5、gpt-5.4、gpt-5.4-mini 和 codex-auto-review 用于文本对话或代码相关请求;gpt-image-2 用于图像能力。具体可调用能力以 FrameAI 返回的模型列表和账户权限为准。模型名称需要完整匹配,不要自行修改大小写、连字符、版本号或模型后缀。
普通对话
curl https://mivsub.com/v1/chat/completions \\
-H "Authorization: Bearer sk-frameai-xxxxxxxx" \\
-H "Content-Type: application/json" \\
--data-binary '{
"model": "gpt-5.4",
"messages": [
{
"role": "system",
"content": "你是一个准确、简洁的技术助手。"
},
{
"role": "user",
"content": "请用三个要点说明 API 网关的主要作用。"
}
],
"stream": false,
"max_tokens": 1024,
"temperature": 0.7
}'响应中的最终文本通常位于:
choices[0].message.content推理模型
需要复杂分析或代码处理时,可以使用支持此类能力的模型,例如 gpt-5.5:
{
"model": "gpt-5.5",
"messages": [
{
"role": "user",
"content": "分析一个高并发 API 服务的限流、重试和幂等设计。"
}
],
"stream": false,
"max_completion_tokens": 2048
}部分推理模型可能返回 reasoning_content 或其他推理扩展字段。业务展示最终回答时,应读取 choices[0].message.content,并兼容推理字段不存在的情况。
流式输出
{
"model": "gpt-5.4",
"messages": [
{
"role": "user",
"content": "分步骤介绍如何设计一个可靠的任务队列。"
}
],
"stream": true,
"stream_options": {
"include_usage": true
},
"max_tokens": 2048
}响应类型为:
Content-Type: text/event-stream客户端需要逐行读取 data: 事件,持续拼接 choices[].delta.content,收到下面的结束标记后停止:
data: [DONE]流式响应最后的用量信息是否返回,取决于模型服务是否支持 stream_options.include_usage。业务逻辑不要依赖某一个流式片段一定包含 usage。
工具调用
{
"model": "gpt-5.4",
"messages": [
{
"role": "user",
"content": "查询订单 A20260904001 的状态。"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_order_status",
"description": "查询订单状态",
"parameters": {
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "订单编号"
}
},
"required": ["order_id"]
}
}
}
],
"tool_choice": "auto"
}模型返回 tool_calls 后,客户端负责:
- 读取工具名称和参数。
- 在自己的业务系统中执行对应函数。
- 将函数结果作为
role: tool消息追加到messages。 - 再次调用同一个模型获取最终回答。
工具定义中的函数不会由 FrameAI 自动执行,客户端必须自行完成工具调用流程。
多轮对话
下一轮请求需要把历史消息按原顺序放回 messages:
{
"model": "gpt-5.4",
"messages": [
{
"role": "user",
"content": "给这个缓存组件设计一个接口。"
},
{
"role": "assistant",
"content": "可以定义 Get、Set、Delete 和 Close 四个方法。"
},
{
"role": "user",
"content": "再补充批量读取和过期时间支持。"
}
],
"stream": false
}不要把上一轮完整 HTTP 响应直接塞进 messages,只保留后续对话需要的消息内容。
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": "gpt-5.4",
"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": "gpt-5.4",
"messages": [
{"role": "user", "content": "你好,请介绍一下自己。"}
],
"stream": False,
"max_tokens": 512,
},
timeout=120,
)
response.raise_for_status()
print(response.json()["choices"][0]["message"]["content"])参数注意事项
max_tokens和max_completion_tokens不要同时传不同值,按当前模型支持的字段选择一个。- 推理模型可能不支持
temperature、top_p等普通采样参数;不确定时省略这些可选参数。 stream必须使用 JSON 布尔值true或false,不能写成字符串或flase。model必须使用实际可用的 OpenAI 模型名称;模型不可用时不会自动切换到其他模型。- OpenAI 文本接口不用于视频生成、图片生成或音频生成,请使用对应的专用接口。
常见问题
| 现象 | 原因 | 处理方式 |
|---|---|---|
| 模型暂不可用 | 当前 API Key 没有该模型权限,或模型服务暂时不可用 | 检查模型名称和账户权限;持续出现时联系管理员。 |
401 | FrameAI API Key 缺失、无效或过期 | 更新请求中的 Authorization。 |
400 | JSON 格式、字段类型或模型参数错误 | 检查 Content-Type、字段拼写和参数类型。 |
429 | 请求频率过高或服务繁忙 | 按指数退避策略重试。 |
返回 reasoning_content 但页面不显示 | 客户端只读取了 content | 根据业务需要单独处理推理字段。 |
| 流式响应无法解析 | 客户端把 SSE 当作完整 JSON | 逐行读取 data:,直到 [DONE]。 |
| 返回没有文本 | 模型返回了工具调用或输出达到限制 | 检查 tool_calls 和 finish_reason。 |
公共请求字段、响应字段、流式结构、Go 示例和统一错误响应见 Chat Completions 接口。