OpenAI API

技术栈
AI 框架
pythonLLMGPTChatGPTEmbeddingsDALL-E

概览

OpenAI API 技术栈概览

OpenAI API 是由 OpenAI 提供的大型语言模型(LLM)云服务,让开发者通过 REST API 或 Python SDK 访问 GPT-4、GPT-4o、DALL·E 3、Whisper、Embeddings 等模型能力,快速构建 AI 驱动的应用。

核心特性:

  • 💬 Chat Completions — GPT-4o/GPT-4/gpt-4o-mini,支持多轮对话、角色扮演、长上下文(128K tokens)
  • 🎨 Image Generation — DALL·E 3,文本到图像生成,支持修订
  • 🎤 Speech-to-Text — Whisper 模型,多语言语音识别与翻译
  • 🔊 Text-to-Speech — TTS 模型,自然语音合成
  • 🧮 Embeddings — 文本向量化,用于语义搜索、聚类、推荐
  • 🔧 Function Calling — 让 LLM 调用外部 API/函数,构建 AI Agent
  • 📊 Assistants API — 托管式 AI 助手,支持代码解释器、文件检索、持久线程
  • 🎯 Vision — GPT-4o/GPT-4V,图像理解与多模态推理

适用场景: 智能客服、内容生成、代码助手、知识库问答(RAG)、AI Agent、多模态应用。

安装

1. 环境准备

  • 操作系统: Windows 10+ / macOS 11+ / Linux
  • Python 版本: Python 3.8 及以上(推荐 3.10+)
  • 依赖项: pip
  • API Key:platform.openai.com/api-keys 创建

获取 API Key

  1. 注册 OpenAI Platform
  2. 进入 API Keys 页面,创建新密钥
  3. 保存为环境变量(推荐):
# Linux/macOS
export OPENAI_API_KEY="sk-..."

# Windows (CMD)
set OPENAI_API_KEY=sk-...

# Windows (PowerShell)
$env:OPENAI_API_KEY="sk-..."

2. 安装命令

# === 安装 Python SDK ===
pip install openai

# === 安装常用配套工具 ===
pip install tiktoken            # Token 计数
pip install python-dotenv       # 从 .env 加载环境变量
pip install httpx               # HTTP 客户端

# === 验证安装 ===
python -c "import openai; print(f'OpenAI SDK {openai.__version__}')"

# === 从 .env 加载 API Key ===
echo 'OPENAI_API_KEY=sk-...' >; .env

3. 常见问题

问题 1:openai.OpenAIError: The api_key client option must be set

# 检查环境变量是否正确设置
import os
print(os.getenv("OPENAI_API_KEY"))

# 或显式传入
from openai import OpenAI
client = OpenAI(api_key="sk-...")

问题 2:API 调用返回 429(速率限制)

# 使用指数退避重试
import time
for attempt in range(5):
    try:
        response = client.chat.completions.create(...)
        break
    except openai.RateLimitError:
        wait = 2 ** attempt
        print(f"速率限制,等待 {wait} 秒...")
        time.sleep(wait)

问题 3:国内无法访问 OpenAI API

# 方案一:使用代理
export HTTPS_PROXY=http://127.0.0.1:7890

# 方案二:使用 Azure OpenAI Service(中国区可用)
# 方案三:使用 OpenAI 兼容的国内 API 服务

问题 4:Token 消耗过大(成本控制)

# 使用 tiktoken 预估 token 数
import tiktoken
enc = tiktoken.encoding_for_model("gpt-4o")
tokens = len(enc.encode(text))

# 使用 gpt-4o-mini 替代 gpt-4o 大幅降低成本

示例

OpenAI Chat Completions —— 对话、流式、多模态

目标

  • 掌握 Chat Completions API 的核心用法
  • 实现多轮对话、流式输出
  • 使用 Vision 理解图像

完整代码

import os
from openai import OpenAI

# 初始化客户端(自动从环境变量读取 OPENAI_API_KEY)
client = OpenAI()

