Harness Engineering 实践:我让 Claude 对项目做了一次改造

6 阅读8分钟

本文记录了一次真实的 AI 辅助重构过程:把一个只有单页JSON格式化功能的 Next.js 项目,如何在 Harness Engineering 思想指导下,演变为拥有 80+ 工具、双语支持、全套 SEO 的工具箱——以及这个过程中架构思想与代码规范是如何一步步沉淀的。

一、背景 这是一个什么项目,原来是什么样

站点: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 EngineeringHarness Engineering
如何写 Prompt如何组织整个 AI 工作流
输入优化系统优化
一次性生成多步骤执行
AI 输出即结束AI 输出只是开始
人工检查自动验证

它不是某个具体的设计模式,可以理解为一种约束项目生长方式的工程哲学。把所有重复、容易遗漏、需要记忆的动作,进行收敛,让系统自动完成所有派生工作。

Claude对项目进行Harness Engineering改造,做了什么,有什么沉淀

改造一:建立注册中心

第一步是建立 lib/tools/registry.ts —— 整个项目的唯一数据来源(Single Source of Truth)。

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 标签
  • 响应式布局

现在只需要:

// 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;
  }
}

页面里直接调用:

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 漏配,不需要纠结样式不一致。

把记忆成本交给系统,把脑力留给真正的业务逻辑。