一文搞懂 OpenAI 接口(含 DeepSeek 兼容 & 流式输出实战)
很多人会用 OpenAI API,但用得很“玄学”:
- role 随便写
- prompt 全塞 user
- 不会流式输出
- 换模型就不会接了
结果就是:能跑,但不稳、不好用、不好扩展。
这篇带你从 0 → 可上线。
一、最小调用(所有一切的起点)
from openai import OpenAI
client = OpenAI(api_key="你的API_KEY")
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "user", "content": "RAG 是什么?"}
]
)
print(resp.choices[0].message.content)
👉 这是最小闭环:
messages → 模型 → 返回结果
但这只是“能用”,远没到“可控”。
二、messages 不是聊天,是“控制协议”
标准结构:
[
{"role": "system", "content": "..."},
{"role": "user", "content": "..."},
{"role": "assistant", "content": "..."}
]
很多人理解成聊天记录,其实更准确的是:
👉 这是模型的执行脚本
1️⃣ system —— 行为控制器(核心)
{
"role": "system",
"content": "你是一个严谨的技术专家,不允许编造内容。"
}
作用:
- 控制风格(专业 / 销售 / 冷静)
- 限制幻觉
- 规定输出格式
👉 一句话:
👉 system 决定“你是谁”
2️⃣ user —— 输入数据
{
"role": "user",
"content": "RAG 是什么?"
}
👉 就是用户问题 + 输入信息。
3️⃣ assistant —— 历史输出(容易被误用)
{
"role": "assistant",
"content": "RAG 是..."
}
作用:
- 维持多轮上下文
- 告诉模型“刚才你说了什么”
👉 注意:
❌ 不是让模型补充信息
✅ 是你在“喂历史记录”
三、推荐的标准调用模板(生产可用)
messages = [
{
"role": "system",
"content": """
你是一个专业助手,请遵守:
1. 只基于提供信息回答
2. 不确定就说不知道
3. 回答简洁
"""
},
{
"role": "user",
"content": f"""
【上下文】
{context}
【问题】
{question}
"""
}
]
👉 这是 RAG / 知识库系统的标准写法。
四、DeepSeek 能不能用 OpenAI SDK?
👉 可以,而且这是强烈推荐做法。
像 DeepSeek、OpenAI、以及很多国产模型,都在做:
👉 OpenAI API 兼容协议
1️⃣ 使用 DeepSeek(OpenAI 兼容方式)
from openai import OpenAI
client = OpenAI(
api_key="你的DeepSeek Key",
base_url="https://api.deepseek.com"
)
resp = client.chat.completions.create(
model="deepseek-chat",
messages=[
{"role": "user", "content": "你好"}
]
)
print(resp.choices[0].message.content)
2️⃣ 这意味着什么?
👉 你可以做到:
- 一套代码 → 多模型切换
- OpenAI / DeepSeek / 其他厂商通用
3️⃣ 推荐策略(实战)
👉 你应该这样设计:
MODEL_PROVIDER = "deepseek" # or openai
if MODEL_PROVIDER == "openai":
base_url = None
model = "gpt-4o-mini"
else:
base_url = "https://api.deepseek.com"
model = "deepseek-chat"
👉 你的系统就“可替换”了。
五、流式输出(Streaming)实战
如果你做产品(聊天、客服),必须用流式输出。
否则体验就是卡顿。
1️⃣ 普通调用(非流式)
resp = client.chat.completions.create(...)
👉 等全部生成完才返回。
2️⃣ 流式调用(关键)
stream = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
stream=True
)
for chunk in stream:
delta = chunk.choices[0].delta
if delta.content:
print(delta.content, end="", flush=True)
3️⃣ 输出效果
RAG 是一种结合检索...
(逐字输出)
👉 用户体验直接提升一个档次。
4️⃣ 前端怎么接?
👉 常见方式:
- SSE(Server-Sent Events)
- WebSocket
👉 后端边读 chunk 边推给前端。
六、关键参数(必须掌握)
1️⃣ temperature(发散程度)
temperature=0.2
| 值 | 适用 |
|---|---|
| 0.0~0.3 | RAG / 客服(稳定) |
| 0.5~0.7 | 通用 |
| 0.8+ | 创作 |
2️⃣ max_tokens
限制输出长度:
max_tokens=500
3️⃣ top_p(采样控制)
一般不用动,默认即可。
七、进阶用法(提升稳定性)
1️⃣ 强约束输出(结构化)
"请用 JSON 输出:{answer: string}"
👉 简单但不稳定。
2️⃣ system 多层控制
messages = [
{"role": "system", "content": "你是金融专家"},
{"role": "system", "content": "必须给出结论"},
]
👉 模型会综合执行。
3️⃣ 上下文裁剪(必须做)
问题:
👉 token 会爆
解决:
- 只保留最近 3~5 轮
- 或做 summary
八、一个完整“可上线”的调用函数
def chat(query, context=""):
messages = [
{
"role": "system",
"content": "你是一个严谨助手,不允许编造。"
},
{
"role": "user",
"content": f"""
上下文:
{context}
问题:
{query}
"""
}
]
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
temperature=0.2
)
return resp.choices[0].message.content
九、最常见的坑(别踩)
❌ 不写 system
→ 输出不可控
❌ 所有东西塞 user
→ 模型理解变差
❌ 不做流式
→ 用户体验很差
❌ 不做模型切换设计
→ 后期重构成本极高
十、一句话总结
👉 OpenAI 接口的本质不是“聊天”,而是:
👉 一个“标准化的大模型调用协议”
你写的不是对话,而是:
👉 一段控制模型行为的脚本(messages)
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)