# ============================================================
# 1. 基础 Chat Completion
# ============================================================
response = client.chat.completions.create(
    model="gpt-4o-mini",  # 性价比最高的模型
    messages=[
        {"role": "system", "content": "你是一个幽默且知识渊博的助手。"},
        {"role": "user", "content": "用一句话解释什么是量子计算?"},
    ],
    temperature=0.7,
    max_tokens=200,
)

print(response.choices[0].message.content)
# 输出:量子计算就像同时抛一万枚硬币然后一次性看完所有结果——
#       传统计算则是一枚一枚地抛。

# ============================================================
# 2. 多轮对话(保持上下文)
# ============================================================
messages = [
    {"role": "system", "content": "你是一个Python编程助手。"},
]

while True:
    user_input = input("\n你: ")
    if user_input.lower() in ["exit", "quit", "q"]:
        break

    messages.append({"role": "user", "content": user_input})

    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=messages,
        temperature=0.5,
    )

    reply = response.choices[0].message.content
    messages.append({"role": "assistant", "content": reply})

    print(f"\n助手: {reply}")

# ============================================================
# 3. 流式输出(打字机效果)
# ============================================================
stream = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "写一首关于编程的五言绝句"}],
    stream=True,
)

print("助手: ", end="", flush=True)
for chunk in stream:
    if chunk.choices[0].delta.content is not None:
        print(chunk.choices[0].delta.content, end="", flush=True)
print()

# ============================================================
# 4. Vision —— 图像理解
# ============================================================
response = client.chat.completions.create(
    model="gpt-4o",  # 支持视觉的模型
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "这张图片里有什么?请详细描述。"},
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg",
                        "detail": "auto",  # low / high / auto
                    },
                },
            ],
        }
    ],
    max_tokens=500,
)

print(response.choices[0].message.content)

# ============================================================
# 5. JSON 模式(结构化输出)
# ============================================================
response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {"role": "system", "content": "你以 JSON 格式回答。只输出 JSON,不要有其他文字。"},
        {"role": "user", "content": "列出3种编程语言及其主要用途"},
    ],
    response_format={"type": "json_object"},
)

import json
result = json.loads(response.choices[0].message.content)
print(json.dumps(result, ensure_ascii=False, indent=2))
# {
#   "languages": [
#     {"name": "Python", "use": "数据科学..."},
#     {"name": "JavaScript", "use": "Web开发..."},
#     {"name": "Rust", "use": "系统编程..."}
#   ]
# }

# ============================================================
# 6. Token 计数与成本预估
# ============================================================
import tiktoken

enc = tiktoken.encoding_for_model("gpt-4o-mini")
text = "Hello, this is a test message to count tokens."
tokens = len(enc.encode(text))
print(f"\n'{text}' → {tokens} tokens")

# 成本参考(2025 年)
pricing = {
    "gpt-4o":        {"input": 2.50, "output": 10.00},  # 每百万 token 美元
    "gpt-4o-mini":   {"input": 0.15, "output": 0.60},
    "gpt-4":         {"input": 30.00, "output": 60.00},
}

model = "gpt-4o-mini"
input_tokens = 500
output_tokens = 200
cost = (input_tokens/1e6 * pricing[model]["input"] +
        output_tokens/1e6 * pricing[model]["output"])
print(f"预估成本: ${cost:.6f}")

模型速查

模型 上下文 特性
gpt-4o 128K 旗舰多模态,最快
gpt-4o-mini 128K 性价比最高,适合大多数场景
o1-preview 128K 深度推理(数学、编程)
gpt-4 8K/32K 精确但较慢
dall-e-3 - 图像生成
whisper-1 - 语音转文字
tts-1-hd - 文字转语音
text-embedding-3-small 8K 向量嵌入

OpenAI Function Calling + RAG 构建 AI Agent

目标

  • 掌握 Function Calling(工具调用)机制
  • 构建基于 Embeddings 的 RAG 知识库问答
  • 实现完整的 AI Agent 循环

