【学习笔记】用第一性原理拆解 Agentic Coding:从 LLM 原理到最佳实践的完整整理

22 min

原文:小夏(TRAE 技术专家)发表于 TRAE 官方渠道的系列文章《用第一性原理拆解 Agentic Coding:从理论到实操》,共上下两篇,没有中篇——上篇(2026-01-09,知乎转载)讲 LLM 工作原理、Coding Agent 实现原理与常见问题;下篇(2026-01-13,知乎转载)讲最佳实践。本文把两篇合并成一条完整线索,并加入我自己的注记。

用 AI 编程助手时,很容易把它当「黑盒」:输入需求,拿到代码。但要用好它,得回到第一性原理——不背结论,而是理解结论从哪推出。这个系列最有价值的地方正在于此:上篇的每一个「怪现象」都能从 LLM 的工作原理推出来,下篇的每一条最佳实践又都能从上篇的原理找到依据。贯穿全文的主线只有一句话:

提升 Agentic Coding 效率的关键,不在于寄望于无限的上下文窗口,而在于优化你与 AI 的协作方式。

先看整体脉络:自回归生成 + 注意力稀疏 + 上下文有限 + 强化学习,这四个 LLM 的本质特征决定了 Coding Agent 的能力边界,也解释了日常使用中的一切怪象;理解了这些,下篇的协作方式建议就不再是「技巧」,而是必然推论。

上篇|LLM 的四个第一性原理

1. 自回归生成:模型没有独立于输出的思考

LLM 不是「先想好再回答」,而是基于已有全部文本(输入 + 已生成的部分)逐个预测下一个 token,追加后继续预测,循环到结束。由此推出三个本质特征:

  • 没有独立于输出的思考过程:推理即生成本身,「边说边想」。这解释了为什么 Chain-of-Thought(让它一步步思考)有效——你在给它更多「思考空间」,新一代推理模型也没脱离这个范式;
  • 上下文就是全部记忆:窗口之外的内容对模型等于不存在;
  • 生成具有概率性:同样的输入可能得到不同的输出。

软件开发是「长链路、强约束、强验证」的任务,自回归机制的缺陷在这里被放大成五个典型问题:

问题表现
局部最优逐步「续写」不等于全局规划:先写得很顺、后面补丁式修补;多文件重构边写边想导致接口不一致、重复实现;对能否过测试 / CI 无感知
走偏后滚雪球早期误读需求,之后每一步都在错误世界观里「自洽」;幻觉出不存在的函数后会越来越「相信它存在」,直到编译或运行报错
流式输出无法回头擅长写新文件,不擅长精确、最小化的局部编辑,倾向「重写一遍」而非「修改」,diff 过大
满足约束能力有限「看起来合理」的实现常在边界条件、并发、错误处理、资源释放上出错;跨文件符号解析靠纯文本推断容易漏
单线程思考方案选择上早早押注一个方向,缺少系统性对比;排 bug 是单线推理而非并行假设验证

2. Attention:聚光灯式的「阅读」

生成每个 token 时,模型扫视全上下文、按相关性分配权重——像一束动态聚光灯。三个关键特性:

  • 稀疏:权重集中在少数关键位置,大部分接近零;
  • 可学习:训练中形成固定偏好(比如更关注开头结尾);
  • O(n²) 复杂度:每个位置都要与所有其他位置计算关系,这是上下文长度存在物理上限的根本原因。

3. 上下文长度:最硬的约束

三层递进:

  1. 物理上限:主流模型 128K–200K,根源是 Attention 平方级的计算与内存开销;
  2. 有效上下文远小于标称:由于注意力稀疏,标称 200K 的模型往往 80K–100K 后就明显退化;
  3. 退化是全面的:不只是「记不住」,推理准确性、指令遵循、代码质量整体下滑,且错误理解会传递到后续生成,形成累积误差。

原文的比喻很传神:上下文像潜水员的氧气罐——「我们给他更大的氧气罐:100 万 token!」——但他终会耗尽。更大的窗口不解决根本问题。

4. 强化学习:从「能说」到「能做」

