2025 年 2 月,我从理想汽车加入小红书,继续做 AI Coding。此前一年半,我做的是代码补全和智能 CR。
入职时,大模型还处在相对早期的阶段,主流方法论停留在 Prompt 优化层面:通过精心设计的提示词,让模型给出更好的结果。没有人讨论 Agent 框架,也没有人谈 Harness Engineering,行业的共识还是“怎么写好一个 Prompt”。
这 14 个月,我经历了 AI Coding 的三次范式跃迁。这不是我个人的节奏,而是整个行业的演进轨迹。
| 阶段 | 时间 | 要解决的问题 | 我做的事 |
|---|---|---|---|
| Prompt Engineer | 2025.02 ~ 05 | 让 AI 完成单次精准任务:决定模型怎么做 | 智能 CR、代码补全 |
| Context Engineer | 2025.06 ~ 12 | 让 AI 稳定执行多步任务:决定模型能看到什么 | VS Code 里的 Code Agent |
| Harness Engineer | 2026.01 ~ 现在 | 让 AI 持续自主迭代:设计整个控制环境 | 桌面端 Agent 客户端 |
三者是层层包含的关系:Harness 包含 Context,Context 包含 Prompt。打个比方:Prompt 是给马一个“向右转”的指令;Context 是提供地图、路标和地形,让马知道去哪里;Harness 是设计缰绳、围栏和道路本身,让十匹马同时安全奔跑。
第一阶段:Prompt Engineer
智能 Code Review
关键决策是选择以过滤为主的路线:不追求发现所有问题,而是确保发现的每一个问题都是高质量的。流程是六步:
- 前置卡控:过滤无意义的变更,包括冲突文件、纯注释、空白行、只有 delete 的 diff、只有 import 的 diff。不是所有 diff 都值得交给 LLM。
- AST 采集:用 tree-sitter 对 diff 做结构化解析,提取函数级上下文,同时采集 call graph 引用,再通过 RAG 召回历史正负 case,配合 MR 标题和 commit 信息一起注入。原始 diff 没有语义边界,模型看到的是碎片;AST 让模型看到函数。
- Prompt 渲染:不同仓库、不同语言注入不同规则,仓库支持自定义模板。
- 双轮 LLM:第一轮识别,第二轮过滤。后来发现,随着模型变强、prompt 描述更准确,第二轮的作用逐渐减弱,改成一轮效果也不错,还更省钱。
- 工程过滤:控制评论数量和等级,相似评论用 embedding 去重,比如多个空指针问题只报一次并汇总。精度优先于召回,宁可漏报,不要误报。
- 数据飞轮:采集采纳和拒绝行为,维护正负 case 评测集,每天分析 Top N 问题。空指针问题采纳率最低、噪声最大,就对它采用更严格的过滤:只有召回到同类 case 时才透出。
这一阶段有两条教训。一是 RAG 召回的相关度提升,并没有线性转化为更高的采纳率,case 库的增长也收不住(详见搭了一年代码 RAG 之后)。二是上下文决定天花板:云端 CR 无法了解项目背景、业务逻辑和特定领域知识。这也为后来做 Agent 和 Harness 提供了宝贵经验:要让 AI 做好一件事,首先要给它足够的上下文。
代码补全
最有杠杆效应的一步是 FIM 格式改造:重构 prompt 结构,把前缀、后缀和待填充区域显式分开。本质是让模型从“蒙着写”变成“做填空题”。
这说明了一个道理:在 LLM 应用里,信息的组织方式比信息的数量更重要。 不是给模型更多代码就能写得更好,而是要用正确的方式呈现代码。
其余优化包括:稠密向量加 BM25 的上下文召回;过滤退格、撤销、删除、复制粘贴这类低价值触发;以及离线挖空评测,用完全匹配、Jaccard 相似度、编辑距离、AST 语义等价四种方式打分。
第一阶段复盘:做得好的是从 0 到 1 交付了完整方案,建立了可复用的评测体系;做得不够的是 RAG 优化没有持续验证效果闭环,功能上线后关注度就降低了。搭完系统只是起点,持续追踪效果闭环才是核心。
第二阶段:Context Engineer
选型:为什么不自研
市面上 Claude Code、Cline、Copilot Chat、OpenCode 百花齐放。团队做 IDE 的条件还不成熟,所以选择做 IDE 插件,基于开源的 RooCode 改造:社区活跃,Provider、Task、Tool 三层分离,改造边界清晰,原生支持 SubAgent。
自研 Agent 框架的成本远超想象,光工具层(bash 安全、文件操作、搜索)就要几个月。我们的核心竞争力在于对自己研发流程的深度适配,而不是又一个通用 Agent 框架。
这期间我对 Claude Code 做了 29 篇源码级分析,最大的发现是:它的稳定感不来自 Prompt 技巧,而来自工程体系。 工具相当于系统调用,权限体系相当于用户权限管理,Skill、Plugin、MCP 相当于应用商店和设备驱动,上下文压缩相当于内存管理。实质上,它是一个以 LLM 为内核的操作系统。
Prompt 优化
原始 prompt 没有风格定义,XML 和 Markdown 混杂,规则全部堆在一起。模型在大任务里频繁出现“焦虑态”:说太复杂了、需要更多上下文,然后主动放弃执行。
我们做了五个方向的优化:
- Tone & Style:简洁直接,不要重复已经做过的事,并给出正反示例;
- 重写工具使用规则:先读后写,最小修改,尽量用专门工具而不是命令行,支持并行调用,任务结束清理临时文件;
- 反谄媚:技术上的准确和真实,优先于认同用户的观点;
- 结构化拆分,按需注入:拆成角色层、通用规则层、工具规则层,不同 Agent、不同场景动态组合;
- Budget Rules:告诉模型上下文足够、复杂任务不需要许可可以继续、允许多次调用工具。这是效果最显著的一项,“做一半停下来问要不要继续”的问题基本消失。
Prompt 工程从“艺术”变成了“工程”:有结构,可测试,可维护。最大的收获不是某个技巧,而是每次改动都有对照基线、量化指标和回归验证。
工具体系重建
读文件做截断,保留头尾和文件结构,不在函数中间截断;搜索用 ripgrep 并限制结果数;用独立终端代替 VS Code 自带终端,解决卡死问题;只读工具并行调用,写操作排队等待读取完成;XML 工具调用改成原生 tool call,适配三家模型接口的差异。
沉淀下来的是工具优化三原则:
- 永远有截断:任何工具输出都要有上限;
- 永远有降级:工具失败要有 fallback;
- 可观测才能提升:没有指标就无法改进。
MCP 与 Skill
设计一个开放的生态系统,核心挑战不在于接入更多工具,而在于让模型知道这些工具存在、知道何时使用,并且不会因为工具太多而迷失。
Skill 采用三层披露:启动时只扫描发现,不放入上下文;每轮对话注入 Skill 的简要定义;模型选中某个 Skill 后,才加载全文。给模型一个菜单,而不是一本百科全书。
上下文管理
代码检索的范式在变:从向量驱动(离线建索引加语义召回),到 Agentic(给 Agent 工具让它自主探索)。我们参考 Claude Code,不再做复杂的向量召回,而是把 Glob、Grep、Read 的用法告诉模型,让它自己去找。
为什么要单独做 Grep、Glob 工具,而不直接用命令行?四个原因:权限控制、token 控制(分页、结构化输出、相对路径)、容错处理(超时返回空、防卡死)、提高结果的信息密度。
上下文压缩分几级:对话几轮后,把旧的文件读取内容替换成占位符,需要时模型会重新读取最新内容;超过阈值时,保留最近的消息,历史变成结构化摘要;仍然超限,就保留首条、删除中间消息,但必须保证工具调用和结果成对。压缩后补回 TODO 和当前进度;压缩后比压缩前还大,直接判定失败,避免死循环。
记忆只存代码看不见的东西:用户偏好、项目决策背景、团队约定。能从代码或 git 历史推导出来的,不存,存了只会过时。
这一阶段教会我:Agent 的天花板,除了基座模型,很大程度上取决于它能看到多少有效信息。 不是替 Agent 决定它该看什么,而是教它怎么选。
第二阶段复盘:做得好的是坚持最小侵入改造,没有返工;工具层是系统性重建,不是打补丁;可观测从零搭起。做得不够的是评测没有接入 CI/CD,每次要手动触发,存在回归风险;Agent 核心也没能完全服务化。评测应该和代码测试一样严肃。
第三阶段:Harness Engineer
2026 年初,LLM 已经能写出可运行的代码,但在复杂工程里,AI 像一个聪明但没有边界感的实习生:能很快堆出功能,却不知道代码会扩散到哪里、打破什么约束、在下一个迭代里制造什么债务。行业的问题从“AI 能不能写代码”,变成了“怎么让 AI 持续写好代码”。
这个阶段起于一个实验:能不能一天做出一个桌面端客户端。同一个需求,粗糙的输入要十几轮澄清,完整的需求 2 轮就能交付。清晰完整的需求能明显提升交付速度和质量。 基于这个实验,我把整理出的规则和方法做成了一个开放共建的项目,用 AI Native 的方式迭代。
Harness 的核心定义:当你发现 Agent 犯了一个错误,就花时间工程化一个解决方案,让它不再犯这个错误。不是“这次帮它改掉”,而是让这类错误在系统层面不可能再出现。
完整的 Harness 包含三层:LLM 内核;Agent 控制层,包括工具、prompt 和上下文管理;用户构建的环境反馈回路,包括自定义规则、hook、MCP、Skill。
它有三大支柱:
- 上下文:分层、按需、精准供给。系统层的架构约定写入 AGENTS.md,任务层按需提供需求和接口,状态层实时维护 TODO 和技术债。还要接入可观测系统,Agent 看到系统全貌和健康状态时,决策质量才会上升。
- 架构约束:传统思路是给 AI 更多权限;Harness 反过来,约束解空间,而不是扩大它。约束分两种:计算型约束,比如 ESLint 规则;大模型约束,比如本地 CR 和各种审查 Skill。
- 垃圾回收:AI 生成代码的速度远超人工审查,不主动清理就会指数级积累:架构漂移、重复代码和文档、过期代码和文档。
Agent 最常犯的两类错:一是跨层依赖,二是明明已有类似实现,还要自己再造一个。这两类问题通过 ESLint 和 CR Skill 基本解决。质量保障的本质,不是检查 AI 写的代码,而是让 AI 的错误类型越来越少。
我的角色也在变:从 human in the loop,和 Agent 一起工作;到 out of the loop,放任它发挥;再到现在的 on the loop,构建和维护 Agent 的控制环境。
还做得不够好的地方:
- 功能正确性验证仍依赖人工。 测试通过不等于功能正确,Agent 倾向于修改测试,而不是修复代码。
- 还有规则停留在文档里,没有沉淀成代码规则。
- 问题识别还不能自动化,可观测的接入有些还依赖人工输入。
- Harness 没有模板化。 AGENTS.md 体系是临时定制的,还没抽象成可复用的模板。
核心洞察
- 上下文是最稀缺的资源。 不是给 Agent 所有信息,而是教它怎么选。Token 预算的思维贯穿三个阶段。
- 约束优于指导。 Prompt 再强,也抵不过一条自动执行的 lint 规则。Agent 失败时,不是帮它解决,而是设计流程让它自己解决:给工具、给指导、给约束,反馈到代码库里,让 Agent 自己修。
- 架构设计的价值被放大,越早越好。 好的架构让 AI 在约束内高速运行,差的架构让 AI 四处扩散、制造债务。
- Harness 不会随模型变强而消失,只会转移。 AI 代码占比升高不可逆,真正稀缺的不是写代码的能力,而是设计一套让 Agent 持续稳定、自迭代写代码的工程体系。
- 工程师的价值,不在于写多少行代码,而在于设计什么样的系统,包括让 AI 高效运作的工程系统。
三个阶段里,AI 的角色也在变:第一阶段,AI 是工具,给工程师用;第二阶段,AI 是平台,工程师在上面构建工作流;第三阶段,AI 是系统的执行者,工程师设计系统,AI 在系统内执行。
接下来我最关注四个方向:Agent 评测的 CI/CD 化,每次改动都能自动验证;Harness 模板化,降低新项目的起步成本;多 Agent 之间的标准化协作;以及 AI 生成的代码,五年后怎么维护。