完整代码

1. Function Calling —— 让 GPT 调用你的函数

import json
from openai import OpenAI

client = OpenAI()

# ============================================================
# 定义工具(函数)
# ============================================================
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取指定城市的当前天气信息",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "城市名称,如 Beijing, Shanghai"
                    }
                },
                "required": ["city"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "search_database",
            "description": "在内部数据库中搜索订单信息",
            "parameters": {
                "type": "object",
                "properties": {
                    "order_id": {"type": "string"},
                    "customer_name": {"type": "string"},
                },
            },
        },
    },
]


# 模拟函数实现
def get_weather(city: str) -> dict:
    """模拟天气查询"""
    return {
        "city": city,
        "temperature": 22,
        "condition": "晴朗",
        "humidity": "45%",
    }


def search_database(order_id: str = None, customer_name: str = None) -> dict:
    """模拟数据库搜索"""
    return {
        "orders": [
            {"id": "ORD-001", "product": "MacBook Pro", "status": "已发货"},
        ]
    }


# 函数映射表
available_functions = {
    "get_weather": get_weather,
    "search_database": search_database,
}


def run_agent(user_query: str):
    """AI Agent 主循环"""
    messages = [{"role": "user", "content": user_query}]

    # 第一次调用:GPT 决定是否要调用工具
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=messages,
        tools=tools,
        tool_choice="auto",
    )

    response_message = response.choices[0].message
    tool_calls = response_message.tool_calls

    # 如果 GPT 需要调用工具
    if tool_calls:
        messages.append(response_message)

        for tool_call in tool_calls:
            function_name = tool_call.function.name
            function_args = json.loads(tool_call.function.arguments)

            print(f"🔧 调用函数: {function_name}({function_args})")

            # 执行函数
            function_to_call = available_functions[function_name]
            function_response = function_to_call(**function_args)

            # 将函数结果添加到消息中
            messages.append({
                "tool_call_id": tool_call.id,
                "role": "tool",
                "name": function_name,
                "content": json.dumps(function_response, ensure_ascii=False),
            })

        # 第二次调用:GPT 根据函数结果生成最终回复
        final_response = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=messages,
        )

        return final_response.choices[0].message.content

    return response_message.content


# 测试
print(run_agent("北京今天天气怎么样?"))
print(run_agent("帮我查一下订单 ORD-001 的状态"))
print(run_agent("你好,你是谁?"))  # 不需要工具调用

2. RAG(检索增强生成)

import numpy as np

# ============================================================
# 构建知识库
# ============================================================
documents = [
    "Vibe 平台是一个智能元器件管理系统,支持元器件搜索、文档生成和代码例程。",
    "用户可以使用自然语言搜索技术栈,如 React、Spring Boot、PyTorch等。",
    "平台支持自动生成 Markdown 格式的技术文档和代码示例。",
    "价格单位为分(cents),1元 = 100分。",
    "所有回复必须使用中文,元器件处理需要按工作流顺序执行。",
]

# 获取 Embeddings
def get_embeddings(texts: list[str]) -> list[list[float]]:
    response = client.embeddings.create(
        model="text-embedding-3-small",
        input=texts,
    )
    return [d.embedding for d in response.data]


doc_embeddings = get_embeddings(documents)
print(f"知识库大小: {len(documents)} 条文档, 向量维度: {len(doc_embeddings[0])}")

# ============================================================
# 语义搜索
# ============================================================
def semantic_search(query: str, top_k: int = 3) -> list[str]:
    """根据语义相似度检索最相关的文档"""
    query_embedding = get_embeddings([query])[0]

    # 计算余弦相似度
    def cosine_similarity(a, b):
        return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

    similarities = [
        cosine_similarity(query_embedding, doc_emb)
        for doc_emb in doc_embeddings
    ]

    # 取 top-k
    top_indices = np.argsort(similarities)[-top_k:][::-1]
    return [documents[i] for i in top_indices]


