共计 2436 个字符,预计需要花费 7 分钟才能阅读完成。
作为开发者,使用 ChatGPT API 时成本控制是一个不可忽视的问题。以 gpt-3.5-turbo 为例,每 100 万 token 的费用大约是 $2,而 gpt- 4 则高达 $30。对于日常调用量大的项目来说,这很快就会变成一笔不小的开销。

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. 开放性问题
- 当响应质量与 token 成本冲突时,你是如何权衡的?
- 你有什么独特的 token 优化技巧可以分享?
通过以上方法,我们可以在保证服务质量的同时,有效控制 API 调用成本。记住,每个 token 都在花钱,优化永远不嫌早!
正文完
