01-AI应用开发实战

知识库
知识库文档
/tech-stacks/openai/tutorial/01-AI应用开发实战.md

文档

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 循环各有什么优劣势?

信息

路径
/tech-stacks/openai/tutorial/01-AI应用开发实战.md
更新时间
2026/5/30