# ============================================================
# RAG 问答
# ============================================================
def rag_qa(query: str) -> str:
    """基于知识库的问答"""
    # 1. 检索相关文档
    relevant_docs = semantic_search(query, top_k=3)
    context = "\n\n".join(relevant_docs)

    print(f"📚 检索到 {len(relevant_docs)} 条相关文档")

    # 2. 用检索到的上下文增强 Prompt
    system_prompt = f"""你是一个知识库助手。请基于以下上下文回答问题。
如果上下文不足以回答,请说明。

上下文:
{context}"""

    # 3. 调用 GPT 生成答案
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": query},
        ],
        temperature=0.3,  # 降低随机性
    )

    return response.choices[0].message.content


# 测试
print("\n" + "="*50)
print(rag_qa("价格单位是什么?"))
print("\n" + rag_qa("如何搜索技术栈?"))

3. 完整的 Agent + RAG 架构

用户提问
    │
    ▼
┌─────────────────────┐
│   Router (GPT-4o)    │ → 判断:需要工具?需要检索?
└──────┬──────────────┘
       │
  ┌────┼────┐
  ▼    ▼    ▼
Tool  RAG  Direct
  │    │    │
  └────┼────┘
       ▼
   Final Answer

关键要点

概念 说明
tools 参数 向 GPT 注册可调用函数
tool_choice: "auto" GPT 自行决定是否调用工具
role: "tool" 返回函数执行结果给 GPT
text-embedding-3-small 性价比最高的嵌入模型
余弦相似度 衡量向量间语义相似度的标准方法
RAG vs 微调 RAG 更新知识只需改文档,微调需重新训练

教程

OpenAI 应用开发实战 —— 构建生产级 AI 应用

本章目标

  • 掌握 Token 管理与成本控制
  • 实现可靠的错误处理与重试
  • 学会 Prompt Engineering 最佳实践
  • 了解 Assistants API

1. Token 管理与成本优化

1.1 Token 是什么?

Token 是 LLM 处理的文本基本单位,约等于英文的 0.75 个词或中文的 0.5 个字。

import tiktoken

enc = tiktoken.get_encoding("cl100k_base")

# 中文 vs 英文 token 效率
text_en = "Hello, how are you today?"
text_zh = "你好,今天过得怎么样?"

print(f"英文 '{text_en}' → {len(enc.encode(text_en))} tokens")
print(f"中文 '{text_zh}' → {len(enc.encode(text_zh))} tokens")
# 中文 token 消耗约为英文的 2-3 倍

1.2 成本优化策略

# ① 使用 gpt-4o-mini 替代 gpt-4o(成本降低 90%+)
# gpt-4o:       $2.50/$10.00 per 1M tokens
# gpt-4o-mini:  $0.15/$0.60  per 1M tokens

# ② 限制输出长度
response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=messages,
    max_tokens=200,  # 不要设为过大的值
)

# ③ 缓存常见回答(用 Embeddings 做语义缓存)
# ④ 分类任务用 gpt-4o-mini,复杂推理才用 gpt-4o

2. 错误处理与重试

import time
from openai import (
    OpenAI, RateLimitError, APIError, APITimeoutError,
    APIConnectionError, AuthenticationError,
)

MAX_RETRIES = 3

def call_with_retry(messages, **kwargs):
    """带重试的 API 调用"""
    for attempt in range(MAX_RETRIES):
        try:
            response = client.chat.completions.create(
                model="gpt-4o-mini",
                messages=messages,
                **kwargs,
            )
            return response

        except RateLimitError:
            wait = 2 ** (attempt + 1)
            print(f"⏳ 速率限制,第 {attempt+1} 次重试,等待 {wait}s")
            time.sleep(wait)

        except (APIError, APITimeoutError, APIConnectionError) as e:
            wait = 2 ** attempt
            print(f"⚠️ API 错误: {e},第 {attempt+1} 次重试")
            time.sleep(wait)

        except AuthenticationError:
            print("❌ API Key 无效!请检查 OPENAI_API_KEY")
            raise

    raise Exception(f"重试 {MAX_RETRIES} 次后仍失败")

