You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenAI带对话历史的Token计数方法是否正确?求优化方案

代码正确性确认与优化建议

一、当前代码的正确性

你的代码核心逻辑是正确的:

  • 通过OpenAI API返回的usage字段分别统计prompt_tokens(输入)和completion_tokens(输出),这是官方提供的最准确的Token计数方式,比第三方工具更适配带对话历史的场景。
  • 每次对话后将助理和用户消息加入example_messages,维护对话内存的逻辑也没问题。

二、改进建议

1. 增强错误处理

当前代码未处理API调用可能出现的异常(如网络故障、限额超限、参数错误等),建议添加异常捕获:

def gpt_response_func():
    try:
        response = client.chat.completions.create(
            model="gpt-3.5-turbo",
            messages=example_messages
        )
        return response
    except Exception as e:
        print(f"API调用出错: {e}")
        return None

在循环中需判断gpt_response是否为None,避免后续代码报错。

2. 实时成本计算

既然要做全面成本分析,可以直接基于OpenAI定价计算实时成本(以GPT-3.5-turbo常规定价为例):

# 定价参考:输入$0.0015/1k tokens,输出$0.002/1k tokens
PRICE_PER_1K_INPUT = 0.0015
PRICE_PER_1K_OUTPUT = 0.002

# 在统计Token后计算成本
cost_input = token_count['input'] * PRICE_PER_1K_INPUT / 1000
cost_output = token_count['output'] * PRICE_PER_1K_OUTPUT / 1000
total_cost = cost_input + cost_output
print(f"累计成本: ${total_cost:.6f}")

3. 对话内存Token管控

当对话历史过长时,会导致输入Token过多、成本上升,还可能触发模型上下文限制。建议添加Token阈值管控:

def count_messages_tokens(messages, model="gpt-3.5-turbo"):
    encoding = tiktoken.encoding_for_model(model)
    num_tokens = 0
    for message in messages:
        # 每条消息的Token计算规则:<|start|>role<|end|>content<|end|>
        num_tokens += 4  # 每条消息固定的起始/结束Token
        for key, value in message.items():
            num_tokens += len(encoding.encode(value))
    num_tokens += 2  # 对话结束的<|end|>Token
    return num_tokens

# 添加新消息后检查总Token,超过阈值则截断历史(保留系统提示和最近消息)
MAX_CONTEXT_TOKENS = 4096  # GPT-3.5-turbo默认上下文长度
while count_messages_tokens(example_messages) > MAX_CONTEXT_TOKENS:
    # 移除最早的非系统消息
    for i in range(1, len(example_messages)):
        if example_messages[i]['role'] != 'system':
            example_messages.pop(i)
            break

三、带对话内存的Token计数更优方法

1. 优先使用API返回的usage字段

官方API返回的usage是最准确的,因为模型实际处理的Token数可能和本地计算存在细微差异(比如特殊字符、模型内部格式处理),你的当前做法已经是最优的实时计数方式。

2. 本地预计算用于阈值管控

如果需要在发送API请求前预估Token数(避免超出上下文限制),可以用tiktoken本地计算,上面的count_messages_tokens函数是OpenAI官方推荐的计算方式,能准确模拟模型对对话消息的Token统计逻辑。

3. 统计数据持久化

如果需要长期统计,可以把Token计数和成本数据持久化到文件或数据库,比如每次对话后写入CSV:

import csv

def save_token_stats(token_count, cost_input, cost_output, total_cost):
    with open('token_stats.csv', 'a', newline='', encoding='utf-8') as f:
        writer = csv.writer(f)
        # 首次写入时添加表头
        if f.tell() == 0:
            writer.writerow(['输入Token', '输出Token', '总Token', '输入成本($)', '输出成本($)', '总成本($)', '时间'])
        writer.writerow([
            token_count['input'],
            token_count['output'],
            token_count['total'],
            f"{cost_input:.6f}",
            f"{cost_output:.6f}",
            f"{total_cost:.6f}",
            time.strftime("%Y-%m-%d %H:%M:%S")
        ])

内容的提问来源于stack exchange,提问作者Mubashir Ahmed Siddiqui

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 15:02:47