Harness Engineering 实践:我让 Claude 对项目做了一次改造
> 本文记录了一次真实的 AI 辅助重构过程:把一个只有单页JSON格式化功能的 Next.js 项目,如何在 Harness Engineering 思想指导下,演变为拥有 80+ 工具、双语支持、全套 SEO 的工具箱——以及这个过程中架构思想与代码规范是如何一步步沉淀的。
## 一、背景 这是一个什么项目,原来是什么样
站点:https://toolgarden.xyz/zh
平时开发过程中,经常会打开各种在线工具网站:
- JSON 格式化
- 图片格式转换
- PDF 处理
- Base64 编解码
- URL 编码
- 文件转换
- Markdown 工具
每个工具都在不同的网站,来回切换非常麻烦,我想让AI做一个在线工具箱,一个网站全部解决,不需要再到处找工具了,省得每次都要去搜索,然后点进一堆广告页面。
项目一开始非常简单,就是一个 `create-next-app` 创建的 Next.js 应用,Harness Engineering 改造前,工具箱只有一个 `/json-format` 页面。所有逻辑塞组件里——UI 状态、JSON 解析、格式化算法、错误处理全部耦合:
项目结构大致如下:
```
app/
page.tsx
json-format/
page.tsx
components/
Header.tsx
Footer.tsx
```
`json-format/page.tsx` 一个页面同时承担:
- UI 渲染
- 状态管理
- JSON 解析
- JSON 格式化
- 错误处理
- 树形展示
如果要加第二个工具(比如 JSON 对比),需要:复制页面、首页增加入口、加导航链接、改面包屑、添加sitemap……每增加一个功能,都需要记住哪里要改、一共要改几处。这是典型的 **认知债务** —— 架构依赖开发者的记忆,而不是代码自身的约束。
SEO和国际化成本也很高,几乎所有页面都要重新组织。实际上,这是一个典型的:功能能跑,但无法持续扩展的项目。
## 什么是 Harness Engineering
Harness Engineering 可以理解为:
**围绕 AI 构建”控制层(Harness)”,让 AI 能够稳定、安全、高质量地完成软件开发任务。**
这里的 **Harness** 并不是 AI 本身,而是连接 **开发者、AI、代码库、工具链** 的一层基础设施。
它负责:
- 提供稳定的上下文(Context)
- 调用各种工具(Tools)
- 执行代码
- 验证结果
- 自动修复错误
- 保证输出质量
Harness Engineering 和 Prompt Engineering 有什么区别:
**Prompt Engineering** | **Harness Engineering** |
| ---------------------- | ----------------------- |
| 如何写 Prompt | 如何组织整个 AI 工作流 |
| 输入优化 | 系统优化 |
| 一次性生成 | 多步骤执行 |
| AI 输出即结束 | AI 输出只是开始 |
| 人工检查 | 自动验证 |
它不是某个具体的设计模式,可以理解为一种约束项目生长方式的工程哲学。把所有重复、容易遗漏、需要记忆的动作,进行收敛,让系统自动完成所有派生工作。
## Claude对项目进行Harness Engineering改造,做了什么,有什么沉淀
### 改造一:建立注册中心
第一步是建立 `lib/tools/registry.ts` —— 整个项目的**唯一数据来源**(Single Source of Truth)。
```typescript
export const toolRegistry = [
{
id: "json-format",
category: "format",
path: "/json-format"
}
]
```
之后,所有与工具相关的信息都从 Registry 自动派生。
包括:
- 首页工具列表
- 分类页面
- 导航菜单
- Breadcrumb
- Sitemap
- 推荐工具
- SEO 配置
整个项目只有一份工具定义,新增工具时,只需要注册一次,其他页面自动更新,再也不用记"还要改哪几个文件"。这就是:**Single Source of Truth**
### 改造二、统一页面布局和响应时规范
Claude 抽出了统一页面骨架, 工具页面只负责自身交互。ToolLayout 负责:
以前每个页面都需要自己维护:
- 页面标题和描述
- 面包屑导航
- JSON-LD 结构化数据
- SEO meta 标签
- 响应式布局
现在只需要:
``` react
// app/json-format/page.tsx
export default function JsonFormatPage() {
return (
<ToolLayout toolId="json-format">
<JsonFormatClient />
</ToolLayout>
);
}
```
### 改造三、建立清晰的分层架构
Claude 把项目拆成:
```
lib/
utils/ // 纯工具函数,无 React,无 DOM
tools/ // 工具业务逻辑
registry.ts
seo.ts
sitemap.ts
components/
ui/ // 通用 UI 组件
tools/ // 工具专用组件
app/
[lang]/ // 路由页面,尽量薄
```
并明确各层职责:
- 页面只负责:State、Event、Render
- lib/utils 负责:JSON.parse、Diff 算法、Schema 校验、文件解析
- 组件负责:展示和交互
真正的业务逻辑全部放到 lib/utils, 比如 JSON 格式化的核心逻辑:
```
// lib/utils/json.ts
export function formatJSON(input: string): {
success: true; data: string } | { success: false; error: string }
{
try {
const parsed = JSON.parse(input);
return {
success: true,
data: JSON.stringify(parsed, null, 2)
};
} catch (e) {
return {
success: false,
error: e instanceof Error ? e.message : 'Unknown error'
};
}
}
export function minifyJSON(input: string): string {
return JSON.stringify(JSON.parse(input));
}
export function validateJSON(input: string): boolean {
try {
JSON.parse(input);
return true;
} catch {
return false;
}
}
```
页面里直接调用:
```ts
const result = formatJSON(input);
if (result.success) {
setOutput(result.data);
} else {
setError(result.error);
}
```
好处很明显:这些函数可以在单元测试里直接跑,不需要挂载 React 组件。而且以后做 CLI 版本或者 Worker 版本,这些逻辑可以直接复用
### 改造四:建立统一设计 Token
用语义 Token 代替硬编码颜色, 项目不再继续使用:
```
bg-gray-100
text-gray-500
```
而是统一改成语义化 Token:
```
--surface
--content-muted
--action
```
这样带来的好处有很多:
- 深色模式切换更容易
- 品牌主题更容易调整
- UI 与颜色彻底解耦
- 不需要全局搜索替换颜色
以后即使整体换一套设计风格,大部分组件都无需修改,实现主题与组件解耦。
### 改造五:SEO 系统化
工具站最大的流量来源就是搜索引擎,因此 SEO 必须工程化,而不是手工维护。
整个系统统一生成:
* sitemap
* robots
* canonical
* hreflang
* Open Graph
* JSON-LD
* llms.txt
* llms-full.txt
所有内容都根据 Registry 自动派生,新增一个工具后,不需要再修改任何 SEO 文件。
### 改造六:统一响应式规范
除了架构,很多体验细节也被整理成统一规范。
例如:
- 输入区域自动撑满剩余空间
- 双栏布局自动适配宽屏
- 避免固定 40vh
- 小屏优先保证编辑体验
- 保持工具之间一致的间距与留白
这些看起来只是一些小细节,但随着工具越来越多,它们决定了整个站点的一致性。
### 改造七:规则文档沉淀
重构完成后,又把所有约束整理成文档:
```
AGENTS.md
CLAUDE.md
```
包括:
- 项目结构
- 开发流程
- 命名规范
- 新增工具步骤
- AI 编码约束
这是整个改造过程中最重要的一步,因为真正能够长期发挥作用的,不是某一段代码,而是能够持续约束后续开发的规则。
### 上面的改造,最终形成了一套完整的 Harness Engineering 规则
#### **规则一:单一事实源**
所有工具信息只能维护在:
```
lib/tools/registry.ts
```
禁止首页、导航、SEO 各维护一份配置。
#### 规则二:Registry 驱动
所有工具逻辑都必须自动派生:
* 首页
* 分类
* 推荐
* Sitemap
* Breadcrumb
不能手写。
#### 规则三:新增工具只改固定位置
标准流程:
1. 注册 Registry
2. 补 messages
3. 实现 utils
4. 创建 page
5. 接入 ToolLayout
如果新增一个工具需要修改第六处代码,说明架构需要继续优化。
#### 规则四:页面保持轻量
页面只负责:
- State
- Event
- Render
禁止直接写在页面中:
- JSON.parse
- Diff算法
- Schema校验
- 文件解析
#### 规则五:纯函数优先
所有业务逻辑统一放到: `lib/utils`
要求:
- 无 React
- 无 DOM
- 无副作用
- 可独立测试
#### 规则六:所有工具统一 Layout
所有工具页面必须接入:
```
<ToolLayout>
```
页面结构保持一致。
#### 规则七:SEO 自动生成
新增工具后,应自动获得:
- metadata
- JSON-LD
- sitemap
- llms
无需额外维护。
#### UI 使用语义 Token
禁止直接使用:
```
text-gray-500
bg-red-100
```
统一使用:
```
text-content-muted
bg-surface
```
保证主题切换和设计演进。
#### 规则九:404 页面也是系统的一部分
404 页面同样需要:
* 国际化
* 推荐工具
* Registry 派生
不能成为一个孤立页面。
#### 规则十:验证成为流程
验证成为开发流程的一部分
每次结构调整后,都必须执行:
```
npm run lint
npx tsc --noEmit
npm run build
```
最后还要进行真实浏览器验证。
## 重构后的变化
经过这一轮改造,项目已经从最初只有一个工具,逐渐发展到拥有 80+ 在线工具。
新增一个工具的成本,也从原来的「到处修改配置」,变成了一套固定流程。
更重要的是,项目开始具备持续演进的能力:
- 工具越来越多,但维护成本没有线性增长
- SEO、导航、国际化等能力自动继承
- 页面职责清晰,业务逻辑可复用
- AI 能够按照统一规范持续开发,而不是每次都重新摸索项目结构
## 总结
Harness Engineering 的本质,不是为了让代码看起来有"设计感"或者"架构感"。
它真正解决的是:在持续迭代中,如何保持一致性、可维护性和低扩展成本。
**先搭好约束和轨道,再让功能沿着轨道生长**。这样每新增一个工具,不需要记住"还要改哪几个文件",不需要担心 SEO 漏配,不需要纠结样式不一致。
把记忆成本交给系统,把脑力留给真正的业务逻辑。
浙公网安备 33010602011771号