3. Prompt Engineering 最佳实践

3.1 结构化 Prompt 模板

def build_prompt(template: str, **kwargs) -> list[dict]:
    """构建结构化 Prompt"""
    system = f"""你是 {kwargs.get('role', '一个有用的助手')}。

规则:
1. 始终用中文回复
2. 如果不知道答案,诚实说不知道
3. 保持回答简洁

输出格式要求:
{kwargs.get('output_format', '纯文本')}
"""
    return [
        {"role": "system", "content": system},
        {"role": "user", "content": template.format(**kwargs)},
    ]


# 使用
messages = build_prompt(
    "分析以下代码的复杂度: {code}",
    role="资深软件工程师",
    output_format="JSON",
    code="def fib(n): return n if n<=1 else fib(n-1)+fib(n-2)",
)

3.2 Few-Shot Prompting

few_shot_messages = [
    {"role": "system", "content": "将用户输入分类为:正面、负面、中性"},
    {"role": "user", "content": "这个产品太棒了!"},
    {"role": "assistant", "content": "分类: 正面"},
    {"role": "user", "content": "一般般,没什么特别的"},
    {"role": "assistant", "content": "分类: 中性"},
    {"role": "user", "content": "物流慢得要命,投诉!"},
    {"role": "assistant", "content": "分类: 负面"},
    # 新的输入
    {"role": "user", "content": "还行吧,凑合用"},
]

3.3 Chain of Thought(思维链)

cot_prompt = """请一步步求解以下数学题。

步骤1: 列出已知条件
步骤2: 列出需要求的未知数
步骤3: 选择合适的公式
步骤4: 代入计算
步骤5: 验证结果

问题:一个班级有 60% 的男生和 40% 的女生。
男生平均分 85,女生平均分 92。求全班平均分。"""

messages = [{"role": "user", "content": cot_prompt}]

4. Assistants API(托管式 Agent)

# 创建 Assistant
assistant = client.beta.assistants.create(
    name="代码审查助手",
    instructions="你是一个代码审查专家,帮助发现代码中的 Bug 和优化机会。",
    model="gpt-4o",
    tools=[{"type": "code_interpreter"}],  # 内置代码执行
)

# 创建 Thread(对话线程)
thread = client.beta.threads.create()

# 添加消息
message = client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content="分析以下代码的时间复杂度:def fib(n): ...",
)

# 运行 Assistant
run = client.beta.threads.runs.create_and_poll(
    thread_id=thread.id,
    assistant_id=assistant.id,
)

# 获取回复
messages = client.beta.threads.messages.list(thread_id=thread.id)
for msg in messages.data:
    if msg.role == "assistant":
        print(msg.content[0].text.value)

5. 安全注意事项

# ❌ 不要这样做!
api_key = "sk-abc123..."  # 硬编码在代码中
# 会被 git 提交到版本库!

# ✅ 正确做法
import os
from dotenv import load_dotenv
load_dotenv()
api_key = os.getenv("OPENAI_API_KEY")

# ✅ 生产环境:使用密钥管理服务(AWS Secrets Manager / Vault)

思考题

  1. Function Calling 和传统的 if-else 路由有何本质不同?
  2. RAG 系统中 Embedding 模型的选择如何影响检索质量?
  3. 如何评估一个 Prompt 的好坏?有哪些量化指标?
  4. Assistants API 与自行实现 Agent 循环各有什么优劣势?

参考资料

  1. [1] OpenAI. OpenAI API 官方文档. 2024.
  2. [2] OpenAI Community. OpenAI Cookbook. 2024.
  3. [3] DAIR.AI. Prompt Engineering Guide. 2024.
  4. [4] Chip Huyen. Building LLM Applications for Production. 2024.