> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tapapi.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Chat Completions

> 文本对话接口的请求结构和返回结构

Chat Completions 是文本模型最常用的调用方式，适合聊天、问答、摘要、改写、分类、结构化输出和自动化任务。

```text theme={null}
POST https://tapapi.ai/v1/chat/completions
```

<Note>示例模型使用 `gpt-5.4`。实际接入时，请以控制台可用模型和模型详情为准。</Note>
<Warning>不要把 `sk-` 开头的 Key 写进前端代码、公开仓库、浏览器插件配置或第三方共享模板里。生产环境建议由服务端代理调用 Tapapi。</Warning>

## 基本请求

<CodeGroup>
  ```bash cURL theme={null}
  curl https://tapapi.ai/v1/chat/completions \
    -H "Authorization: Bearer sk-xxx" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "gpt-5.4",
      "messages": [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "用一句话解释 Tapapi 是什么"}
      ]
    }'
  ```

  ```python Python theme={null}
  from openai import OpenAI

  client = OpenAI(api_key="sk-xxx", base_url="https://tapapi.ai/v1")

  resp = client.chat.completions.create(
      model="gpt-5.4",
      messages=[
          {"role": "system", "content": "You are a helpful assistant."},
          {"role": "user", "content": "用一句话解释 Tapapi 是什么"},
      ],
  )

  print(resp.choices[0].message.content)
  ```

  ```javascript Node.js theme={null}
  import OpenAI from "openai";

  const client = new OpenAI({
    apiKey: "sk-xxx",
    baseURL: "https://tapapi.ai/v1",
  });

  const resp = await client.chat.completions.create({
    model: "gpt-5.4",
    messages: [
      { role: "system", content: "You are a helpful assistant." },
      { role: "user", content: "用一句话解释 Tapapi 是什么" },
    ],
  });

  console.log(resp.choices[0].message.content);
  ```
</CodeGroup>

## 请求字段

| 字段                  |  必填 | 说明                              |
| ------------------- | :-: | ------------------------------- |
| `model`             |  是  | 文本模型名，以控制台和模型中心为准               |
| `messages`          |  是  | 对话消息数组                          |
| `temperature`       |  否  | 控制随机性，低值更稳定，高值更发散               |
| `top_p`             |  否  | 采样范围；通常不要和 `temperature` 同时大幅调整 |
| `max_tokens`        |  否  | 限制最大输出长度                        |
| `presence_penalty`  |  否  | 降低重复话题概率，支持情况取决于模型和渠道           |
| `frequency_penalty` |  否  | 降低重复用词概率，支持情况取决于模型和渠道           |
| `stream`            |  否  | 是否开启流式输出                        |
| `stream_options`    |  否  | 流式附加选项，例如是否返回 usage             |
| `response_format`   |  否  | 结构化输出，视模型支持情况而定                 |
| `tools`             |  否  | 工具调用，视模型支持情况而定                  |
| `tool_choice`       |  否  | 控制是否指定工具，视模型支持情况而定              |

参数是否生效取决于具体模型和上游渠道。上线前不要只验证 200 状态码，还要验证返回质量、错误结构、用量字段和账单扣费是否符合预期。

## messages 怎么写

| role        | 用途               |
| ----------- | ---------------- |
| `system`    | 放长期规则、身份、风格和输出约束 |
| `user`      | 放用户输入和本次任务       |
| `assistant` | 放历史回答，用于多轮上下文    |

最小可用请求只需要一条 `user` 消息。生产环境建议把稳定规则放到 `system`，把本次输入放到 `user`。

文本消息最常见写法是：

```json theme={null}
{"role": "user", "content": "Hello"}
```

部分多模态模型也接受数组形式的 content，例如 `{"type": "text", "text": "Hello"}`。文本 API 入门先使用字符串形式即可。

## 返回结构

非流式请求通常读取：

```text theme={null}
choices[0].message.content
```

常见字段：

| 字段                           | 说明                       |
| ---------------------------- | ------------------------ |
| `id`                         | 请求结果 ID                  |
| `model`                      | 实际使用的模型                  |
| `choices`                    | 模型输出候选                   |
| `choices[0].message.content` | 文本结果                     |
| `usage`                      | token 用量，字段完整性视模型和上游返回而定 |

生产环境建议同时保存响应头里的 `X-Oneapi-Request-Id`。排查超时、扣费、上游失败和重试问题时，这个 ID 比单纯保存错误文案更有用。

## 解析建议

| 场景            | 建议                                                                 |
| ------------- | ------------------------------------------------------------------ |
| 非流式文本         | 先判断 `choices` 是否存在，再读取 `choices[0].message.content`                |
| 流式文本          | 使用 SSE 逐块读取，跳过空 chunk、ping/keep-alive 事件，再拼接 `delta.content`       |
| 结构化输出         | 不要只相信模型输出，业务侧仍然要做 JSON parse、字段校验和失败兜底                             |
| 工具调用          | Tapapi 返回的是模型的 tool call 意图，真正的工具鉴权、执行和结果写回由业务侧负责                  |
| Responses API | `/v1/responses` 是另一套响应结构，不要复用 Chat Completions 的 `choices[0]` 解析逻辑 |

## 常见错误

| 错误        | 常见原因                           |
| --------- | ------------------------------ |
| 401       | API Key 缺失、写错或格式不对             |
| 400 / 5xx | 请求体缺字段、上游错误或模型不可用；具体状态码以实际响应为准 |
| 429       | 请求过快或达到限流                      |
| 余额不足      | 账户余额不足或模型权限不可用                 |

错误响应通常包含 `error.message`、`error.type` 或 `error.code`。建议日志至少记录：HTTP 状态码、`error.message`、`error.type`、`error.code`、模型名、业务用户 ID、请求耗时和 `X-Oneapi-Request-Id`。

更多处理方式见 [错误码与重试](/errors)。
