news 2026/4/28 3:26:54

【AI 应用】Harness Engineering:不靠玄学 Prompt,让 AI Agent 稳定交付的工程方法(约束+上下文+验证闭环)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【AI 应用】Harness Engineering:不靠玄学 Prompt,让 AI Agent 稳定交付的工程方法(约束+上下文+验证闭环)

前言
本文面向的是希望把 AI 用到“可交付”的开发者。
核心目标不是追求一次输出多惊艳,而是把结果变成可复用、可验证、可迭代
内容来自一次围绕Harness Engineering的讨论整理:从概念到落地,从 Skill 到自动检测闭环。

⚡ 快速参考

  • 适用场景:LLM/Agent 辅助写代码、写文档、生成页面、对接接口,且需要“长期稳定交付”的项目/团队/个人工作流
  • 核心结论Harness Engineering不是单一工具,而是“围绕模型构建约束、上下文、验证与反馈闭环”的工程体系;可靠性主要来自 Harness,而非模型本身
  • 最简步骤:沉淀规范(Constraints)→ 组织上下文(Context)→ 上自动检测(Validation)→ 让错误可回写可修复(Feedback)→ 全链路留痕(Observability)
  • 必备代码:最小校验脚本(例如:路由与docs/spec一致性检测;资源命名/台账检测;失败输出可修复指引)
  • 高危避坑:只写“规范文档”但不做自动检测;把 Skill 当万能提示词;上下文一次性塞爆;错误信息不含修复动作导致无法形成闭环

📚 学习目标

  1. 掌握Harness Engineering的定义、组成与与 Prompt/Context 的边界
  2. 能独立完成一个“最小 Harness”:规范文档 + few-shot/检索上下文 + 自动检测脚本 + 可修复的失败反馈
  3. 能说出“自动检测的目的与收益”,并能用一个路由案例解释闭环如何工作

一、基础概念

1.1 Prompt / Context / Harness 三个概念的分工

  • Prompt Engineering:把指令写清楚,让模型“更懂任务”
  • Context Engineering:让模型“看见正确资料”,包括文档组织、few-shot 示例、检索上下文(RAG)等
  • Harness Engineering:把 Agent 放进一个“能长期稳定交付”的系统里,系统包含约束、上下文、验证、反馈、观测与成本控制

1.2 一句话定义 Harness Engineering

Harness Engineering = 设计并运行一套“约束 + 上下文 + 自动验证 + 反馈闭环 + 可观测”的工程系统,让 AI Agent 的输出可交付、可回归、可持续。

1.3 Skill 属于哪一类?

以一个真实 Skill(用于 uni-app Vue3 小程序交付)为例,它包含 Hard Rules、流程分阶段、目录契约、交付清单。
这种 Skill 更像“结构化操作手册 + 工作流约束”,主要落在:

  • Constraints(约束层):禁止假设跳转逻辑、冲突优先级、重命名先提案后执行、文档分层边界等
  • Orchestration(编排层):Mode A/B 切换、四阶段执行流程
  • Verification(验证层)的雏形:交付 checklist(但多为人工检查)

结论是:Skill 不是一句提示词,但 Skill 也不等于完整 Harness。完整 Harness 还需要“可执行的验证脚本 + 可回写修复的反馈机制 + 留痕与观测”。

1.4 核心概念对比表(必须有表格)

维度Prompt EngineeringContext EngineeringHarness Engineering
目标单次输出更像“想要的”让模型“看对资料”让系统“持续产出可交付结果”
主要手段指令、格式要求、角色设定文档组织、few-shot、RAG、渐进披露约束+验证+反馈闭环+观测+成本/权限
失败表现改 prompt 反复试上下文缺失/过载导致跑偏有护栏与回归,失败可定位可修复
成熟标志靠经验调参有稳定资料入口与索引有自动检测与闭环,质量可回归

二、原理详解

2.1 为什么只靠 Prompt 很难稳定交付?

LLM 的输出具有概率性。任务一旦变成多步骤(读文档→改代码→跑验证→修复→提交),失败面会迅速扩大:

  • 上下文缺失:缺页面映射、缺接口字段、缺资源命名规则
  • 工具调用失败:命令报错、路径不一致、文件没更新
  • 质量不可控:风格漂移、规范遗忘、文档与代码不同步

Prompt 解决“表达”,但很难覆盖“长期的工程秩序”。

2.2 Harness 的核心:把“规范”变成“可执行护栏”

Harness 的关键转折点是:

  • 规范写在文档里→ 仍然需要人工盯
  • 规范写成检测脚本/CI→ 系统自动守住边界

这一步带来的收益通常是:

  • 漂移更早发现(越早越便宜)
  • 返工更少(错误在合并前被挡住)
  • 可规模化(页面/模块变多时,人眼检查会崩,机器检查成本几乎不变)
  • 可形成反馈闭环(错误信息包含修复指引,Agent 能自修)

2.3 一个最直观的闭环(Mermaid)

下面这张流程图可以当作本文的“工程主线”:

通过

