1. 项目概述:当大模型成为日常开发伙伴

如果你和我一样,已经把 Claude、ChatGPT 这类大语言模型(LLM)当成了日常编程的“结对编程”伙伴,那你肯定也经历过那种“肉疼”的时刻:看着一个复杂的代码生成请求,模型思考了半天,返回了洋洋洒洒几百行,结果账单上的 Token 消耗数字也跟着跳了一大截。尤其是在处理大型项目、进行深度代码重构或者要求模型理解整个代码库上下文时,Token 的消耗会呈指数级增长。“Claude Code 的工程化落地”这个命题,绝不仅仅是把 API 调通那么简单,其核心挑战之一,就是如何在保证代码生成质量和开发效率的前提下,把成本(尤其是 Token 消耗)降下来。这不仅仅是省钱,更是一种工程思维的体现——如何高效、可持续地将 AI 能力集成到开发工作流中。

“省 Token”不是简单地让模型少说点话,而是一套贯穿提示词设计、上下文管理、任务拆解和结果验证的完整策略。它关乎我们如何更聪明地与模型协作,如何将宝贵的上下文窗口(Context Window)用在刀刃上,以及如何构建可复用的自动化流程。接下来,我将结合过去一年多的实战经验,拆解从思路到实操的完整“省流”方案。

2. 核心思路:从粗放问答到精准协作

工程化使用 Claude 写代码,与在聊天窗口里零散提问有本质区别。前者是设计一个系统,后者是进行单次消费。省 Token 的起点,正是改变我们与模型交互的模式。

2.1 范式转变:从“魔法提问”到“需求规格说明书”

新手常犯的错误是给模型一个模糊的目标,比如“帮我写一个用户登录模块”。这个请求对于模型来说,上下文信息严重不足。它需要猜测:用什么语言和框架?需要哪些功能(邮箱登录、手机登录、第三方 OAuth)?数据库 schema 是什么?安全要求有哪些?为了补全这些信息,模型要么会在回复中提出一连串问题(消耗输出 Token),要么会基于最常见的假设生成一套代码,而这套代码很可能不符合你的实际技术栈,导致你需要多次迭代修正,每次迭代都在浪费 Token。

工程化的做法是, 你自己先充当“产品经理”和“系统架构师” 。在调用 API 前,准备好一份清晰的“需求规格说明书”:

  1. 技术栈明确 :精确到语言版本、框架名称及版本、主要依赖库。
  2. 接口定义先行 :对于函数或 API,先定义好输入、输出、异常类型。这相当于给模型画好了框框。
  3. 提供代码范例 :如果是在现有项目中添加功能,提供一两个类似功能的代码文件作为风格和模式的参考,比用文字描述“遵循项目现有风格”有效得多。
  4. 划定边界 :明确告诉模型“不需要处理什么”,比如“不需要前端界面”、“不需要数据库迁移脚本”。

这样一份清晰的输入,虽然可能多花你几分钟准备时间,但能极大减少模型的困惑和后续的返工,从源头上降低总 Token 消耗。 核心原则是:让模型专注于它最擅长的“填充”和“实现”,而把“决策”和“定义”工作留给自己。

2.2 上下文管理:策略性喂食,而非倾倒仓库

Claude 等模型支持巨大的上下文窗口(如 200K Token),但这绝不意味着你应该把整个项目的代码都塞进去。无差别地输入所有文件,是最昂贵的 Token 浪费方式。

分层次、按需加载上下文 是关键策略:

  • L0 - 项目元信息 :一个精简的 README.md project_context.txt ,说明项目目标、核心架构图(用文字或 ASCII 艺术描述)、目录结构。这通常在会话开始时一次性输入,帮助模型建立整体认知。
  • L1 - 直接相关文件 :与当前任务强相关的 1-3 个核心文件。例如,你要修改一个 API 路由,那么就提供这个路由文件、它对应的 Service 层文件、以及相关的数据模型文件。
  • L2 - 关键工具函数/配置 :提供项目中通用的工具函数、配置常量或基类文件。这些文件被频繁引用,提供它们可以避免模型重复“发明”轮子。
  • L3 - 运行时反馈 :一种高级用法是,将代码执行后的错误信息、日志输出或测试失败结果,作为后续请求的上下文。这能让模型的调试和修正极其精准。

注意 :在提供文件内容时,使用清晰的标记,如 【文件:src/utils/auth.js】 ,并在请求中明确指出“请重点参考【文件:src/utils/auth.js】中的 validateToken 函数实现模式”。这能引导模型的注意力。

一个实用的技巧是 维护一个上下文缓存字典 。在自动化脚本中,记录哪些文件已经在当前会话中被发送过。当新的请求需要关联上下文时,优先从缓存中提取,而不是重新读取和发送文件内容。虽然模型会话本身有上下文记忆,但主动管理可以避免在单次请求提示词中携带过多历史内容。

