尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

告别Tokenmaxxing:让AI辅助编程从“多写”到“写准”

告别Tokenmaxxing:让AI辅助编程从“多写”到“写准” 近期技术社区里流传微软工程师在内部沟通中的一句话Tokenmaxxing is not what we are optimizing for。直译过来就是“Token 最大化不是我们正在优化的目标”。这句话引发了不少讨论因为它直接戳中了一个普遍现象许多开发者在 AI 辅助编程时会不自觉地把模型的输出长度当成回答质量的标准。模型生成的代码越多、注释越全、解释越长就倾向于认为 AI 干得越卖力然而这种直觉在真实工程里往往是错的。这篇文章围绕这句话展开先解释 Tokenmaxxing 是什么再分析为什么输出更长不等于结果更好然后给出从提示词设计、上下文管理到 API 参数控制的具体做法。重点是帮助你学会把“让 AI 多写一点”改成“让 AI 写准一点”让 AI 辅助开发回归到交付可运行、可读、可维护的代码这条主线上。1. Tokenmaxxing 是什么开发者圈里正在形成的坏习惯1.1 一个典型场景从“简短函数”变成“大型重写”假设你在一个 Python 项目中让 AI 实现一个解析 CSV 行的工具函数。最初的提示词可能只是“写一个解析 CSV 行的函数”模型快速返回了一个 20 行的实现。此时你心里犯嘀咕觉得这个函数太短边界情况可能没覆盖于是追加了一句“再详细一点把所有情况都考虑进去”。模型收到“详细”和“全面”这两个指令后很难判断你需要的边界到底有哪些它最稳妥的做法就是把一切可能的情况都铺开空字符串、空白字符、转义引号、连续逗号、异常输入、性能优化注释、防御性判空、类型注解、使用示例。最终它返回了 180 行代码看起来内容丰富但真正要修改的核心逻辑只有 30 行其余全是“安全覆盖”产生的冗余分支。这个例子不是模型能力的问题而是提示词把优化目标带偏了。你没有告诉模型“什么情况下算完成任务”模型只能通过增大输出量来降低漏掉需求的概率。结果就是 token 开销上升、代码评审成本上升、后续维护负担也跟着上升。1.2 Tokenmaxxing 的三种常见表现形式Tokenmaxxing 不是一个官方术语它是开发者社区里对“以生成量代替产出质量”行为的一种概括。常见的表现形式有三种表现形式典型提示词习惯常见后果数量导向反复要求“写详细一点”“不要遗漏任何情况”输出膨胀核心逻辑被大段注释和无关分支淹没复述式输出已经拿到结论还要“换一种说法再解释一遍”token 消耗翻倍信息量没有增加全量重写让 AI 整个文件重写而不是生成 diff 或新增函数大 diff、大量无关注释、review 成本急剧上升复述式输出在聊天类 AI 助手里尤其常见。模型第一次解释了某个概念开发者觉得不够“深入”要求再解释一次。模型通常只是换了一套措辞并没有补充新信息但用户会误以为自己学到了更多内容。这种交互在技术提问中会造成一种虚假的充实感。全量重写则是代码场景里最危险的形式。一个文件可能包含 300 行与需求无关的配置代码开发者为了让 AI 增加一个函数选择把整个文件粘贴进去并要求“重写”。模型输出后开发者需要逐行检查哪里被改过哪里只是格式变化。相比之下让 AI 只生成新增函数或者只生成需要修改的片段风险要小得多。1.3 为什么开发者会掉进 Tokenmaxxing 的陷阱第一个原因是信任不足。很多开发者担心 AI 模型“偷懒”认为它输出太短意味着没认真思考。为了获得心理上的安全感他们会在提示词里加入“尽量详细”“全面一点”这类的防御性措辞。第二个原因是验收惯性。传统软件开发中代码量常常被当作粗粒度的产出信号。虽然这不准确但在汇报工作时总有人用“这个月写了多少行代码”来衡量进度。当这种惯性被带到 AI 交互中用户自然会追求更多输出。第三个原因是刚才提到的上下文不足。当开发者没有提供足够的项目背景、编码规范、依赖信息和验收条件时模型无法准确判断边界只能通过多写多覆盖来应对不确定性。这也是为什么往往提示词越短输出越容易膨胀。第四个原因来自工具本身。很多 AI 编程插件会在界面上展示“本次生成 245 行”“覆盖 12 个文件”等统计信息。这些指标如果被当作正面反馈呈现用户就会被引导到“生成越多越好”的方向Tokenmaxxing 就变成了工具设计塑造出来的行为。2. 为什么“Token 最大化”不应该是 AI 辅助开发的优化目标2.1 优化目标错位从“生成量”回到“交付价值”微软工程师那句话的核心是在提醒团队重新审视优化目标。产品团队评估一个 AI 编程助手应该看任务完成率、代码可接受率、需求落地时间而不是平均单次生成 Token 数。如果团队把“每日生成 Token 数”写进看板工程师自然会倾向于把提示词写长、把 max_tokens 调高、用重写代替增量修改。指标看起来在涨代码库却在变差。这个逻辑同样适用于个人开发者。当你在对话框里要求模型“再详细一点”时你实际上是在优化“输出长度”这个指标。可是从工程视角看一次成功的 AI 辅助开发应该是一段明确的需求描述对应一个可验证的代码增量。这个增量可能只有 15 行也可能需要 300 行但它必须与任务直接相关而不是为了凑数而存在。优化目标决定行为模式。目标如果是“生成足够多的 token”行为就会变成堆字数和堆代码目标如果是“交付可用代码”行为就会变成描述需求、限定边界、检查验证结果。2.2 长输出带来的隐性成本阅读成本、上下文污染与错误扩散即使抛开费用问题长输出也会给工程带来具体损失。最明显的是阅读成本。开发者的阅读速度远低于 AI 的生成速度。一次生成 2000 token 的内容你可能需要 5 到 10 分钟才能完整读完并判断质量如果模型只生成 300 token你 1 分钟就能看完。当输出中大量内容是重复解释和无关分支时阅读成本就更难接受。其次是上下文污染。模型的上下文窗口是有限资源输入和输出共同占用同一块空间。输出过长会挤压后续对话可用的空间导致后面提出的问题难以获得完整回应。同时长输出中夹杂的无关信息会成为噪声干扰模型在后续回合中对关键诉求的识别。第三是错误扩散。生成内容越多夹带错误逻辑的概率越高。AI 写了一个包含 12 个分支的函数其中可能有 10 个分支是正确的但有 1 个分支在当前业务中并不应该存在另外 1 个分支的异常处理写法会掩盖真正的错误。冗长代码会让评审者产生“既然写都写了应该没问题”的盲区最终导致 bug 进入测试环境甚至生产环境。2.3 输出长度与成本、延迟之间的现实关系从 API 调用角度看费用模型通常是总费用 ≈ 输入 token 数 × 输入单价 输出 token 数 × 输出单价大多数模型对输出 token 的定价高于输入 token有时是 3 到 5 倍。假设某个模型输入单价为 1 美元 / 百万 token输出单价为 3 美元 / 百万 token一次输出 500 token 的费用是 0.0015 美元一次输出 2000 token 的费用是 0.006 美元。单次调用看起来差距不大但放到团队每日上千次调用的规模里就是不可忽略的成本差。延迟的变化更直观。模型生成是逐 token 进行的输出越长等待时间越长。用户在使用 AI 编程助手时的专注度有限如果每次请求都要等很久很多人会中途切走回来后甚至忘了自己原本要问什么。下面是一个示意性的对比说明输出长度对开发体验的影响输出长度典型任务延迟感受输出费用倍率质量风险200 token生成一个简短函数快1 倍低800 token函数加测试用例中约 3 倍中2000 token全文件重写或长文解释慢约 8 到 10 倍高这里的具体倍率取决于实际模型定价但规律是确定的输出越长成本越高、延迟越高、评审负担越重。3. 把“生成多少”改成“生成好”工程化提示词设计3.1 用约束条件替代“详细一点”要改变 Tokenmaxxing 行为第一步是修改提示词习惯。不要总说“写详细一点”而是要给出输入、输出、边界和禁止事项。下面是一组对比。常见的坏提示词请帮我写一个解析 CSV 行的函数。要非常详细把每一步都解释清楚 注释越多越好不要遗漏任何情况。最好把常见的边界情况都包含进去 写得全面一点。更符合工程交付要求的提示词实现函数 parse_csv_line(line: str) - list[str]。 要求 1. 支持带双引号的字段字段内的双引号用 转义。 2. 输入为空字符串时返回 []。 3. 不引入第三方依赖。 4. 注释只写函数职责不逐行解释。 输出格式只给代码不要额外说明。最后用 assert 写两个测试用例。两个提示词的目标都是“让 AI 写出一个 CSV 解析函数”但结果差异很大。第一个让模型自己决定边界它自然会写得又长又全面第二个把接口签名、边界规则、依赖限制、输出格式都定义清楚模型不需要靠堆字数来应对不确定性生成的代码反而更紧凑、更可用。3.2 分阶段提问先给方案再要代码对于复杂任务不要一开始就要求完整代码。可以先让模型给出实现方案确认方向后再要求具体实现。这样既能避免方向错误也能防止模型一次性输出大量无用代码。推荐的做法是分成两轮。第一轮我要在 Python 中实现一个轻量级的 CSV 行解析函数不引入第三方库。 请先给出实现方案说明你打算如何处理引号转义、空字段和换行。 不要写代码先列方案。第二轮方案可以。请按这个方案实现 parse_csv_line(line: str) - list[str]。 输出只包含代码和两个 assert 测试用例。分阶段提问的核心思路是让模型分步交付减少一次性输出量。第一步输出的是一个可读的短方案第二步输出的是有约束的实现。两步加起来可能比一次性生成“完整代码加详细解释”更短但信息密度更高。3.3 限定输出格式让结果可以直接使用很多时候开发者并不需要 AI 的解释只需要代码或结构化数据。此时应该在提示词中明确“只输出代码”“只输出 JSON”“不要加 Markdown 包裹”。例如请把下面这段配置转换成 JSON 格式只输出 JSON不要解释不要用代码块包裹。 配置内容 - 服务名user-service - 端口8080 - 日志级别info - 数据源mysql://localhost:3306/users当输出格式被限定后模型的回答会变得紧凑也更容易被直接消费。这不只是在节省 token也是在减少人工处理步骤。3.4 API 参数层面的输出控制如果是在代码中调用模型 API除了提示词还可以通过参数控制输出行为。下面是一个使用 Python 客户端调用模型的示例from openai import OpenAI client OpenAI( base_urlhttps://your-endpoint.example.com/v1, api_keyyour-api-key ) response client.chat.completions.create( modelyour-model, messages[ { role: system, content: 你是一位严谨的软件工程师。输出只包含代码不要解释。 }, { role: user, content: ( 请实现 parse_csv_line 函数约束如下\n 1. 返回 list[str]\n 2. 支持带引号的字段和转义引号\n 3. 空行返回空列表\n 4. 不引入第三方库\n 5. 最后给出两个 assert 测试用例 ) } ], temperature0.2, max_tokens800, stop[# END] ) output response.choices[0].message.content print(output)这里有几个关键参数值得关注参数作用建议取值调大后调小后max_tokens限制单次输出的最大 token 数量按任务需要预留 20% 余量延迟和成本上升输出可能被截断temperature控制输出的随机程度0.2 到 0.4输出更发散不稳定输出更稳定偏保守stop设置生成结束标记自定义业务标记影响较小可能提前结束输出max_tokens 是控制 Tokenmaxxing 最直接的参数。如果任务只需要一个短函数把它设为 300 到 500可以避免模型无限制扩展。但要注意max_tokens 过小会导致输出被截断结果缺少闭合括号或测试用例。因此建议先设一个较小的值观察输出是否完整再逐步调整。temperature 对代码生成的影响很容易被低估。温度太高时模型可能在不同的运行中使用不同的写法导致输出不稳定。代码生成任务建议保持低频在需要探索多种方案时再临时调高。4. 上下文管理真正的瓶颈往往在输入不在输出4.1 上下文窗口是共享资源看到“模型输出太长”时很多开发者的第一反应是调小 max_tokens但如果输入侧已经塞满了无关内容即使把 max_tokens 调大模型也可能无法给出高质量回答。上下文窗口是输入和输出共享的空间。假设模型支持 128k token 上下文你在对话框里粘贴了 100k token 的无关代码那么剩下给模型推理和输出的空间只有 28k。更严重的是模型需要在大量噪声中定位真正有用的信息注意力会被分散回答质量会明显下降。所以在排查输出异常时不要只盯着输出参数也要检查输入侧是否塞入了太多与当前任务无关的代码、注释和历史对话。4.2 按需注入相关代码而不是粘贴整个仓库在 IDE 里使用 AI 编程助手时模型通常能通过插件读取当前文件的部分内容。但如果你是在网页端或本地脚本里使用 API就需要自己组织上下文。糟糕的做法是把整个项目 README、全部配置文件和多个工具类一口气粘贴进对话。模型无法判断哪些信息与当前问题相关它只能把这些内容全部视作背景回答时也会尽力“照顾”所有信息导致输出冗长且重点模糊。更推荐的做法是只注入与任务直接相关的片段我需要修改一个 Python 函数让它支持新的时间格式。 当前函数签名 def parse_time(value: str, fmt: str %Y-%m-%d) - datetime | None: ... 调用示例 parse_time(2024/01/15, %Y/%m/%d) parse_time(2024-01-15) 请只修改函数内部实现不要改变函数签名。输出只给修改后的函数。这个提示词里包含函数签名、调用示例和修改目标但没有把整个项目粘贴进去。模型有了足够的锚点就不需要通过大量输出覆盖未知情况。4.3 用系统提示词定义边界在 API 调用场景中系统提示词是约束模型行为的重要工具。好的系统提示词可以把模型的默认状态从“尽量多说”切换到“按需输出”。一个面向代码生成任务的系统提示词示例你是一名熟悉 Python 的软件工程师擅长编写小函数。回答要求 1. 输出只包含实现代码和测试用例不要解释。 2. 如果需求不明确先列出需要确认的问题不要写代码。 3. 单个函数不超过 40 行除非必须。 4. 不要重复用户已经给出的代码。 5. 代码风格遵循 PEP 8。系统提示词的要点不是写得长而是把“不做什么”说清楚。现实中很多开发者的系统提示词只写了“你是一个资深工程师”这给模型留下了太多自由发挥空间输出长度自然不可控。把禁止事项加上之后模型的回答会明显收敛。5. 常见问题排查输出过长、效果变差、重复内容5.1 输出越来越长且重复内容多该查什么现象同一个会话中前几轮回答还很精炼后面几轮突然变得很长而且内容反复出现类似结论。可能原因历史对话里积累了“再详细一点”“多考虑一些情况”等指令模型在后续回合持续遵循这类要求。上下文被无关信息塞满模型找不到关键信息只能用长回答覆盖不确定性。每次回答都包含前面的全部代码导致内容叠加变长。检查方式先看当前会话的上下文占用情况再回溯提示词历史找出哪些句子带有“详细”“全面”“完整”一类指令。把这类指令删除或改成明确约束。处理建议如果一次对话出现了明显的冗余积累直接开启新会话把最终需要的代码签名和约束在新会话中重新提交。不要尝试在长会话里修剪效率太低。5.2 换成更大参数模型后效果反而变差现象从一个小模型切换到更大的模型本期待更高质量结果生成的代码反而偏离需求或者输出了大量不必要的设计模式。可能原因大模型有更强的“理解扩展指令”的能力。当提示词中没有明确禁止时它会把“完整实现”理解成“包括完整的工程化包装”于是加入抽象类、依赖注入、注册机制这些都不是当前项目需要的。检查方式查看模型输出里是否出现提示词中完全没有提到的技术组件。如果出现了说明提示词缺少禁止性约束。处理建议在提示词中增加“不要引入额外的设计模式”“不要修改现有接口”“保持最小实现”等禁止性条款。大模型的优势在于理解复杂需求但如果约束不清晰它的能力反而会放大输出膨胀问题。5.3 长输出完全没用吗也不是。在探索方案、学习概念、进行头脑风暴时长输出是有价值的。问题不在于输出长度本身而在于是否匹配当前任务类型。可以把交互分为两类任务类型适合的输出控制策略探索型多种方案、优缺点对比、边界讨论可以放开输出允许模型列举多种可能交付型代码、配置、SQL、补丁严格约束格式和篇幅只输出可落地的内容关键是在进入交付型任务时明确告诉模型切换到“交付模式”不要再列出备选方案。换句话说让模型知道“现在不要 tokenmaxxing请聚焦到可验收的增量”。下面是一份排查清单适合在遇到输出质量问题时逐条检查问题现象常见原因检查方式处理建议输出过长且重复内容多提示词包含“详细”“全面”指令或历史上下文污染回溯提示词历史观察上下文占用删除冗余指令开启新会话重新提交输出偏离需求约束不足模型自行扩大了实现范围检查输出中是否出现提示词未提及的组件增加禁止性条款限制改动范围输出被截断max_tokens 设置过小查看返回中的 finish_reason调大 max_tokens 或把任务拆成多步多次生成结果不一致temperature 偏高或提示词语义模糊固定同一提示词多次运行对比降低 temperature补充更多约束给了足够上下文但输出还是长系统提示词没有定义输出边界检查系统提示词是否只写了角色没写规则加入输出格式、禁止事项、篇幅限制6. 团队落地建议避免把 AI 辅助开发变成 Token 竞赛6.1 先定义什么是“可用产出”个人可以靠意志力控制自己的提示词但团队要避免 Tokenmaxxing必须有统一的产出标准。建议在团队内部明确一段 AI 生成代码在合入之前必须满足哪些条件。一个可参考的验收清单1. 通过现有单元测试或为新增逻辑补充了单测。 2. 不改变已有函数签名除非需求明确要求变更。 3. 没有引入额外依赖除非在评论中说明理由。 4. 代码格式符合项目规范。 5. diff 中不包含与当前任务无关的改动。 6. 注释只解释原因和复杂逻辑不逐行复述代码。这个清单并不复杂但能有效过滤掉大部分为了“写得全面”而生成的冗余代码。当模型输出无法通过清单时不应直接合入而应修改提示词后重新生成。6.2 代码审查只看 diff不看生成行数代码评审阶段最容易感知到 Tokenmaxxing 带来的痛苦。评审者面对一个大 diff第一反应是抵触第二反应是快速滑过这正好给了隐藏 bug 机会。推荐在评审时只关注三个维度改动是否对应需求描述中的具体行为。新增逻辑是否有对应测试。删除或修改的原有行为是否经过确认。如果某个 PR 中的大部分内容只是 AI 生成的注释、空行、防御性判断和“顺便”重构的格式评审者应该直接打回并要求提交者收缩改动范围。长 diff 不应该被当作“工作量大”的证据反而应该被当作“需求范围失控”的信号。6.3 沉淀提示词模板和预设约束团队可以维护一个内部提示词模板库比如放在.ai_prompts/目录或知识库中包含“新增函数”“修复 bug”“补充测试”“重构小段代码”等常见场景。每个模板都固定输出格式和禁止事项。修复 bug 场景的模板示例场景修复 bug 任务分析下面代码中的空指针原因并给出最小修复。 约束 1. 只修改必要的行不要重构整个函数。 2. 输出格式原因 diff 格式补丁 一个回归测试。 3. 如果无法复现请说明缺少的信息。有了这类模板团队成员就不需要在每次交互时重新口头描述约束也不容易回到“请写详细一点”的习惯里。模板本身还能作为团队知识沉淀让新成员更快掌握与 AI 协作的方式。6.4 用结果指标衡量 AI 辅助开发最后是指标问题。建议团队只保留结果型指标不要引入生成型指标。推荐指标 - 功能开发周期 - 首次合入通过率 - 缺陷回退率 - 单次需求迭代时间 不推荐指标 - 日均生成 token 数 - 日均生成代码行数 - 单次对话轮数 - 提示词字数原因在于生成型指标只能衡量“工作量”表象无法衡量“有效产出”。一个开发者用 10 次精确对话完成了需求另一个开发者用 50 次冗长对话把同一段逻辑写出了一堆分支前者的指标价值远超后者。如果把指标设在生成侧团队会往更坏的方向靠拢。7. 从 Tokenmaxxing 转向结果优化实践工具与扩展方向7.1 每次生成后先验证再决定要不要补充一个简单但有效的顺序调整是先验证结果再要求补充。拿到 AI 生成的代码后不要先看注释全不全而是先运行测试、检查类型、执行 lint。只有代码本身通过验证后才考虑让模型补充文档或解释。如果反过来先让模型写一堆解释开发者很容易被解释说服忽略代码实际存在的问题。长解释和正确的代码没有任何必然联系验证动作才是唯一可信的质量信号。在 IDE 中可以这样操作让 AI 只生成函数实现和测试用例。立刻运行pytest或npm test。测试通过后再决定是否需要生成使用说明。如果测试失败把失败信息贴给 AI重新生成修复。这个流程把 AI 从“一次性写完全部答案”的角色变成“先交付可验证的增量、再按反馈迭代”的协作对象。7.2 更进一步的评估方法评估集与回归测试当团队已经熟悉了提示词模板后可以进一步把评估工作自动化。可以准备一组固定题目每个题目包含输入需求、期望输出和禁止事项。每次修改提示词模板后用这组题目跑一遍模型结果统计以下指标通过测试的比例。输出中超出约束的比例。需要人工改写才能合入的比例。平均输出 token 数。这套做法本质上是在给提示词模板做回归测试。它能帮你发现某个模板调整后是否再次引入 Tokenmaxxing 倾向也能辅助判断不同模型的适用性。这里的关键是不要只记录“生成行数”这种单一指标要把“通过率”和“改造成本”放在一起看。平均输出 token 数可以保留作为观察项但不单独作为优化目标。7.3 扩展开来AI 辅助开发可以走向 Agent 工作流如果把 Tokenmaxxing 的讨论放到更大的背景下看它其实是 Agent 工作流出现前的一种过渡问题。在简单的问答式交互里模型只能通过一次输出尽量满足需求所以容易走向“多写一点”。而在 Agent 工作流中模型可以分步执行先读取文件、再定位函数、然后生成补丁、最后运行测试每一步的输出都服务于下一步的验证。这意味着未来的 AI 辅助开发优化重点会从“单次输出长度”转向“多步执行的任务完成率”。但无论是单次问答还是 Agent 工作流核心原则不变模型应该为最终结果负责而不是为输出数量负责。回到那句引起讨论的原话。Tokenmaxxing is not what we are optimizing for。微软工程师真正想表达的其实是优化目标应该落在用户价值上需求是否被正确理解代码是否可运行、可维护团队是否能更快交付。这个判断对使用 AI 编程助手的每个开发者都适用。给新手的练习建议很直接连续一周不要在提示词里使用“详细”“全面”“尽量多写”这类词。把所有要求改写成接口签名、边界条件、禁止事项和测试用例。你会发现模型输出变得更短、更准代码评审更轻松回退和返工也会明显减少。这个练习比纠结于哪种模型更聪明更有价值。
返回列表