跳转到内容
API 入口

Cookbook

聊天补全 Chat Completions 示例

Chat Completions API 接入 OfApp.cn 教程,覆盖 messages、system/user/assistant、curl、Python、JavaScript、stream、多轮对话、finish_reason、常见错误和上线前检查。

预计阅读
8 分钟
最近更新
2026/07/03
维护方式
人工编辑

Chat Completions 是许多 OpenAI 兼容服务、AI 客户端和旧项目仍在使用的聊天请求形态。它的核心很简单:把一组 messages 发给模型,再从 choices[0].message.content 读取回复。

本文示例基于 OfApp.cn 的 OpenAI 兼容接口写法。Base URL 使用 https://api.ofapp.cn/v1。具体可用模型、价格、额度、套餐和能力,请以 OfApp.cn 控制台或官方文档为准。

项目 内容
阅读时间 约 8 分钟
更新时间 2026-07-03
适合场景 OpenAI 兼容 API 连通性验证、旧项目迁移、AI 客户端配置、聊天功能封装、Prompt 学习
核心问题 如何用 messages 稳定组织一次聊天请求,并判断 OfApp.cn 兼容入口是否适合当前项目
你会完成 curl、Python、JavaScript 三种最小请求,一份任务选择矩阵,以及 messages、finish_reason、stream 和上线前检查清单
边界提醒 OfApp.cn 官方文档展示了 /v1/chat/completions 示例;具体可用模型、价格、额度、套餐、速率限制和能力边界请以 OfApp.cn 控制台或官方文档为准
读者 正在处理的问题 读完能得到什么
第一次接 API 的开发者 不确定 Base URL、Key、模型名怎么放 用最小请求确认接口能返回内容
迁移旧项目的人 项目里已经写了 chat.completions.create 判断哪些配置可以替换,哪些能力要验证
AI 客户端用户 客户端要求填写 OpenAI 兼容接口 理解 /v1/chat/completions 和模型名的关系
后端维护者 要把聊天能力接进服务端 建立错误处理、超时、日志脱敏和流式输出习惯
Prompt 学习者 想理解 system、user、assistant 的位置 学会把指令、问题和历史对话分开组织
准备配置Key URL Model组织消息messages发送请求POST /chat读取回复choices处理错误状态码接入业务服务端 / 客户端

这张图提醒你把调试顺序拆开。只要最小请求没有稳定返回,就先不要叠加工具调用、长上下文、复杂 Prompt、数据库检索或业务侧状态管理。

Chat Completions 是一种面向对话的生成接口。请求体通常包含:

字段 作用 调试建议
model 指定要调用的模型 不要猜模型名,先用账号可用模型或控制台展示的名称
messages 按顺序提供对话消息 最小验证只放一条 user 消息即可
stream 是否开启流式输出 调试阶段先用 false,页面体验再打开
temperature 控制输出随机性 业务场景要求稳定时调低
max_tokens 限制输出长度 出现 finish_reason: "length" 时检查这里

OpenAI 官方文档中,Chat Completions 的响应会返回 choices 数组;每个 choice 包含 messagefinish_reason。很多兼容服务也沿用这种结构,但边界能力仍要按服务商当前文档验证。

Chat Completions 最适合那些已经围绕 messages 组织输入的场景。它不只服务聊天窗口,也常用于把一段材料转成可读回复、分类结果或办公初稿。

任务 推荐 messages 结构 第一次验证 主要风险
连通性测试 一条 user 消息 curl 最小请求能返回 choices[0].message.content 一开始就加入复杂参数,导致问题难定位
AI 客户端配置 客户端按 OpenAI 兼容格式生成 messages 确认最终地址是 /v1/chat/completions 客户端自动拼接 /v1,造成路径重复
多轮聊天 system 固定边界,保留必要 user / assistant 历史 用 2 到 4 轮脱敏对话验证上下文效果 历史过长、旧信息冲突、成本不可控
办公初稿 system 写格式和语气,user 放会议、邮件或资料摘要 先生成一份人工可复核初稿 敏感内容进入日志,缺少人工复核
旧项目迁移 保留原有 messages,替换 Base URL、Key 和模型名 先跑原有最小用例 模型名、工具调用或返回结构差异被忽略
流式聊天界面 非流式成功后再开启 stream: true 终端或服务端先打印增量片段 代理缓冲、前端取消、中途断开未处理