3. 提示词工程:精炼与结构化的艺术

提示词是与模型沟通的“编程语言”。编写省 Token 的提示词,就像在编写高效的代码。

3.1 指令设计:明确、可执行、可验证

模糊的指令导致冗长的、试探性的回复。清晰的指令直达目标。

  • 反面例子 :“检查一下这段代码有没有问题。”
  • 正面例子 :“分析以下函数中的潜在安全漏洞,特别是 SQL 注入和 XSS 风险。对于每个发现的风险,请直接给出修复后的代码片段,无需解释原理。函数功能是接收用户输入并查询数据库。”

后一个指令明确了:

  1. 分析范围 :安全漏洞(并具体到两种)。
  2. 输出格式 :直接给出修复后的代码片段。
  3. 输出限制 :无需解释原理。
  4. 上下文 :说明了函数用途。

模型会严格按照这个指令执行,输出紧凑而有用。 在指令中预先定义好回复的格式 ,例如“请用 JSON 格式输出: {“issue”: “描述”, “fixed_code”: “代码”} ”,可以让你更容易用程序解析结果,也避免了模型生成多余的叙述性文字。

3.2 系统提示词与角色扮演:固化高效协作模式

对于工程化应用,强烈建议使用“系统提示词”(System Prompt)来设定模型的初始角色和行为准则。这相当于一次投入,持续受益。你可以在每次会话开始时,给模型一个这样的身份设定:

你是一位资深、高效、注重细节的软件工程师。你擅长根据给定的精确需求和现有代码上下文,生成简洁、合规、可直接运行的代码。你的回复风格应严格遵循以下规则:
1. 除非明确要求,否则不解释代码逻辑。
2. 优先复用现有上下文中的函数和模式。
3. 如果发现需求不明确或存在矛盾,直接指出最关键的一点并询问,而非罗列所有问题。
4. 输出代码时,使用最必要的注释,仅解释非常规操作。

通过系统提示词将“省 Token”的理念内化为模型的行为模式,后续的每次交互都会更加高效。你可以为不同类型的任务(代码生成、代码审查、调试)设计不同的系统提示词模板。

3.3 迭代策略:增量与修正,而非推倒重来

当生成的代码不完美时,避免说“不对,重写”。这会导致模型丢弃所有之前的“思考”,从头开始消耗 Token。

采用 增量修正和焦点提问

  • 错误反馈 :将编译错误或测试失败信息直接提供给模型,并问:“根据这个错误,请只修改 calculate 函数中的第15-20行。”
  • 风格微调 :“代码功能正确,但请将变量命名风格从 camelCase 改为 snake_case,仅输出修改后的完整函数。”
  • 功能追加 :“在上一版 UserService 的基础上,增加一个 deactivateUser(id) 方法,保持其他方法不变。仅输出新增的方法代码。”

这种策略尊重了模型已完成的“工作”,将 Token 集中在解决新问题上,总消耗远低于多次完整重写。

4. 工程化实践:构建自动化“省流”流水线

将上述思路固化到工具和流程中,才能实现规模化的 Token 节省。

4.1 工具链集成:CLI 与 IDE 插件

手动复制粘贴代码、计算 Token 是低效的。我构建了一个简单的 CLI 工具,核心功能包括:

  1. 智能上下文收集 :通过配置文件(如 .claudecontext )定义项目模块。当请求涉及 auth 模块时,工具自动读取该模块下的关键文件(如 auth.service.ts , auth.guard.ts , user.model.ts ),并自动截取文件中的相关部分(例如,只读取最近修改过的函数或特定类),而非整个文件。
  2. 提示词模板化 :将常用的代码审查、单元测试生成、文档编写等任务做成模板。调用时只需指定模板和目标文件,工具会自动组装符合规范的提示词。
  3. 成本预估与日志 :在发送请求前,工具会基于字符数粗略估算 Token 消耗并提示。所有请求和回复被结构化地记录到日志文件,便于分析哪些类型的任务消耗最大,从而优化策略。

在 IDE(如 VS Code)中,则可以配置代码片段或使用相关插件,快速插入设计好的提示词模板,并对选中的代码块直接调用审查或解释功能,避免切换上下文。

4.2 任务分解与链式调用

对于复杂功能,不要奢望一个提示词就能生成完美代码。应采用“人类项目经理”的思路进行分解。

例如,实现一个“带缓存的数据查询服务”:

  1. 第一步(设计接口) :提示词:“基于以下数据模型 User ,设计一个 UserQueryService 的 TypeScript 接口,包含 getUserById(id: string) searchUsers(keyword: string) 方法。只输出接口定义。”
  2. 第二步(实现核心逻辑) :将第一步的输出作为上下文,提示词:“实现这个接口,使用提供的 databaseClient 进行查询。暂不考虑缓存。只输出类实现。”
  3. 第三步(添加缓存层) :将前两步的输出作为上下文,提示词:“在第二步实现的类基础上,为 getUserById 方法添加 Redis 缓存逻辑,缓存键为 user:{id} ,TTL 为 300 秒。输出完整的最终类。”