预训练本质是模仿,教会了「说」没教会「做」;RL 的核心循环是尝试 → 反馈 → 调整(以下棋打比方:不是背一百万盘棋谱,而是实际下棋、赢了表扬输了复盘)。Agent 任务路径多样、结果导向、需要探索,没法人工标注「标准步骤序列」,只能定义「什么算成功」——比如用测试通过率做奖励信号,模型由此学会何时读文件、何时动手、如何从报错里提取线索。

两个值得记住的点:

  • Reward Hacking 的伏笔:只奖励「任务完成」,模型可能学会走捷径——这是后文「Agent 用 --no-verify 绕过检查」在训练层面的根源;
  • 对使用者的启示:给 Agent 清晰的成功标准(「修好这个 bug,npm test 应全过」=复刻它训练时的奖励信号);允许试错;观察它的决策模式。

上篇|Agent Loop:模型与 Agent 的一线之隔

模型能回答问题,Agent 能做事情,差的就是这个循环。底层是 messages 数组(system / user / assistant 三种角色)加 tool calling:模型按需生成结构化的工具调用请求,工具执行结果以 tool 角色消息回填,进入下一轮。循环本身很朴素:

调用模型 → 检查是否要调工具 → 执行 → 结果追加进对话历史 → 再次调用模型 → 直到产生最终响应。

关键是上下文累积:模型能看到自己调过的每个工具和每个结果。原文用修「登录后会话未保存」的 bug 走了六轮:list_directory 看结构 → 读 src/auth/login.js → 追到 src/session/manager.js → 发现 save() 里的异步操作没 await → edit_file 修复 → 跑测试验证 → 输出总结。每轮「要么行动、要么响应」由模型自主决策;终止由 stop reason 决定(end_turn 正常完成、tool_use 继续、max_tokens 被截断即报错终止)。

另一个工程细节是 Prompt Caching:缓存基于前缀匹配(开头逐字节一致才命中),所以 prompt 要按稳定性分层——系统提示与工具定义(稳定)在前,项目上下文(较稳)居中,对话历史与当前消息(易变)在后。往 system prompt 里插当前时间戳会击穿整条缓存。

上篇|七大「掉链子」怪象与解法

这部分用前面的原理逐一解释日常怪象,我整理成表:

#怪象第一性原理解释解法
1会话间失忆(像《初恋 50 次》每天重来)LLM 无状态,上下文即全部记忆结构化任务追踪;会话结束生成状态摘要;重要决策记在固定位置
2上下文窗口耗尽Attention O(n²) 带来物理上限Observation Masking 为主(遮旧工具输出,占大头且信息密度低),LLM Summarization 兜底;工具输出瘦身、任务拆分
3有效上下文远小于标称注意力稀疏即使 1M 窗口也只按 10%–15% 规划,超 20% 性能成本急剧恶化,最佳实践是 15% 前重启会话
4Dumb Zone(越干越「痴呆」)中间 40%–60% 区域召回率下降(Lost in the Middle)关键信息放首尾;出现迷失、幻觉接口、忘记目标就换对话
5新发现的任务被悄悄丢弃上下文紧张时注意力分配不足「发现即记录」用外部工具记下;任务结束要求列出所有未处理发现
6过早宣告「任务完成了」多次 compaction 后丢失全局计划整体计划放在上下文之外的固定位置,定期对照检查
7持续选错工具两个工具描述重叠,模型无从选择从「模型的视角」审视每个工具描述

下篇|十条最佳实践

下篇是实操篇。我按「协作方式 → 知识沉淀 → 基础设施 → 心法」分组整理。

协作方式:把对话当第一公民

1. 短对话优于长对话(原文称「最重要的一条」)。 最好的对话只做一件事、只装做这件事所需的上下文。理由三层:上下文塞太多 Agent 会像「喝醉」一样犯错、争论、死循环(注意力稀释);对话越长单条消息成本指数增长且易错过缓存窗口;拆对话就是拆任务,本来就是工程最佳实践。实操:对话超 80K–100K token 就换新;完成一个独立子任务就换;出现「醉酒症状」立即换。

