免费POC, 零成本试错
AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


我要投稿

用第一性原理拆解 Agentic Coding:从理论到实操

发布日期:2026-01-12 17:32:37 浏览次数: 1549
作者:字节跳动技术团队

微信搜一搜,关注“字节跳动技术团队”

推荐语

Agentic Coding 实践指南:优化与 AI 协作的关键策略,助你成为驾驭 AI 的专家型通才。

核心内容:
1. 理解 LLM 本质:从自回归生成机制到 Coding Agent 的局限
2. 提升效率的三大策略:短对话模式、复利工程、开发者体验优化
3. 从理论到实操:如何将 AI 协作转化为可刻意练习的技能

杨芳贤
53AI创始人/腾讯云(TVP)最具价值专家

在 Agentic Coding 实践中,提升效率的关键在于优化与 AI 的协作方式,而非寄望于无限的上下文窗口。核心策略是采用“短对话、精简上下文”的模式,将复杂任务拆解为专注的子对话,并借助“复利工程”将 bug 修复、代码审查等日常经验沉淀为可复用的项目知识库,使系统获得记忆并实现效率的持续增长。此外,改善开发者体验(如清晰文档、快速测试)具有双重价值,既能帮助人类开发者,也能显著提升 AI 的表现。最终,与 AI 的协作应被视为一门需要刻意练习的技能,通过不断实践,开发者可以成为驾驭 AI 的“专家型通才”,在更广阔的领域创造价值。


第一性原理|理解 LLM 的本质


LLM 是如何「思考」的


大语言模型的工作方式可以用一句话概括:预测下一个 token。


当你向 LLM 提问时,它并不是先在「脑中」构思好完整答案再输出。相反,它每次只做一件事:基于当前看到的所有文本(你的输入 + 它已经生成的内容),预测最可能的下一个词是什么。然后把这个词加入序列,再预测下一个,如此循环直到生成结束,这种方式被称为 自回归生成(Autoregressive Generation)


理解这一点至关重要,因为它揭示了 LLM 的几个本质特征:


1. 没有独立于输出的「思考」过程LLM 的推理就是生成本身。它不能先想好再说,只能边说边想。这就是为什么让模型「一步步思考」(Chain-of-Thought)会提升效果 — 你实际上是在给它更多的「思考空间」,让它通过生成中间步骤来辅助推理。尽管新一代模型很多都带有显式的 reasoning 能力,依然脱离不了这个范式。

2. 上下文就是全部记忆:LLM 没有独立的记忆存储。它对当前对话的所有「理解」,完全来自于输入给它的上下文窗口。窗口之外的内容,对模型来说就是不存在的。

3. 生成具有概率性:每一步预测都是基于概率分布采样,这意味着同样的输入可能产生不同的输出。


自回归(autoregressive)LLM 的核心工作方式是:一次只预测下一个 token,然后把自己刚生成的内容再喂回去继续生成。这个机制很强(通用、可扩展、能「写出」复杂结构),但也天然带来一些局限,在 Coding Agent 里这些局限会被放大,因为软件开发是「长链路、强约束、强验证」的任务。


当前 Coding Agent 普遍存在的问题:


1. 局部最优:一步一步「续写」,不等于全局规划

  • 容易先写得很像、很顺,然后在后面发现不对再补丁式修修补补(历史债务快速累积)。

  • 多文件重构/架构调整这种「先规划后落地」的任务,会变成边写边想,导致接口不一致、重复实现、遗漏迁移步骤。

  • 对「最终能不能通过测试/CI」缺乏感知,除非你把测试结果显式喂回 agent 循环。


2. 一旦走偏,会沿着偏差继续滚雪球

  • 早期误读需求/误判代码库的约束 ,导致后面每一步都在错误世界观里自洽。

  • 生成了一个不存在的函数名/类型后,后续会越来越「相信它存在」,直到编译/运行时打脸。

  • 在长对话、长任务里尤其明显:越写越像「另一个项目」。


3. 输出是流式的,无法回头修改之前输出的内容

  • 擅长「写新文件/新段落」,相对不擅长在复杂代码中做精确、最小化、局部一致的编辑。

  • 容易倾向于「重写一遍」而不是「进行修改」,导致 diff 过大、review 成本高。

  • 在需要保持大量不变量(API、格式、风格、兼容性)的仓库里尤其痛苦。


4. 满足约束的能力有限,而代码是强语法/强语义约束的

  • 「看起来合理」的实现,经常在边界条件、并发、错误处理、资源释放上出错。

  • 跨文件的符号解析、泛型/模板推导、宏/代码生成等,靠纯文本推断很容易漏。

  • 复杂的重构(rename、move、split)没有 AST/语义工具辅助时,错一个引用就全盘崩。


5. 天然单线程思考,难并行探索

  • 在方案选择(架构、依赖、实现路径)上容易早早押注一个方向,缺少系统性对比。

  • 排查 bug 时更像「单线推理」,不如人类/工具那样并行假设、并行验证


Attention:LLM 如何「阅读」上下文


在预测下一个 token 时,模型需要从上下文中提取相关信息,这个过程由 Attention(注意力)机制 完成。


你可以把 Attention 想象成一个动态的「聚光灯」:当模型生成每个新 token 时,它会扫视整个上下文,对不同位置的内容分配不同的「注意力权重」。权重高的部分会对当前生成产生更大影响,权重低的部分则几乎被忽略。


具体来说,对于当前要生成的 token,模型会:


  • 计算相关性:当前位置与上下文中每个位置的相关程度

  • 分配权重:相关性高的位置获得更高权重,形成一个概率分布

  • 加权聚合:根据权重汇总上下文信息,用于预测下一个 token


这个机制有几个重要特性:


  • 注意力是稀疏的:模型不会均匀地关注所有内容。在实践中,Attention 权重往往集中在少数关键位置,大部分位置的权重接近于零。

  • 注意力需要「学习」的:模型通过训练学习在什么情况下关注什么内容。这意味着它可能会形成某些偏好模式,比如更关注开头和结尾。

  • 计算复杂度是平方级的:标准 Attention 需要计算每个位置与所有其他位置的关系,计算量随上下文长度的平方增长。这是上下文长度存在物理上限的根本原因之一。


理解了 Attention 机制,我们就能更好地理解上下文长度为什么会带来多种限制。


上下文长度:最关键的约束


上下文窗口的限制是影响 Coding Agent 设计最核心的约束条件。结合对 Attention 机制的理解,我们可以更清楚地看到这个限制的多个层次。


物理上限


每个模型都有最大 token 限制,目前主流模型通常在 128K 到 200K 之间。这个硬性边界的存在有两个根本原因:

1. Attention 的计算复杂度通常是 O(n²),上下文长度翻倍,计算量变成四倍

2. 需要存储完整的注意力矩阵,内存消耗同样是平方级增长

超过这个长度的内容根本无法被处理。


有效上下文远小于标称上下文


虽然模型宣称支持 200K tokens,但这不意味着在 200K 长度下都能保持良好表现。