失败

需求/任务输入

Context 组装
docs/spec + few-shot + 检索上下文

Agent 生成/修改

自动检测 Validation
lint/test/spec一致性/命名规则

交付/合并/发布

失败信息含修复指令
Feedback 回写上下文

留痕与观测
变更记录/质量指标/成本

2.4 few-shot + 检索上下文(RAG)到底是什么?

  • few-shot:给模型少量“高质量样例”,让输出风格和结构趋于稳定(例如:文章开头、实战段落、总结段落的范例)
  • 检索上下文(RAG):每次任务前从知识库/代码库里“检索相关片段”再喂给模型,避免靠记忆和猜测

它们偏向 Context Engineering,但在 Harness 中通常会被当作“上下文供给系统”的一部分。

三、完整实战代码(怎么做)

本节给一个“最小可落地”的示例:用路由事实推动docs/spec显式化,并用脚本做一致性检测。
示例的路由代码(原始素材)如下:

import{createRouter,createWebHistory}from'vue-router'importGenerateResumePagefrom'../views/GenerateResumePage.vue'importGreetingPagefrom'../views/GreetingPage.vue'importPersonalInfoPagefrom'../views/PersonalInfoPage.vue'importProjectsPagefrom'../views/ProjectsPage.vue'constrouter=createRouter({history:createWebHistory(),routes:[{path:'/',redirect:'/personal'},{path:'/resume',name:'resume',component:GenerateResumePage,meta:{keepAlive:true}},{path:'/greeting',name:'greeting',component:GreetingPage,meta:{keepAlive:true}},{path:'/personal',name:'personal',component:PersonalInfoPage},{path:'/personal/projects',name:'projects',component:ProjectsPage}]})exportdefaultrouter

3.1 第一步:把隐含在代码里的“导航事实”写进 spec

例如docs/spec/screens.md(示意):

## 入口 - / -> redirect /personal ## 页面清单(slug / path) - personal: /personal - projects: /personal/projects - greeting: /greeting - resume: /resume ## 约束 - resume.keepAlive = true - greeting.keepAlive = true

3.2 第二步:写一个最小校验脚本(Node 版)

目标:校验docs/spec/screens.md中声明的 path,必须在路由里存在;并校验关键约束(redirect、keepAlive)。

// scripts/validate-routes.mjsimportfsfrom'node:fs'constrouterFile=process.argv[2]||'src/router/index.ts'constscreensFile=process.argv[3]||'docs/spec/screens.md'functionfail(msg){console.error(`[VALIDATE_FAIL]${msg}`)process.exit(1)}if(!fs.existsSync(routerFile))fail(`router file not found:${routerFile}`)if(!fs.existsSync(screensFile))fail(`screens file not found:${screensFile}`)constrouterText=fs.readFileSync(routerFile,'utf8')constscreensText=fs.readFileSync(screensFile,'utf8')// 1) 从 screens.md 抽取 path(非常简化版:匹配 `: /xxx`)constdeclaredPaths=Array.from(screensText.matchAll(/:\s*(\/[a-zA-Z0-9/_-]+)/g)).map(m=>m[1])if(declaredPaths.length===0)fail(`no declared paths found in${screensFile}`)// 2) 在 router 文件中检查 path 是否存在constmissing=declaredPaths.filter(p=>!routerText.includes(`path: '${p}'`)&&!routerText.includes(`path: "${p}"`))if(missing.length){fail(`routes missing in router:${missing.join(', ')}. Fix: add routes or update${screensFile}`)}// 3) 检查入口 redirect 约束if(!(routerText.includes(`{ path: '/', redirect: '/personal' }`)||routerText.includes(`path: '/'`)&&routerText.includes(`redirect: '/personal'`))){fail(`root redirect constraint violated. Expect '/' redirect to '/personal'. Fix router or update spec.`)}// 4) 检查 keepAlive 约束(示例:要求 resume/greeting keepAlive true)for(constnameof['resume','greeting']){constok=routerText.includes(`name: '${name}'`)&&routerText.includes(`keepAlive: true`)if(!ok)fail(`${name}.keepAlive constraint violated. Fix: set meta.keepAlive=true for route '${name}'.`)}console.log('[VALIDATE_OK] routes/spec constraints satisfied')

3.3 第三步:本地一键验证(示例命令)

nodescripts/validate-routes.mjs src/router/index.ts docs/spec/screens.md

3.4 这段“自动检测”的目的是什么?

  • docs/spec不再靠人工维护
  • 让“路由变化”会强制触发“spec 更新”,避免文档失真
  • 让失败信息携带修复动作,便于下一轮 Agent 直接按报错修到通过
  • 让交付结果可回归:同一套检测在未来迭代继续有效

四、场景应用(固定2个真实场景)

场景1:AI 帮写页面,如何避免“跳转逻辑瞎编”?

  • 需求:页面按原型实现,跳转/参数/返回刷新策略必须真实可追溯
  • 方案:用 Skill 约束“无交互定义不假设”,把页面映射与跳转写进文档中,并用脚本校验路由与 spec是否一致
  • 收益:交互逻辑从“口头约定”变成“可验证事实”,减少联调返工与口径不一致