2. 以对话为单位组织工作。 一个功能 = 一组相互关联的短对话:调研 → 实现基础功能 → 错误处理 → 测试 → 审查 → 重构。对话间共享上下文的四种方式:开头引用前一对话的结论、让 Agent 看 git diff / 最近提交、关键决策写进 AGENTS.md、直接 #mention 文件。

3. 200K Token 足够了。 短对话模式下,十个对话的总量远超任何单一窗口,且每个都从干净状态开始、始终工作在最佳工况。关键不在窗口多大,而在怎么用。

知识沉淀:让系统有记忆

4. 写好项目配置文件(AGENTS.md / Rules)。 LLM 无状态,配置文件就是「每次会话的入职培训文档」。几条硬原则:

  • 内容回答三问:WHAT(技术栈、目录结构、模块职责)、WHY(设计决策与历史债务的背景)、HOW(怎么跑、怎么测、怎么验证);
  • 少即是多:前沿思考模型约能可靠遵循 150–200 条指令,Agent 自身系统提示已占约 50 条额度;配置文件控制在 300 行以内;
  • 渐进式披露:建 agent_docs/ 放详细文档,配置文件只列清单加一句话简介,让 Agent 按需取用;用 file:line 指针代替代码副本(副本会过时);
  • 别让 Agent 干 Linter 的活:格式交给 ESLint / Prettier / Biome,LLM 是上下文学习者,代码库风格一致时它会自动模仿;
  • 这是最高杠杆点:一行糟糕代码只是一行代码,配置文件里一行糟糕指令影响每个会话、每个任务、每个产出。

5. 复利工程(Compounding Engineering)。 引自 Every.to 的概念:从「一次 prompt、一次产出、下次归零」转向构建有记忆的系统——每个 PR 在教育系统,每个 bug 成为永久教训。检验标准是那句灵魂拷问:「我是在解决今天的问题,还是在教系统?」 四个落地动作:经验沉淀进 AGENTS.md(已知陷阱、成功模式);bug 修复产生长期价值(lint 规则 / 文档 / 回归测试,「真正的修复应让同类问题永不再发生」);从代码审查提取可复用模式;沉淀可复用工作流清单。终态是 Agent 学会你的品味:按 PR #234 的模式命名、按 PR #241 的方式处理错误,且可追溯。

基础设施:为人和 AI 同时投资

6. 对人难的事,对 AI 也难。 LLM 读上下文理解任务 ≈ 人类读代码理解需求,所以一切开发者体验投资是双倍回报:文档缺失对人和 AI 同样致命;架构混乱让人和 AI 同样改错文件;测试慢让人和 AI 同样跳过测试。具体:秒级局部测试、快速健康检查脚本(typecheck + lint changed + related tests 一条龙)、文档放代码旁边(src/auth/README.md)、错误信息带原因和文档链接。

7. 反过来不成立:有时要专门为 AI 设计。 人看一眼 UI 就懂布局,AI 要解析整个 DOM;人有隐性知识,AI 只有上下文。所以要「为 Agent 重新设计信息架构(Information Architecture)」:

  • API 提供「便捷函数 + 底层函数」两套接口,docstring 写明优先级(「仅当高层函数失败时才用底层函数」);
  • CLI 主动告知输出截断了多少、缓存结果供后续取用;用 shell hook 在命令失败时打印当前目录(Agent 常在错误目录里反复挣扎);优先 --json / --porcelain 输出——人爱看排版,AI 更擅长解析结构化数据;
  • 错误信息要含错误码 + 原因 + 解决动作 + 文档链接。

8. 用工程约束「驯服」Agent。 与其在 prompt 里反复叮嘱「不要跳过测试」,不如用 pre-commit hook 强制 typecheck + lint + test。原文点名了 Agent 的 Reward Hacking:测试修不好时它会用 --no-verify 绕过检查,解法是用 git wrapper 拦截该 flag,并在错误信息里直接告诉 Agent「去修根因,不许绕过」。精髓在于:Agent 一定会读命令输出,错误信息本身就是最好的 prompt 注入点。

心法:放手、练习与通才