如果新项目需要结构化输出、工具调用、多模态或代理式流程,可以同时评估 Responses API 示例。如果只是验证 Key、Base URL 和模型名,Chat Completions 仍然是一条短路径。

messages 是 Chat Completions 的核心。它不是一段长文本,而是一段对话历史。

role 放什么内容 例子
system 助手身份、回答风格、边界要求 你是一个简洁的中文技术助手。
user 用户这轮提出的问题或任务 把这段会议记录整理成 5 个行动项。
assistant 历史中模型已经说过的话 我已经整理出初稿,请确认负责人。

实用写法:

  • 系统指令保持短而明确,不要把整份业务规则都塞进去。
  • 用户输入和系统指令分开,方便日志、审计和 Prompt 版本管理。
  • 多轮对话要保留必要历史,但过旧、重复、无关的内容应压缩或摘要。
  • 如果某个兼容服务要求使用其他 role,按该服务当前文档调整。

很多 Chat Completions 问题不是接口坏了,而是消息组织不清。上线前可以用这张表做一次自检。

检查项 通过标准 不通过时的表现
角色分工 system 管边界,user 放任务,assistant 只放历史回复 模型把规则当材料,或把历史回复当新问题
输入来源 用户材料、系统规则和调试信息分开保存 日志难脱敏,Prompt 版本难回放
历史长度 只保留当前任务必要事实,旧内容摘要化 上下文过长、成本升高、回答被旧信息带偏
输出要求 格式、语气、长度和禁止事项写清楚 回复漂移,人工编辑成本高
敏感信息 Key、账号、客户资料和内部文件已脱敏 响应和日志里出现不该公开的内容
失败复现 能用同一组脱敏 messages 复现错误 线上问题只能靠猜,难以定位模型、接口还是业务层

把配置放进环境变量,避免把 Key 写进代码、截图、日志或公开仓库。

Terminal window
export OPENAI_BASE_URL="https://api.ofapp.cn/v1"
export OPENAI_API_KEY="sk-xxxx"
export OPENAI_MODEL="以 OfApp.cn 控制台可用模型为准"

如果你的工具会自动拼接 /v1,Base URL 可能需要填写 https://api.ofapp.cn。判断标准很简单:最终请求路径应只出现一个 /v1/chat/completions

curl 适合排查 Key、Base URL、模型名和网络问题。它绕开了 SDK 封装,能更快看清真实请求。

Terminal window
curl "$OPENAI_BASE_URL/chat/completions" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"model\": \"$OPENAI_MODEL\",
\"messages\": [
{\"role\":\"user\",\"content\":\"用一句话说明 Chat Completions 的用途。\"}
],
\"stream\": false
}"

预期结果不是固定文案,而是一个带有 choices 的 JSON。调试时先保存完整响应,再提取 choices[0].message.content

Python 适合脚本、数据处理、自动化办公、研究辅助和服务端任务。

import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["OPENAI_API_KEY"],
base_url=os.environ["OPENAI_BASE_URL"],
)
completion = client.chat.completions.create(
model=os.environ["OPENAI_MODEL"],
messages=[
{"role": "system", "content": "你是一个简洁的中文技术助手。"},
{"role": "user", "content": "把 Chat Completions 解释给非技术同事。"},
],
stream=False,
)
print(completion.choices[0].message.content)

生产代码里建议再加上超时、重试、错误分层和日志脱敏。不要把 OPENAI_API_KEY 打印到日志系统。