这种链式调用(Chain-of-Thought)不仅让每一步的生成目标更简单、出错率更低,而且允许你在中间环节进行人工审核和修正,防止错误累积到后期造成更大的浪费。每一步的输入和输出都更小、更精准,总 Token 消耗在可控范围内。

4.3 缓存与复用生成结果

工程中经常遇到类似的任务。不要每次都从头生成。

  • 建立代码片段库 :将模型生成的通用工具函数、标准配置、样板代码(如 Express.js 的错误处理中间件)保存到一个片段库中。下次需要时,直接复用或微调。
  • 对生成本地进行版本管理 :如果模型为你生成了一个复杂的模块,将其保存到项目文件中。后续需要修改时,以这个文件为上下文进行“修改”,而不是重新描述需求生成。你可以对模型说:“以下是现有的 NotificationService 类,请为其添加一个发送微信模板消息的方法 sendWechatTemplateMsg() 。” 这比描述整个服务从头创建要节省得多。

5. 效果评估与常见陷阱

实施一系列“省流”策略后,如何评估效果?最直接的指标是完成特定类型任务的平均 Token 消耗下降比例。在我的实践中,通过上述方法,将“代码生成与迭代”类任务的总消耗降低了约 40-60%。

5.1 监控与成本分析

定期查看 API 使用日志,按“提示词模板类型”或“任务类别”进行聚合分析。你会发现:

  • “模糊需求澄清”消耗的 Token 可能占很大一部分 -> 强化需求定义阶段。
  • “大型文件上下文”是输入 Token 的主要来源 -> 优化上下文选择策略。
  • “冗长解释”是输出 Token 的浪费点 -> 强化系统提示词,要求回复精简。

5.2 必须避开的“省 Token”陷阱

  1. 过度裁剪上下文导致模型“失明” :为了省输入 Token,不给模型提供必要的依赖文件,导致生成的代码无法与项目其他部分集成,反而需要更多轮次来修正。 省 Token 的前提是保证生成质量 ,否则就是本末倒置。
  2. 指令过于苛刻而丧失创造性 :如果要求模型“只输出代码,不输出任何文字”,当需求确实存在模糊点时,模型可能生成一个基于错误假设的代码,导致后续调试更困难。 允许模型在关键歧义点上进行极简提问 ,是更经济的做法。
  3. 忽视输出 Token 的成本 :有时我们只关注输入的文件大小,却忽略了模型可能生成一篇冗长的“技术文章”。通过系统提示词和明确指令控制输出长度和格式至关重要。
  4. 盲目追求单次请求解决所有问题 :这是最大的陷阱。把十个需求塞进一个提示词,看似只发起了一次请求,但模型需要处理极其复杂的上下文和指令,极易出错或产生混乱的输出,总消耗可能更高,且结果不可用。 拆解任务永远是最高效的策略

5.3 一个实战案例:重构一个老旧函数

假设有一个旧的、冗长的 processData 函数需要重构为模块化、可测试的版本。

  • 低效方式 :将整个 500 行函数文件扔给模型,说“重构它”。输入 Token 多,模型输出一个巨大的、不确定是否正确的 diff,难以审查。
  • 高效方式
    1. 分析 :自己(或用一个简单的脚本)先将函数粗略按功能拆分成几个逻辑块,并标注输入输出。
    2. 分步生成
      • 请求1:“根据以下 数据验证 逻辑块,创建一个纯函数 validateInput(data) ,只输出函数。”
      • 请求2:“根据以下 核心计算 逻辑块,创建函数 coreCalculation(validatedData) ,依赖 utils/math.js 中的 calculateStandardDeviation 函数。只输出函数。”
      • 请求3:“将原函数中的 结果格式化 逻辑,创建为 formatResult(calculationResult) 函数。只输出函数。”
    3. 组装 :最后,请求4:“使用上面生成的三个函数 validateInput , coreCalculation , formatResult ,重新实现 processData 函数的主体,处理错误流。只输出新的 processData 函数。”

每一步的上下文都很小,目标极其明确,生成的代码质量高,且总消耗远低于一次性重构。你作为开发者,全程保持着对重构方向和进度的控制。

最终,Claude Code 的工程化落地,特别是“省 Token”篇,本质上是一场关于 开发者与 AI 如何高效分工 的思维升级。它要求我们从漫无目的的提问者,转变为精明的系统设计者和对话引导者。每一次 Token 的节省,都代表着一次更精准的沟通和一次更高效的协作。当这套方法论成为习惯,你会发现不仅成本可控,代码质量与开发体验也获得了同步提升。

更多推荐