如果你也试过让 AI 一路狂飙写了三千行业务代码,然后发现没人说得清它到底实现了哪些需求,这篇就是写给你的。SDD 规范驱动、Harness 驾驭工程 AI,这两个词最近在 AI 原生软件工程圈子里被反复讨论,而我想聊的是,它们怎么一起把我从“氛围编码”的舒适区里捞出来。
过去一年,我最大的感受是:AI 写代码已经不难,难的是让 AI 写的代码“算数”——能验收、能回滚、能解释为什么,而不是像蹦迪一样嗨完就散。所谓“氛围编码”(vibe coding),最典型的画面就是开着一个聊天框,用自然语言让 AI 不断“再改一下”,最后得到一个没人敢动的代码堆。它爽在即时反馈,坑在失控。
这篇内容适合三类人:被 vibe coding 坑过的开发者、想在团队里推行 AI 工程化的技术负责人、以及正在研究怎么把 DeepSeek 这类模型真正接入开发流程的工具党。我会从失控的本质讲起,展开 SDD(规范驱动开发)如何把需求变成可验证的规格,再结合 DeepSeek Harness(DSH)本地部署的实操经验,讲清楚一个让 AI 从“聊天助手”变成“工程执行器”的完整闭环。最后是安装排错和团队落地建议,全都是我自己踩过坑之后留着血写下来的。
1. “氛围编码”为什么爽完了就崩:先理解失控的本质
1.1 vibe coding 的爽点,恰恰是失控点
Vibe coding 之所以流行,是因为它把写代码从“翻译需求”变成了“表达情绪”。你只需要描述一个大概要什么东西,AI 就会给出一段似乎能跑的代码。那种即时反馈的爽感,说实话,比写单元测试上头一百倍。
但问题也出在这里:情绪是模糊的,工程是精确的。当你对 AI 说“把这个搜索接口优化一下”,AI 可能理解为“加个缓存”,也可能理解为“改造查询逻辑”,还可能理解为“重写整个服务”。自然语言天然存在多义性,而 vibe coding 的典型做法是一路顺着 AI 的思路走,没有在任何一个节点把双方的共识固定下来。
我见过太多人(包括我自己)在这种模式下开发的代码:功能看起来是齐全的,但如果你问 AI“你为什么这么做”,它自己也说不清楚;如果你问“验收标准是什么”,更是哑口无言。代码的即时生成速度掩盖了一个事实——没有任何一份可追溯的需求规约,没有任何一个可自动执行的验收测试,整个项目完全建立在聊天气泡堆成的流沙上。
1.2 我遇到的三次翻车现场
这里先说三个最典型的失控形态,都是我在真实项目里吃过的亏。
第一是上下文漂移。有一次让 AI 写一个数据同步模块,三小时前明确要求使用 ESM 规范、输出 NodeNext 模块格式。结果聊到后来,AI 悄悄把一部分文件写成了 CommonJS。它没有“想起”之前约定,是因为上下文太长被截断,而且这个约定从没被写进任何持久化文件里。vibe coding 的上下文,本质上是易失内存,关机就归零。
第二是没有验收标准。AI 告诉我“完成了”,然后确实生成了几十个文件。但当我尝试写验收用例时,发现核心流程根本没有实现,只是把接口骨架和 mock 数据堆了出来。你没法批评它——因为从始至终,你根本没给它定义过“完成”的边界。
第三是胶水代码失控。随着需求不断追加,“再改一下”变成一种惯性,AI 不断打补丁,最后产出了一个谁也看不懂的胶水层。每次改动都像是在拆炸弹,因为你不知道哪条逻辑和另一条逻辑有隐耦合。氛围编码的代码,最大特点不是有 bug,而是有 bug 你也不知道怎么定位,因为整个设计意图没有锚点。
1.3 可控的本质是“规格-验证”闭环
把三次翻车放在一起看,会发现共性:人和 AI 之间只有对话,没有契约。而软件开发几十年的经验早就告诉我们,对话是不可靠的,契约才是可靠的。
这里说的契约,不是装模作样的设计文档,而是三件事:需求有明确规格(spec)、行为有自动验证(test)、过程有执行记录(log)。我需要 AI 去做的不只是“写代码”,而是在一套规格和验证的闭环里交付行为。
这就引出了两个关键工具:SDD 负责定义“要什么”,Harness 负责保障“怎么执行”。没有 SDD,AI 只会自由发挥;没有 Harness,SDD 也只能躺在文档目录里积灰。它们俩合在一起,才是我理解的 AI 原生软件工程——不是传统软件流程外挂一个 AI 助手,而是整个开发链路从规格到验证都围绕 AI 的能力重新设计。
2. SDD:给 AI 下需求书,而不是说“帮我写”
2.1 SDD 和 TDD、BDD 到底差在哪
很多人一听 SDD(Specification-Driven Development)就问:这不就是 TDD 换了个名字吗?还真不是。
TDD(测试驱动开发)的核心是“先写测试,再写实现”,它的交付物是测试代码。BDD(行为驱动开发)的核心是“用自然语言描述行为”,强调业务人员和开发者的沟通。而 SDD 的核心,是把规格当成第一公民——先有一份结构化的规格文件,描述输入、输出、业务规则、异常场景和验收条件,然后 AI 的任务是“实现这份规格”。
对传统开发者来说,这三者可能只有细微差别;但放到 AI 编程场景下,差别就非常明显了。TDD 要求人先写出细致的测试,这等于人已经把实现接口都想清楚了;BDD 的自然语言描述仍然太松,模型容易发挥;SDD 则把规格当作一份可以被 AI 消费的“需求契约”,它既可以是人写的,也可以是人和 AI 协作拆解出来的。
用生活化的比喻:TDD 是“先定考卷再让学生答题”,BDD 是“把考点用大白话告诉学生”,SDD 则是“先发布教学大纲、评分标准和考场纪律,再让学生答题”。AI 不需要你替它写代码,但它迫切需要一份像教学大纲一样清晰的执行蓝图。
2.2 一份能落地的 Spec 长什么样
这一步我非常建议直接抄作业。下面是我在自己项目里用的一份规格文件,领域是一个搜索缓存模块。你可以看到,它没有一句废话,每一段都会被 AI 原样读取并作为实现依据。
# spec: search-cache ## 目标 - 为搜索接口提供进程内缓存,降低后端查询压力。 - 缓存 key 为规范化后的查询字符串,value 为 JSON 快照。 ## 契约 - `get(key: string) -> {value: object | null, hit_at: number | null}` - `set(key: string, value: object, ttl_seconds: number): void` - key 规范化规则:trim、转小写、压缩连续空格。 ## 业务规则 - 默认 TTL 为 30 秒,config.ttl 可覆盖。 - 最大容量 10000 条;超出后按 LRU 淘汰。 - 禁止缓存 auth_token、user_id 等敏感字段。 ## 异常场景 - key 为空字符串:直接返回 miss,不抛异常。 - 缓存命中但 TTL 过期:删除该条目并返回 miss。 ## 验收(可执行) - 单测覆盖 get/set 的常规路径、TTL 过期、LRU 淘汰、敏感字段过滤。 - 并发 100 次写入不同 key,不丢失已确认写入。 - 所有验收命令通过 `pytest tests/test_search_cache.py -x` 执行。你可能会问:这份 spec 里写的很多内容,好像普通需求文档也会写?对,但区别在于两点。
第一,它把“质量”翻译成了“可执行脚本”。AI 没有能力判断自己的代码“好不好”,但它能运行 pytest,能看看这几条验收过没过。把质量变成命令,是给 AI 下规格的关键技巧。第二,它明确写出了“禁忌边界”——比如哪些字段不能缓存,哪些异常不能抛。因为如果你不告诉 AI 什么不能做,它一定会按最顺手的方式做,而“顺手”往往意味着安全隐患和代码腐化。
2.3 验收条件是 SDD 的灵魂
在 SDD 的实践里,我认为验收条件比目标描述重要一个量级。目标描述给 AI 一个方向,验收条件才真正约束了行为。
一个合格的验收条件要满足三个要求:可观察、可自动执行、不可被含糊绕过。拿上面的例子来说,“性能要好”就是不合格的验收条件,因为不可观察;“100 次并发写不丢失”就是合格的,因为可以写脚本自动跑。
另一个经验是:为每个 spec 建立“负面验收清单”。这是我在一次重写登录模块时学到的。AI 实现“密码重置”功能时,逻辑上通过了正向用例,但它把旧 token 失效逻辑写错了,导致重置后原 session 还能继续访问。我没法在 prompt 里“警告”AI 千万别犯这种错,但我可以在 spec 里加一条可执行的验收规则:“验证重置密码后旧 token 立即失效”。从此之后,AI 每次实现密码重置都会带着这条验收跑一遍,正面负面都覆盖,事故率大幅下降。
此外,规格粒度也要拿捏好。规格太大,AI 会把整个系统当成一次 prompt 的输入,上下文爆炸,质量直线下降;规格太小,拆分和调度成本又比写代码本身还高。我推荐的节奏是:每一个任务对应一份独立 spec,任务粒度控制在“半天到一天能完成并验证”的量级。这样既不会让 AI 陷入长期无反馈的蒙头开发,也不会让你陷入规格地狱。
3. Harness:把 AI 从“聊天框”请进“工程流水线”
3.1 Harness 到底驾驭了什么
如果你理解了 SDD 是“给 AI 下需求书”,那 Harness 要解决的就是另一个问题:谁来执行这份需求书?怎么保证执行过程不跑偏?
聊天框里的 AI,本质上是一个无状态、无约束、无权限管理的“建议生成器”。你给它一段 prompt,它给你一段回复,然后这段回复和你之间没有任何长期关系。但 Harness 做的事情是:在模型外面套一层工程控制面,负责上下文管理、工具调度、步骤编排、验证回环、日志持久化。模型仍然是那个模型,但它的行为被装进了一个有方向盘、有刹车、有行车记录仪的壳子里。
用驾驶来类比:模型是发动机,决定动力上限;Harness 是变速箱和仪表盘,决定动力怎么输出、速度怎么控制、什么时候该预警。氛围编码相当于你在副驾对着一台发动机大喊“快点再快点”,而 Harness 让你的操作回到了驾驶座上——有档位、有转向、有刹车,甚至还有自动巡航。
举个例子。同样让 DeepSeek 模型实现搜索缓存模块,直接开聊天框,它可能一口气给你生成十来个文件,其中三个是冗余的、两个是错的,还有一个擅自改了你的 schema。而在 Harness 里,它会按照 skill 定义的流程走:先读 spec、再生成执行计划、然后在限定文件范围内写代码、最后自动跑验收脚本,失败就把报错带回上下文,继续迭代。每一步都留痕。
3.2 DeepSeek Harness 本地部署实录:模型、硬件、安装选择
关于“DeepSeek Harness”这个词,有人会把它理解成 DeepSeek 模型的一种特殊封装,有人把它理解成一个可插拔的 harness 框架。从我实际使用的经验看,它就是一套以 DeepSeek 系列模型为主要后端、带 skill 插件扩展机制的执行框架。这套东西跑起来之后,你的 AI 编程工作流就不再是“打开网页聊天”,而是“在本地 CLI 工程环境里被调度执行”。
部署前先想清楚模型和硬件基线。我在一台内存 64G、单张 24G 显存的机器上跑过两条路线:
| 方案 | 模型 | 显存需求 | 内存需求 | 体验 |
|---|---|---|---|---|
| 纯本地方案 | DeepSeek-R1 蒸馏版 14B(GGUF 量化) | 12GB 左右 | 32GB 以上 | 响应稳,推理偏慢 |
| 混合方案 | API 接入 DeepSeek-V3 / 本地 Qwen3 27B 兜底 | 16GB 以上 | 32GB 以上 | 体验平衡,可切换 |
| 轻量方案 | Qwen3 8B 量化 | 8GB 左右 | 16GB 以上 | 能用,但复杂 spec 推理质量下降 |
如果你的目标是跑通 SDD 闭环,我建议至少 24GB 显存。不要一上来就冲最大的模型,先把流程跑通——流程比模型聪明更重要。初期可以先接 API 后端,让 Harness 的调度和验证逻辑先跑起来;等确认这套工程模式适合你了,再考虑本地模型部署。
安装的核心步骤并不复杂:从项目仓库拉取代码、创建 Python 虚拟环境、安装依赖、配置模型后端地址、初始化插件目录。这里有一个非常容易被忽略的点:安装前先确认项目的 Python 版本要求。我见过周围很多人失败在 0.1.5 这个版本上,就是因为环境是 Python 3.10,而项目依赖里要求 3.11 的新特性。解决方式也很简单,用python3.11 -m venv .venv重建虚拟环境,再重新执行安装命令即可。
3.3 Skill 插件机制:把“能力”编译为可调用单元
Harness 的一大亮点是 skill 机制。你可以把它理解成“可复用的任务执行模板”,它不是传统的 IDE 插件,而是把一类任务的执行流程、约束条件和验证逻辑固化成代码或配置文件,让模型在这个框架内行动。
比如我写了一个sdd-planningskill,作用是:当检测到新的 spec 文件提交时,自动加载规划器,生成实现计划,并检查计划是否覆盖 spec 里每一条验收条件。它的配置很简单:
name: sdd-planning version: 1.0 trigger: event: spec_created path: specs/** steps: - action: parse_spec input: "{file}" - action: generate_plan constraints: - plan must reference every acceptance criterion - plan must not modify files outside scope/ - action: save_plan output: "plans/{spec_name}.plan.md" verify: - check: plan_acceptance_coverage level: required注意这里最关键的是 constraints 里那两条:计划必须引用每一条验收标准,计划不得修改 scope/ 之外的文件。这两条约束的价值在于:AI 的自由度被限定在“如何实现”而不是“实现什么、在哪儿实现”。这正是从 vibe coding 到可控工程的关键一步——模型还是那个模型,但它的权限和行为空间被 skill 收拢了。
很多人以为 skill 就是“更长的 system prompt”,这是误解。Prompt 是建议,模型可以不遵守;skill 是流程,Harness 会在每个 step 之间检查和强制。你可以用普通 Prompt 让 AI“多想一步”,但只有 skill 能让 AI 在生成计划后必须停下来等验证结果。这个“停下来等验证”的机制,才是可控性的根本保证。
4. 在 Harness 里跑通 SDD 闭环:一个完整案例
4.1 拆需求:把“做个搜索缓存”写成规格
理论说了不少,现在走一个完整案例。我拿自己项目里的真实需求举例:给搜索接口加一个进程内缓存。
这个需求听起来很简单,但如果直接让 AI 实现,它一定会在三个地方自由发挥:缓存 key 怎么规范化?TTL 从哪读配置?淘汰策略用什么?不提前定好,AI 就会拍脑袋。
我把它拆成了上一节那份 spec。拆解的时候有几个要点:一是把“正常功能”和“禁忌行为”分开写;二是明确输入输出的类型签名,因为模型非常擅长遵循签名;三是把验收标准压缩成一条可执行命令,让 Harness 自动运行,而不是人肉审查。
4.2 执行链路:spec → plan → code → verify
spec 编写完成并放到specs/search-cache.md后,Harness 开始介入。完整执行链路是四步循环:
parse spec:Harness 加载 spec 文件,提取目标、契约、验收列表,格式化成结构化的任务描述。generate plan:sdd-planningskill 触发,模型基于 spec 生成实现计划。计划里必须说明会创建哪些文件、每个文件承担什么职责、打算如何满足验收条件。这份计划保存为plans/search-cache.plan.md,作为后续执行的依据。
# Implementation Plan: search-cache ## Files - src/cache.py # LRU cache implementation - src/normalize.py # key normalization - config.yaml # ttl and capacity settings ## Approach 1. Use OrderedDict for LRU eviction. 2. Normalization: lowercase, trim, collapse spaces. 3. Store JSON serialized value to avoid object mutation. ## Acceptance Coverage - [x] pytest test_search_cache.py -x - [x] TTL expiry covered in test_expired_key - [x] Sensitive fields filter covered in test_no_auth_cacheimplement:模型根据 plan 在限定文件范围内生成代码,每生成一个步骤,Harness 检查它是否触碰了 scope 之外的路径。verify:自动执行pytest tests/test_search_cache.py -x。如果失败,Harness 会把报错信息、失败的测试名、相关代码片段一起带回上下文,让模型修改,然后重新进入 implement 步骤。我在配置里设置了最多重试三轮,超过三轮就暂停并通知人类介入,避免模型在一个坑里无限打转。
这套链路跑起来之后,你会发现最明显的区别:AI 不再“一口气交底”,而是每次只前进一小步,并且每走一步都要回来对表。这个过程有点慢,但可控性完全是另一个维度。
4.3 验证结果与日志回放:可控性在哪里体现
跑完三轮迭代后,模型通过了全部验收条件。但我觉得这个案例里真正有价值的不是“代码通过了测试”,而是整套过程的日志回放能力。
Harness 会为每次执行生成一份 session 日志,记录模型在每个 step 读到了什么、做了什么决策、改了哪些文件、测试输出是什么。比如有一段日志清清楚楚写着:模型在实现淘汰策略时,最初选择了 FIFO,但在读取计划中的 “LRU eviction” 和验收条件 “LRU 淘汰” 之后,主动调整了实现。这个过程你可以事后在日志里看到,就像看一个初级工程师的 coding 复盘。
对比一下 vibe coding 的聊天记录:消息一长,根本找不到“当初为什么这么设计”,而 Harness 的结构化日志是把 AI 的决策过程变成了可审计资产。这一点对团队协作的意义怎么强调都不为过——你终于能在代码之外,向同事解释“这个方案是怎么来的”。
5. 安装和排错:DeepSeek Harness 实录中那些坑
5.1 版本选择的教训
如果你看了热词榜上那一堆“deepseek harness 安装失败”,不要焦虑,绝大多数坑我都踩过。
第一个坑是版本和依赖环境的匹配。当时我拿到的是 0.1.5 版本,装完依赖之后启动告诉我缺少 Web 组件依赖,我还以为是网络问题。后来查看项目的 requirements 文件,发现它要求 Python 3.11,而我用的默认环境是 3.10。Python 版本差异会带来大量隐性问题,比如类型语法解析错误、标准库行为不同,而安装过程中 pip 未必会报错。
所以我的建议是:动手前先花两分钟看 toolchain 要求,确认 Python 版本、Node 版本、系统架构。宁愿重建一个干净环境,也不要在一个老环境里硬塞新工具。这一点和传统软件部署没有区别,但很多 AI 工具使用者因为习惯“一个命令跑起来”而忽视了它。
5.2 “failed to load plugins web boot: 2 entries did not activate”完整排查链路
这个报错我在本地启动时也遇到过,当时的完整报错是harness failed to load plugins web boot: 2 entries did not activate。很多人一看到 failed 就慌了,实际上原因多半不是框架坏了,而是插件激活环境不完整。
下面是我当时的排查链路,直接贴出来给你参考。
| 步骤 | 操作 | 观察与判断 |
|---|---|---|
| 1 | 复现启动,记录完整报错 | 确认报错中“2 entries”固定出现,非偶发 |
| 2 | 检查 plugins 目录下的 manifest 文件 | 用 JSON 格式化工具检查,发现语法合法 |
| 3 | 逐个插件单独激活 | Harness 提供harness diagnose --plugins命令,输出显示两个 skill 依赖 Node 侧 loader |
| 4 | 检查 Node 运行时 | 系统 Node 版本为 16,而插件定义的 loader 要求 18+ |
| 5 | 升级 Node 到 20 LTS,重新执行激活 | 两个插件正常激活,Web Boot 启动成功 |
核心结论是:插件没有激活,不是“没有加载”,而是它的前置运行时条件没被满足。Harness 的插件机制对运行环境有非常具体的版本要求,这类问题在传统 IDE 插件生态里往往会被自动处理,但在这种轻量级框架里,环境一致性就得自己保证。
之后我还发现,测试环境里如果用了精简版容器镜像,缺少make、g++这类构建工具,也会导致部分插件依赖无法编译。所以如果你在安装时遇到 “build failed” 或者 “did not activate”,先补全基础构建链,可能比去改插件配置更有效。
5.3 模型接入与 skill 配置的常见坑
模型接入这块,主要有三个坑需要记下来。
第一个坑是 Base URL 配置不一致。如果你走 Ollama 后端,Harness 配置文件里填写的 endpoint 要和 Ollama 的监听地址完全一致(包括/v1路径)。本地部署 DeepSeek 模型时,很多人直接把 API 的 base_url 填成了模型服务地址,漏了版本路径,结果连接报错。另外,如果你有多个模型后端,建议在配置文件里给每个模型单独写一个 provider 块,不要偷懒共用同一个默认配置,不然模型切换时会出现“请求 Ver3 却发给了 8B 模型”这种乌龙。
第二个坑是 skill 的输出格式声明不够严格。我在写 skill 时有一段时间没给 step 声明 output schema,模型在生成计划时偶尔会返回纯文本而不是结构化 YAML,导致后续解析失败。后来强制要求每个 step 的 output 声明格式,并把 schema 直接写进 skill 配置,这类问题基本消失。让模型处理“格式模糊“的任务,它就会按它认为最顺的格式来;把格式钉死,它反而会老实执行。
第三个坑是模型选择对质量的非线性影响。我在同一条 SDD 流程里对比过 DeepSeek 蒸馏版和 Qwen3 8B:简单 CRUD 任务相差不大;但涉及多文件、多入参、多异常场景的复杂 spec,Qwen3 8B 常常会忽略特定负面验收,而 27B 或 R1 蒸馏版就能覆盖更多边界。后来我的策略是:日常维护走轻量模型,复杂规格切换到更大的模型。这本质上是一种“按规格复杂度调度模型算力”的思路,也和 Harness 的模型路由能力契合。
6. 从个人装机到团队工程:把可控性变成流程
6.1 Harness 和普通 Agent 到底差在哪
网上经常有人问“harness 和 agent 区别”。我的理解:普通 Agent 是“会做事的人”,Harness 是“管理做事方式的体系”。
| 维度 | 普通 Agent(聊天式) | Harness 工程框架 |
|---|---|---|
| 上下文 | 单次会话内,易失 | 持久化状态,跨 session 保留关键决策 |
| 工具权限 | 模型想调就调 | skill 限定范围,按步骤分配 |
| 验证 | 无内置验证 | 每个 step 后可强制执行测试/检查 |
| 可审计性 | 聊天记录难以检索 | 结构化日志,可回放决策 |
| 多步编排 | 靠 prompt 硬撑 | 流程驱动,失败可重试、可暂停 |
用一句大白话说:普通 Agent 是一个很聪明但不记事的实习生,Harness 是这位实习生所在的项目组——有流程、有评审、有周报、有验收。单个 Agent 再聪明,没有流程约束,也早晚会把项目带偏。
6.2 自我纠错是模型能力还是工程能力
很多人在选型时会纠结一个问题:到底是选一个号称“自我纠错”能力的模型/工具,还是选 Harness 这种靠外部循环纠错的框架。热词里“harness和hermes哪个是自我纠错”大概就是在问这个。
我的实测体会是:模型层面的自我纠错,本质上是“在推理过程中自己发现不对并修正”,这依赖模型的内隐能力,不稳定、不可控;而 Harness 的纠错是外部的、确定性的——spec 里写了验收条件,测试跑了没过,那就是没过,没有任何商量余地。
打个比方:让一个司机“自己感觉方向偏了并修正”,和给车装上车道保持系统,是两件完全不同的事。前者看状态,后者看机制。所以我的选择很明确:纠错不要押在模型自觉上,押在验证脚本上。Harness 的价值不在于让模型“更聪明”,而在于让模型的每一次错误都能被迅速暴露、被记录、被修复。这才是工程意义上的自我纠错。
6.3 在真实项目里推进的节奏与边界
最后说说团队落地。我不建议你在一个大型遗留项目上直接推行 SDD + Harness,那样大概率会在第一周就被业务压力压垮。我的经验是把推进节奏拆成三个阶段。
第一阶段(1 周):个人验证。找一个边界清晰的小模块,比如日志格式化、缓存策略、数据脱敏工具,按 SDD 流程写 spec、跑 Harness。目标是让你自己熟悉工具链和失败模式,不需要团队参与。
第二阶段(2-3 周):单服务试点。选一个内部服务,规定所有新增功能必须带 spec 文件,所有代码必须通过自动验收。这个阶段的核心是积累适配团队业务的 skill 模板,把常见的“代码评审意见”转化为 skill 里的约束规则。比如我们团队经常要求“所有 Redis 操作必须带超时时间”,那我就把它写进公共 skill,让 AI 在生成代码时自动遵守。
第三阶段(1-2 个月):建立 skill 库和规格评审习惯。当团队成员开始主动反馈“哪些规格写得好、哪些验收不好写”,就说明这套流程真正扎下根了。此时再用 Harness 的日志来开技术评审会,效果会比看聊天记录好很多——因为你能直接展示 AI 的决策过程和验证结果,而不是事后猜它的实现意图。
同时要划清边界:不是所有工作都适合 SDD + Harness。探索性原型、一次性数据分析、 UI 视觉调优这类“边看边改”的工作,仍然适合更轻量的交互模式。SDD 的价值在“需求相对明确、行为可以验证”的工程任务上才会最大化。强行套用,只会制造大量的规格废话和验证负担。
我自己跑完这套流程的最大体会是:所谓“AI 原生软件工程”,不是让 AI 接管一切,而是把人的工程纪律翻译成 AI 能理解和执行的规格,再用一个可靠的执行器去落地。SDD 提供的是“方向”,Harness 提供的是“路况反馈”,模型提供的是“动力”。三者缺一不可。
最后分享一个小技巧。当 AI 交付的结果不符合预期时,别急着在 prompt 里骂它,也别临时加一句“下次注意”。把这次不满意翻译成一条负面验收规则,补进 spec 的异常场景或验收列表里。比如它这次缓存了敏感字段,你就加一条“敏感字段永不入缓存”的执行断言。坚持一个月,你会发现 AI 的“性格”越来越稳,因为它不再靠猜你的心情,而是靠守你的规则。这大概就是把氛围编码升级成工程的最实在的一步。