问题出在 Attention 的「稀疏性」上:当上下文很长时,注意力权重需要分散到更多位置。如果关键信息只是海量内容中的一小部分,它获得的注意力权重可能会被稀释到难以有效利用的程度。实际上,一个支持 200K 的模型,可能在超过 80K 或 100K 之后,就开始出现明显的性能退化。


性能退化曲线


随着上下文变长,不仅是「记忆」变差,模型的整体能力,包括推理准确性、指令遵循能力、代码生成质量都会下降。


这是自回归 + Attention 组合带来的累积效应:


  • 每一步生成都依赖于对上下文的正确理解

  • 更长的上下文意味着更稀疏的注意力分布

  • 错误理解会传递到后续生成,形成累积误差


理解这些限制,你就能明白为什么 Coding Agent 需要精心设计上下文管理策略,而不是简单地把所有信息塞进窗口。


强化学习:让模型学会「做事」


前面我们讨论的是 LLM 的基础能力,预测下一个 token。但要让模型从「能说会道」进化到「能做事情」,还需要另一个关键技术:强化学习(Reinforcement Learning, RL)。


预训练的局限


LLM 的预训练本质上是「模仿」:通过阅读海量文本,学会预测「人类会怎么写下一个词」。这让模型获得了广泛的知识和流畅的表达能力,但也有明显的局限:


  • 模型学会的是「文本看起来应该是什么样」,而不是「什么行动能解决问题」

  • 预训练数据中很少有「调用工具 → 观察结果 → 调整策略」这样的交互序列

  • 模型可能会生成看起来合理但实际无效的操作步骤


简单来说,预训练教会了模型「说」,但没有教会它「做」。


强化学习的核心思想


强化学习用一个简单的循环来解决这个问题:尝试 → 反馈 → 调整。


想象教一个小朋友下棋:你不会给他看一百万盘棋谱让他背(这是预训练的方式),而是让他实际下棋,赢了就表扬,输了就复盘。通过无数次的尝试和反馈,他逐渐学会什么是好棋、什么是坏棋。


对 LLM 来说,强化学习的过程类似:


  • 尝试:让模型在真实或模拟的环境中执行任务(比如调用工具、编辑文件)

  • 反馈:根据结果给出奖励信号(任务完成了?代码能运行?测试通过了?)

  • 调整:更新模型参数,让它更倾向于选择能获得高奖励的行动


这个过程会重复成千上万次,模型逐渐学会:在什么情况下应该调用什么工具、如何解读工具返回的结果、什么时候应该继续尝试、什么时候应该换个方向。


为什么 RL 对 Agentic 能力至关重要


传统的 LLM 微调(比如监督学习)需要人类标注「正确答案」。但 Agent 任务的特点是:


  • 路径多样:完成同一个编程任务可能有无数种合理的步骤组合

  • 结果导向:我们真正关心的是最终结果,而不是中间每一步是否「标准」

  • 需要探索:有时候必须尝试几种方法才能找到可行的路径


RL 天然适合这种场景。它不要求你定义「正确的步骤序列」,只需要定义「什么算成功」。模型通过自己的探索,学会找到通往成功的路径。


实际训练中的应用


现代 Coding Agent 背后的模型通常会经历这样的 RL 训练:


  • 在模拟的编程环境中执行任务(创建文件、运行代码、修复 bug)

  • 用测试通过率、代码质量评分等作为奖励信号

  • 学习何时应该读取更多文件来获取上下文,何时应该直接动手修改

  • 学习如何从错误信息中提取有用线索,调整下一步策略


值得注意的是,RL 训练的效果高度依赖奖励信号的设计。如果只奖励「任务完成」,模型可能学会走捷径(Reward Hacking);如果奖励信号太复杂,训练可能不稳定。这也是为什么不同模型在 Agent 任务上的表现差异很大,背后的 RL 训练策略可能完全不同。


对使用者的启示


理解了 RL 的作用,你会更清楚为什么某些使用方式更有效:

  • 提供清晰的成功标准:当你告诉 Agent 「修好这个 bug,运行 npm test 应该全部通过」,你实际上是在给它一个明确的「奖励信号」,这与它训练时的模式一致

  • 允许试错:Agent 在训练中学会了通过尝试来解决问题,给它多次尝试的机会往往比期待一次成功更实际

  • 观察它的决策模式:当 Agent 做出某个决定(比如先读文件而不是直接修改),这往往反映了它在 RL 训练中学到的策略


Coding Agent 的实现原理


理解了 LLM 的本质和限制后,我们来看 Coding Agent 是如何在这些约束下被设计出来的。


LLM API 的核心结构


现代 LLM API 采用基于消息的对话结构。理解这个结构是构建 Agent 的基础。


Messages 数组

API 的核心是一个消息数组,每条消息包含角色(role)和内容(content):


{  "messages": [    {      "role": "system",      "content": "你是一个专业的编程助手..."    },    {      "role": "user",      "content": "帮我写一个快速排序函数"    },    {      "role": "assistant",      "content": "好的,这是一个 Python 实现的快速排序..."    }  ]}


三种角色各有用途:

  • system:设定 Agent 的行为准则、能力范围和工具定义

  • user:用户的输入

  • assistant:模型的回复


Tool Calling 机制

Coding Agent 的核心能力来自工具调用。API 允许你定义工具的 schema,模型会在需要时生成结构化的工具调用请求:


{  "tools": [    {      "name": "read_file",      "description": "读取指定路径的文件内容",      "parameters": {        "type": "object",        "properties": {          "path": {            "type": "string",            "description": "文件路径"          }        },        "required": ["path"]      }    }  ]}


当模型决定调用工具时,它的响应会包含工具调用信息:


{  "role": "assistant",  "content": null,  "tool_calls": [    {      "id": "call_abc123",      "name": "read_file",      "arguments": "{\"path\": \"src/main.py\"}"    }  ]}


工具执行结果作为新消息返回给模型:


{  "role": "tool",  "tool_call_id": "call_abc123",  "content": "def main():\n    print('Hello, World!')\n..."}


Reasoning Content 的保留

对于具有显式推理能力的模型,API 响应中可能包含 reasoning 或 thinking 字段,记录模型的思考过程:


{  "role": "assistant",  "reasoning_content": "用户需要读取文件来理解项目结构。我应该先查看 src 目录下的主要文件...",  "content": "让我先看一下项目的主文件。",  "tool_calls": [...]}


在多轮对话中保留这些推理内容,可以帮助模型维持思维的连贯性。模型可以「回顾」自己之前的思考过程,从而做出更一致的决策。


Prompt Caching:工程实践的关键


由于 LLM 的自回归特性,每次请求都需要重新处理整个上下文。对于动辄几万 token 的 Coding Agent 对话来说,这意味着大量的重复计算和延迟。


Prompt Caching 通过缓存上下文前缀的计算结果来解决这个问题。关键在于:缓存基于前缀匹配。只有当新请求的开头部分与之前的请求完全一致时,才能命中缓存。