JavaScript 适合 Node.js 服务端、命令行工具、Next.js API Route、Astro 后端接口和内部自动化工具。

import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
baseURL: process.env.OPENAI_BASE_URL,
});
const completion = await client.chat.completions.create({
model: process.env.OPENAI_MODEL,
messages: [
{ role: "system", content: "你是一个简洁的中文技术助手。" },
{ role: "user", content: "给我一个适合新手的 Chat Completions 示例。" },
],
stream: false,
});
console.log(completion.choices[0]?.message?.content);

浏览器前端不要直接暴露 API Key。把请求放在服务端接口、边缘函数或后端服务中,再由前端调用你自己的接口。

Chat Completions 本身不会自动记住你的前文。你需要在下一次请求里把必要历史一起发送。

const messages = [
{ role: "system", content: "你是一个负责整理会议纪要的助手。" },
{ role: "user", content: "今天会议讨论了新版官网、SEO 和错误页优化。" },
{ role: "assistant", content: "可以整理为目标、决策、行动项和风险。" },
{ role: "user", content: "请把行动项按负责人和截止时间整理成表格。" },
];
const completion = await client.chat.completions.create({
model: process.env.OPENAI_MODEL,
messages,
});

多轮对话越长,请求越重,也越容易遇到上下文限制。更稳的做法是保留关键轮次,把旧内容压缩成摘要,并在业务数据库中保存结构化状态。

聊天界面通常希望边生成边显示,这时可以打开 stream: true。流式响应读取的是增量片段,不是完整 message

const stream = await client.chat.completions.create({
model: process.env.OPENAI_MODEL,
messages: [
{ role: "user", content: "用 5 个短句解释为什么流式输出适合聊天界面。" },
],
stream: true,
});
for await (const chunk of stream) {
const text = chunk.choices[0]?.delta?.content ?? "";
process.stdout.write(text);
}

如果非流式请求能返回、流式请求失败,优先检查客户端是否支持 Server-Sent Events、代理是否缓冲响应、超时时间是否过短。

非流式响应建议按这几个字段检查:

字段 说明 常见用途
id 本次生成的响应标识 排查日志、关联请求
model 实际返回使用的模型名 确认模型路由是否符合预期
choices[0].message.content 模型文本输出 展示给用户或进入下一步处理
choices[0].finish_reason 生成停止原因 判断是否被长度、工具调用或安全策略影响
usage token 用量信息,是否返回取决于服务 做成本观察和异常排查

如果页面只显示空白,不要只看 content。把完整 JSON 临时打印出来,确认返回结构、错误字段和 finish_reason

finish_reason 不应只作为调试字段丢掉。它往往决定下一步怎么处理。

finish_reason 常见含义 建议动作
stop 正常停止 读取 message.content,进入业务复核
length 达到输出长度限制 压缩输入、提高允许输出长度或提示用户缩小任务
content_filter 内容被安全策略影响 给用户明确提示,不要当作空白回复
tool_calls 模型请求调用工具 只有在项目支持工具调用时才继续处理
function_call 旧式函数调用路径 老项目要保留兼容处理,新项目应评估当前服务商推荐方式
现象 可能原因 建议处理
401 Unauthorized Key 缺失、拼错、过期或没有放进 Authorization 检查环境变量和请求头,不在日志里暴露完整 Key
404 Not Found Base URL 重复或漏掉 /v1,路径拼错 确认最终路径是 /v1/chat/completions
model not found 模型名不可用或账号没有权限 使用 OfApp.cn 控制台或官方文档中的可用模型名
choices 为空 服务返回错误结构,或被代理改写 打印完整响应和状态码
finish_reasonlength 输出达到长度限制 调整 max_tokens 或压缩输入
流式输出中断 客户端、代理或网关超时 先跑非流式,再检查 SSE、超时和重试策略
上下文过长 messages 历史太长 摘要旧历史,只保留必要事实
本地能跑,线上失败 线上环境变量、网络出口或运行时不同 对比线上最终 Base URL、Key 来源和 Node/Python 版本

