欢迎访问 AI Skills Video ! 海量优质视频教程,助你提升技能。

在超大规模项目中,如何节约AI编程工具Token

ios-小兵 2026年7月29日 0 次阅读
当项目规模达到 3 万+ 源文件、4000+ 行 AppDelegate,AI 编程工具的 Token 消耗会成为致命瓶颈。本文基于某企业 iOS 项目的真实重构经验,从模块化拆分、路由解耦、Entry 注册模式、资源隔离、常量替代硬编码、小文件原则和单向依赖链 7 个维度,分享如何通过架构优化让 AI「看得少、看得准」,最高节约 86% 的 Token 消耗。

一、问题:Token 正在吃掉你的生产力

如果你在一个中小型项目上用 AI 编程工具(Cursor、Copilot、Qoder CLI),体验可能是「真香」。但当你把 AI 丢进一个 3 万+ 源文件、4000+ 行 AppDelegate、双 APP + 三引擎 的超大规模 iOS 项目中,画风就变了:

  • 上下文窗口频繁打满,AI 开始「失忆」
  • 每轮对话消耗数千 Token,很快就到限额
  • AI 给出的建议越来越离谱——因为它根本看不完你的项目
  • 修改一个功能,AI 却加载了整个 AppDelegate 和所有无关模块

这不是 AI 不行,是你的项目结构在强制 AI 无效消耗 Token

本文以某企业 iOS 项目的实际重构经验为例,分享我们在 Token 节约 维度上总结的 7 条实战策略。


二、我们的项目有多「大」

先给个直观的数字:

指标 数值
源文件数(.m/.h/.mm) 31,801 个
代码行数 约 167 万行(仅算 ObjC)
AppDelegate.mm 4,376 行
主工程目录 6,544 个文件
依赖引擎 Unity + Cordova + Flutter
模块数 30+ Feature Pod

光是 AppDelegate 就有 4376 行。如果你的 AI 工具每次要加载这个文件来分析一个按钮点击的逻辑——那 90% 的 Token 都浪费在了无关代码上。


三、7 条 Token 节约实战策略

策略 1:模块化拆分——让 AI 只加载它需要的上下文

问题:单工程 + 单 Target 下,AI 无法区分「我该看哪里」。一个来自 主工程/classes/ 的调用可能跳转到另一个目录的代码,AI 不得不把整个项目索引都拉进上下文。

解法:用 CocoaPods 本地 Pod 做物理拆分。

# Podfile
pod 'MedicoolCore', :path => 'MedicoolCore/'
pod 'YikuFeatureBase', :path => 'YikuFeatureBase/'
pod 'YikuAbstract', :path => 'YikuAbstract/'
pod 'FeatureHomeV6', :path => 'Features/FeatureHomeV6/'

每个模块一个独立 Pod,有明确的 podspec 和头文件暴露边界。当 AI 需要分析首页功能时,它的上下文只需要加载:

  • FeatureHomeV6/ — 首页模块代码
  • YikuAbstract/ — 抽象层协议
  • YikuFeatureBase/ — 基础工具(非全部源码)

而不是:整个 主工程/ + 30 个 Feature 模块 + 三引擎集成代码。

效果:AI 分析一个模块的平均 Token 消耗降低 约 60%(实测从 ~8K 降到 ~3K)。

策略 2:路由解耦——消灭跨模块 Import

问题:传统架构中,FeatureA 调用 FeatureB 需要 #import "FeatureBViewController.h" 并直接 alloc/push。AI 分析这条链路时,必须递归加载 FeatureB 的所有头文件——Token 爆炸。

解法:FeatureRouter + 统一调度层。

// 注册(只在模块启动时执行一次)
[[FeatureRouter sharedRouter] registerRoute:@"feat.homev6.search"
                                    handler:^(UIViewController *src, NSDictionary *params) {
    FHV6SearchVC *vc = [[FHV6SearchVC alloc] init];
    [src.navigationController pushViewController:vc animated:YES];
}];

// 调用(一行代码,无 Import)
[YikuFeatureDispatcher startSearchWithSourceVC:self params:nil];

关键设计

  • FeatureRouter 是 O(1) 注册/查询的单例路由表
  • YikuFeatureDispatcher 对外暴露 150+ 静态方法,只增不减
  • 调用方不需要 import 目标模块的任何头文件

Token 收益:AI 分析调用链时,不需要递归加载目标模块的源码。它只需要知道 Dispatcher 方法的签名和路由 key——上下文从 5 层递归降到 1 层。

策略 3:Entry 注册模式——给 AI 一个「文件索引」

问题:AI 在超大规模项目中最大的痛点是 不知道从哪里入手。它可能在 3 万个文件中迷失。

解法:每个模块实现一个 XxxEntry 类,统一注册路由。

// FeatureHomeV6/Classes/HomeV6Entry.m
@implementation HomeV6Entry
+ (void)registerFeatureRouter {
    FeatureRouter *router = [FeatureRouter sharedRouter];
    [router registerRoute:@"feat.homev6.search" handler:^...{}];
    [router registerRoute:@"feat.homev6.discovery" handler:^...{}];
    [router registerRoute:@"feat.homev6.me" handler:^...{}];
}
@end

然后在 AppDelegate 中统一调用:

- (void)initFeatureRouter {
    [HomeV6Entry registerFeatureRouter];
    [LiveChatRoomEntry registerFeatureRouter];
    [ShareEntry registerFeatureRouter];
    // ... 28 个 Entry
}