这直接影响了 prompt 的组织方式:


┌─────────────────────────────┐│  System Prompt              │  ← 稳定不变,可缓存│  (角色定义、行为准则)         │├─────────────────────────────┤│  Tool Definitions           │  ← 稳定不变,可缓存│  (工具的 schema 定义)        │├─────────────────────────────┤│  Project Context            │  ← 相对稳定,尽量少变│  (项目说明、代码规范)         │├─────────────────────────────┤│  Conversation History       │  ← 动态增长│  (对话历史)                  │├─────────────────────────────┤│  Current User Message       │  ← 每次都变│  (当前用户输入)              │└─────────────────────────────┘


最佳实践参考:

  1. 把稳定内容放在前面:system prompt 和工具定义应该保持稳定,避免频繁修改

  2. 动态内容放在后面:对话历史和当前输入放在最后

  3. 避免在稳定前缀中插入可变内容:比如不要在 system prompt 中插入当前时间戳


Agent Loop:核心循环


语言模型可以回答问题,而 Agent 可以做事情。Agent Loop 正是实现这一差异的关键。


当模型收到一个无法仅凭训练知识完成的请求时,它需要与外部世界交互:读取文件、查询数据库、执行代码。Agent Loop 就是管理这个「推理-行动」循环的编排层,使模型能够处理需要多个步骤、外部信息或产生实际影响的任务。


循环的基本原理


Agent Loop 的运作遵循一个简单的原则:调用模型 → 检查是否需要使用工具 → 如果需要则执行工具 → 将结果返回给模型再次调用 → 重复直到模型产生最终响应。


这个循环的关键在于上下文的累积。每次迭代都会向对话历史中添加新内容。模型不仅能看到原始请求,还能看到它调用过的每个工具以及收到的每个结果。这种累积的上下文使得复杂的多步骤推理成为可能。


一个具体的例子


假设用户请求:「帮我修复项目中的这个 bug:用户登录后会话没有正确保存」。


这不是模型仅凭知识就能完成的任务,它需要通过 Agent Loop 逐步探索:


  • 第一轮:模型收到请求,首先需要了解项目结构。它调用 list_directory 工具查看项目根目录。

  • 第二轮:模型看到了目录结构,识别出 src/auth/ 目录可能与登录相关。它调用 read_file 查看 src/auth/login.js

  • 第三轮:模型看到了登录代码,发现它调用了 sessionManager.save()。为了追踪问题,它调用 read_file 查看 src/session/manager.js。

  • 第四轮:模型发现了问题,save() 方法中有一个异步操作没有被正确 await。它调用 edit_file 工具修复这个 bug。

  • 第五轮:修复完成,模型调用 shell 工具运行测试来验证修复是否有效。

  • 第六轮:测试通过。模型不再请求工具,而是生成最终响应:总结问题原因、修复内容和验证结果。


每一轮都遵循相同的模式:模型接收上下文,决定是继续行动还是给出响应,要么继续循环,要么退出。关键在于,模型基于对任务不断演进的理解自主做出这些决策。


循环的终止条件


每次模型调用都会返回一个停止原因(stop reason),决定接下来发生什么:


  • end_turn:模型完成了响应,没有进一步的行动需要执行。这是正常的成功终止,循环退出并返回最终消息。

  • tool_use:模型想要执行一个或多个工具后再继续。循环执行请求的工具,将结果追加到对话历史,然后再次调用模型。

  • max_tokens:模型的响应因达到 token 限制而被截断。这在当前循环中无法恢复,循环以错误终止。


理解这些终止条件有助于预测 Agent 的行为并处理边界情况。


Coding Agent 的典型工具


一个功能完整的 Coding Agent 通常需要以下几类工具:


文件操作

  • read_file:读取文件内容

  • write_file:创建或覆盖文件

  • edit_file:对文件进行局部编辑(而非完全重写)


代码执行

  • shell terminal:执行命令行命令,用于运行代码、安装依赖、执行测试等


代码搜索

  • grep / search:在代码库中搜索文本或模式

  • semantic_search:基于语义的代码搜索


项目导航

  • list_directory:列出目录内容

  • find_files:根据模式查找文件


这些工具的设计直接影响 Agent 的能力边界,工具的粒度、参数设计、返回格式都需要仔细考量。


常见问题与解决方案


在了解了 LLM 和 Coding Agent 的基本原理后,我们再来看看一些常见的问题就能更好地理解了。


会话间失忆


Coding Agent 面临的一个根本性问题是:它们在会话之间没有持久记忆。


每次启动新会话时,Agent 只知道它能在磁盘上找到的内容。就像电影《记忆碎片》或《初恋 50 次》中的主角一样,Agent 每天醒来都不记得昨天发生了什么。而典型的工程工作流往往需要跨越多个会话才能完成一个功能——因为需要测试、代码审查和后续清理。


这导致了一个荒谬的局面:你需要在每个新会话开始时,重新向 Agent 解释项目背景、当前进度和接下来的计划。


💡 解决方案:


  • 使用结构化的任务追踪系统(如 issue tracker)

  • 在每个会话结束时,让 Agent 生成一个状态摘要,供下次会话使用

  • 将重要决策和发现记录在固定位置,而不是对话历史中


上下文窗口耗尽


每轮循环都会向对话历史添加消息。对于需要多次工具调用的复杂任务,历史记录可能超出模型的上下文窗口。当这种情况发生时,Agent 无法继续。


具体表现包括:模型提供商返回输入长度错误,或随着上下文填满不太相关的早期消息,模型性能明显下降。


目前有两种主流的上下文管理策略:


💡 Observation Masking(观察遮蔽)


这种方法只针对工具返回的观察结果进行处理,而完整保留 Agent 的推理和行动历史。具体做法是:用占位符替换较早轮次的观察内容(比如 「内容已省略」),只保留最近 N 轮的完整输出。


这种方法简单高效,因为典型 Coding Agent 的每轮交互中,工具输出(如文件内容、命令执行结果)往往占据了绝大部分 token。通过遮蔽旧的观察内容,Agent 仍然可以访问自己过去的推理和决策,但不再重复处理早期轮次的冗长文本。


💡 LLM Summarization(LLM 摘要)


这种方法使用另一个 LLM 将较早的交互历史(包括观察、行动和推理)压缩成简短的摘要。摘要会替代原始的详细历史,而最近的几轮对话保持完整。


这种方法理论上可以支持无限长的对话,因为历史会被反复压缩。但它也有代价:每次生成摘要都需要额外的 API 调用,而且摘要可能会丢失某些细节信息。研究发现,摘要有时会掩盖 Agent 应该停止尝试的信号,导致 Agent 运行更多轮次,反而增加了成本。


两种方法各有优劣:Observation Masking 实现简单、成本低,但上下文仍会缓慢增长;LLM Summarization 可以更彻底地压缩历史,但引入了额外开销和信息损失风险。实践中,可以考虑混合使用,以 Observation Masking 作为主要策略,仅在上下文确实过长时触发 LLM Summarization。


