1. 为什么“模型强弱”在企业落地里被高估了1.1 一个反直觉的观察起点我在一家两百多人的研发团队里推 AI 编程工具前后折腾了差不多一年。这一年里团队从最初的“尝鲜式试用”走到“日常提交里有三成以上代码由 AI 参与生成”中间换过好几轮模型从早期的通用大模型到后来的代码专用模型也试过不同厂商的 API 和本地部署方案。如果只看模型跑分榜单我们换模型的理由应该很充分——新模型在 HumanEval、SWE-bench 这类基准上分数确实更高。但真正落地之后我发现一个很反直觉的事实模型强不强对最终产出的影响远没有大多数人想象得那么大。真正决定一个团队能不能把 AI 编程用起来的是三件看起来“不性感”的事Spec规格说明、Context上下文、Harness工程外壳。这三个词在热搜里反复出现但很多人只是把它们当成技术名词没有意识到它们才是决定成败的变量。模型是发动机Spec 是方向盘Context 是油路Harness 是底盘和传动系统。发动机再猛方向盘乱打、油路堵塞、底盘散架车照样开不动。这篇文章我想把这一年踩过的坑、试过的方案、最后沉淀下来的做法完整讲一遍。适合两类人看一类是正在团队里推 AI 编程、但发现“买了工具没人用”的技术负责人另一类是个人开发者想搞清楚为什么同样的模型在别人手里好用、在自己手里拉胯。全文会围绕 Spec、Context、Harness 三个核心概念展开穿插具体的配置、参数、排查方法和实操心得。1.2 模型差距在真实任务里被稀释的原因先说清楚为什么模型强弱会被高估。榜单上的任务通常是“给定一个完整函数签名和清晰描述写出实现”这种任务边界清晰、上下文自足、评判标准单一。但企业里的真实任务长这样需求来自一个模糊的工单代码散落在十几个文件里命名风格不统一还有历史遗留的兼容逻辑改完之后要过 CI、要过 code review、不能破坏现有测试。在这种场景下模型能力的差距会被三个因素稀释信息缺口模型不知道你们团队的约定比如日志格式、错误码规范、某个字段为什么不能为空。这些信息不在训练数据里只能靠 Context 喂进去。任务分解一个真实需求往往要拆成五六个子任务模型单次能处理的是其中一小块。拆得好不好比模型强不强更影响结果。验证成本模型生成的代码你要花多少时间验证它是对的如果验证成本高于自己写那模型再强也没意义。而验证成本主要由 Harness 决定。我做过一个粗略的对比同一个需求用当时最强的模型和次一档的模型分别做在没有做好 Spec 和 Context 的情况下两者的一次通过率都在 30% 上下差距不到 10 个百分点。但当我们把 Spec 写清楚、Context 组织好之后次一档模型的一次通过率能到 70% 以上反而超过了“裸用”最强模型的水平。这个数据不一定普适但方向是明确的工程化的收益大于换模型的收益。2. Spec把“你懂的”变成“模型也懂的”2.1 Spec 到底是什么为什么它排第一位Spec 是 Specification 的缩写直译是规格说明。在 AI 编程语境里我把它定义为在让模型动手之前用结构化方式把“要做什么、做到什么程度、不能碰什么”讲清楚的那份东西。它可以是一段提示词可以是一个 Markdown 文件也可以是仓库里的一份约定文档。为什么它排第一位因为模型不会读心术。你脑子里那个“这个接口要兼容老版本、返回体不能加字段、超时统一走 3 秒”的隐性知识如果不写出来模型就只能猜。猜对了是运气猜错了是常态。我见过太多人抱怨“AI 写的代码不能用”一问才发现他给模型的输入就一句话“帮我实现一个用户查询接口。”这种输入换谁来都写不好。Spec 的核心价值是把隐性知识显性化。这件事在传统开发里也重要但那时候执行者是人人可以问、可以猜、可以凭经验补全。模型不会问它只会按概率生成最“常见”的写法而“常见”往往不等于“符合你们团队规范”。2.2 一份可复用的 Spec 模板长什么样我最后沉淀下来的 Spec 模板包含六个部分按重要性排序目标一句话说清楚这个任务要达成什么。比如“新增一个按用户 ID 查询订单列表的接口”。输入输出请求参数、返回结构、字段类型、是否可空。这部分要精确到字段级别。约束条件性能要求、兼容性要求、安全要求、不能改动的文件或接口。边界情况空值、超长、并发、权限不足时分别怎么处理。参考实现指向仓库里已有的类似代码让模型照着风格写。验收标准怎么判断做完了、做对了。最好能对应到具体的测试用例。我举个实际例子。早期我们让模型写一个分页查询输入只有“实现订单分页查询”。模型给了一个用 offset/limit 的实现但我们内部规范是游标分页因为订单表数据量大、offset 深分页性能差。后来我把 Spec 改成目标实现订单列表的游标分页查询 输入cursor上一页最后一条的 ID首次为空、size默认 20最大 100 输出{ items: [...], nextCursor: string | null } 约束 - 必须用游标分页禁止 offset - 查询走 order_idx_user_time 索引 - size 超过 100 时截断为 100不报错 边界 - cursor 为空时返回第一页 - cursor 指向的记录已被删除时从该位置之后继续 参考参见 OrderService.listByUser 的现有实现 验收单测覆盖空 cursor、超 size、cursor 失效三种情况改完之后模型一次通过率从不到四成提到了八成以上。差别不在模型在于我把“你懂的”写成了“模型也懂的”。2.3 写 Spec 的常见误区与避坑第一个误区是写得太长。有人觉得越详细越好把整个需求文档贴进去结果模型抓不住重点。Spec 不是文档是给模型的“任务卡”要精炼。我的经验是控制在 300 到 800 字之间超过就说明任务该拆了。第二个误区是只写要做什么不写不要做什么。模型很“勤奋”你不说禁止它就会自作主张加东西。比如你让它改一个函数它顺手把旁边的代码也重构了review 的时候一片红。所以约束条件里一定要有“禁止改动范围”。第三个误区是没有验收标准。没有验收标准你就没法判断模型做完了没有只能靠人肉读代码。而验收标准最好能自动化比如对应到具体的测试命令。提示Spec 不是一次性的。同一个任务类型做多了就把 Spec 沉淀成模板下次直接改参数。我们团队现在有十几个常用 Spec 模板新人上手直接套效率提升非常明显。3. Context模型看不到的东西等于不存在3.1 Context 的本质是“信息供给”Context 是上下文在 AI 编程里指的是你在发起请求时一并提供给模型的全部信息。包括当前文件、相关文件、目录结构、依赖关系、历史对话、报错信息等等。模型的能力再强也只能基于你给它的 Context 做推理。Context 里没有的信息模型只能靠训练时的“常识”补而常识往往不符合你的项目实际。热搜里有个词叫“滑动窗口滤波模型”还有个报错是“maximum context length is 1048576 tokens”。这两个词其实指向同一个问题Context 是有容量上限的怎么在有限容量里塞进最有用的信息是核心难点。一百万 token 听起来很多但一个中型项目全量代码轻松超过这个数所以你必须做取舍。我踩过的最大的坑就是早期直接把整个文件甚至整个目录丢给模型以为给得越多越好。结果模型被无关代码干扰生成的代码风格混乱还经常引用不存在的函数。后来我才明白Context 的关键不是“多”是“准”。3.2 分层组织 Context 的实操方法我把 Context 分成四层按优先级从高到低层级内容作用是否必给第一层当前编辑的文件让模型知道改哪里必给第二层直接依赖与被依赖文件让模型知道接口契约必给第三层同目录的相似实现让模型对齐代码风格建议给第四层项目级约定文档让模型遵守全局规范按需给第一层和第二层是硬性要求。很多人只给第一层结果模型改了函数签名调用方全挂了。第二层的作用就是让模型看到“谁在调用我、我调用了谁”避免破坏契约。第三层是提升风格一致性的关键。模型有很强的“模仿”倾向你给它看一段同项目的相似代码它写出来的风格就会贴近。我们团队的做法是在每个模块目录下放一个_example.ts之类的参考文件让工具自动带上。第四层是项目级规范比如命名约定、日志格式、错误处理方式。这部分内容多不适合每次都全量塞我的做法是把它压缩成一份不超过 500 字的“项目须知”放在仓库根目录工具按需读取。3.3 Context 超限时的取舍策略Context 超限是高频问题。热搜里那个“maximum context length”报错本质就是你塞太多了。我的取舍策略是三步先砍第四层项目级规范如果太长只保留和当前任务相关的几条。再砍第三层相似实现只保留最接近的一个不要给三个。最后砍第二层只保留接口定义部分函数体可以省略。如果砍完还是超说明任务太大该拆了。我一般把单次任务的 Context 控制在容量的 60% 以内留出余量给模型的输出和后续对话。这个比例不是硬性规定但实测下来留余量能明显降低模型“忘记前面内容”的概率。注意不同工具对 Context 的组织方式不一样。有的工具会自动做检索和裁剪有的需要你手动指定。用之前一定要搞清楚它的 Context 策略否则你以为给了其实没给。4. Harness决定 AI 编程能不能“跑起来”的工程外壳4.1 Harness 是什么为什么它最容易被忽视Harness 直译是“挽具、外壳”在 AI 编程语境里我把它定义为包裹在模型外面、负责把模型能力接入实际工作流的那一整套工程设施。它包括提示词编排、工具调用、文件读写、命令执行、结果验证、错误重试等等。热搜里有“harness engineering”“harness 和 agent 区别”“harness failed to load plugins”这些词说明大家开始意识到它的重要性了。但很多人还是把注意力放在模型上觉得换个更强的模型就能解决问题。我的结论恰恰相反Harness 决定了 AI 编程的下限模型只决定上限。下限上不去上限再高也用不上。举个最直观的例子。同样一个模型A 工具只能让它生成代码片段你得手动复制粘贴B 工具能让它直接读写文件、跑测试、根据报错自动修复。这两者的产出效率差好几倍但模型是同一个。差别全在 Harness。4.2 一个合格 Harness 应该具备的能力我总结了一个合格 Harness 的六个核心能力按重要性排序文件读写能直接读项目文件、写回修改而不是只输出文本让你手动搬。命令执行能跑测试、跑 lint、跑构建并根据结果调整。错误反馈闭环命令失败时能把报错信息喂回给模型让它自己修。Context 管理能自动检索相关文件、控制上下文容量。变更预览与回滚改之前能看 diff改错了能一键回滚。权限与安全边界能限制模型只能改指定目录不能碰敏感文件。前三个是基础没有这三个AI 编程就退化成“高级代码补全”。第四个决定效率上限。第五、第六个决定能不能在团队里安全推广。我们团队在选型时把“错误反馈闭环”作为硬性指标。因为实测下来模型第一次生成的代码有错是常态关键是能不能自己修。有闭环的工具一个任务平均 1.8 次迭代就能过没有闭环的全靠人肉修效率差一大截。4.3 Harness 与 Agent 的区别别搞混了热搜里有人问“harness 和 agent 区别”这个问题很关键。简单说Agent 是一种工作模式Harness 是支撑这种模式的工程设施。Agent 强调模型自主规划、自主调用工具、自主完成任务Harness 是让 Agent 能真正落地的那套“脚手架”。没有 Harness 的 Agent就是个只会聊天的规划器说得好听但干不了活。没有 Agent 思路的 Harness就是个被动的代码补全器你得一步步指挥。两者结合才是完整的 AI 编程工作流。我见过一些团队上来就追求“全自动 Agent”结果因为 Harness 不完善模型乱改文件、跑挂测试、污染仓库最后不得不全部回滚团队信心大受打击。我的建议是先把 Harness 做扎实再逐步放开 Agent 的自主权。从“只读不写”到“写但需确认”再到“写指定目录”最后才是“自主完成小任务”。每一步都要有回滚兜底。5. 从零搭建一套可用的 AI 编程工作流5.1 环境准备与工具选型搭建工作流的第一步是选工具。市面上的 AI 编程工具大致分三类IDE 插件类、独立编辑器类、命令行 Agent 类。我的建议是不要一上来就 all in 某一类而是先明确你的核心场景。如果你的团队主要是写业务代码、改 bugIDE 插件类上手最快学习成本低。如果你需要处理跨文件的大改动独立编辑器类的 Context 管理通常更强。如果你要做批量重构、自动化任务命令行 Agent 类更合适。选型时重点看四个指标Context 管理能力、错误反馈闭环、变更可控性、团队协作支持。前两个决定效率后两个决定能不能推广。我实测过几款主流工具在同一个任务上的表现差异主要就来自这四个指标而不是底层模型。环境准备上我建议单独建一个试验仓库不要直接在主仓库上试。试验仓库里放一些典型的代码结构用来测试工具的各项能力。等摸清楚了再往主仓库推。5.2 配置参数与关键设置配置这块有几个参数必须调对否则体验会差很多。Context 容量设置不要设成最大值。设成最大值的 60% 到 70%留余量。比如容量是 100 万 token实际用到 60 到 70 万就够了。设太满会导致模型响应变慢还容易触发超限报错。温度参数写业务代码建议调低0.1 到 0.3 之间。温度高会让模型更有“创意”但业务代码要的是稳定和一致不需要创意。做探索性任务时可以调高。自动执行开关初期一定要关。让模型先给方案你确认了再执行。等信任建立起来再对低风险操作开自动执行。文件访问范围严格限制。只允许访问项目目录禁止访问系统目录和敏感配置。这条是安全底线不能省。重试次数设 2 到 3 次。模型第一次失败很正常给它一两次自我修复的机会。但不要设太多超过 3 次还修不好说明任务本身有问题该人工介入了。我踩过一个坑早期把重试次数设成 10 次结果模型在一个错误上反复打转烧了一堆 token 还没解决。后来改成 3 次效率反而更高因为超过 3 次的情况基本都是 Spec 或 Context 有问题该回头改输入而不是让模型硬试。5.3 完整实操流程演示我以一个真实任务为例走一遍完整流程。任务是“给用户服务新增一个批量查询接口”。第一步写 Spec。按前面说的六部分模板写清楚目标、输入输出、约束、边界、参考、验收。这一步花 5 分钟但能省后面半小时。第二步组织 Context。打开用户服务的目录让工具自动带上当前文件、相关的 model 和 dao 文件、同目录下一个已有的批量接口作为参考。检查一下 Context 总量控制在容量的一半左右。第三步发起请求。把 Spec 和 Context 一起给模型让它先输出实现方案不要直接写代码。这一步是“方案确认”能提前发现理解偏差。第四步确认方案后生成代码。模型输出代码工具展示 diff。我逐行看一遍重点看有没有超出约束范围的改动。第五步跑测试。让工具执行相关测试命令。如果有失败把报错喂回去让它修。一般一到两次能过。第六步人工 review。测试过了不代表没问题还要看代码风格、命名、注释是否符合团队规范。这一步不能省但比从零写快多了。整个流程走下来一个中等复杂度的接口从 Spec 到可提交大概 20 到 30 分钟。纯手写的话熟悉的人也要一两个小时。效率提升是实打实的但前提是前面几步做到位。5.4 团队推广的节奏把控个人用得好不代表团队推得动。我们团队推广分了三阶段第一阶段是“种子期”找三五个愿意尝试的人在小范围里跑通流程沉淀出 Spec 模板和配置方案。这个阶段的目标不是提效是验证可行性。第二阶段是“扩散期”把种子成员的经验整理成文档做内部培训让更多人用起来。这个阶段会遇到各种“为什么我这不好用”的问题大部分是 Spec 和 Context 没做好需要一对一辅导。第三阶段是“规范期”把成熟的做法固化成团队规范比如提交代码时标注 AI 参与比例、Spec 必须随任务一起提交等。这个阶段的目标是让 AI 编程从“个人技巧”变成“团队能力”。整个推广周期大概半年。急不得一上来就全员强制使用只会引发抵触。6. 常见问题与排查技巧实录6.1 高频报错与对应处理这一年遇到的报错不少我整理成一张速查表报错关键词可能原因处理方式maximum context lengthContext 超限按四层优先级裁剪或拆分任务invalid version spec依赖版本约束冲突检查 Spec 里的版本要求放宽或明确failed to load pluginsHarness 插件加载失败检查插件路径、权限、版本兼容性error during compaction上下文压缩出错减少历史对话开新会话out of context per ip请求频率或容量限制降低并发错峰使用400 api error请求参数不合法检查 Spec 格式、特殊字符转义这些报错里最常见的是 Context 超限。我的处理原则是先怀疑输入再怀疑工具最后才怀疑模型。大部分问题都是输入没组织好。6.2 模型“不听话”的排查思路模型不按 Spec 执行是另一个高频问题。排查顺序是Spec 是否明确有没有写清楚禁止项模糊的表述模型会自由发挥。Context 是否冲突给的参考代码和 Spec 要求是否矛盾模型会优先模仿参考代码。任务是否太大任务太大时模型会“偷懒”省略细节。拆小一点。模型是否选错有些任务确实需要更强的模型但这是最后才考虑的。我遇到过一次模型总是给函数加多余的日志Spec 里明明没要求。查了半天发现我给的参考代码里每个函数都有日志模型是在模仿。把参考代码换掉就好了。这个例子说明Context 里的“示范”比 Spec 里的“要求”影响力更大给参考代码要格外小心。6.3 独家避坑心得最后分享几条踩坑换来的经验不要在周五下午推大改动。AI 生成的代码需要 review周五下午没人有精力仔细看容易埋雷。Spec 和代码一起提交。这样后人能看懂这段代码是怎么来的出问题也好追溯。给模型起个固定的“角色”。比如在项目须知里写“你是一个严格遵守本团队规范的资深工程师”实测能提升规范遵守率。定期清理 Context 缓存。缓存里如果有过时的代码会误导模型。每次大改动后清一次。保留人工否决权。再顺的流程也要有人能一键叫停。这是团队信任的基础。我个人在实际操作中的体会是AI 编程这件事前期投入在 Spec、Context、Harness 上的时间会在后面成倍地还回来。模型会一直更新今天的最强模型明天就过时了但一套好的工程化方法能一直用下去。与其追着榜单换模型不如把这三件事做扎实。