2.2 Token管理与优化 — 大模型应用开发从零到一 关键词短语 本节导读:深入理解Token在大模型中的工作机制,学习有效的Token管理和优化策略,提升应用性能和降低API调用成本。 学习目标 掌握Token的基本概念和计算方法 理解上下文窗口限制及其影响 学会Token计费模型和成本控制 掌握Token压缩和优化的实用技术 了解多语言Token处理的特殊考虑 核心概念 什么是Token Token是语言模型处理的基本单元,可以是单词、子词或字符。不同的模型使用不同的分词器: Token分词对比图:OpenAI GPT系列 vs Claude系列 vs LLaMA系列 主流模型的Token标准: OpenAI (GPT-3.5/4):1个Token ≈ 0.
本节导读:深入理解Token在大模型中的工作机制,学习有效的Token管理和优化策略,提升应用性能和降低API调用成本。
Token是语言模型处理的基本单元,可以是单词、子词或字符。不同的模型使用不同的分词器:
主流模型的Token标准:
OpenAI GPT-4计费标准(2026年):
实际成本示例:
输入1000字符 ≈ 1333输入Token ≈ $0.013 输出1000字符 ≈ 1333输出Token ≈ $0.040 总计成本:$0.053/次对话
# Token计算工具安装 pip install tiktoken transformers torch # 基础依赖检查 import tiktoken import transformers import torch print(f"tiktoken版本: {tiktoken.__version__}") print(f"transformers版本: {transformers.__version__}")
# OpenAI模型分词器 import tiktoken # GPT-4分词器 enc = tiktoken.encoding_for_model("gpt-4") text = "Hello, world! 你好,世界!" tokens = enc.encode(text) print(f"原始文本: {text}") print(f"Token数量: {len(tokens)}") print(f"Token列表: {tokens}") print(f"解码文本: {enc.decode(tokens)}")
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Token监控和管理工具 """ import tiktoken import json from typing import Dict, List, Any class TokenManager: """Token管理工具类""" def __init__(self, model_name: str = "gpt-4"): """ 初始化Token管理器 Args: model_name: 模型名称,支持 gpt-4, gpt-3.5-turbo, claude-3等 """ self.model_name = model_name self.enc = self._get_encoder() def _get_encoder(self): """获取对应模型的分词器""" model_mapping = { "gpt-4": "cl100k_base", "gpt-3.5-turbo": "cl100k_base", "gpt-4-turbo": "cl100k_base", "claude-3": "p50k_base", # Claude使用的分词器 } encoding_name = model_mapping.get(self.model_name, "cl100k_base") return tiktoken.get_encoding(encoding_name) def count_tokens(self, text: str) -> int: """ 计算文本的Token数量 Args: text: 要计算的文本 Returns: Token数量 """ if not text: return 0 return len(self.enc.encode(text)) def calculate_costs(self, input_tokens: int, output_tokens: int = 0, json_mode: bool = False) -> Dict[str, float]: """ 计算API调用成本 Args: input_tokens: 输入Token数量 output_tokens: 输出Token数量 json_mode: 是否使用JSON模式 Returns: 成本字典 """ # OpenAI GPT-4定价 (2026年) input_rate = 0.01 / 1000 # $0.01 per 1K tokens output_rate = 0.03 / 1000 # $0.03 per 1K tokens json_surcharge = 0.01 / 1000 if json_mode else 0 input_cost = input_tokens * input_rate output_cost = output_tokens * output_rate json_cost = max(input_tokens, output_tokens) * json_surcharge total_cost = input_cost + output_cost + json_cost return { "input_cost": round(input_cost, 6), "output_cost": round(output_cost, 6), "json_cost": round(json_cost, 6), "total_cost": round(total_cost, 6) } # 使用示例 def token_monitor_example(): """Token监控工具使用示例""" manager = TokenManager("gpt-4") # 测试不同文本 test_cases = [ "Hello, world!", "Hello, world! 你好,世界!", "This is a longer text that will contain multiple tokens.", "Python代码示例:\nprint('Hello, World!')\nfor i in range(5):\n print(i)" ] print("=== Token分析报告 ===") for i, text in enumerate(test_cases, 1): info = manager.get_token_info(text) costs = manager.calculate_costs(info["token_count"]) print(f"\n测试案例 {i}:") print(f"原始文本: {text[:50]}{'...' if len(text) > 50 else ''}") print(f"Token数量: {info['token_count']}") print(f"字符/TOKEN: {info['characters_per_token']:.2f}") print(f"预计输入成本: ${costs['input_cost']}") # 模拟对话成本 print("\n=== 对话成本模拟 ===") conversation = [ {"role": "user", "content": "什么是机器学习?"}, {"role": "assistant", "content": "机器学习是人工智能的一个分支,它使计算机能够在不被明确编程的情况下学习和改进。"}, {"role": "user", "content": "能给我一些实际应用例子吗?"}, {"role": "assistant", "content": "当然!机器学习在图像识别、自然语言处理、推荐系统、自动驾驶等领域都有广泛应用。"} ] total_input_tokens = sum(manager.count_tokens(msg["content"]) for msg in conversation if msg["role"] == "user") total_output_tokens = sum(manager.count_tokens(msg["content"]) for msg in conversation if msg["role"] == "assistant") costs = manager.calculate_costs(total_input_tokens, total_output_tokens) print(f"输入Token: {total_input_tokens}") print(f"输出Token: {total_output_tokens}") print(f"总成本: ${costs['total_cost']}") print(f"平均轮次成本: ${costs['total_cost']/len(conversation):.4f}") if __name__ == "__main__": token_monitor_example()
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Token压缩和优化工具 """ import tiktoken import re from typing import List, Dict, Tuple from dataclasses import dataclass @dataclass class CompressionStrategy: """压缩策略配置""" name: str description: str compression_ratio: float quality_impact: str class TokenOptimizer: """Token优化器""" def __init__(self, model_name: str = "gpt-4"): self.model_name = model_name self.enc = tiktoken.encoding_for_model(model_name) self.strategies = self._init_strategies() def _init_strategies(self) -> List[CompressionStrategy]: """初始化压缩策略""" return [ CompressionStrategy( name="whitespace_compression", description="去除多余空白字符", compression_ratio=0.95, quality_impact="极低" ), CompressionStrategy( name="remove_repetitions", description="去除重复内容和过长的解释", compression_ratio=0.8, quality_impact="中等" ), CompressionStrategy( name="summarize_context", description="对长文档进行摘要", compression_ratio=0.3, quality_impact="较高" ), CompressionStrategy( name="vector_search", description="用向量检索替代全文传递", compression_ratio=0.1, quality_impact="取决于检索质量" ) ] def compress_text(self, text: str, strategy: str = "whitespace") -> Tuple[str, Dict]: """ 文本压缩 Args: text: 原始文本 strategy: 压缩策略名称 Returns: (压缩后的文本, 压缩信息) """ original_tokens = len(self.enc.encode(text)) if strategy == "whitespace": compressed = self._compress_whitespace(text) elif strategy == "remove_repetitions": compressed = self._remove_repetitions(text) elif strategy == "summarize_context": compressed = self._summarize_text(text) elif strategy == "vector_search": compressed = self._vector_search_compression(text) else: compressed = text compressed_tokens = len(self.enc.encode(compressed)) compression_ratio = compressed_tokens / original_tokens return compressed, { "original_tokens": original_tokens, "compressed_tokens": compressed_tokens, "compression_ratio": compression_ratio, "saved_tokens": original_tokens - compressed_tokens, "strategy": strategy } def _compress_whitespace(self, text: str) -> str: """去除多余空白字符""" text = re.sub(r'\s+', ' ', text) text = '\n'.join([line.strip() for line in text.split('\n')]) return text.strip() def _remove_repetitions(self, text: str) -> str: """去除重复内容""" lines = text.split('\n') unique_lines = [] last_line = "" for line in lines: if line.strip() and line.strip() != last_line.strip(): unique_lines.append(line) last_line = line return '\n'.join(unique_lines) def _summarize_text(self, text: str) -> str: """文本摘要""" if len(text) < 200: return text n = len(text) // 3 summary = text[:n] + "\n...\n" + text[2*n:3*n] return summary def optimize_prompt(self, prompt: str, max_tokens: int, compression_level: str = "moderate") -> Tuple[str, Dict]: """ 优化提示词 """ original_tokens = len(self.enc.encode(prompt)) if original_tokens <= max_tokens: return prompt, { "original_tokens": original_tokens, "optimized_tokens": original_tokens, "compression_ratio": 1.0, "status": "无需优化" } # 根据压缩级别选择策略 if compression_level == "aggressive": strategies = ["vector_search", "summarize_context", "remove_repetitions"] elif compression_level == "moderate": strategies = ["summarize_context", "remove_repetitions", "whitespace"] else: strategies = ["whitespace", "remove_repetitions"] optimized_prompt = prompt optimization_log = [] for strategy in strategies: optimized_prompt, info = self.compress_text(optimized_prompt, strategy) optimization_log.append(info) if len(self.enc.encode(optimized_prompt)) <= max_tokens: break final_tokens = len(self.enc.encode(optimized_prompt)) return optimized_prompt, { "original_tokens": original_tokens, "optimized_tokens": final_tokens, "compression_ratio": final_tokens / original_tokens, "max_tokens": max_tokens, "compression_level": compression_level, "optimization_log": optimization_log, "status": "完成" if final_tokens <= max_tokens else "超出限制" } # 使用示例 def token_optimization_example(): """Token优化示例""" optimizer = TokenOptimizer("gpt-4") long_prompt = """ 我需要你作为一位资深的机器学习工程师,帮助我设计一个完整的机器学习项目架构。 项目背景:我们正在开发一个电商推荐系统,需要基于用户的历史行为数据和商品特征来个性化推荐商品。 数据规模:100万用户,10万商品,用户行为数据约5000万条记录。 技术要求: 1. 需要支持实时推荐(响应时间<100ms) 2. 需要支持离线模型训练(每日更新) 3. 需要支持A/B测试框架 4. 需要监控推荐效果指标 请设计: 1. 整体系统架构 2. 数据处理流程 3. 模型选择和训练策略 4. 推荐算法设计 5. 部署和监控方案 """ print("=== Token优化测试 ===") original_tokens = len(optimizer.enc.encode(long_prompt)) print(f"原始提示词Token数: {original_tokens}") # 测试不同压缩级别 for level in ["low", "moderate", "aggressive"]: print(f"\n--- {level.upper()} 压缩级别 ---") optimized, info = optimizer.optimize_prompt(long_prompt, 1000, level) print(f"优化后Token数: {info['optimized_tokens']}") print(f"压缩比例: {info['compression_ratio']:.2%}") print(f"状态: {info['status']}")
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 上下文窗口管理工具 """ import tiktoken from typing import List, Dict, Any, Optional from dataclasses import dataclass from enum import Enum class ContextStrategy(Enum): """上下文管理策略""" SLIDING_WINDOW = "sliding_window" RECURSIVE_SUMMARY = "recursive_summary" KEY_EXTRACTION = "key_extraction" SEGMENTATION = "segmentation" HYBRID = "hybrid" @dataclass class ContextSegment: """上下文片段""" id: int content: str token_count: int importance_score: float position: int class ContextManager: """上下文窗口管理器""" def __init__(self, model_name: str = "gpt-4"): self.model_name = model_name self.enc = tiktoken.encoding_for_model(model_name) self.context_window = self._get_context_window() def _get_context_window(self) -> int: """获取模型上下文窗口大小""" context_windows = { "gpt-4": 128000, "gpt-4-turbo": 128000, "gpt-3.5-turbo": 16384, "claude-3": 200000, "claude-3-5": 200000, } return context_windows.get(self.model_name, 8192) def segment_text(self, text: str, max_tokens: int = None) -> List[ContextSegment]: """将长文本分割成上下文片段""" if max_tokens is None: max_tokens = self.context_window // 4 segments = [] words = text.split(' ') current_segment = [] current_tokens = 0 for i, word in enumerate(words): test_tokens = current_tokens + self.count_tokens(f" {word}") if test_tokens > max_tokens and current_segment: segment_content = ' '.join(current_segment) segments.append(ContextSegment( id=len(segments), content=segment_content, token_count=current_tokens, importance_score=self._calculate_importance(segment_content), position=len(segments) )) current_segment = [word] current_tokens = self.count_tokens(f" {word}") else: current_segment.append(word) current_tokens = test_tokens if current_segment: segment_content = ' '.join(current_segment) segments.append(ContextSegment( id=len(segments), content=segment_content, token_count=current_tokens, importance_score=self._calculate_importance(segment_content), position=len(segments) )) return segments def _calculate_importance(self, text: str) -> float: """计算文本重要性分数""" important_keywords = ['important', 'key', 'critical', 'essential', 'major', 'significant'] text_lower = text.lower() importance_score = 0 for keyword in important_keywords: importance_score += text_lower.count(keyword) length_factor = min(len(text.split()), 100) / 100 return importance_score * length_factor def count_tokens(self, text: str) -> int: """计算Token数量""" return len(self.enc.encode(text)) def manage_context(self, conversation: List[Dict[str, str]], strategy: ContextStrategy = ContextStrategy.SLIDING_WINDOW, max_context_tokens: int = None) -> Dict[str, Any]: """管理上下文窗口""" if max_context_tokens is None: max_context_tokens = self.context_window * 0.8 total_tokens = sum(self.count_tokens(msg['content']) for msg in conversation) if total_tokens <= max_context_tokens: return { "status": "无需管理", "total_tokens": total_tokens, "max_tokens": max_context_tokens, "retained_messages": conversation, "strategy": strategy.value } if strategy == ContextStrategy.SLIDING_WINDOW: return self._sliding_window_strategy(conversation, max_context_tokens) elif strategy == ContextStrategy.RECURSIVE_SUMMARY: return self._recursive_summary_strategy(conversation, max_context_tokens) else: return self._sliding_window_strategy(conversation, max_context_tokens) def _sliding_window_strategy(self, conversation: List[Dict], max_tokens: int) -> Dict: """滑动窗口策略""" retained = [] current_tokens = 0 for msg in reversed(conversation): msg_tokens = self.count_tokens(msg['content']) if current_tokens + msg_tokens <= max_tokens: retained.insert(0, msg) current_tokens += msg_tokens else: break return { "status": "滑动窗口", "total_tokens": current_tokens, "max_tokens": max_tokens, "retained_messages": retained, "strategy": "sliding_window", "discarded_messages": len(conversation) - len(retained) } # 使用示例 def context_management_example(): """上下文管理示例""" manager = ContextManager("gpt-4") long_conversation = [ {"role": "user", "content": "我想了解机器学习的基础知识"}, {"role": "assistant", "content": "机器学习是人工智能的一个分支,它让计算机能够从数据中学习模式和规律。主要包括监督学习、无监督学习和强化学习三大类。"}, {"role": "user", "content": "能详细解释一下监督学习吗?"}, {"role": "assistant", "content": "监督学习使用标记数据来训练模型。算法通过输入特征和对应的输出标签来学习映射关系。常见算法包括线性回归、逻辑回归、决策树、随机森林、神经网络等。"}, {"role": "user", "content": "那无监督学习呢?"}, {"role": "assistant", "content": "无监督学习使用无标记数据,算法需要自己发现数据中的结构和模式。主要方法包括聚类、降维、异常检测等。"} ] print("=== 上下文窗口管理测试 ===") print(f"模型上下文窗口: {manager.context_window} tokens") print(f"对话总Token数: {sum(manager.count_tokens(msg['content']) for msg in long_conversation)}") strategies = [ContextStrategy.SLIDING_WINDOW] for strategy in strategies: print(f"\n--- {strategy.value} 策略 ---") result = manager.manage_context(long_conversation, strategy) print(f"保留消息数: {len(result['retained_messages'])}") print(f"保留Token数: {result['total_tokens']}") print(f"状态: {result['status']}") if __name__ == "__main__": context_management_example()
A: 使用官方分词器库是最准确的方法。OpenAI推荐使用tiktoken库,不同模型使用不同的编码方式。对于中文文本,1个汉字通常对应1-2个Token,英文单词约1.3个Token。
A: 适度的Token压缩(如去除重复内容、优化格式)通常不会显著影响质量。但在压缩长文档或复杂内容时,可能会丢失细节。建议使用渐进式压缩,从轻度压缩开始,逐步增加压缩级别。
A: 主要策略包括:滑动窗口(保留最近的对话)、关键信息提取(保留重要内容)、递归摘要(对旧对话进行摘要)。根据应用场景选择合适的策略,客服对话适合滑动窗口,文档分析适合摘要策略。
A: 综合策略包括:优化提示词长度、使用缓存机制、选择合适规格的模型、实现批处理请求、对长文本进行压缩等。关键是找到成本和质量的最佳平衡点。
A: 不同语言的Token密度差异很大。中文通常1字符=1Token,英文1单词≈1.3Token,代码中的特殊符号可能1字符=1Token。在处理多语言混合内容时,需要分别计算各语言的Token占比,制定相应的优化策略。
通过本节的学习,你已经掌握了:
✅ Token的基本概念和计算方法
✅ Token计费模型和成本控制策略
✅ Token压缩和优化的实用技术
✅ 上下文窗口管理的高级方法
✅ 多种应用场景的优化策略
这些技术将帮助你在开发大模型应用时有效控制成本、提升性能,确保在有限的Token预算下提供最佳的用户体验。下一节我们将继续探讨"上下文窗口处理"的深入技术。
关键词:大模型应用开发从零到一, Token管理, Token优化, 上下文窗口, 成本控制, API调用效率, 分词器, Token压缩
难度:进阶
预计阅读:45 分钟