如何在OpenAI API中充分利用模型的最大Token数?
确保GPT-4 API调用使用最大Token数的方案分析
问题背景
从非结构化数据中提取文本时,GPT-4是唯一可靠的实现方案。在ChatGPT网页版(搭载GPT-4)中可正常完成提取(文本量大时需点击续接按钮),但通过OpenAI API调用时,响应会过早终止。需确认当前实现代码是否正确,以及如何确保始终使用模型的最大Token数。
当前实现代码
def extract_content_from_with_gpt( text_list: str, model_name: str = 'gpt-4-1106-preview', # model_name: str = 'gpt-3.5-turbo', temperature: float = 0.7, ) -> list[tuple[int, str]]: prompt: str = get_prompt_extract_list_from_text(text_list) response = openai.chat.completions.create( model = model_name, messages = [ {"role": "user", "content": prompt}, ], temperature = temperature, # max_tokens=128_000, ) response_text: str = response.choices[0].message.content.strip() pattern = r"<extracted>(.*?)</extracted>" match: list[str] = re.findall(pattern, response_text, re.DOTALL) assert len(match) == 1 # extracted_list: list[str] = eval(match[0]) extracted_list: list[str] = ast.literal_eval(match[0]) return extracted_list
代码正确性分析
当前代码不正确,核心问题是注释掉了max_tokens参数:
- OpenAI API不会默认使用模型的最大Token生成上限,必须显式指定该参数,否则模型会在生成较短内容后终止响应。
- 对于
gpt-4-1106-preview(GPT-4 Turbo)模型,其总上下文窗口上限为128000 Token,但max_tokens指的是模型生成内容的Token数上限,而非总上下文(prompt+生成内容)的Token数。
正确实现方案
1. 动态计算并设置max_tokens
需先计算prompt占用的Token数,再用模型最大上下文Token数减去该值,得到可分配给生成内容的Token上限,避免总上下文超出模型限制:
import tiktoken def count_tokens(text: str, model: str = "gpt-4-1106-preview") -> int: encoder = tiktoken.encoding_for_model(model) return len(encoder.encode(text)) def extract_content_from_with_gpt( text_list: str, model_name: str = 'gpt-4-1106-preview', temperature: float = 0.7, ) -> list[tuple[int, str]]: prompt: str = get_prompt_extract_list_from_text(text_list) # 计算prompt的Token数量 prompt_token_count = count_tokens(prompt, model_name) # 模型最大上下文Token数 max_context_tokens = 128000 # 计算可用于生成内容的Token数,确保至少为1 max_generated_tokens = max(max_context_tokens - prompt_token_count, 1) response = openai.chat.completions.create( model = model_name, messages = [{"role": "user", "content": prompt}], temperature = temperature, max_tokens = max_generated_tokens, ) response_text: str = response.choices[0].message.content.strip() pattern = r"<extracted>(.*?)</extracted>" match: list[str] = re.findall(pattern, response_text, re.DOTALL) assert len(match) == 1 extracted_list: list[str] = ast.literal_eval(match[0]) return extracted_list
2. 处理超长文本场景
如果prompt本身已接近或超过128000 Token,需对输入文本进行分块处理,分批调用API后再合并结果,这与ChatGPT网页版的“续接”逻辑一致。
关于max_tokens的关键说明
- 不要直接硬写
max_tokens=128000,因为prompt会占用部分上下文Token,硬写会导致总上下文超出模型上限,触发报错。 max_tokens仅控制模型生成内容的Token数,总上下文(prompt+生成内容)不得超过模型的最大上下文窗口。
内容的提问来源于stack exchange,提问作者Charlie Parker
相关产品推荐
相关产品推荐