Chat Completions 很适合验证兼容接口和迁移旧项目,但不是所有新需求都必须从它开始。

需求 更适合的方向 原因
新项目文本生成 同时了解 Responses API OpenAI 已把 Responses 作为新项目推荐方向
工具调用、联网搜索、文件检索 查看服务商支持的 Responses 或专用接口 Chat Completions 的兼容边界可能更窄
Claude 生态工具 使用 Anthropic Messages 风格接口 请求结构和 OpenAI Chat Completions 不一样
只想普通聊天、写作、读文件 先用天才游乐场 不必从接口参数开始理解

OfApp.cn 官方文档展示了 /v1/chat/completions 示例,也展示了 /v1/responses/v1/messages 等入口。具体项目选哪个,应看工具要求、服务商支持情况和你要用的模型能力。

检查项 通过标准
Key 管理 Key 只存在服务端环境变量或安全密钥系统中
Base URL 最终请求地址只出现一个 /v1
模型名 来自控制台、官方文档或 Models API 返回结果
最小请求 curl、Python 或 JavaScript 至少一种能稳定返回
错误处理 401、404、429、5xx、超时和上下文过长都有明确提示
日志 记录 request id、状态码、耗时,不记录完整 Key 和敏感用户内容
流式输出 客户端能处理中断、重连和空增量
成本观察 记录调用频率、平均输入长度和异常长输出
降级方案 接口失败时给用户可理解的错误,不让页面一直转圈

常见 Chat Completions 接口会支持 systemuserassistant 这种 messages 结构,但兼容服务的细节可能不同。最小验证可以只保留一条 user 消息,跑通后再加入系统指令。

可以。连通性验证时,一条 user 消息反而更清楚。需要稳定人格、格式和边界时,再加入 system

choices[0].message.content 为空怎么办?

Section titled “choices[0].message.content 为空怎么办?”

先打印完整响应。检查是否返回了错误对象、finish_reason 是否为 content_filtertool_calls、是否开启了流式输出却按非流式结构读取。

多轮对话要把历史全部发过去吗?

Section titled “多轮对话要把历史全部发过去吗?”

不建议无脑全发。只保留当前任务需要的事实、约束和结论。旧对话可以压缩成摘要,详细历史放在你自己的数据库或文件里。

Chat Completions 和 Responses 应该选哪个?

Section titled “Chat Completions 和 Responses 应该选哪个?”

旧项目、AI 客户端和 OpenAI 兼容工具通常更容易从 Chat Completions 起步。新项目可以同时了解 Responses API。真正的选择取决于服务商支持情况、项目代码结构和你要使用的能力。

OfApp.cn 官方文档展示了 POST /v1/chat/completions 示例。具体可用模型、计费规则、额度、速率限制和能力边界,请以 OfApp.cn 控制台或官方文档为准。

流式输出和非流式输出返回结构一样吗?

Section titled “流式输出和非流式输出返回结构一样吗?”

不一样。非流式通常读取 choices[0].message.content;流式要按 chunk 读取 choices[0].delta.content,并处理空片段和结束事件。

可以把真实对话历史写进日志吗?

Section titled “可以把真实对话历史写进日志吗?”

谨慎处理。聊天内容可能包含个人信息、业务资料、文件摘要或客户数据。生产环境建议做脱敏、采样、权限隔离和保留周期控制。

Chat Completions 的价值在于稳定、直观、容易验证。先用一条 user 消息跑通 /v1/chat/completions,再按业务需要加入系统指令、多轮历史、流式输出和错误处理。接入 OfApp.cn 时,Base URL、Key、模型名和能力边界都以 OfApp.cn 控制台或官方文档为准。