其他解决方案:

  • 减少工具输出的冗长程度,返回摘要或相关片段,而非完整数据

  • 简化工具 schema,深度嵌套的结构会在工具配置和模型推理中消耗大量 token

  • 将大型任务分解为子任务,每个子任务使用新的上下文


有效上下文远小于标称值


即使拥有 1M token 的上下文窗口,Coding Agent 实际上只能有效利用其中的 10-15%。超过 20% 后,成本和性能都会急剧恶化。大多数 Agent 会在达到约 20% 时强制中断,而最佳实践是在 15% 之前就重启会话。


这意味着,以全速工作时,你大约只有 5-10 分钟的有效工作时间,然后 Agent 就会「耗尽上下文」,需要重启(相当于死亡)或进行 compaction(相当于记忆清除)。


有一个生动的比喻:上下文窗口就像潜水员的氧气罐。所有人都说「我们给他一个更大的氧气罐:100 万 token!」但他最终还是会耗尽氧气,更大的窗口并不能解决根本问题。


「Dumb Zone」:中间区域的性能退化


研究发现,上下文窗口的中间 40-60% 区域存在一个「Dumb Zone」,在这个区域,模型的召回率下降,推理能力变差。这与前面提到的「Lost in the Middle」现象相呼应。


当 Agent 深入工作时,它会逐渐表现出类似「痴呆」的症状:迷失方向、产生幻觉接口、忘记原始目标。这不是因为模型变笨了,而是因为关键信息被淹没在大量的上下文中,无法被有效利用。


新发现的任务被丢弃


这是 Agentic Coding 中一个容易被忽视但影响巨大的问题:LLM 在工作过程中会注意到各种问题,但在上下文空间紧张时,会选择忽略这些发现,不采取任何行动。


例如,Agent 在修复一个 bug 时,可能会注意到代码中的另一个潜在问题、一个需要重构的地方、或一个缺失的测试用例。但如果当前上下文已经很满,Agent 可能会「假装没看到」,继续专注于手头的任务。这些被发现但被丢弃的工作,就这样悄悄消失了。


💡 解决方案:

  • 使用外部工具让 Agent 随时记录发现的问题

  • 在任务结束时,要求 Agent 列出所有观察到但未处理的问题

  • 建立「发现即记录」的工作流程


过早宣告完成


当 Agent 经历多次 compaction 后,可能会出现一个荒谬的情况:它会自信地宣布「恭喜,任务完成了!让我们开始手动测试吧!」而实际上还有大量的阶段没有完成。


解决方案:

  • 将整体计划保存在上下文之外的固定位置

  • 定期让 Agent 对照原始计划检查进度

  • 使用结构化的任务追踪,而不是依赖 Agent 的记忆


工具选择不当


当模型持续选择错误的工具时,问题通常出在工具描述的模糊性上。从模型的角度审视描述:如果两个工具的描述有重叠,模型就没有选择的依据,我们应该确保每个工具的用途清晰且互不重叠。



通过上述的探讨,我们已经完成了从 LLM 本质到 Agentic Coding 原理的理论铺垫:从逐个预测 token 的底层逻辑,到注意力机制的上下文约束,再到强化学习如何让模型学会「做事」;从 API 结构的基础框架,到 Agent Loop 的核心循环,最后到解决上下文耗尽、会话失忆等工程问题的实践策略。


这些内容共同构成了 Agentic Coding 的第一性原理基石——理解这些,你就能跳出"黑盒工具"的使用层面,看到各种最佳实践背后的深层逻辑。


接下来,我们将从理论走向实操:结合具体案例拆解如何设计高效的 Agent 对话流程、如何选择合适的工具集、如何优化上下文管理策略,以及如何将这些原理应用到实际的编码任务中(如 bug 修复、功能开发、代码重构)。你将看到,当我们用第一性原理的视角重新审视 Agentic Coding 时,那些看似零散的技巧会形成一套系统的方法论,帮助你真正成为 AI 编程助手的「驾驭者」而非「使用者」。


了解了 LLM 的特性、Coding Agent 的实现原理以及常见问题后,我们总结出了一些最佳实践,帮助大家更高效地使用这些工具。


短对话优于长对话


这可能是最重要的一条实践:保持对话简短、专注,每个对话只做一件事。


很多人认为更大的上下文窗口意味着更强的能力,可以把更多任务塞进一个对话里。但实际情况恰恰相反,最好的对话是短对话,它们只做一件事,并且只包含完成这件事所需的上下文。


为什么短对话更好?


当你往上下文里塞太多内容时,Agent 的表现就像喝醉了一样:它会开始犯错、跌跌撞撞、甚至开始和你争论,如果你继续喂它更多 token,它甚至会「吐」得你一身(产生大量无意义的输出)或者进入死循环。


对话越长,上下文窗口里就会积累越多与当前任务不太相关的内容。为了让 Agent 发挥最佳工况,你需要给它完成当前工作所需的上下文。


长对话不仅效果差,还更贵。每次发送消息时,整个上下文都会被发送给模型提供商。这意味着对话越长,新消息的成本就会指数级增长。而且长对话更容易因为消息间隔时间长而错过缓存窗口,导致费用飙升。所以,长对话既效果差,又花费高,尤其在以 tokens 消耗计费的套餐下面。


拆分对话,本质上是拆分任务,大任务应该被分解为小任务。这在 Agent 时代之前就是软件工程的最佳实践,现在看也依然如此,短对话让任务拆分这件事变得自然甚至有趣。就像小任务更容易管理一样,小对话也更容易追踪:每个对话都有明确的目标,你可以轻松掌握整体进度。


以对话为单位组织工作


如果把对话视为任务的基本单位,那么一个功能或 bug 修复就自然变成了一组相互关联的对话。


一个典型的工作流程


假设你要实现一个新功能,可以这样组织对话:


功能:用户登录后的会话管理
[对话 1] 调研现有代码结构    ├── 了解 auth 模块的实现    ├── 查看 session 管理的现状    └── 输出:关键文件列表和当前架构理解
[对话 2] 实现基础功能    ├── 参考对话 1 的发现    ├── 实现核心的 session 保存逻辑    └── 输出:基础实现代码
[对话 3] 添加错误处理    ├── 参考对话 2 的实现    └── 增加边界情况处理
[对话 4] 编写测试    ├── 参考对话 23 的实现    └── 添加单元测试和集成测试
[对话 5] 代码审查    ├── 检查实现是否符合项目规范    └── 确认没有引入安全问题
[对话 6] 清理和重构    └── 根据审查结果进行调整


每个对话都很短,只专注于一件事。它们加在一起,完成了整个功能的开发。


那对话之间如何共享上下文?


当你开始一个新对话时,可以通过以下方式传递必要的上下文:


  • 引用之前对话的结论:在新对话开头简要说明之前的发现或决策

  • 利用 Git 状态:让 Agent 查看 git diff 或检查最近的提交

  • 使用项目文档:将重要决策记录在 AGENTS.md 或类似文件中,Agent 每次都能读取

  • 直接提及相关文件:在新对话中 #mention 需要的文件


