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

使用Node.js调用OpenAI API时token计数与实际不符的问题排查

问题:用tiktoken计算token数远低于实际,触发OpenAI上下文超限错误

我用Node.js通过OpenAI API调用gpt-3.5-turbo,提交messages数组作为上下文:

const completion = await this.openai.chat.completions.create({
    messages: messages,
    model: 'gpt-3.5-turbo'
});

提交前用自己实现的TokenCounter类,通过tiktoken统计token数:

import {get_encoding, encoding_for_model} from 'tiktoken';

class TokenCounter{

    constructor(){
        this.enc = get_encoding('cl100k_base');
    }
       
    countFromUserMessages(userMessages){
        const initialValue = 0;
        const result = userMessages.reduce((accumulator,currentValue) => {
            const messageTokenCount = this.enc.encode(currentValue.content).length;
            return accumulator + messageTokenCount;
        },initialValue);
        return result;
    }
}
export default TokenCounter;

我认为只统计content的token数就足够,但提交计算为2097token的消息数组后,OpenAI返回超限错误:

This model's maximum context length is 4097 tokens. However, your messages resulted in 4337 tokens. Please reduce the length of the messages.

消息数组包含历史对话(用户+助手回复,每条助手回复100-300token),还有限制响应长度的系统消息:

{
 role: 'system',
 content: 'Your response must be 2000 characters or less.'
}

原因分析

  • 忽略了Chat消息的结构开销:OpenAI的Chat Completions API处理消息时,每个消息不仅包含content,还会添加role字段对应的token,以及<|start|>、<|end|>这类特殊分隔符token,这些都会占用上下文token数。你的代码只统计了content的token,完全没算这些结构开销,导致计数严重偏低。
  • 编码方式的选择不够严谨:虽然gpt-3.5-turbo确实使用cl100k_base编码,但直接固定编码不如用encoding_for_model('gpt-3.5-turbo')获取对应模型的编码,避免后续模型更新编码规则时出现偏差。
  • 字符数限制不等于token数限制:系统消息里的2000字符限制,和token数没有直接的1:1对应关系(比如中文单字通常对应1-2个token),但这不是当前超限的直接原因。

修正后的TokenCounter实现

import { encoding_for_model } from 'tiktoken';

class TokenCounter{
    constructor(){
        // 根据模型自动获取对应编码
        this.enc = encoding_for_model('gpt-3.5-turbo');
    }
       
    countFromUserMessages(userMessages){
        let totalTokens = 0;
        // 遍历所有消息,计算每个消息的完整token数(包含role、分隔符)
        for (const msg of userMessages) {
            const fullMessage = `<|start|>${msg.role}\n${msg.content}<|end|>`;
            totalTokens += this.enc.encode(fullMessage).length;
        }
        // 添加Chat模型所需的额外结束token(官方计算规则要求)
        totalTokens += 3;
        return totalTokens;
    }
}
export default TokenCounter;

这个实现会完整统计OpenAI实际计算的所有token,包括消息结构开销,计算结果会和API返回的token数一致。

内容的提问来源于stack exchange,提问作者sigil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 02:15:57