ChatGPT API成本优化指南:如何精确计算每个token的费用

5次阅读
没有评论

共计 2436 个字符,预计需要花费 7 分钟才能阅读完成。

image.webp

作为开发者,使用 ChatGPT API 时成本控制是一个不可忽视的问题。以 gpt-3.5-turbo 为例,每 100 万 token 的费用大约是 $2,而 gpt- 4 则高达 $30。对于日常调用量大的项目来说,这很快就会变成一笔不小的开销。

ChatGPT API 成本优化指南:如何精确计算每个 token 的费用

1. 了解定价模型

首先,我们需要清楚不同模型的定价差异。以下是 OpenAI 官方定价的对比(以每 1000token 计费):

  • gpt-3.5-turbo: $0.002
  • gpt-4: $0.03(输入)/$0.06(输出)

这意味着使用 gpt- 4 的成本可能是 gpt-3.5-turbo 的 15-30 倍!

2. 精确计算 token 数量

使用 tiktoken 库可以精确计算文本的 token 数量。这是一个 Python 示例:

import tiktoken

def count_tokens(text: str, model: str = "gpt-3.5-turbo") -> int:
    """计算文本的 token 数量"""
    encoding = tiktoken.encoding_for_model(model)
    return len(encoding.encode(text))

print(count_tokens("Hello, world!"))  # 输出: 4

3. 构建成本监控装饰器

为了实时监控 API 调用成本,我们可以创建一个装饰器:

from functools import wraps
import time

def cost_monitor(model: str):
    """API 调用成本监控装饰器"""
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            start_time = time.time()
            try:
                response = func(*args, **kwargs)
                prompt_tokens = count_tokens(kwargs.get('prompt', ''), model)
                completion_tokens = count_tokens(response.choices[0].message.content, model)
                total_cost = (prompt_tokens + completion_tokens) * get_model_price(model) / 1000
                print(f"调用耗时: {time.time()-start_time:.2f}s, 消耗 token: {prompt_tokens+completion_tokens}, 预估成本: ${total_cost:.4f}")
                return response
            except Exception as e:
                print(f"API 调用失败: {str(e)}")
                # 实现简单的重试逻辑
                time.sleep(1)
                return func(*args, **kwargs)
        return wrapper
    return decorator

4. 优化 token 消耗的技巧

(1) 精简系统提示词

系统提示词往往占据了不小的 token 量。通过以下方式可以精简 15% 以上:

  • 去掉不必要的礼貌用语
  • 使用缩写(如用 ”AI” 代替 ”artificial intelligence”)
  • 合并相似指令

(2) 响应长度限制

通过设置 max_tokens 参数可以控制响应长度:

response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=[{"role": "user", "content": prompt}],
    max_tokens=150  # 限制响应长度
)

(3) 对话历史压缩

对于多轮对话,可以只保留关键信息:

def compress_conversation(history: list) -> list:
    """压缩对话历史,只保留关键信息"""
    compressed = []
    for msg in history[-5:]:  # 只保留最近 5 条
        if is_important(msg):  # 实现你的重要性判断逻辑
            compressed.append(msg)
    return compressed

5. 生产环境注意事项

(1) 预算熔断设计

设置每日 / 每周预算上限,超过阈值时自动降级或停止服务:

class BudgetGuard:
    def __init__(self, daily_budget: float):
        self.daily_budget = daily_budget
        self.consumed = 0.0

    def check_budget(self, cost: float) -> bool:
        if self.consumed + cost > self.daily_budget:
            return False
        self.consumed += cost
        return True

(2) 敏感信息过滤

避免发送无用信息消耗 token:

def sanitize_input(text: str) -> str:
    """过滤敏感信息"""
    # 实现你的过滤逻辑
    return text

(3) 日志埋点规范

在日志中记录 token 使用情况:

import logging

logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    level=logging.INFO
)
logger = logging.getLogger(__name__)

def log_token_usage(prompt_tokens: int, completion_tokens: int):
    logger.info(f"Token usage - prompt: {prompt_tokens}, completion: {completion_tokens}")

6. 开放性问题

  1. 当响应质量与 token 成本冲突时,你是如何权衡的?
  2. 你有什么独特的 token 优化技巧可以分享?

通过以上方法,我们可以在保证服务质量的同时,有效控制 API 调用成本。记住,每个 token 都在花钱,优化永远不嫌早!

正文完
 0
评论(没有评论)