关键是:不要试图在一个对话里完成所有事情。每当你发现当前任务已经完成,或者对话开始变得混乱,就应该开始一个新对话。


编写有效的项目配置文件


大多数 Coding Agent 都支持在项目根目录放置配置文件(比如 Rules 或者 Agent.md),这个文件会自动注入到每一个对话,这意味着它是你影响 Agent 行为的杠杆支点,但这把双刃剑也很容易用错。


理解 Agent 的无状态本质


LLM 是无状态函数。它的权重在推理时是冻结的,不会随着使用而学习,Agent 对你代码库的全部了解,完全来自于你放进上下文窗口的 token,这有三个重要含义:


1. 每次新对话开始时,Agent 对你的代码库一无所知

2. 任何重要的项目信息都需要在每次会话中告诉它

3. 项目配置文件是实现这一点的首选方式


因此,你应该把这个文件视为每次会话的入职培训文档。


配置文件应该包含什么


一个好的项目配置文件应该回答三个问题:


  • WHAT(是什么):技术栈、项目结构、各模块的职责。这在 monorepo 中尤其重要,应该告诉 Agent 有哪些应用、哪些共享模块、每个部分是做什么的

  • WHY(为什么):项目的目的、设计决策的背景。为什么选择这个架构?为什么有些代码看起来不合理(比如历史债务)?

  • HOW(怎么做):如何运行项目、如何测试、如何验证改动。用 bun 还是 npm?测试命令是什么?


少即是多


这是最容易犯的错误:试图把所有可能需要的信息都塞进配置文件。


研究表明,前沿的思考模型大约能可靠地遵循 150-200 条指令,而 Coding Agent 的系统提示本身可能已经包含了约 50 条指令。这意味着你的配置文件应该尽可能精简,理想情况下只包含那些对所有任务都普遍适用的内容。


# 不好的做法:塞满各种可能用到的信息## 数据库 Schema 设计规范(500 行详细规范...)
## API 设计指南(300 行规范...)
## 代码风格指南(200 行规范...)
# 好的做法:简洁 + 指向详细文档## 项目概述这是一个 Next.js 电商平台,使用 PostgreSQL + Prisma。
## 关键目录- `apps/web`: 前端应用- `apps/api`: 后端服务- `packages/shared`: 共享类型和工具
## 开发命令- `bun dev`: 启动开发服务器- `bun test`: 运行测试- `bun typecheck`: 类型检查
## 详细文档根据任务需要,查阅以下文档:- 数据库设计:`docs/database-schema.md`- API 规范:`docs/api-guidelines.md`- 代码风格:`docs/code-style.md`


一个经验法则:配置文件应该控制在 300 行以内,越短越好。有些团队的配置文件甚至不到 60 行。


渐进式披露


与其在配置文件中塞满所有信息,不如使用渐进式披露策略:


agent_docs/  ├── building_the_project.md  ├── running_tests.md  ├── code_conventions.md  ├── service_architecture.md  └── database_schema.md


在配置文件中列出这些文档并简要描述,让 Agent 根据当前任务决定读取哪些。这样,只有相关的信息才会进入上下文,避免不必要的干扰。


偏好指针而非副本:不要在文档中复制代码片段——它们很快会过时。使用 file:line 引用指向代码的权威位置。


不要让 Agent 做 Linter 的工作


很多人喜欢在配置文件中写详细的代码风格指南,这不是个好的实践。


LLM 做格式检查既慢又昂贵,更重要的是,这些指南会增加指令数量,降低 Agent 对其他指令的遵循能力。


更好的做法:

  • 使用真正的 linter 和 formatter(如 ESLint、Prettier、Biome)

  • 配置自动修复,让工具处理格式问题

  • 如果 Agent 产生了格式错误,让 linter 在后处理阶段修复它


LLM 是上下文学习者。如果你的代码库遵循一致的风格,Agent 通常会自动模仿这种风格,不需要你明确告诉它。


这是最高杠杆点,要认真对待


一行糟糕的代码就是一行糟糕的代码,一个糟糕的技术方案可能产生很多行糟糕的代码,而配置文件中的一行糟糕的指令会影响每一个会话、每一个任务、每一个产出。

杠杆效应:
配置文件 → 影响每个会话的行为    ↓研究/规划阶段 → 影响实现计划的质量    ↓实现阶段 → 影响最终代码的质量


花时间仔细考虑配置文件的每一行,这是你能做的 ROI 最高的投资之一。


200K Token 足够了


当大家都在追求更大的上下文窗口时,一个反直觉的事实是:200K token 对于大多数任务来说已经绰绰有余了。


关键不在于你有多大的上下文窗口,而在于你如何使用它。一个 200K 的窗口,如果你用短对话的方式工作,可以支持你完成非常复杂的功能。因为虽然每个对话只有几十 K 到上百 K 个 token,但你可以开启 10 个、20 个甚至更多对话,它们加起来的总量远超任何单一上下文窗口。而且,由于每个对话都是从相对干净的状态开始,Agent 的表现会一直保持在最佳水平,而不是随着上下文膨胀而逐渐退化。


实践建议

  • 当对话超过 80K-100K token 时,考虑开始新对话

  • 完成一个独立的子任务后,开始新对话处理下一个任务

  • 如果 Agent 开始表现出「醉酒」症状(重复、遗忘、偏离目标),立即开始新对话

  • 把「开始新对话」视为正常工作流程的一部分,而不是「失败后的重试」


Compounding Engineering:让系统自我改进


传统的 AI 编程是关于短期收益的:你给 prompt,它写代码,然后发布,然后从头开始。Every.to 提出的 Compounding Engineering(复利工程) 则是关于构建具有记忆的系统:每个 PR 都在教育系统,每个 bug 都成为永久的教训,每次代码审查都在更新 Agent 的默认行为。普通 AI 工程让你今天更高效,Compounding Engineering 让你之后的每一天都更高效。


核心理念:你不只是在解决问题,而是在教育系统


当你使用 Coding Agent 时,问自己一个问题:我是在解决今天的问题,还是在教系统?


  • 每次修复 bug 时,如果不能防止同类问题再次发生,就只完成了一半

  • 每次代码审查如果不能提取出可复用的教训,就是浪费时间

  • 每次成功的工作流程如果不能被记录和复用,就会随着会话结束而消失


如何实践 Compounding Engineering


1. 将经验沉淀到项目文档


大多数 Coding Agent 都支持读取项目根目录下的特定文件,这是你指导系统的主要途径:


# AGENTS.md
## 代码风格- 使用 async/await 而非 Promise.then()- 错误处理必须包含具体的错误类型- 变量命名遵循 PR #234 确立的模式
## 已知陷阱- session 模块的 save() 方法是异步的,必须 await- 不要在循环中调用 API,使用批量接口
## 成功模式- 新增 API 端点时,参考 PR #241 的错误处理方式- 测试覆盖率要求参考 PR #219 的反馈


