_AI Engineer_利用 Harness Engineering 解决复杂问题_BV1EyQ9BCEwC_笔记
问题背景:AI 编码的现实困境
斯坦福大学针对 100,000 名开发者的调研(涵盖各种规模公司)显示,当前 AI 编程工具在软件工程中存在显著的返工(Rework)和代码变动(Code Churn)问题:
- 遗留代码库(Brownfield Codebase):在 10 年以上历史的代码库中,AI 往往降低开发效率,产生大量需反复修改的"垃圾代码(Slop)"
- 新项目(Greenfield):如 Vercel Dashboard 等小型新项目表现良好
- 核心矛盾:AI 生成的代码量增加了,但大部分是上周已发布代码的返工修改
团队实践数据:通过系统化的上下文工程方法,在 30 万行 Rust 代码库中实现了 2-3 倍吞吐量提升,且保持了代码质量(无垃圾代码)。
核心概念:智能区与迟钝区(Smart Zone vs. Dumb Zone)
LLM(大语言模型)虽是非确定性的,但本质上是无状态(Stateless)的。唯一影响输出质量的因素是输入的上下文(Context Window)。
上下文窗口效能曲线
以 claude-code 为例(约 168,000 tokens,部分保留给输出和压缩):
| 区域 | 占比 | 状态 | 表现 |
|---|---|---|---|
| Smart Zone(智能区) | 0-40% | 高效 | 准确的工具调用、逻辑推理 |
| Dumb Zone(迟钝区) | >40% | 低效 | 产生错误、重复犯错、无法有效利用工具 |
关键阈值:当上下文使用超过 40% 时,开始出现收益递减(Diminishing Returns)。如果加载过多 MCP(Model Context Protocol)工具导致上下文膨胀,所有工作都将在迟钝区完成,无法获得好结果。
轨迹(Trajectory)的重要性:LLM 会根据对话历史预测下一步。如果历史记录是"犯错→被纠正→再犯错→再被纠正",模型会倾向于继续犯错以符合对话模式。因此需要主动管理对话轨迹,避免负面循环。
关键技术:有意压缩(Intentional Compaction)
什么是压缩(Compaction)
将当前上下文窗口中的信息提炼为结构化的 markdown 文件,包含:
- 关键文件路径和行号
- 代码流程理解
- 已完成的编辑记录
- 测试和构建输出摘要
操作步骤:
- 在对话进行中(无论是否偏离轨道),要求 AI 将当前理解压缩为
context.md - 人工审查并标记该文件
- 开启新对话窗口,将压缩文件作为初始上下文输入
- AI 可直接基于精炼信息工作,无需重新搜索和理解代码库
压缩内容优先级
应保留:
- 确切相关的文件和行号
- 问题核心逻辑
应剔除:
- 文件搜索过程
- 完整的文件内容(仅保留相关片段)
- MCP 工具输出的原始 JSON 和 UUID 数据
实战工作流:Research → Plan → Implement
通过"频繁有意压缩(Frequent Intentional Compaction)"策略,始终保持上下文在智能区内。
阶段一:Research(研究)
目标:客观理解系统运作方式,定位关键文件,保持价值中立。
具体操作:
- 使用专门的 Research Prompt(开源可用)引导 AI 探索代码库
- 限制 AI 仅进行读取和分析,禁止修改
- 输出结构化报告,包含:
- 相关文件路径
- 代码依赖关系
- 关键函数/类定义位置
压缩点:完成研究后,立即将研究结果压缩为精炼文档,丢弃探索过程中的中间文件和错误路径记录。
阶段二:Plan(规划)
目标:制定精确实施步骤,包含文件名和代码片段。
核心要求:
- 列出确切的文件路径和行号
- 包含代码片段(Line Snippets)而非完整文件
- 明确每步修改后的验证方法(测试命令、预期输出)
- 定义回滚策略
Plan 文档结构示例:
## 任务:重构 X 模块
### 步骤 1:修改数据层
- 文件:`src/db/connection.rs:45-67`
- 当前代码:
```rust
fn connect() -> Result<Conn> { ... }- 修改为:
async fn connect() -> Result<Conn> { ... } - 验证:
cargo test db::tests::connection_test
步骤 2:更新业务逻辑层
...
**关键原则**:计划应详细到"即使最笨的模型也能正确执行"。
### 阶段三:Implement(实施)
**执行策略**:
- 基于 Plan 文档逐步执行,每步验证
- 保持上下文极小化(仅保留当前步骤相关代码)
- 每完成一个逻辑单元立即压缩上下文,开启新会话处理下一步
**命令示例**:
```bash
# 执行单步修改后验证
cargo test specific_module::test_name进阶策略:子代理(Subagents)
目的:子代理不是用于拟人化角色(如"前端专家"),而是用于控制上下文。
工作流程:
- 父代理遇到需要深入代码库搜索的任务
- 启动子代理(新上下文窗口),赋予特定搜索任务:
- 输入:"查找用户认证流程的实现"
- 子代理执行:读取多文件、理解依赖、搜索符号
- 子代理返回极精简的结果:
- 输出:"认证逻辑在
src/auth.rs:120-150,入口函数为validate_token()"
- 输出:"认证逻辑在
- 父代理仅读取该特定文件片段,保持自身上下文清洁
优势:避免父代理的上下文被文件搜索过程污染,始终维持在 Smart Zone。
实战案例与数据
成功案例:Boundary ML(30 万行 Rust 代码库)
背景:为 Boundray ML 的编程语言实现功能,代码库规模 30 万行 Rust。
过程:
- 使用 Research-Plan-Implement 工作流
- 对比实验:无研究直接规划 vs. 有研究规划
- 结果:生成的 PR 被 CTO 直接认可,认为"看起来很好,可合并"
效能数据:
- 后续 7 小时配对编程会话
- 产出:35,000 行代码(含代码生成和测试金文件更新)
- 等效人工:约 1-2 周工作量
失败案例:Parquet Java(Hadoop 依赖移除)
任务:从 Parquet Java 中移除 Hadoop 依赖。
结果:失败。
关键转折:
- 即使经过研究和规划,生成计划后仍发现无法执行
- 必要步骤:回到白板(Whiteboard),人工理解架构后重新设计
- 教训:AI 无法替代对复杂架构的深度思考,只能放大已有思考的质量
关键原则:不要外包思考(Do Not Outsource the Thinking)
AI 不能替代思考,只能放大你已完成的思考(或思考的缺失)。
人机协作的文化转变:
- 不是"告诉 AI 做什么然后纠正它"
- 而是"设计上下文使 AI 必然成功"
- 当 AI 反复失败时,问题通常在于上下文设计而非模型能力
关于 Spec-Driven Development 的澄清
该术语已发生语义扩散(Semantic Diffusion)(Martin Fowler, 2006),导致含义模糊化:
| 常见误解 | 实际有效实践 |
|---|---|
| 更详细的 Prompt(提示词) | 可验证的反馈循环与回压机制(Back Pressure) |
| 产品需求文档(PRD) | 将代码视为汇编,专注高层设计 |
| 编码时使用的 Markdown 文件集合 | 系统化的上下文管理与压缩 |
| 开源库的文档 | 研究-计划-实施的具体工作流 |
结论:单纯追求"更好的 Spec"是死胡同,应专注于上下文工程的具体技术。
代码库接入:渐进式披露(Progressive Disclosure)
问题
在大型代码库(如 500 万行 Monorepo)中,传统的单一代码库 onboarding.md 会导致:
- 文件过长,占用全部 Smart Zone 用于基础理解
- 无剩余上下文进行实际工具调用
解决方案:分层上下文
repo-root/
├── .cursor/
│ └── context.md # 全局架构(极简)
├── src/
│ ├── core/
│ │ └── context.md # 核心层特定上下文
│ └── api/
│ └── context.md # API 层特定上下文工作流程:
- 代理接入时先加载根目录
context.md(系统级架构) - 进入具体工作目录时,动态加载该层级的
context.md - 不重复文档化文件本身(文件即真相),仅提供导航和架构决策记录
优势:通过分层加载,始终保持工作上下文在 Smart Zone 内,实现频繁有意压缩的持续应用。
注:视频字幕在"we won't talk about any specific"处截断,后续内容可能包含更多具体实现细节或问答环节。
