在实际 AI 应用开发中尤其是在调用大语言模型LLMAPI 时成本控制是一个无法回避的工程问题。API 调用成本的核心计算单元通常是token无论是输入还是输出都按token数量计费。当你的 AI 智能体AI Agent需要处理复杂的代码库、冗长的文档或进行多轮对话时token消耗会迅速攀升直接转化为可观的财务支出。因此如何优化token使用成为提升 AI 应用经济效益的关键技术点。Thoughtworks 的 CTO 曾通过一项实验揭示了代码库重构对降低 AI 智能体token消耗的显著影响。这并非简单的代码格式化而是指通过改善代码结构、命名、模块化等方式提升代码的“可读性”和“信息密度”使得 AI 在理解相同业务逻辑时需要“阅读”的文本量大幅减少。对于开发者而言这意味着一个清晰的结论良好的代码质量不仅是团队协作的基石在 AI 时代它直接等同于更低的模型调用成本和更高的智能体运行效率。本文将深入探讨这一现象背后的原理并提供一个可操作的实践框架。我们将从理解token与代码文本的关系开始分析 AI 智能体处理代码的典型模式然后通过具体示例展示重构如何减少token消耗最后给出在项目中系统性地实施此类优化的检查清单和最佳实践。无论你是正在构建基于 AI 的代码分析工具、智能编程助手还是希望优化现有 AI 工作流的成本本文都将提供直接的参考。1. 理解 Token 消耗AI 智能体成本的核心在讨论优化之前必须首先建立对token消耗机制的基本认知。这对于后续评估重构效益至关重要。1.1 Token 是什么它与代码文本如何映射Token是大语言模型处理文本的基本单位。它不等同于一个单词或一个字符。对于英文一个token大约对应 0.75 个单词对于中文一个汉字通常被切分为 1-2 个token。在代码语境下情况更为复杂。以 OpenAI 的 GPT 系列模型为例其使用的分词器Tokenizer会将代码文本进行切分。变量名、函数名、关键字、操作符、括号、甚至缩进都可能被切分为独立的token。一个长变量名可能被切分为多个token而一个简洁的变量名可能只是一个token。考虑以下两段功能相同的 Python 代码片段片段 A (重构前命名冗余结构松散):def calculate_the_total_amount_of_money_for_all_the_items_in_the_shopping_cart(list_of_items_in_the_cart): total_price_of_all_items 0.0 for each_individual_item in list_of_items_in_the_cart: price_of_the_current_item each_individual_item.get(‘price’) quantity_of_the_current_item each_individual_item.get(‘quantity’) total_price_for_this_item price_of_the_current_item * quantity_of_the_current_item total_price_of_all_items total_price_of_all_items total_price_for_this_item return total_price_of_all_items片段 B (重构后命名简洁结构紧凑):def calculate_total(cart_items): total 0.0 for item in cart_items: total item[‘price’] * item[‘quantity’] return total通过在线分词工具如 OpenAI 的官方tiktoken库可以统计片段 A 的token数量远多于片段 B。这意味着当 AI 智能体需要将整段代码作为上下文Context提供给模型时片段 A 会消耗更多的输入token。如果 AI 需要基于此代码生成解释或修改建议其输出也可能因为输入上下文的冗长而变得更长进一步增加输出token的消耗。1.2 AI 智能体如何处理代码库典型的代码分析 AI 智能体工作流程如下代码获取智能体从版本控制系统或本地目录读取源代码文件。上下文构建为了理解一个函数或模块智能体可能需要将相关代码如函数定义、被调用的其他函数、类定义、导入语句等拼接成一个长的提示词Prompt。模型调用将这个包含代码上下文的 Prompt 发送给 LLM API。结果解析与执行解析模型的返回结果可能包括代码解释、修改建议、生成的代码片段等。在这个流程中第 2 步“上下文构建”是token消耗的主要来源。代码库越庞大、越混乱为了提供足够的上下文所需包含的文本就越多token消耗就越大。此外如果 AI 需要执行多轮对话来分析代码例如先理解整体结构再深入某个模块每一轮交互都会累积token消耗。1.3 为什么重构能降低 Token 消耗Thoughtworks CTO 的实验核心在于证明了代码质量与 AI 处理效率正相关。重构从以下几个直接途径减少token消耗减少冗余文本消除不必要的注释、过长的命名、重复的代码块直接减少了需要传输的字符数从而降低token数。提升信息密度通过提取函数、复用模块相同的业务逻辑可以用更少的代码行和更简洁的表达来实现。AI 理解高内聚、低耦合的模块所需的外部上下文更少。改善结构清晰度清晰的模块边界和依赖关系使得 AI 智能体在构建上下文时能更精准地只选取必要的相关文件避免将大量不相关的代码纳入 Prompt。降低理解难度结构良好的代码本身对人类和 AI 都更容易理解。模型可能需要更少的“思考”即更短的输出就能给出准确的回答。2. 环境准备与量化分析工具要验证重构的效果我们需要能够量化token消耗。以下是在实际项目中可以采用的工具和方法。2.1 安装与配置 Token 计数工具最直接的工具是 OpenAI 的tiktoken库。它允许你使用与 GPT 模型相同的分词器来统计文本的token数量。# 安装 tiktoken pip install tiktoken你可以编写一个简单的 Python 脚本来统计单个文件或整个目录的token数量。以下是一个示例脚本count_tokens.pyimport tiktoken import os from pathlib import Path def count_tokens_in_text(text: str, model_name: str “gpt-4”) - int: “””计算给定文本在指定模型下的token数量。””” try: encoding tiktoken.encoding_for_model(model_name) except KeyError: print(f“Warning: Model {model_name} not found. Using cl100k_base encoding.”) encoding tiktoken.get_encoding(“cl100k_base”) # GPT-4, GPT-3.5-turbo 等使用的编码 tokens encoding.encode(text) return len(tokens) def count_tokens_in_file(file_path: Path, model_name: str “gpt-4”) - int: “””计算单个文件的token数量。””” try: with open(file_path, ‘r’, encoding‘utf-8’) as f: content f.read() return count_tokens_in_text(content, model_name) except Exception as e: print(f“Error reading {file_path}: {e}”) return 0 def count_tokens_in_directory(dir_path: Path, extensionsNone, model_name: str “gpt-4”) - dict: “””计算目录下所有指定后缀文件的token数量返回文件路径与token数的映射。””” if extensions is None: extensions [‘.py’, ‘.js’, ‘.java’, ‘.go’, ‘.rs’, ‘.cpp’, ‘.h’] # 常见代码文件后缀 token_counts {} total_tokens 0 for ext in extensions: for file in dir_path.rglob(f“*{ext}”): count count_tokens_in_file(file, model_name) token_counts[str(file)] count total_tokens count print(f“{file}: {count} tokens”) print(f“\nTotal tokens for extensions {extensions}: {total_tokens}”) return token_counts, total_tokens if __name__ “__main__”: # 示例统计当前目录下所有.py文件的token数 current_dir Path(“.”) counts, total count_tokens_in_directory(current_dir, extensions[‘.py’], model_name“gpt-4”)运行此脚本可以建立一个代码库的token基线。重构前后运行此脚本就能直观看到变化。2.2 模拟 AI 智能体上下文构建单纯的代码行数或字符数统计不足以反映真实场景。AI 智能体通常会以特定的方式组织上下文。我们可以模拟一个简单的上下文构建器def build_context_for_function(file_path: Path, function_name: str, context_lines: int 10) - str: “”” 模拟AI智能体为理解某个函数而构建的上下文。 返回函数定义本身及其前后若干行上下文。 “”” context [] with open(file_path, ‘r’, encoding‘utf-8’) as f: lines f.readlines() # 这里是一个简化的查找逻辑实际项目可能需要更复杂的AST解析 for i, line in enumerate(lines): if function_name in line and ‘def ‘ in line: # 简单匹配函数定义行 start max(0, i - context_lines) end min(len(lines), i context_lines 1) context lines[start:end] break return ‘’.join(context) # 使用示例 context build_context_for_function(Path(“my_module.py”), “calculate_total”) token_count count_tokens_in_text(context, “gpt-4”) print(f“Context for ‘calculate_total’: {token_count} tokens”)通过比较重构前后为理解同一个功能点所需构建的上下文token数量可以更精确地衡量优化效果。3. 重构策略与 Token 优化实战并非所有重构都能等量地降低token消耗。以下是一些针对性强、效果显著的重构策略并辅以代码示例说明。3.1 策略一简化命名与消除冗余这是最直接有效的策略。过长的、描述性的命名在人类协作中可能有其价值但对于 AI简洁准确的命名同样可读且消耗更少token。优化前class CustomerOrderProcessingAndInvoiceGenerationSystem: def __init__(self, customer_data_provider, invoice_template_repository): self.customer_data_provider_instance customer_data_provider self.invoice_template_repository_instance invoice_template_repository def process_order_and_generate_invoice_for_customer(self, order_id_number): customer_details self.customer_data_provider_instance.retrieve_customer_details_by_order_id(order_id_number) order_details self.customer_data_provider_instance.retrieve_order_details_by_order_id(order_id_number) invoice_template self.invoice_template_repository_instance.find_template_by_type(‘standard’) # … 冗长的处理逻辑优化后class OrderSystem: def __init__(self, customer_provider, template_repo): self.customer_provider customer_provider self.template_repo template_repo def process_order(self, order_id): customer self.customer_provider.get_by_order(order_id) order self.customer_provider.get_order(order_id) template self.template_repo.find(‘standard’) # … 逻辑不变效果分析类名、方法名、变量名都大幅缩短。在 AI 需要反复引用这些名称的对话或分析中token节省是累积的。使用tiktoken统计仅上述代码片段优化后可能减少 30% 以上的token。3.2 策略二提取函数与模块化将重复的逻辑提取成函数或移至独立模块不仅遵循 DRY 原则还能让 AI 上下文更聚焦。优化前def generate_report(data): # 计算平均值 total 0 for item in data: total item[‘value’] avg total / len(data) if data else 0 # 计算最大值 max_val float(‘-inf’) for item in data: if item[‘value’] max_val: max_val item[‘value’] # 计算最小值 min_val float(‘inf’) for item in data: if item[‘value’] min_val: min_val item[‘value’] # 生成报告字符串 report f“Avg: {avg}, Max: {max_val}, Min: {min_val}” return reportAI 智能体在分析此函数时需要将整个冗长的循环和计算逻辑都作为上下文。优化后def calculate_average(data): return sum(item[‘value’] for item in data) / len(data) if data else 0 def calculate_max(data): return max((item[‘value’] for item in data), default0) def calculate_min(data): return min((item[‘value’] for item in data), default0) def generate_report(data): avg calculate_average(data) max_val calculate_max(data) min_val calculate_min(data) return f“Avg: {avg}, Max: {max_val}, Min: {min_val}”现在如果 AI 只需要理解generate_report的总体功能它可能不需要将三个计算函数的细节全部纳入上下文。上下文可以更短。即使需要分析某个计算细节也可以单独提供那个小函数上下文更精准。3.3 策略三使用标准库与内置语法充分利用语言的内置函数和简洁语法可以用更少的代码表达相同的逻辑。优化前 (使用显式循环和临时变量):result_list [] for number in range(1, 11): if number % 2 0: squared_number number * number result_list.append(squared_number)优化后 (使用列表推导式):result_list [x**2 for x in range(1, 11) if x % 2 0]列表推导式更简洁token数更少且对于熟悉 Python 的 AI 模型来说理解起来没有任何障碍。3.4 策略四移除过时与调试代码项目中遗留的注释掉的代码、陈旧的注释、打印语句等对人类是噪音对 AI 则是需要付费处理的无效token。清理前def compute(data): # TODO: This algorithm is too slow, need to optimize later. (Added by John, 2020-01-15) # result old_slow_method(data) # Deprecated since v2.1 # print(“DEBUG: Entering compute function, data length:”, len(data)) # Debug line result fast_new_method(data) # print(“DEBUG: Result is:”, result) # Debug line return result # Return the final result清理后def compute(data): result fast_new_method(data) return result定期执行代码清理是保持代码库“瘦身”的良好习惯直接减少 AI 处理时的负担。4. 构建可验证的效益评估流程为了系统性地评估重构带来的经济效益建议在项目中建立以下流程4.1 建立量化基准选择关键场景确定你的 AI 智能体最常执行的任务例如“生成函数注释”、“查找 Bug”、“代码重构建议”。录制典型对话针对每个场景录制一组真实的、具有代表性的用户与 AI 智能体的交互记录Prompts 和 Responses。计算基准 Token 消耗使用tiktoken等工具精确计算在当前代码库状态下完成这些典型对话所消耗的总token数包括输入和输出。将此作为基准数据。4.2 执行针对性重构根据第 3 节的策略对代码库中与上述关键场景相关的模块进行重构。优先重构那些在对话上下文中频繁出现的核心模块。本身冗长、重复率高的代码文件。命名极其复杂的类和方法。4.3 进行 A/B 测试与效益计算使用相同的对话记录在重构后的代码库上使用完全相同的录制对话Prompt再次调用 AI 智能体。统计新的 Token 消耗记录新的输入/输出token数量。计算节省比例与金额Token节省比例 (基准Token数 - 新Token数) / 基准Token数 * 100%月度/年度成本节省 (基准月均Token消耗 - 新月均Token消耗) * Token单价分析结果如果某些场景节省不明显分析原因。是因为上下文构建逻辑问题还是该部分代码本身已足够优化4.4 示例效益计算表假设你的 AI 智能体主要处理代码审查日均调用 1000 次平均每次对话消耗 2000token输入输出使用 GPT-4 模型假设输入 $0.03/1K tokens输出 $0.06/1K tokens此为示例价格请以官方最新价格为准。指标重构前重构后 (假设优化15%)计算过程日均总 Token 数2,000,0001,700,0002000 * 1000 * (1-15%)日均输入 Token 成本$60$512,000,000/1000*0.03 * 85%日均输出 Token 成本$120$1022,000,000/1000*0.06 * 85%日均总成本$180$153月度成本节省$810($180 - $153) * 30年度成本节省$9,720$810 * 12这张表清晰地展示了即使是一次中等规模、针对性的代码重构也能带来持续且可观的经济回报。5. 集成到开发流程与常见问题排查将“为 AI 优化代码”的理念集成到日常开发中才能形成长效机制。5.1 开发流程集成建议代码审查清单在团队的代码审查清单中增加一条“检查新增代码的命名简洁性与模块性考虑其对未来 AI 辅助工具处理成本的影响。”预提交钩子Pre-commit Hook可以创建一个简单的脚本在提交代码前估算修改文件的token变化趋势虽然绝对值意义不大但大幅增长值得警惕或检查是否有明显的“坏味道”如超长函数、重复代码块。定期专项优化每个季度或每个版本安排一次针对核心模块的“代码瘦身”专项任务目标之一就是降低 AI 处理上下文复杂度。5.2 常见问题与排查在实施优化过程中可能会遇到以下问题问题现象可能原因检查与解决思路重构后 Token 消耗未明显下降1. 重构未触及 AI 高频使用的代码路径。2. 上下文构建逻辑未优化仍然发送了过多无关代码。3. AI 输出变得冗长。1. 分析 AI 日志确定其最常读取哪些文件/函数针对性地优化。2. 审查智能体的上下文组装算法使其更智能地截取和过滤。3. 优化 Prompt 工程明确要求模型输出简洁。过度优化导致代码可读性下降为了追求极致的简短使用了过于晦涩的缩写或奇技淫巧。牢记原则对人友好是基础。优化应在保持人类可读性的前提下进行。使用有意义的缩写如ctx代表context而非无意义的短名。难以量化某个具体重构的收益代码库庞大单一改动的影响被稀释。采用第 4 节所述的场景化 A/B 测试方法而非全量统计。聚焦于特定任务流进行评估。团队成员不理解或不支持认为这是额外负担或怀疑其实际价值。展示像上文第 4.4 节那样的具体财务测算。组织一次小范围实验用数据证明效果。将其定位为“提升代码质量”的衍生价值而非额外工作。5.3 需要注意的边界不要牺牲可读性永远将人类开发者的可读性和可维护性放在第一位。AI 优化是高质量代码的副产品而不是目标本身。一个只有 AI 能懂的代码库是失败的。关注整体架构比局部命名更重要的是模块的边界和依赖关系。一个清晰的架构能让 AI 智能体更准确地定位所需上下文其带来的token节省可能远大于重命名几个变量。Prompt 工程同样重要除了优化代码本身优化 AI 智能体的 Prompt例如明确要求其总结时精简、使用特定格式也能有效控制输出token两者结合效果最佳。重构 AI 智能体所处理的代码库本质上是一次对代码“信息效率”的升级。它迫使开发者从机器AI理解代码的视角重新审视自己的作品去除冗余强化结构提升表达密度。这个过程带来的不仅是直接的token成本下降更深层次的是代码质量的整体提升和团队工程实践的优化。开始行动的最佳时机就是现在选取一个核心模块用工具量化其当前的 AI 处理成本实施一轮有针对性的重构然后再次测量。数据会给你最有力的答案。