每次你发现一个重复出现的问题或一个有效的解决方案,就把它加入这个文件。Agent 在每次对话开始时都会读取它,自动应用这些经验。


2. 让 bug 修复产生长期价值


当你修复一个 bug 时,不要只是改代码。问自己:


  • 这类问题能否通过添加 lint 规则来预防?

  • 是否应该在 Rules 或者 AGENTS.md 中记录这个陷阱?

  • 能否编写一个测试来防止回归?

  • 代码审查清单是否需要更新?


一个真正的 bug 修复应该让同类问题再也不会发生。


3. 从代码审查中提取模式


每次你在审查中指出问题或提出建议,可以考虑:


  • 这个反馈是否适用于未来的类似代码?

  • 是否应该成为项目的编码规范?

  • Agent 能否在下次自动应用这个改进?


如果答案是肯定的,就把它记录下来。让你的审查意见成为系统的永久知识,而不是一次性的对话。


4. 建立可复用的工作流程


当你找到一个有效的工作模式时,把它进行沉淀:


## 工作流程:添加新的 API endpoint
1. 先编写接口测试(参考 tests/api/example.test.ts)2. 实现端点,遵循 src/api/users.ts 的模式3. 添加错误处理,使用 AppError 类4. 更新 API 文档5. 运行完整测试套件验证


下次你或 Agent 需要做类似的任务时,可以直接说「按照添加新 API endpoint 的工作流程来做」,系统已经知道该怎么做了。


复利效应


Compounding Engineering 的魔力在于累积效应。第一周,你可能只是记录了几条编码规范。第一个月,你有了一套完整的项目知识库。三个月后,Agent 开始自动应用你从未明确告诉它的模式,因为它从之前的 PR、bug 修复和代码审查中学习了这些。


想象一下:你打开一个 PR,发现 Agent 的评论是「根据 PR #234 的模式修改了变量命名,按照 PR #219 的反馈移除了过度测试,添加了与 PR #241 类似的错误处理」。它学会了你的品味,就像一个聪明的同事,而且还有记录可查。这就是复利,每次修复、每次审查、每次教训都在为未来投资。


对人难的事,对 AI 也难


有一个简单但常被忽视的事实:如果一个任务对人类开发者来说很难,那么它对当前的 AI 来说大概率也很难。


这听起来显而易见,但它的推论却很深远:所有那些能提升人类开发者体验的工作,对 AI 同样有价值。更好的文档、更清晰的架构、更快的反馈循环,这些「老生常谈」的工程实践,在 AI 时代不仅没有过时,反而变得更加重要。


为什么 AI 面临和人类相似的挑战?


回想一下 LLM 的工作原理:它通过阅读上下文来理解任务,然后生成响应。这个过程和人类开发者阅读代码、理解需求、编写解决方案的过程惊人地相似。


  • 当文档缺失或过时时,人类需要花大量时间阅读源码猜测意图。AI 也一样,它会在代码库中反复搜索,消耗大量上下文空间,最终可能还是理解错误。

  • 当架构混乱、模块边界不清时,人类很难知道该改哪里。AI 也会迷失,它可能改了错误的文件,或者遗漏了需要同步修改的地方。

  • 当测试运行缓慢时,人类倾向于跳过测试。AI 也面临同样的压力,长时间的等待会消耗对话的「耐心」和上下文空间。


值得投资的开发者体验


既然 AI 和人类面临相似的挑战,那么以下这些传统的「开发者体验」优化就具有了双重价值:


更好的文档


# 好的文档对 AI 的价值
## 之前(无文档)Agent 需要:1. 读取 5-10 个相关文件2. 猜测模块的职责和边界3. 推断 API 的使用方式4. 可能还会猜错
消耗:大量上下文 + 高错误率
## 之后(有文档)Agent 只需要:1. 读取 README 或 API 文档2. 直接了解正确的使用方式
消耗:少量上下文 + 高准确率


好的文档不仅帮助新人上手,也帮助 AI 快速建立正确的心智模型,比如:


  • 架构决策记录(ADR):解释「为什么这样设计」,避免 AI 做出违背设计意图的修改

  • API 使用示例:比纯粹的类型定义更有效

  • 已知陷阱和常见错误:直接告诉 AI 什么不该做


更清晰的代码结构


当你在纠结要不要花时间重构一个混乱的模块时,考虑一下:这个混乱不仅困扰你,也会困扰每一个试图理解它的 AI。


  • 清晰的命名:processUserData() 比 doStuff() 对 AI 的帮助和对人类一样大

  • 单一职责:一个做一件事的函数,比一个做十件事的函数更容易被正确修改

  • 显式依赖:依赖注入比全局变量更容易被 AI 理解和测试


更快的反馈循环


这可能是最容易被低估的一点。Agent Loop 的每一轮都需要等待工具执行完成,如果:

  • 测试套件需要 10 分钟才能跑完 → Agent 要么跳过测试,要么在等待中浪费大量上下文

  • 构建需要 5 分钟 → 每次小改动的验证成本都很高

  • 部署需要 30 分钟 → 几乎不可能让 AI 做端到端的验证


相反,如果你有:

  • 秒级的单元测试 → Agent 可以频繁验证,快速迭代

  • 快速的增量构建 → 改动能立即得到反馈

  • 本地可运行的环境 → 不需要等待远程部署


具体的改进建议


1. 为 AI 优化你的测试


# 不好:运行所有测试需要 10 分钟npm test
# 好:可以只运行相关测试,几秒完成npm test -- --grep "session"npm test -- src/auth/__tests__/


确保 Agent 知道如何运行局部测试,而不是每次都跑完整套件。


2. 提供快速的健康检查


# 创建一个快速验证脚本# scripts/quick-check.sh
#!/bin/bashecho "Type checking..."npm run typecheck
echo "Linting changed files..."npm run lint -- --changed
echo "Running related tests..."npm test -- --related


让 Agent 可以在几秒内验证基本的正确性。


3. 文档放在代码旁边


src/  auth/    README.md          # 这个模块是做什么的    login.ts    login.test.ts    session/      README.md        # session 管理的设计决策      manager.ts


当 AI 浏览目录时,它能立即看到相关文档,而不需要去别的地方找。


4. 让错误信息更有帮助


// 不好thrownew Error("Invalid input");
// 好thrownew Error(  `Invalid session token: expected format 'sess_xxx', got '${token}'. ` +  `See docs/auth.md for token format specification.`);


好的错误信息帮助 AI(和人类)快速定位问题,而不是盲目搜索。


反过来未必成立,有时需要专门为 AI 设计


需要注意的是,反过来的推论并不总是成立:对人来说简单的事,对 AI 未必简单,例如:


  • 人类可以轻松地「看一眼」就理解一个 UI 的布局问题,但 AI 需要解析整个 DOM 结构

  • 人类可以凭直觉判断「这个改动风险很高」,但 AI 缺乏这种隐性知识

  • 人类可以在飞书里随口问一句就获得关键信息,但 AI 只能依赖文档化的知识