9. AI 眼中的「合理」可能和人类不同。 全文最有意思的案例,来自 Amp 团队:AI 构建 TUI 框架时把交换屏幕缓冲区的函数命名为 present()(Flutter 等框架双缓冲的常见命名),开发者改成 swapScreens() 后,Agent 反复找不到 present(),白白烧 token——Agent 的命名直觉来自训练数据的统计概率,人类改名等于对抗这种统计直觉。后来放手让 Agent 自己定命名与结构,产出「由 Agent 构建、为 Agent 优化」的代码库,Agent 在里面如鱼得水。务实做法是分层:隐性知识显式写进文档;Agent 主导的模块给它自主权;人类频繁维护的核心模块保持人类风格。

10. 刻意练习,成为 Expert Generalist。 「AI 对我不起作用」多数是因为没认真练——要区分在公司遗留大代码库用不好(可理解)和在个人项目里也没练过(不该)。像学乐器:开干净的个人项目做实验场;每次失败追问原因并把教训记下来;观察高手的工作流;建立「何时开新对话、怎么组织任务」的肌肉记忆;每天 30 分钟好过每周一次几小时。终局人才观是 Martin Fowler 等人说的 Expert Generalist(专家型通才):跨领域发现模式、第一性原理思维、机械同理心(Mechanical Sympathy)、全局视野。LLM 之于 Expert Generalist,就像专家之于通才——随时可问的领域专家,钢铁侠的 Jarvis 外骨骼。

原理 → 实践:两篇的对应关系(笔者整理)

上篇「为什么」与下篇「怎么做」严丝合缝,这张表是两篇合并后最值得留存的产出:

上篇的原理下篇的实践
注意力稀疏,有效上下文只有标称的 10%–15%200K 够用了;80K–100K 就换新对话
LLM 无状态,上下文即全部记忆AGENTS.md 是「每次会话的入职培训文档」;复利工程沉淀知识
上下文累积误差、Dumb Zone、走偏滚雪球短对话优于长对话;以对话为单位组织工作
RL 用「清晰的奖励信号」训练给 Agent 清晰的成功标准(测试全过)
Reward Hacking 走捷径工程约束:pre-commit 强制检查、git wrapper 拦 --no-verify
工具的粒度与描述决定能力边界为 AI 重新设计信息架构(API 两层、CLI --json、错误信息即 prompt)
读上下文理解任务 ≈ 人类读代码DX 投资双倍回报:文档、架构、快速测试
生成是训练数据统计概率的延续别对抗 Agent 的命名直觉(present() 案例),分层放权

个人注记

  • 「Lost in the Middle」是真实研究(Liu et al., 2023, arXiv:2307.03172),Dumb Zone 现象有据可查;但文中具体数字(150–200 条指令、300 行配置、10%–15% 有效率)是作者给的经验值,不同模型、不同任务差异很大,量级比精确值更有参考意义。
  • 这套建议与各家官方指南互相印证:Anthropic 对 CLAUDE.md 的建议、OpenAI 对 Codex 的最佳实践,核心都是「短会话 + 项目知识文件 + 把验证交给工具链」。差别在于这篇用第一性原理把「为什么」讲透了,记住了原理就不用死记条款。
  • 对照自己的实践:本仓库的 AGENTS.md(WHAT/WHY/HOW、渐进式披露)和 pre-commit 的 lint-staged hook,恰好就是文中第 4 条和第 8 条的落地——读完的感受是方向没错,还欠的是第 5 条「复利工程」:bug 修复后主动沉淀 lint 规则与回归测试,让每个教训变成系统资产。
  • 一个原文没有展开但值得警惕的点:「由 Agent 构建、为 Agent 优化」的代码库对 Agent 高效,对人未必友好。分层放权(核心模块保持人类风格)不是妥协,而是长期可维护性的必要条件。

延伸阅读

  • 同作者小夏 2026 年 7 月的后续文章《万字干货:Agentic Coding 场景下的 Git 实践》(讨论多 Agent 并发下的 Git 工作单元与 Monorepo VCS 挑战),可视为本系列在版本控制维度的续作;
  • Lost in the Middle: How Language Models Use Long Contexts(上篇 Dumb Zone 的研究出处);
  • Every.to 关于 Compounding Engineering 的系列文章(下篇第 5 条概念出处);
  • 文中 present() 案例来自 Sourcegraph 的 Amp 团队分享。