场景2:AI 写技术博文,如何避免“风格漂移、结构散、空话多”?

  • 需求:长期持续输出同一风格的高质量文章,结构稳定、内容可复现
  • 方案:few-shot 固化“开头/实战/总结”段落范式;检索上下文(素材库)提供真实依据;引入发布前自检脚本/清单(例如标题层级、必备模块是否齐全、是否包含对比表格与流程图)
  • 收益:从“灵感驱动”升级为“流程驱动”,质量波动更小,复用成本更低

五、开发避坑总结

  1. 问题:规范写得很完整,但交付还是不稳定
    原因:规范停留在文档层,缺少可执行验证
    解决:把关键规范变成脚本/CI 校验,失败信息包含修复指令,形成闭环

  2. 问题:Skill 越写越长,反而不好用
    原因:上下文一次性塞爆,任务信息被挤掉,且规则很难验证
    解决:Skill 保持“入口索引 + 核心 Hard Rules”,细节拆到docs/并建立目录契约;校验“文档存在性/一致性”而不是堆文字

  3. 问题:检索(RAG)做了,但效果不稳定
    原因:检索出来的片段不具备“可执行事实”,或者缺少 few-shot 对输出结构的约束
    解决:RAG 提供事实材料,few-shot 提供结构范式,验证层负责兜底一致性与格式要求

六、面试考点

Q1:Harness Engineering 和 Prompt Engineering 的区别是什么?
A:Prompt 关注“单次指令与输出”,Harness 关注“围绕模型的系统”:约束、上下文组织、工具编排、自动验证、反馈闭环与观测。Prompt 是输入之一,Harness 是让系统可靠的主体。

Q2:为什么说 Harness 比换模型更重要?
A:模型提升通常影响“单次输出质量”,而 Harness 影响“端到端稳定性与可回归能力”,能把失败变成可定位可修复的问题,并让质量在迭代中不漂移。

Q3:自动检测(Validation)的工程价值是什么?
A:把“人脑记住的规范”变成“系统自动守住的护栏”,更早发现漂移,减少返工,并让 Agent 能根据失败信息自动修复,形成闭环。

追问1:few-shot 和 RAG 各解决什么问题?
A:few-shot 固化输出结构与风格;RAG 提供任务所需事实资料。两者配合,再由验证层兜底。

追问2:Skill 在 Harness 中扮演什么角色?
A:Skill 多数属于约束层与编排层:规定边界与流程;要成为完整 Harness 仍需接入验证、反馈与观测。

七、总结(复盘+下一步)

本文把Harness Engineering从“概念”落到“工程动作”:

  • 规则与流程属于约束/编排层
  • few-shot 与检索上下文属于上下文工程
  • 自动检测与可修复失败信息是闭环的关键
  • 留痕与观测让系统可持续迭代而不漂移

下一步的落地路径通常是:先做一个最小校验脚本,把最痛的漂移点(路由/spec、资源命名/台账、接口字段对齐、文章结构自检)先变成“红线”。


本文为MY_TRUCK原创实战学习笔记,持续更新Java后端与AI应用领域干货,问题欢迎评论区交流。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/28 3:16:03

Husky机器人ROS 2与NVIDIA Isaac Sim仿真实践

1. 项目概述Husky机器人是Clearpath Robotics开发的一款四轮移动平台,专为室内外研究应用设计。这款机器人的独特之处在于其高度模块化特性——用户可以根据研究需求灵活加装各类传感器或更换主控板。本教程将详细演示如何利用NVIDIA Isaac Sim仿真环境,…

作者头像 李华
网站建设 2026/4/28 3:16:03

从‘++i’崩溃说起:深入理解C++ atomic的compare_exchange_weak与强内存屏障

从‘i’崩溃说起:深入理解C atomic的compare_exchange_weak与强内存屏障 在某个深夜的调试中,你盯着屏幕上那个看似简单的计数器——shared_counter——它本应在多线程环境下稳定递增,却总是莫名其妙地丢失更新。这个场景或许唤起了许多C开发…

作者头像 李华
网站建设 2026/4/28 3:15:36

DROID-SLAM:动态环境中的实时RGB SLAM技术解析

1. DROID-SLAM:动态环境中的实时RGB SLAM系统解析 在计算机视觉和机器人领域,同步定位与地图构建(SLAM)技术一直是核心研究方向。传统SLAM系统在静态环境中表现出色,但当场景中存在动态物体时,其性能往往会…

作者头像 李华
网站建设 2026/4/28 3:15:06

ODPS每个worker里面有个http请求,报错timeout

有监控的话,看下http请求的服务端的QPS多少, 大概率是QPS太低了, 配置odps.sql.mapper.split.size小点: SET odps.sql.mapper.split.size 4; SET odps.stage.mapper.num 32; -- 一般实际没啥作用 SET odps.stage.reducer.num 4…

作者头像 李华