更有趣的是,有时候你需要专门为 AI 设计工具和接口,即使这对人类来说可能不是最自然的方式。


LLM 需要专门的信息架构


用户体验领域有一个概念叫「信息架构(Information Architecture)」,它关注的是如何组织和呈现信息,以提供最佳的用户体验,好的信息架构你很少会注意到,但糟糕的信息架构会让你抓狂。当我们观察 Agent 使用现有命令行工具时的困惑和迷失,这强烈表明:我们现有工具的信息架构对 LLM 来说是不够的。


LLM 是在我们现有的 CLI 工具上训练的,所以它们知道如何使用这些工具。但这些工具是为人类设计的,它们的输出格式、错误信息、交互方式都假设用户是人类。我们需要为 Agent 增强这些工具,提供对 LLM 更有用的上下文,甚至调整输出格式以便 Agent 更好地消费。


API 设计:在信息量和上下文消耗之间取得平衡


当你为 Agent 设计工具接口(比如 MCP 工具)时,需要在两个目标之间取得平衡:


  • 提供足够的信息:减少 Agent 需要的工具调用次数

  • 避免填满上下文:不要返回过多无关信息


一个好的实践是:提供便捷函数和底层函数两套 API,并通过工具描述引导 Agent 优先使用便捷函数。


@jsonrpcdef get_global_variable_at(address: str) -> dict:    """    Get the value of a global variable at the specified address.    Automatically identifies the type and returns the best string    representation.        This is the preferred method for reading global variables.    """    # 智能的、高层的实现    ...
@jsonrpcdef data_read_byte(address: str) -> int:    """    Read the 1 byte value at the specified address.        Only use this function if `get_global_variable_at` failed.    """    # 底层的、更通用的实现    ...


通过在 docstring 中明确指出「只有在 get_global_variable_at 失败时才使用这个函数」,你可以引导 Agent 优先使用更智能的 API,减少不必要的工具调用。


为 AI 设计友好的命令行输出


如果你观察 Agent 的工作方式,会发现它经常使用类似 head -n100 的方式来限制输出。这看起来是在节省 token,但实际上引入了新问题:Agent 不知道还剩多少行没看到,如果需要完整信息就必须重新运行命令,而重新构建项目是非常耗时的。


一个更好的设计是:让工具主动告诉 Agent 还有多少内容被截断了,甚至缓存输出以便后续获取。


另一个常见问题是 Agent 在错误的目录中执行命令,它会反复尝试,在不同目录之间跳来跳去,浪费大量 token。一个简单的 shell hook 可以帮助它快速定位:


# 在 .zshrc 中添加command_not_found_handler() {   echo "zsh: command not found: '$1'"   echo "zsh: current directory is $PWD"   return127}


现在当命令失败时,Agent 能立即知道自己在哪个目录:


$ npm run buildzsh: command not found: 'npm'zsh: current directory is /Users/ryanzsh: Perhaps you meant to run: cd project_directory; npm run build


很多命令行工具都提供了 --json 或 --porcelain 选项,在给 Agent 使用的工具中优先使用这些格式——人类喜欢格式化的输出,但 AI 更擅长解析结构化数据。


用工程约束来「驯服」Agent


Agent 有时会试图走捷径,绕过你设定的规则。与其在 prompt 中反复强调「不要跳过测试」,不如用工程手段来强制执行。


借助 linters、formatters 和 git hooks


让 Agent 频繁提交代码是个好习惯(在Rules 或者 Agent.md 中告诉它),但它往往会忽视「确保构建不失败」和「修复失败的测试」这样的指令。一个 .git/hooks/pre-commit 脚本可以强制执行项目标准:


#!/bin/bash# .git/hooks/pre-commit
echo "Running type check..."npm run typecheck || exit1
echo "Running linter..."npm run lint || exit1
echo "Running tests..."npm test || exit1
echo "All checks passed!"


这样,无论 Agent 多么想跳过验证,它都必须通过所有检查才能提交。


拦截 Agent 的「偷懒」行为


Agent 有时很「聪明」,当它发现测试一直失败时,可能会进入这样的循环:


1. 修改代码

2. 构建:通过

3. 运行测试:失败

4. 尝试修复测试

5. 修复失败

6. 说「这个测试之前就是失败的,我用 --no-verify 提交」


然后它就绕过了所有检查!(RL 训练中的 Reword Hacking)


解决方案是用一个 git 命令 wrapper 脚本拦截这种行为:


$ git commit --no-verify------------------------------------------------------------------❌ ERROR: Commit Rejected.------------------------------------------------------------------
🤖 GUIDANCE FOR THE AI AGENT:You have attempted to bypass the required pre-commit verification.All code must pass quality checks before it can be committed.
DO NOT BYPASS THE CHECKS. YOU MUST FIX THE UNDERLYING ERRORS.
The pre-commit hook is likely failing. Diagnose and fix the issues.After all commands complete successfully, attempt the commit again*without* the '--no-verify' flag.


这个技巧的本质是:把对 Agent 的指导嵌入到工具的输出中,Agent 会读取命令执行的结果,所以错误信息本身就是最好的 prompt 注入点。


每当 Agent 发明新的「偷懒」方式,你就需要堵上这个漏洞。但总体来说,工程约束比 prompt 指令更可靠。


显式优于隐式

// 对人友好,对 AI 可能困难(隐含状态)client.connect()client.authenticate(user, password)client.query("SELECT * FROM users")
// 对 AI 更友好(显式、无状态)const result = await db.query({  connection: { host, port },  auth: { user, password },  sql"SELECT * FROM users"})


有状态的 API 需要 AI 理解和跟踪隐含的状态变化,而无状态的、显式的 API 更容易被正确使用。


结构化的错误信息


# 对人足够,对 AI 可能困惑Error: Something went wrong. Please try again later.
# 对 AI 更友好Error [AUTH_TOKEN_EXPIRED]: Token expired at 2024-01-15T10:30:00Z. Call refreshToken() to obtain a new token. See: docs/auth.md#token-refresh


人类可以通过上下文推断「something went wrong」是什么意思,但 AI 需要明确的错误代码、原因和解决方案。


AI 眼中的「合理」可能和人类不同


这是一个更微妙的发现:AI 认为合理的代码结构和命名,可能和人类的直觉不一致。


Amp 团队分享过一个有意思的案例:他们让 AI 构建了一个 TUI 框架,过程中开发者一开始会干预 AI 的决策。比如,AI 给一个交换屏幕缓冲区的函数命名为 present(),开发者觉得这个名字不够直观,改成了 swapScreens()


但随后他们发现了问题:Agent 在后续工作中反复尝试寻找一个叫 present() 的函数,找不到后报告「让我尝试其他方法」,最终才找到 swapScreens()。这浪费了 token,也浪费了时间。


