【免费下载链接】learn-harness-engineering
Harness engineering beginner tutorial, from 0 to 1
本篇指南基于 learn-harness-engineering 仓库中 Project 01 的课程设计,讲解如何通过"两次运行"对比实验,量化验证一个核心论断:让能力强大的 AI Agent 完成任务,难点往往不在任务本身,而在于缺少约束与验收规则的引导。第一次运行只给 Agent 一段裸提示词,第二次运行让仓库中预置AGENTS.md、init.sh、feature_list.json组成的最小 harness,最后对比两次的表现差异。读完本文,你将掌握最小 harness 的完整结构、每条规则背后的设计意图、以及如何用源码与验收证据判断 Agent 是否真正完成了任务。
实验要回答的问题
本实验对应的课程背景是两讲关键内容:"为什么能力强的 Agent 仍然会失败" 与 "harness 到底是什么"。实验要构建的最小 Electron 知识库应用本身并不复杂:一个窗口、左侧文档列表、右侧问答面板、一个本地数据目录。真正的难点在于——让 Agent 在没有外部约束的情况下稳定、完整、可验证地交付这些功能。
实验通过"同一个 Agent、同一个任务、两种环境"的对照设计来揭示差异:
| 运行 | 环境准备 | 观察重点 |
|---|---|---|
| 第一次 | 仅提供任务提示词(裸 prompt),无任何额外结构 | Agent 在没有规则约束时能完成多少、偏离任务有多远 |
| 第二次 | 仓库中预置最小 harness(AGENTS.md+init.sh+feature_list.json) | 规则与验收清单如何让同一任务变得具体、可验证 |
需要注意的是,本课程场景将"两次运行之间的重新研究/准备间隔"设定得较短,作为教学示例,而不是作为固定测量结果——对比的目的是观察 harness 带来的行为差异,而非产出可复现的基准数据。
实验工具清单
运行本实验需要以下工具:
- Claude Code 或 Codex:二选一即可,但两次运行必须使用同一个工具,保证对照变量只有 harness 有无;
- Git:用分支隔离两次实验,便于事后用
git diff对比两次产出; - Node.js + Electron:项目技术栈,需提前安装依赖;
- 计时器:分别记录两次运行的耗时,作为对比的辅助维度。
使用仓库中已准备好的项目
仓库中已经为本次实验准备好了完整素材,路径为 projects/project-01/,分为starter/与solution/两个目录:
| 目录 | 内容 | 用途 / 对比要点 |
|---|---|---|
| starter/ | 弱 harness 起点:只有 task-prompt.md 作为任务描述,没有AGENTS.md、feature_list.json | 把提示词交给 Agent,测量它在没有额外结构时能完成什么 |
| solution/ | 同一产品切面,但带显式 harness 产物:AGENTS.md、CLAUDE.md、init.sh、feature_list.json、claude-progress.md | 对比规则与验收检查如何让同一任务变得具体、可验证 |
两边的src/目录结构一致,均包含 Electron 主进程、preload 桥接层、React 渲染层与 service 业务逻辑层,且都带有示例文档数据 data/sample-documents/。区别只在 harness 产物本身。
第一次运行:裸提示词环境
进入starter/目录,将 task-prompt.md 交给 Agent。这份提示词的完整内容只有一句话:
# Task Build an Electron app that can show documents and answer questions.这段描述蕴含了三个典型问题,正是本实验想暴露的:
- 验收标准缺失:"show documents and answer questions" 没有定义什么叫"完成",Agent 可能做到一半就自行宣布胜利;
- 边界约束缺失:没有说明 Electron 分层、安全配置、数据目录位置,Agent 可能自由发挥,把逻辑写进渲染进程、关闭
contextIsolation或把数据存在任意位置; - 任务范围缺失:没有列出具体的 feature 清单,Agent 可能遗漏功能(比如不做本地数据目录),也可能过度发挥(引入无关依赖或功能)。
启动后给 Agent 计时,观察它产出的代码、运行结果与耗时,记录在分支baseline上,作为对照组。
第二次运行:最小 harness 环境
切回主分支(或新分支harness),这次使用 solution/ 作为工作目录。该目录已预置了最小 harness,其核心由三件套组成:
最小 harness =
AGENTS.md+init.sh+feature_list.json
AGENTS.md:把规则写进 Agent 的启动上下文
AGENTS.md 是 Agent 每次会话首先读取的规则文件。它定义了五个层次的内容:
启动规则(Startup Rules):要求 Agent 在写任何代码之前,按顺序完成:
- 完整阅读本文件;
- 阅读 docs/ARCHITECTURE.md 理解 Electron 分层结构;
- 阅读 docs/PRODUCT.md 理解功能需求;
- 运行
bash init.sh验证项目可干净构建,失败则先修复构建错误; - 阅读
feature_list.json查看所有功能当前状态。
Electron 分层边界(Layer Boundaries):明确规定主进程、preload、渲染层、service 四层各自的权利与禁忌。例如渲染层"绝不导入 Node.js 模块(fs、path、electron)",preload 是主进程与渲染层之间唯一的桥梁,所有文件系统访问必须经由 service 层发生在主进程。
约定(Conventions):启用 TypeScript 严格模式、使用命名导出、IPC 通道名统一在 src/shared/types.ts 的IPC_CHANNELS中定义一次、渲染层禁止同步 I/O。
完成定义(Definition of Done):一个 feature "完成"需要同时满足:npm run check编译零错误、npm run dev能启动并看到窗口、该 feature 在feature_list.json中状态为"pass"并附有证据、代码遵守分层边界、正常运行无控制台错误。
功能清单协作方式:feature_list.json是项目进度的唯一事实来源(source of truth),每个 feature 有"pass"/"fail"/"not-started"三种状态,实现后更新状态并附证据,阻塞时置"fail"并写明原因,且永远不允许从清单中删除 feature。
此外 solution/ 中还提供了 CLAUDE.md(Claude Code 专用规则入口)与 claude-progress.md(会话进度记录),作为对AGENTS.md的补充,保证多轮会话间的连续性。
init.sh:把"环境可用"变成可执行命令
init.sh 是一个带set -euo pipefail的 bash 脚本,克隆仓库或恢复工作时运行,依次执行三步:
echo "[1/3] Installing dependencies..." npm install echo "[2/3] Running type checks..." npm run check echo "[3/3] Building project..." npm run build三步全部通过后输出 "Init complete",并提示npm run dev启动应用。它的价值在于:把"项目能不能跑"从 Agent 的自由判断,变成一条确定性命令——AGENTS.md的启动规则第 4 条强制 Agent 先执行它,任何构建问题都会在写业务代码之前暴露。
feature_list.json:把"验收"变成机器可读的证据
feature_list.json 定义了本项目的四个具体 feature,以及每条对应的预期验收证据:
| feature id | 名称 | 描述 | 预期证据(evidence) |
|---|---|---|---|
window-launch | Window Launch | Electron 打开具有正确尺寸与 preload 脚本的 BrowserWindow | npm run dev启动 1200x800 窗口,contextIsolation=true且nodeIntegration=false |
document-list | Document List Panel | 左侧边栏展示已导入文档,含空状态提示 | DocumentList 组件在无文档时渲染空状态,有数据时渲染文档卡片 |
question-panel | Question Panel | 底部输入条接收问题并通过 IPC 提交 | QuestionPanel 渲染文本输入与 Ask 按钮,回车或点击时提交到window.knowledgeBase.qa.ask |
data-directory | Data Directory | PersistenceService 创建并管理userData/knowledge-base-data目录 | PersistenceService 构造函数调用ensureDirectories(),创建 data、documents、index 三个子目录 |
这四条 feature 恰好覆盖了裸提示词中那句 "show documents and answer questions" 的全部隐性要求——窗口能启动、文档能展示、问题能提交、数据有落盘位置。
源码佐证:feature 与验收证据的落地实现
feature_list.json中的每条证据都可以在源码中找到对应实现,这正是它"可验证"的原因。
window-launch对应 src/main/main.ts 的createWindow():窗口以width: 1200, height: 800(最小 800x600)创建,webPreferences明确设置contextIsolation: true、nodeIntegration: false,并挂载preload/preload.js——与证据描述逐字对应。
data-directory对应 src/services/persistence-service.ts:构造函数接收app.getPath('userData')/knowledge-base-data作为数据目录(见main.ts的initializeServices()),并在构造时调用ensureDirectories(),用fs.mkdirSync(..., { recursive: true })递归创建data、documents、index三个子目录。该服务同时提供原子化 JSON 写入(writeJson先建目录再写文件)、文本读写、文件拷贝与删除等能力,是 docs/ARCHITECTURE.md 中数据存储方案(documents-meta.json、content/、chunks/、index/、qa-history.json)的底层实现。
document-list 与 question-panel对应渲染层组件:src/renderer/components/DocumentList.tsx 与 src/renderer/components/QuestionPanel.tsx,它们不直接访问 Node.js,而是通过 preload 暴露的window.knowledgeBase类型化 API(documents、indexing、qa)与主进程通信——这正是AGENTS.md分层边界在代码层面的落实。
完整的分层与数据流说明见 docs/ARCHITECTURE.md:渲染层 → preload(contextBridge.exposeInMainWorld)→ipcRenderer.invoke(IPC_CHANNELS.*)→ 主进程registerIpcHandlers()→ service 层(DocumentService / IndexingService / QaService / PersistenceService)→ 返回渲染层更新状态。功能需求与产品约束(三栏布局、仅支持.txt/.md、单文件上限 10 MB、本地 mock Q&A 无 LLM 集成)见 docs/PRODUCT.md。
对比维度与预期差异
两次运行结束后,用git diff对比两个分支的产出,并从以下维度分析:
- 任务具体性:裸 prompt 环境中,Agent 需要自行推断"文档列表""问答面板""数据目录"这些概念;harness 环境中,四个 feature 与证据描述直接写死,Agent 无需猜测;
- 完成可验证性:裸 prompt 环境只能依赖 Agent 的自我声明判断完成;harness 环境中,
feature_list.json要求每条 feature 附带可核对的证据,并可用npm run check/npm run dev客观验证; - 越界行为:
AGENTS.md的四层边界直接约束 Agent 的代码组织,减少"渲染层导入 Node 模块""关闭安全隔离"这类常见越界; - 遗漏与过度发挥:feature 清单防止 Agent 漏掉
data-directory这类"看不见的隐性需求",同时也把范围锁死,避免无关扩展; - 耗时与返工:用计时器数据对比两次运行的总时长与中途返工次数(构建失败、反复修改)——这也是本实验设定较短"重新研究/准备间隔"作为示例的原因:差异体现在行为模式,而非精确的基准数字。
实验注意事项
- 控制变量:两次运行必须使用同一个 Agent 工具,分支隔离 +
git diff保证可回溯; - harness 需在运行前就位:第二次运行的
AGENTS.md、init.sh、feature_list.json应预先提交在仓库中,而不是由你在运行中临时创建,否则就违背了"环境 vs 提示词"的对照设计; - 验收以证据为准:不要轻信 Agent 的"已完成"声明,逐一核对
feature_list.json中四条 feature 的证据是否能在源码与运行结果中复现; - 本实验的边界:这是教学性对比实验,两次运行间隔较短,结果用于理解 harness 的作用机制,而非作为性能或成功率基准。
通过亲手跑完两次实验,你会直观理解:同样的 Agent、同样的任务,有 harness 与没有 harness 的差别,不在于模型能力,而在于任务是否被转化成一套可执行、可验证、有边界的工程契约——这正是后续项目中逐步升级 harness(多会话连续性、增量索引、运行时可观测性等)的起点。
【免费下载链接】learn-harness-engineering
Harness engineering beginner tutorial, from 0 to 1
相关推荐
从"只给提示词"到"最小 Harness":在 learn-harness-engineering 中复现 Project 01 的对照实验
从"只给提示词"到"最小 Harness":在 learn harness engineering 中复现 Project 01 的对照实验 本指南完整讲解 l
Learn Harness Engineering 实战项目 01:仅 Prompt 与规则先行(Minimal Harness)到底差多少
Learn Harness Engineering 实战项目 01:仅 Prompt 与规则先行(Minimal Harness)到底差多少 本篇技术指南围绕
从 prompt 到 harness:learn-harness-engineering 五子系统模型与实战落地
从 prompt 到 harness:learn harness engineering 五子系统模型与实战落地 导读 "harness"(驾驭/夹具)一词在
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考