# harness-engineering **Repository Path**: fociceo/harness-engineering ## Basic Information - **Project Name**: harness-engineering - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-14 - **Last Updated**: 2026-04-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Harness Engineering:为 AI Coding Agent 构建工程系统 ## 前言 生成式 AI 正在快速进入软件开发的核心流程。从最初的代码补全工具,到能够生成完整模块的 Coding Agent,再到可以自主修复 Bug、执行测试甚至生成 Pull Request 的智能体,软件开发的生产方式正在发生明显变化。许多团队已经开始尝试将 AI 引入开发流程,例如让 Agent 分析 Issue、生成实现代码,并根据 CI 反馈不断修复问题。 然而,当 AI 开始在真实项目中承担更多工作时,一个现实问题很快浮现出来:**AI 写代码的速度,远远超过团队能够控制系统复杂度的能力**。开发者很快会发现,AI 可以在几分钟内生成数千行代码,但这些代码并不一定理解系统架构、历史设计决策或领域规则。如果缺乏工程约束,AI 很容易绕过既有结构,引入新的依赖关系,甚至悄悄改变系统边界。 很多团队最初会把这些问题归因于模型能力,但随着实践深入,一个更清晰的结论逐渐浮现出来:**问题并不在模型,而在软件工程系统本身**。我们今天的大多数工程体系,代码结构、开发工具、流程设计,都是围绕人类开发者构建的。这些系统默认开发者理解上下文、遵守约定,并在评审过程中发现问题。但 AI 并不具备这样的隐性知识。 如果 AI 将成为软件开发流程中的长期参与者,那么软件工程系统本身也需要进化。这正是 **Harness Engineering** 试图解决的问题。 ## 目录 ### 第一部分 定义问题 1. AI Coding 的问题,不只是模型能力问题 2. 从 Human-first 到 Agent-aware 3. Harness Engineering Capability Model ### 第二部分 让系统能够被 Agent 使用 1. 可读性:让系统能够被 AI 理解 2. 高度自动化的工作流 3. 防御机制:收敛 AI 的行动空间 4. 从 Codex Security 看 AI 生成代码的治理 5. 反馈回路:让系统能够持续学习 ### 第三部分 定义完成条件 1. Fitness Function:定义 AI Agent 的完成条件 2. 多层次适应度函数:从架构治理到 Agent Loop ### 第四部分 从工具到系统 1. 软件开发正在变成循环系统 2. Human 与 Agent 共同运行的软件工程系统 ## 1. AI Coding 的问题,不只是模型能力问题 Harness Engineering 之所以在过去几个月迅速成为一个热门话题,很大程度上是因为越来越多团队意识到:AI Coding 的问题,从来不只是模型能力问题。上下文工程、提示词策略、多 Agent 协作都很重要,但这些讨论大多仍然停留在“生成侧”。一旦 AI Agent 真正进入软件交付流程,问题的重心就会迅速转移。 真正困难的问题不是“Agent 能不能写出代码”,而是:**系统究竟如何判断,这个 Agent 已经完成了任务。** 在传统软件工程中,“完成”是一种被团队经验默契支撑的判断。开发者写完代码、跑过测试、提交 PR、经过 code review,团队逐渐形成共识。但在 Agent Loop 中,这个默认前提不再成立。Agent 可以很快生成代码、修掉报错,但它同样很容易制造另一类结果:代码看起来已经完成,实际上只是完成了一半。 这种情况在实践中并不少见。功能路径可以跑通,但负向路径没有覆盖;接口已经修改,但契约没有同步;测试数量增加了,但关键不变量并没有被验证。**如果系统没有明确的完成条件,Agent Loop 很容易在“看起来差不多了”的状态下提前结束。** 因此,当 Harness Engineering 真正落地时,它面对的下一个问题并不是如何生成代码,而是如何把“完成”这件事,从经验判断转化为**可执行、可审计、可阻断的工程信号**。 ## 2. 从 Human-first 到 Agent-aware 传统的软件工程体系是围绕人类开发者设计的。代码仓库的结构、开发工具的界面、CI/CD 的操作方式,都假设使用者是人类。例如,很多开发工具依赖图形界面或隐含约定,而不是机器接口;许多关键知识存在于团队经验或历史文档中,而不是结构化数据。 当 AI 进入开发流程时,这些假设开始失效。AI 并不能像人类一样通过阅读零散文档理解系统,也无法从团队经验中获得隐性知识。如果没有明确表达系统结构和规则,AI 生成的代码往往会偏离设计意图。 因此,AI Coding 的关键并不是简单地把模型接入开发工具,而是要将软件工程系统从 **Human-first system** 转变为 **Agent-aware system**。这意味着工程系统需要被重新设计,使其能够被机器理解、调用和验证。 Harness Engineering 正是在这样的背景下提出的一种工程实践。 ## 3. Harness Engineering Capability Model 在实践中,团队通常需要在三个层面重新设计工程系统。为了理解这些能力之间的关系,可以用一个简单的模型来描述: ```text 反馈回路 ▲ │ 系统可读性 ─── 防御机制 ─── 自动化反馈 ``` 这个模型的含义并不复杂。系统首先需要具备足够的可读性,使 AI 能够理解结构和上下文;在此基础上,工程系统需要提供明确的边界,以限制 AI 的行为范围;最后,系统还必须持续向 AI 提供反馈,使其能够不断修正行为并改进结果。 这三个能力共同构成了 Harness Engineering 的核心。 ## 4. 可读性:让系统能够被 AI 理解 在很多软件项目中,系统知识往往分散在不同位置。代码中包含实现细节,文档记录部分设计,而真正的领域规则和架构意图往往存在于团队经验之中。对于人类开发者来说,这些信息可以通过交流逐渐理解,但 AI 并没有这样的能力。 如果希望 AI 能够可靠地生成代码,就必须逐渐将这些隐性知识显性化。系统的结构、架构原则和领域概念需要被明确表达,并以机器可读的形式组织起来。代码仓库在这种环境中不再只是代码存储空间,而更像是一张可导航的知识地图。AI 可以从高层架构文档进入系统,然后逐步探索模块结构、领域模型以及实现细节。 另一个重要变化是上下文提供方式。复杂系统往往包含大量信息,如果一次性提供全部文档,反而会增加推理的不稳定性。更有效的方式是逐步披露上下文,使 AI 根据任务逐渐获取所需信息。这样一来,AI 的理解过程更接近人类开发者探索系统的方式。 同时,工程工具本身也需要调整。许多开发工具最初是为人类界面设计的,例如 Web UI 或交互式流程。对于 AI 来说,这些接口并不友好。将系统能力暴露为 CLI 或 API,使其可以通过机器接口访问,是构建 Agent-aware 系统的重要一步。 从更早的架构治理实践来看,这种“可读性”并不只是文档问题,也是一种架构表达问题。正如我在过往文章里写的: > C4 代表上下文(Context)、容器(Container)、组件(Component)和代码(Code)——一系列分层的图表,可以用这些图表来描述不同缩放级别的软件架构,每种图表都适用于不同的受众。 换句话来说,系统需要有一种可以真正反映系统结构的表达方式。对人类开发者如此,对 AI Agent 更是如此。 ## 5. 高度自动化的工作流 如果系统只是“可读”,还不足以支撑 Agent 持续工作。对于 Agent 来说,工作流同样需要被明确表达,并尽可能自动化。过去很多流程之所以能够运转,是因为团队成员默认知道该先做什么、后做什么、遇到异常时找谁处理。但这些隐性知识对 Agent 并不成立。 在更早的架构治理讨论里,我曾经把这类问题归纳为“高度自动化的工作流”: > 作为一个程序员,我们除了不喜欢写文档,我们还不喜欢看别人写的文档。 这句话放在 AI 时代同样成立。区别在于,人类可以靠经验跳过文档,Agent 做不到。因此,工作流不能只存在于团队默契里,而需要以脚本、命令、Hooks、CI 配置和可视化路径的方式存在。 对于一个技术先进的组织来说,一个新的项目成员来到这个项目时: - ta 的开发机器应该能执行一个或者多个脚本,便能完成开发系统的初始化 - ta 的开发环境应该能执行一个或者多个脚本,便能完成开发环境的设备 - ta 的开发环境应该能执行一个或者多个脚本,便能运行起来 - ta 的代码提交到版本管理服务器时,便能完成自动部署到测试环境 如果做不到自动化,那么就可视化。这也是为什么 Path to Production、提交 Hooks、Lint、命名规范、提交信息规范这些看似“老派”的工程实践,在 Agent 时代反而重新变得重要。它们不是为了让流程更正式,而是为了让流程可以被稳定执行。 除此,在这些工作流中,我们还会穿插一些代码规范: - 提交 Hooks,诸如于 `prepush` 或者是 `precommit` - 代码风格自动审查(Lint) - 提交信息格式 - 命名规范 对于 Agent 来说,入口往往比说明更重要。系统首先需要把 Agent 带到正确的位置,而不是一开始就理解整个工程。 ## 6. 防御机制:收敛 AI 的行动空间 在传统开发流程中,系统通常依赖开发者的经验来避免架构问题。例如,当代码评审发现不合理的依赖关系时,团队会手动修正。然而,当代码生成速度大幅提高时,这种方式很难维持系统稳定。 AI 的生成能力非常强,如果缺乏约束,它可能在系统中引入新的复杂度。例如重复实现已有逻辑、绕过既有模块边界,或者创建新的隐式依赖关系。这些变化在短期内可能并不明显,但随着时间推移,系统结构会逐渐腐化。 因此,在 AI Coding 环境中,工程系统需要承担更多防御职责。许多团队已经在持续交付实践中使用类似机制,例如静态分析、自动化测试和架构验证。但在 AI Coding 环境中,这些机制的意义发生了变化。它们不再只是质量保障手段,而是系统边界的一部分。 换句话说,这些工程约束就像系统的“物理定律”。AI 可以自由探索解决方案,但无法突破这些规则。通过自动化工具持续执行这些约束,团队可以确保系统在高频修改的情况下仍然保持结构稳定。 如果从更早的演进式架构视角来看,这类约束其实并不陌生。我们曾经把它们统称为“适应度函数”: > 当我们划定了四层架构之后,我们会发现大部分软件系统的设计有出现一定的问题,只设计了顶层架构,缺少了代码级别的基础适应度函数的设计。 以及: > 只要能帮助系统持续性变好,就可以称之为适应度函数。 放到 AI 时代,这句话变得更具体了。它不只是帮助系统持续性变好,也是在限制 AI 和人类共同生成代码时的误用空间。 ## 7. 从 Codex Security 看 AI 生成代码的治理 在过去一段时间里,我们对多个开源项目运行了 **Codex Security** 的安全扫描工具,并对这些项目产生的 findings 做了一次系统性分析。与传统的安全扫描不同,这些报告不仅包含漏洞列表,还提供了完整的攻击路径、动态验证结果以及可应用的修复补丁。某种意义上,它更像一次自动化安全审计,而不是一次简单的静态代码检查。 这些扫描覆盖的项目大多并不是所谓的“AI 系统”。它们只是普通应用,只不过部分代码由 AI 辅助生成。这一点非常重要,因为它改变了我们理解问题的方式。AI 并没有创造一种新的软件系统类型,也没有发明全新的漏洞类别。最终运行在服务器上的仍然是一个普通应用,它有 API、前端渲染链、数据库访问、外部请求以及部署环境。真正发生变化的,是代码的生产方式。 当代码生成成本下降时,代码产量会迅速上升。如果工程系统没有相应的约束机制,这种增长往往会同时放大缺陷传播速度。因此,与其说我们需要“AI 安全”,不如说我们需要一种新的方式来治理 **大规模自动生成的代码**。这正是 Harness Engineering 在防御视角下的价值所在。 如果从漏洞类型来看,Codex Security 的 findings 并没有太多陌生内容。扫描结果中最常见的仍然是那些已经存在几十年的安全模式:未认证 API、命令注入、SSRF、HTML 渲染未清洗内容以及权限绕过。换句话说,我们面对的仍然是熟悉的软件缺陷。 真正发生变化的不是漏洞类型,而是 **缺陷扩散机制**。 在传统开发模式中,一个不严谨的实现可能来自某个开发者的疏忽或经验不足。代码 review、测试以及团队经验通常可以在一定程度上阻止这些问题扩散。但在 AI 辅助开发中,一旦模型生成了一种“看起来合理”的实现模式,这种模式就可能在多个模块、多个文件甚至多个仓库中重复出现。模型不会自动理解团队的安全边界,它只会复现训练数据中常见的实现方式。因此,如果系统没有明确的工程约束,错误实现就可能被系统化复制。 从软件工程角度看,AI 更像一个 **缺陷放大器**。过去偶尔出现的错误模式,现在可能在短时间内被复制几十次。这也是为什么在 AI 时代,仅依赖人工 code review 已经难以维持同样的安全水平。代码生成速度越高,约束就必须越自动化。 在分析 Codex Security 的 findings 时,我们还观察到了一类新的风险模式。这些问题并不是传统应用中的典型漏洞,而是与 AI 开发工具的行为直接相关。例如在多个项目中,都出现了类似这样的配置: ```text --dangerously-skip-permissions --allow-all-tools bypassPermissions: true ``` 这些参数通常出现在 AI Agent 或 CLI 工具的启动配置中,其目的往往是减少交互成本,让 Agent 可以自动调用工具。在本地开发环境中,这种配置可能只是一个便利选项。但一旦代码被部署到服务器环境,这类参数就可能绕过所有权限确认机制,使系统能够在没有用户干预的情况下执行高风险操作。 这种风险与传统漏洞的不同之处在于,它并不是某一段代码的问题,而是 **工具行为与系统环境之间的不匹配**。模型可能会生成这些参数,因为它们在某些示例中是合法的;但在真实系统中,它们意味着权限控制被完全绕过。 因此,AI 时代的安全扫描开始出现新的方向:不仅需要检查代码中的危险调用,还需要识别 **AI 工具的危险使用模式**。这些模式往往隐藏在配置、命令行参数或工具调用链中,如果没有专门规则,很容易被忽略。 从这个角度看,Harness Engineering 不只是一个提升 AI 编程效率的实践,它同样是一种防御架构。 ## 8. 反馈回路:让系统能够持续学习 如果说工程约束为 AI 提供了边界,那么反馈系统则为 AI 提供了方向。在传统开发流程中,开发者通过编译错误、测试结果和代码评审不断调整实现方式。AI Coding 其实需要类似的机制,只不过这一循环可以发生得更快。 在一个设计良好的工程系统中,AI 每完成一次修改都会立即获得反馈。开发环境中的静态分析和测试可以提供第一层信号,而代码提交后,CI 系统又会产生新的验证结果。当系统上线后,监控数据和运行日志则提供了更长期的反馈。 当这些信号能够被统一收集并提供给 AI 时,软件开发就逐渐从线性流程演变为循环系统。AI 不再只是一次性生成代码,而是在反馈驱动下不断调整实现方式,直到系统达到稳定状态。 这种模式与传统 DevOps 的持续交付理念非常相似。不同之处在于,在 AI Coding 环境中,这些循环往往可以在更短时间内完成。 ## 9. Fitness Function:定义 AI Agent 的完成条件 Fitness Function 最早来自演进式架构(Evolutionary Architecture)。它的作用是持续验证系统是否满足某些架构特征,例如模块边界、性能约束或依赖方向。但在 AI Agent 参与开发之后,这个概念的角色正在发生变化。 在 Agent 驱动的开发模式下,Fitness Function 不再只是“架构质量检查”,而逐渐成为一种**完成条件机制**。 AI Agent 并不天然理解“真正完成”意味着什么。它往往依赖局部信号来判断进度:命令执行成功、测试通过、报错消失。这些信号在单次操作中是有效的,但它们从来不等价于系统层面的完成。一个 Agent 可能修复了一个错误,同时又引入了新的不一致;也可能通过了现有测试,但破坏了系统契约。 Fitness Function 在这里的价值,是把这些隐性的工程条件编码成系统可执行的规则。它明确告诉系统:**哪些信号必须出现,哪些条件必须满足,否则任务就不能被视为完成。** 从这个角度看,Fitness Function 不再只是一个架构术语,而逐渐成为 Harness Engineering 的核心机制:**它决定 Agent 在什么条件下才被允许退出循环。** 在 Routa 项目中,我们尝试直接在代码库中构建一套完整的 Fitness 架构。一个关键原则是:**Fitness 规则必须成为仓库的一部分,而不是 CI 系统的附属配置。** 只有当规则存在于代码库中,它才能被 Agent 读取、被脚本执行、被 CI 消费,并在失败时真正阻断流程。 项目中的 Fitness 目录结构大致如下: ```text docs/fitness/ ├── README.md # 规则手册 ├── unit-test.md # 测试证据 ├── api-contract.md # 契约证据 ├── rust-api-test.md # API 测试矩阵 ├── security.md # 安全规则 ├── code-quality.md # 代码质量规则 └── scripts/ └── fitness.py # 统一执行器 ``` 整个执行路径从 `AGENTS.md` 开始。这个文件并不试图解释整个系统,而只是提供一个最小入口:当代码发生变更时,Agent 必须运行 Fitness 检查;提交必须保持 baby-step。对于 Agent 来说,入口往往比说明更重要。系统首先需要被带到正确的位置,而不是一开始就理解整个工程。 如果进一步拆开来看,Routa 的实现并不是“写了一些测试”,而是把完成条件编码成了一条完整的仓库内链路: - `AGENTS.md` 提供最小入口,只声明 Agent 必须遵守的执行边界,例如先看哪里、改完后必须跑哪些检查。 - `docs/fitness/*.md` 用 Markdown frontmatter 声明规则,让规则同时对人和机器可读。 - `docs/fitness/scripts/fitness.py` 负责扫描 frontmatter、执行命令、根据输出模式或退出码判断通过与否。 - `.husky/pre-commit` 与 `.husky/pre-push` 再把这些规则接到真实提交流程里,其中 `scripts/smart-check.sh` 会区分 AI 环境与人工环境,决定是直接阻断还是引导修复。 这几个部件合在一起,形成的不是“文档 + CI”的松散组合,而是一个真正能被 Agent 消费的执行框架。也正因为如此,Fitness 在 Routa 中不是 CI 的附属配置,而是代码库本身的组成部分。 ## 10. 多层次适应度函数:从架构治理到 Agent Loop 适应度函数并不是一个新概念。在更早的架构治理实践里,我们已经尝试用它来约束系统演进。 我在更早的文章里写过: > 软件架构的复杂与业务系统的复杂度成正相关,复杂的业务系统其架构自然也就复杂了,简单的业务系统其架构也相对地就简单了。不过,多数的软件系统都是随着业务的发展,而慢慢变得复杂。这种情况下,架构只能不断去演进。 于是,为了设计出演进式架构,我们需要设计出多个适应度函数,以帮助系统不断地演进。而软件架构本身是多层次的,对应的架构适应度函数也是对应于不同的层次。 对应于我们的四个层级,便有了一些常见的适应度函数映射: - 应用 / 监控级:架构守护测试、架构衡量指标、集成测试、监控、契约测试 - 模块级:组件测试、集成测试 - 代码级:单元测试、代码质量指标 如果换一种更简短的写法,它也可以是一组面向工程治理的维度清单: - 代码:代码坏味道、静态分析的技术债务 - 架构设计:分层架构识别、耦合度分析 - 测试:测试覆盖率 - 安全 - 弹性:Docker 配置、K8S 配置、压力测试 - 实时性:应用探针 - 依赖:依赖版本检查 放在今天的 Agent Loop 里,这些内容不再只是“帮助架构演进”的分析维度,而是“定义 Agent 不允许跳过什么”的完成条件维度。 因此,在很多团队里,规则必须可读,也必须可执行。Routa 中一个测试维度的 Fitness 规则可以写成: ```yaml --- dimension: testability weight: 14 threshold: pass: 80 warn: 70 metrics: - name: ts_test_pass command: npm run test:run 2>&1 pattern: "Tests\\s+(\\d+)\\s+passed" hard_gate: true - name: rust_test_pass command: cargo test --workspace 2>&1 pattern: "test result: ok" hard_gate: true --- ``` Frontmatter 提供了一种折中方式:它既是文档的一部分,也是一种结构化声明。如果规则只对机器友好,团队很难自然维护它们;但如果规则只对人友好,系统就无法统一执行。 在 Routa 里,这种 frontmatter 并不只用于“声明要跑什么命令”,它还承担了另一层作用:把规则从零散说明文档里收拢成统一入口。Agent 不需要去猜“这个仓库是不是该先跑 lint、是不是该补契约测试”,而是可以直接读取 `docs/fitness` 下的规则文件,再交给统一执行器做解释。规则解释权因此从“经验”转移到了“仓库内的可执行声明”。 规则声明只是第一层。一个可靠的 Fitness 系统还需要记录验证状态,哪些场景已经 `VERIFIED`,哪些仍然 `TODO`,哪些被标记为 `BLOCKED`。这些文件并不是普通的测试说明书,而更像是**工程账本**。它们把系统中的验证经验沉淀为稳定结构,使代码库逐渐形成一种可被机器和人同时理解的验证上下文。 在 AI Agent 场景中,单纯的评分体系往往是不够的。Agent 很容易把“还不错”误解为“可以结束”。因此,Fitness 系统最终必须具备一个更直接的机制:**Hard Gate**。 | Gate | 命令 | 阈值 | | --- | --- | --- | | ts_test_pass | `npm run test:run` | 100% | | rust_test_pass | `cargo test --workspace` | 100% | | api_contract_parity | `npm run api:check` | pass | | lint_pass | `npm run lint` | 0 errors | Hard Gate 失败会直接阻断流程,而不是进入评分体系。它把“质量折损”和“流程终止”明确区分开来。 在某种意义上,**Hard Gate 就是 Agent 时代的 Definition of Done**:它明确规定,在什么条件下,这个自动化参与者才被允许退出循环。 ## 11. 软件开发正在变成循环系统 一些公司已经开始在真实环境中尝试类似的工程体系。例如 Stripe 在其 Agent Engineering 实践中构建了一套完整的执行循环:工程师通过 Slack 或 CLI 触发任务,Agent 负责生成实现代码并运行测试,如果 CI 失败,系统会自动进入修复循环,直到代码满足基本质量标准后再生成 Pull Request。人类工程师的角色更多是进行最终评审,而不是逐行编写代码。 另外一个典型案例是 **Routa.js**。它的核心特点是:**整个项目既是 AI Agent 的工作环境,也依赖 AI Agent 自身参与开发**。多种 AI Agent 必须协作在同一代码库中,同时遵循统一的工程规范和质量门禁。 更值得注意的是,Routa 某种意义上已经具备了“自举”特征。它一方面是一个面向多 Agent 协作的软件系统,另一方面又把这些 Agent 自己需要遵守的规则写回仓库:`AGENTS.md` 提供入口,`docs/fitness` 定义完成条件,`docs/issues` 沉淀失败经验,hooks 与 `smart-check.sh` 将规则接入提交路径。也就是说,Routa 不是先有一个外部治理系统再去管理 Agent,而是让项目本身逐步成为 Agent 可读、可验证、可纠偏的运行环境。 在这样的系统中,人类开发者的角色开始发生变化。他们不再只是编写代码,而是设计系统、制定规则,并管理这些工程循环。从某种意义上说,人类负责构建系统杠杆,而 AI 则负责放大这些杠杆。 从 Codex Security 的扫描分析中得到的最大启发,并不是 AI 让软件变得更危险,而是 AI 让工程系统中长期存在的问题变得更加明显。当代码生成能力提升时,工程系统必须具备更强的自动化防御能力,否则缺陷只会以更快速度进入代码库。 在这个意义上,AI 时代的软件工程并不是一个完全新的领域。它只是把一个旧问题推到了新的规模:**当代码越来越多时,我们如何确保系统仍然保持正确的边界与约束。** 随着 AI 的加入,软件开发的结构也在发生变化。未来的软件开发将运行在两个不同的循环中。一个循环关注“为什么要做”,也就是业务目标和产品价值,这一部分仍然主要由人类主导;另一个循环关注“如何实现”,也就是代码生成、测试、修复和验证,这一部分越来越多地由 AI 执行。 当 AI 成为软件开发的重要参与者时,软件工程系统也需要随之演进。Harness Engineering 提供了一种新的视角:通过提升系统可读性、建立工程防御机制以及构建高频反馈回路,我们可以让 Coding Agent 在复杂系统中安全运行,并持续提升软件开发效率。 AI Coding 的未来并不是完全自动化的软件开发,而是一个 **Human 与 Agent 共同运行的软件工程系统**。Harness Engineering,正是这一系统的工程基础设施。 ## 12. Human 与 Agent 共同运行的软件工程系统 如果把前面的讨论放在一起,一个更完整的图景就出现了。Harness Engineering 并不是某一个工具、某一套提示词技巧,或者某一个 Agent 平台的代名词。它更接近一组工程原则:让系统具备可读性,让流程具备自动化,让边界具备防御性,让反馈可以持续流动,让完成条件可以被明确定义。 从这个意义上说,Harness Engineering 既继承了传统软件工程中的很多能力,也改变了这些能力的语境。文档不再只是给新人阅读的材料,而是给 Agent 导航的入口。测试不再只是回归质量的手段,而是 Agent 能否退出循环的硬门禁。安全扫描也不再只是安全团队的专属工具,而是约束代码生成速度的一部分。 在更早的文章里,我曾经把适应度函数理解为“指标衡量结构体系”。今天回头看,这个说法仍然成立,只是需要再向前推进一步:当软件生产者不再只有人类时,指标不仅要衡量结构,还要决定行为;不仅要评价结果,还要决定流程何时结束。 因此,AI 时代的软件工程系统,并不是要抛弃我们过去关于演进式架构、持续交付、架构治理、测试策略和自动化工作流的积累。恰恰相反,它是在新的规模下重新理解这些实践。Harness Engineering 提供的,不是一个替代传统软件工程的新名词,而是一种把传统工程能力重新组织起来、使其足以承载 Agent 的方法。