为什么会这样?因为 Agent 的命名「直觉」来自训练数据的统计概率。present() 是 Flutter 等框架中双缓冲交换的常见命名,对于 Agent 来说是「最可能」的名字。当开发者用自己的命名覆盖它时,实际上是在对抗 Agent 的统计直觉。Agent 不能再问「过去的我会怎么命名这个」并从权重中找到答案——它必须记住人类的特殊习惯。


后来,开发者决定放手让 Agent 自己决定命名和代码结构。结果呢?Agent 在这个代码库上的工作效率大幅提升。


最终的代码可能看起来有些「奇怪」:

  • 比代码库其他地方更多的 OOP 模式和类

  • 开发者不会选择的命名约定

  • 不太常见的泛型用法

  • 文件布局和人类习惯不同


但 Agent 在这个自己构建的框架中如鱼得水:它知道如何添加滚动条,知道动画系统如何工作,知道键盘快捷键的处理方式——尽管这个框架没有任何文档,甚至无法完整放入一个上下文窗口。


这是一个「由 Agent 构建、为 Agent 优化」的代码库。在这里,东西放在 Agent 的「直觉」认为它们应该在的地方,命名符合 Agent 的统计预期,语法和概念在「统计上最可能」和「实际能编译」之间取得平衡。


启示与权衡


这给我们的启示是:


  • 不要过度干预:如果你频繁地因为「我觉得这个名字更好」而覆盖 Agent 的决策,可能反而在降低效率

  • 注意「找不到」的信号:如果 Agent 反复在某个地方「找不到」东西,考虑是否是你的命名和它的预期不一致

  • 拥抱常见模式:使用广泛使用的设计模式和命名约定,AI 的训练数据中更可能包含这些

  • 模块级的风格隔离:在某些由 Agent 主导开发的模块中,可以考虑让 Agent 保持它自己的风格


当然,这需要权衡。人类仍然需要阅读和维护代码,完全「AI 风格」的代码可能会让人类开发者困惑。一个务实的做法是:


1. 把「只存在于人脑中」的知识显式化:写下来,放进文档

2. 在 Agent 主导的模块中,给 Agent 更多自主权

3. 在人类频繁维护的核心模块中,保持人类友好的风格

4. 在工具接口上,提供 AI 友好的选项(如 --json 输出)


投资回报是双倍的


当你投资于更好的文档、更清晰的架构、更快的测试时,你获得的回报是双倍的:


1. 人类开发者(包括未来的你)会更高效

2. AI 助手也会更高效


这些投资不会因为 AI 的进步而贬值。相反,随着你越来越多地依赖 AI 来完成任务,这些基础设施的价值只会越来越高。


所以,下次当你犹豫要不要花时间写文档、重构代码、优化测试速度时,记住:你不只是在帮助人类,你也在帮助 AI。而在这个 AI 辅助编程越来越普遍的时代,这是一笔非常划算的投资。


刻意练习:像学乐器一样学习 AI


为什么有些人说「AI 对我不起作用」,而另一些人却能用 AI 完成大量的工作?


这个问题需要区分来看,如果你只在公司的大型私有代码库中使用过 AI,你的体验可能确实不好,那些代码库可能有古老的架构和专有模式,AI 的训练数据中根本没有这些,这是完全可以理解的。但问题是:你有没有在个人项目中尝试过 AI?你有没有进行刻意的、有意识的练习?


AI 就像一件乐器


以吉他为例,每个人都知道吉他是什么,也都知道如果投入刻意练习,就能变得擅长,但这需要时间、努力和实验。


AI 工具也是一样。那些从 AI 中获益最多的人,都投入了刻意练习。他们不会因为一次失败就下结论说「它给了我完全错误的答案」,然后假设这将是他们的常态体验。


他们会玩/Hack


AI 工具也有这种潜力,它们的「正确用法」还在被发现中,那些愿意实验、愿意失败、愿意从失败中学习的人,会找到别人看不到的可能性。


如何进行刻意练习


1. 创造一个干净的实验环境


不要只在工作的复杂代码库中评估 AI 的能力,启动一个个人项目,一个没有历史包袱的新项目。在这里,AI 可以展示它真正的能力,你也可以专注于学习如何与它协作。


2. 从失败中提取教训


当 AI 给出错误的结果时,不要只是说「它不行」然后放弃。问自己:


  • 我的 prompt 是否足够清晰?

  • 我是否提供了足够的上下文?

  • 我是否在一个对话里塞了太多任务?

  • 这个错误是否揭示了 AI 的某个系统性弱点?


每次失败都是一次学习机会。把它记录下来,下次避免同样的陷阱。


3. 观察和模仿高手的实践


关注那些公开分享 AI 工作流程的开发者,观看他们的演示,阅读他们的文章,尝试复制他们的技巧。很多时候,差距不在于 AI 工具本身,而在于如何使用它。


4. 建立肌肉记忆


就像弹吉他需要建立手指的肌肉记忆一样,高效使用 AI 也需要建立某种「肌肉记忆」:


  • 什么时候应该开始新对话?

  • 如何组织一个复杂任务的 prompt?

  • 遇到某类问题时,哪种工具组合最有效?


这些直觉只能通过大量练习获得。没有捷径。


5. 投入时间


最关键的是:你需要投入真正的时间。不是偶尔试一试,而是持续地、有意识地练习。就像学习任何乐器一样,每天练习 30 分钟,坚持几个月,效果会远超每周练习一次几个小时。


总结


AI 正在以惊人的速度发展。本文讨论的许多「限制」和「问题」:上下文窗口的约束、会话间的失忆、中间区域的性能退化等等,这些很可能在未来几年内被大幅改善甚至解决。每隔几个月,我们就会看到新的突破:更长的有效上下文、更好的长程推理、更可靠的工具使用。


但这并不意味着我们应该等待这一天的到来。恰恰相反,正是这个充满限制的阶段,给了我们工程师极大的探索和成长空间。那些现在就开始深入理解 LLM 工作原理、积极实践最佳方法、在限制中寻找创造性解决方案的人,将在 AI 能力进一步释放时获得最大的杠杆效应。


这是一个转型的窗口期。通过刻意练习,我们不仅能提升当下的生产力,更重要的是在构建自己的核心竞争力——理解这些工具的本质,知道何时信任它们、何时质疑它们,以及如何让它们发挥最大价值。


从第一性原理理解 LLM 的本质,理解它们如何「思考」、如何受到上下文的限制、如何在 Agent Loop 中发挥作用,这些知识不会随着具体工具的迭代而过时。


无论你使用的是哪个 Coding Agent,无论模型如何更新换代,这些基础原理都将帮助你更好地与 AI 协作。短对话优于长对话、刻意管理上下文、将经验沉淀为可复用的知识、为 AI 友好的工作环境投资,这些实践同样具有持久的价值。


AI 编程的未来会是什么样子,没有人能确切知道。但有一点是确定的:那些现在就开始认真学习、积极实践、深入理解的人,将最有能力塑造和适应这个未来。


去实验,去失败,去学习。像学习乐器一样学习 AI。


这个过程本身,就是价值所在。


53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询