Token 收益:AI 理解一个功能的入口点变成了 读一个 Entry 文件(~50 行),而不是在 4000 行的 AppDelegate 中搜索。

策略 4:资源隔离——别让 AI 分析重复的资源

问题:使用 s.resources 且用 **/* 通配符时,CocoaPods 会把资源扁平化复制到 main bundle。AI 在分析资源引用时,经常搞不清「这个图片到底属于哪个模块」,因为所有资源都在同一个命名空间里打架。

解法:使用 resource_bundles + 单级目录 规则。

# ❌ 旧写法 - 资源重复打包,AI 无法区分
s.resources = 'FeatureHomeV6/Assets/**/*'

# ✅ 新写法 - 资源隔离,AI 一目了然
s.resource_bundles = {
  'FeatureHomeV6' => [
    'FeatureHomeV6/Assets/Media/*.xcassets',
    'FeatureHomeV6/Assets/Media/*.lproj',
    'FeatureHomeV6/Assets/Controllers/*.xib',
    'FeatureHomeV6/Assets/Cell/*.xib'
  ]
}

配合模块内的 ResourceBundle 类:

// FHV6ResourceBundle.m
+ (NSBundle *)featureBundle {
    NSBundle *bundle = [NSBundle bundleForClass:[self class]];
    NSURL *bundleURL = [bundle URLForResource:@"FeatureHomeV6" withExtension:@"bundle"];
    return bundleURL ? [NSBundle bundleWithURL:bundleURL] : bundle;
}

Token 收益:AI 分析资源引用时,可以精确追溯到模块内部的 bundle,不需要在全局资源池中搜索。

策略 5:FeatureDefines.h——用常量替代硬编码

问题indexPath.row == 3 这样的硬编码在大型项目中数不胜数。AI 分析一个 tableView 方法时,不得不加载整个数据源的上下文来判断 row == 3 是哪个功能。

解法:定义全局功能键常量,彻底消灭 magic number。

// Features/FeatureDefines.h
#define FEATURE_ACTION_HOME_DISCOVERY      @"home_discovery"
#define FEATURE_ACTION_HOME_LIVE           @"home_live"
#define FEATURE_ACTION_HOME_VIDEO          @"home_video"

Token 收益:AI 看到 FEATURE_ACTION_HOME_LIVE 就知道这是直播入口,不需要分析周围的数值上下文。每个判断节省 ~200 Token 的上下文解释。

策略 6:小文件原则——一口吃得下的上下文

问题:4376 行的 AppDelegate 是 Token 黑洞。AI 加载它一次就占了 ~10K Token,而其中 90% 的内容与当前任务无关。

解法:把巨型文件按职责拆分。

重构前的 AppDelegate(4376 行):

  • 应用生命周期:200 行
  • 第三方 SDK 初始化:800 行
  • 路由注册:100 行
  • 推送回调:600 行
  • 自动登录:400 行
  • ... 其余 2000+ 行杂项

重构方向:每个职责独立为文件,AppDelegate 只做编排。

Token 收益:AI 加载一个 ~100 行的 RouterRegistration.swift 比加载 4376 行的 AppDelegate 节省 97% 的 Token

策略 7:明确的依赖方向——防止 AI「绕路」

问题:循环依赖或混乱的依赖关系会让 AI 陷入死循环分析。它会反复加载 A→B→C→A 的代码,浪费大量 Token 却得不到有效结论。

解法:建立单向依赖链,用 podspec 的 s.dependency 强制执行。

依赖方向(从上到下,禁止反向):
  Features/*  →  YikuAbstract  →  YikuFeatureBase  →  MedicoolCore
                                                      →  MedicoolNetwork
                                                      →  MedicoolComponent

Token 收益:AI 分析 Feature 模块时,只需要沿依赖方向向上查找,永远不会走回头路。上下文加载路径从 O(n²) 降到 O(n)。


四、实战数据:重构前后的 Token 对比

以一个典型的「AppDelegate 初始化 → 点击首页搜索按钮 → 跳转搜索页面」场景为例:

维度 重构前 重构后 节约比例
AI 需加载的源文件 ~50 个(整个 AppDelegate + 所有 Entry + 目标 VC 链) ~8 个(Router + Entry + Dispatcher + VC) 84%
上下文内容量 ~25,000 Token ~3,500 Token 86%
AI 理解调用链需要深度 5 层递归 Import 1 层路由查找 80%
误判率(无效建议占比) ~40% ~10% 75%

数据来源于我们内部使用 AI 工具重构该项目的实测对比。


五、总结:Token 节约的本质是信息密度

AI 编程工具的 Token 消耗,和项目结构的信息密度直接相关。你的代码写得越清晰、模块边界越干净、依赖关系越简单,AI 就能在有限的 Token 预算内做出越准确的判断。

不要把 Token 浪费在让 AI 理解「这个 indexPath.row 是什么功能」「这个 import 链最终会走到哪里」「这个资源属于哪个模块」——这些都是人应该替 AI 解决好的问题。

好的架构,就是对 AI 也友好的架构。


附录:我们的重构工具链

用途 技能/工具
功能解耦 → 路由化 .skill/feature-router
资源隔离 → resource_bundles .skill/single-level-resource-bundle
更新资源加载模式 .skill/update_submodule_with_resource_bundle
第三方头文件修复 .skill/fix_third_import
代码评审与质量检查 Skill: simplify
安全审查 Skill: security-review

本文基于某企业 iOS 项目的真实重构经验编写。