先把仓库改造成 Agent 能干活的地方:Harness 的作用 📅 2026/7/22 5:26:53 先把仓库改造成 Agent 能干活的地方Harness 的作用本文是「AI 编程铁三角」系列的第一篇。铁三角由三层构成各管一件事Harness管工程环境——让 Agent 在一个可理解、可验证、可约束的仓库里工作OpenSpec管需求规格——把模糊需求变成 Agent 无法误读的可执行规格Superpowers管执行流程——把编码过程拆成小步每步留证据。三者不是三个工具选一个用而是「规范—执行—验证」的闭环。本篇只讲第一件事为什么不能先装 AI 工具再摸索以及怎么把仓库变成 Agent 真正能干活的地方。一、先问一个问题你的仓库Agent 看得懂吗很多团队上 AI Coding 的顺序是反的先装工具再让开发者自行摸索。结果是每个人用法不同Agent 反复猜测构建方式和目录边界最终形成大量不可复用的对话。对 Agent 而言看不到的工程事实等于不存在。仓库里必须有一套稳定、可执行的最短路径如何初始化如何编译如何运行单元测试如何执行静态分析如何在目标板部署哪些目录属于生成物哪些文件严禁修改这些不是文档里的散文而是 Agent 一条命令就能跑出来、并能据此判断我现在能不能开始干活的事实。没有这套基线Agent 就会在错误分支、脏工作区或过期构建结果上继续工作并把工程风险放大。二、Harness 的五层上下文Harness 不是一份 AGENTS.md而是分层的上下文体系。从稳定到易变大致分五层组织级安全红线、编码规范、合规要求。稳定适合版本化管理。仓库级仓库用途、构建入口、禁止修改目录。稳定。模块级模块所有权规则、热路径约束、并发模型。半稳定。任务级本次变更的规格、允许修改范围、审批点。随变更更新。动态上下文当前分支、未提交修改、基线测试、工具链版本、目标板状态。每次任务前由脚本自动生成。组织级和仓库级内容稳定适合版本化管理任务级和动态上下文随变更更新应由脚本自动生成避免人工抄写过期信息。三、指令文件一份源多入口不同 Agent 对项目指令文件的名称和加载规则不同Codex 用AGENTS.mdClaude Code 用CLAUDE.md和目录级 rules。企业落地时不应维护两套互相矛盾的内容。推荐做法以一份平台无关的ENGINEERING_GUIDE.md为源再通过软链接、生成脚本或精简映射同步到各工具入口。判断是否落地成功只看三类职责是否完整不看工具名字是否一致。仓库级AGENTS.md的骨架大致长这样以一个含控制面/数据面分层的系统级项目为例字段可按实际仓库替换# AGENTS.md仓库级示例 ## Repository purpose 本仓库用于系统级软件开发包含 controlplane、dataplane、platform 和 tests。 ## Mandatory workflow 1. 修改前读取本文件、目标模块的 AGENTS.override.md 和对应 OpenSpec 变更。 2. 先运行 scripts/context.sh确认分支、基线测试和工具链。 3. 新增或修复行为必须先提交失败测试不能主机测试的内容必须说明原因并提供替代证据。 4. 不得修改 third_party、generated、sdk/vendor确需修改必须等待人工审批。 5. 每次完成任务必须执行 scripts/verify_changed.sh并在报告中列出命令与返回码。 ## Critical constraints - 数据面热路径禁止动态内存分配、阻塞 I/O 和无采样日志。 - 所有网络长度字段在加减乘前完成上界与溢出检查。 - 跨线程对象必须声明所有权和同步方式。 - 不得改变持久化配置格式、HA 协议和对外 API除非 design.md 已明确。有效指令的关键是短、具体、可验证。代码要高质量几乎没有约束力所有网络长度字段在计算前检查新增解析器必须通过 fuzz_parser 语料 10 分钟且 ASan/UBSan 无报告才是可以执行的规则。四、权限默认拒绝最小授权Coding Agent 通常具备读文件、写文件、执行 Shell、访问网络和调用外部工具的能力。源代码、漏洞信息、私有 SDK、签名密钥和客户数据都可能属于敏感资产。权限设计的原则是默认拒绝、按任务最小授权敏感目录由文件权限和 Agent ignore 共同保护外发流量经过 API 网关和 DLP执行环境使用容器或受限用户危险命令由 PreToolUse/Hook 阻断审计日志关联用户、角色、阶段和场景仅靠员工承诺不能构成保护。安全策略必须落到技术控制上。五、Hooks把建议变成无法绕过的门禁Harness 的价值在于把建议变成无法绕过的门禁。三类 Hook 职责不同Agent HookPreToolUse/PostToolUse防止即时危险动作例如阻止写入third_party/。Git Hook提交前检查格式、敏感信息、禁止修改路径提前反馈。CI合并前完成独立验证提供可信的最终结果。门禁可以分阶段执行开发早期跑增量和主机侧检查合并前再跑多配置构建、目标板、性能和回归。一个可复用的增量验证脚本长这样#!/usr/bin/env bash# scripts/verify_changed.shset-euopipefailBASE${BASE_REF:-origin/main}CHANGED$(gitdiff--name-only$BASE...HEAD)echo[1/5] formattingclang-format --dry-run--Werror$(echo$CHANGED|grep-E\.(c|h|cc|cpp|hpp)$||true)echo[2/5] host buildcmake--presethost-debug cmake--build--presethost-debug-jecho[3/5] unit testsctest--presethost-unit --output-on-failureecho[4/5] static analysisscripts/run_clang_tidy_changed.sh$BASEecho[5/5] policy checksscripts/check_forbidden_changes.sh$BASE这个脚本的意义不是跑一遍而是让 Agent 在每次任务结束时必须列出命令与返回码把验证变成可复查的证据。六、动态上下文让 Agent 看见当前事实静态指令描述长期规则动态上下文描述当前事实。Agent 开始任务前应自动生成CONTEXT.md或 JSON内容包括当前分支、HEAD未提交修改基线测试是否通过编译器和 SDK 版本目标板状态最近失败本次允许修改的文件一个最小可用的生成脚本#!/usr/bin/env bash# scripts/context.shset-e{echo# Dynamic Contextechogenerated_at:$(date-Iseconds)echobranch:$(gitbranch --show-current)echohead:$(gitrev-parse--shortHEAD)echodirty_files:gitstatus--short|seds/^/ - /echocompiler:$(clang--version|head-1)echotoolchain:${TARGET_TOOLCHAIN:-unknown}echobaseline_unit_test:ctest--presethost-unit --output-on-failureecho status: pass||echo status: fail}.ai/CONTEXT.md这一步看似简单却能挡掉一类高频错误Agent 在错误分支、脏工作区或基线已坏的情况下继续努力工作。七、熵管理Harness 也会退化Harness 不是一次建好就永远有效。长期使用后会出现退化指令越来越长同一规则重复出现测试变慢忽略项累积Agent 频繁犯同类错误建议的维护节奏每个迭代对 Harness 做一次小维护去重、补漏、收紧。每季度做一次系统审计评估指令有效性、门禁覆盖率和 Agent 错误模式。熵管理不是打扫卫生而是保证 Harness 持续约束 Agent 行为的能力。八、小结Harness 先行的真正含义Harness 先行不是先写文档再写代码而是先把仓库变成 Agent 可理解、可验证、可约束的工程再开始批量使用。判断 Harness 是否到位可以问三个问题Agent 一条命令能否拿到当前分支、基线测试和工具链版本Agent 试图修改third_party/或改变对外 API 时会不会被自动阻断每次任务结束时Agent 能不能列出验证命令和返回码而不是用代码看起来正确交差三个都能答是Harness 才算到位。这时再进入下一篇的 OpenSpec规格才有意义——因为 Agent 已经在一个可约束的环境里读规格、写测试、跑验证。下一篇我们讲怎么把模糊需求变成 Agent 无法误读的可执行规格。系列最后一篇会把三层合起来看它们如何共同构成 AI 编程的完整闭环。