大模型Agent面试硬核拆解:Harness Engineering如何让AI真正解决复杂任务?
❝
最近公众号后台被大家的留言刷屏了——很多小伙伴都在说,面试时频频被一个叫 Harness 的词卡住。有人翻遍了资料还是似懂非懂,跑来问我能不能写一篇真正讲透的文章。 说实话,看到这些留言,我比你们还急。晚上躺在床上反复构思,想找到一种最清晰、最易懂的组织方式。凌晨五点多,脑子里突然有了一个清晰的思路,我立刻从睡梦中坐起来,趁着记忆还新鲜,赶紧起床打开电脑,一字一句地敲下这篇文章。 写完之后天都快亮了,但想到能帮大家少走点弯路,一切都值得。
最近面试圈频繁出现一个词:Harness。Anthropic、LangChain都在提,面试官也开始问:“你做的Agent为什么总是半途而废?Harness范式怎么落地?”
这篇文章不绕弯子,直接给你把Harness Engineering的核心考点、流程图、实战坑位全拆开。看完你不仅能答,还能画出让面试官眼前一亮的架构图。
考点一:为什么你的Agent总是“烂尾”?Harness解决了哪两个致命痛点?
【⭐⭐⭐】当前AI Agent处理复杂编程任务时,最常见的两个失败模式是什么?Harness分别如何应对?**
参考答案
两个致命问题:
- 任务过载与上下文“烂尾”
Agent一上来就想“一口吃成胖子”,在长上下文窗口里写几千行代码。写到一半,上下文窗口被压缩(Compaction)或直接溢出,后半段功能只留下半截代码和缺失的依赖。下一个接手的Agent面对残局,只能靠“猜”——浪费时间修bug,而不是推进新功能。 - 任务提前结束
后继Agent看到项目里已经有部分代码、部分测试通过,就误判“任务已完成”,直接输出“All done”退出。结果是功能只完成30%,但流程停了。
Harness的应对:
- 引入环境隔离 + 增量式任务清单,强制Agent每次只做一个功能点,从根源上杜绝“一口吃胖子”。
- 通过自动化测试守卫 + 进度文件,只有真正通过所有验收测试的变更才被认为“完成”,防止Agent偷懒误报。
❝
💡 面试官追问:“那你觉得无限上下文的模型(如Gemini 1.5 Pro、Claude 3.5 Sonnet)能解决烂尾问题吗?”
答:不能。无限上下文只缓解了“窗口溢出”,但没解决信息丢失和任务理解断层。压缩后的摘要仍然会遗漏细节,而且模型对“已做了多少”的判断依然会出错。Harness本质是流程管理,不是上下文扩容。
考点二:Harness的核心工作流——画出来你就赢了
【⭐⭐⭐⭐】请画出Harness管理多个Agent协作解决复杂任务的序列图,并解释每一步的职责。**
参考答案
下面这张图是面试必画图。注意用activate表示生命周期,用alt/else区分成功与失败分支。
关键细节(面试加分点) :
- 步骤4:Agent不是直接改主分支,而是在隔离分支上操作。
- 步骤6:Harness通过轮询或webhook监听环境状态变化,不是靠Agent主动汇报(Agent可能说谎)。
- 回滚逻辑:Harness必须有能力
git reset --hard,环境要暴露原子性的恢复接口。
考点三:Environment设计——为什么用JSON不用Markdown?
【⭐⭐⭐】在Harness范式中,features.json承担什么角色?为什么强制要求用JSON而不是Markdown?如果Agent私自修改测试用例怎么防?**
参考答案
features.json 本质是 可机读的验收清单。典型结构:
{
"features": [
{
"id": "feat_001",
"description": "用户密码输入框应显示掩码",
"test_file": "tests/test_login.py::test_password_mask",
"passes": false
},
{
"id": "feat_002",
"description": "登录成功跳转首页",
"test_file": "tests/test_login.py::test_redirect",
"passes": false
}
]
}
为什么用JSON?
| 维度 | Markdown | JSON |
|---|---|---|
| 结构化约束 | 弱,Agent可随意改格式 | 强,解析器可直接校验schema |
| 防篡改 | 无,Agent可能删掉失败项 | 可配合只读权限 + 校验工具 |
| 增量更新 | 需要正则提取,容易出错 | 直接修改布尔字段,原子操作 |
| 与测试框架集成 | 需要额外解析 | 可直接映射到pytest标记 |
防止Agent作弊的三个工程手段:
- 文件权限:Environment挂载
features.json为只读,Agent只能通过专用接口(如update_feature_status)修改passes字段,不能删除或改动test_file。 - 测试哈希校验:Harness在启动前对所有测试文件计算SHA256,Agent执行后重新校验,如果测试文件被改,直接判定失败。
- 双重验证:Agent声称“测试通过”后,Harness自己重新运行一遍测试(不信任Agent的输出)。
❝
💡 面试官追问:“如果Agent绕过接口,直接用shell命令写入呢?”
答:环境用容器(Docker)隔离,挂载features.json为ro(read-only),Agent的shell无法写入。只有Harness通过宿主机修改。
考点四:Initializer Agent + Coding Agent 协作流程图
【⭐⭐⭐⭐】请描述Initializer Agent和Coding Agent的职责分工,并用状态图展示一个功能点从“failing”到“passing”的生命周期。**
参考答案
Initializer Agent(一次性任务) :
- 接收用户原始需求(自然语言)
- 拆解为极细粒度功能点(每个功能点对应一个可自动化测试的断言)
- 生成
init.sh(安装依赖、创建目录)、features.json(全部passes: false)、claude-progress.txt(空日志) - 执行首次Git commit,标记
init
Coding Agent(循环执行) :
- 每个会话只拿一个功能点(从
passes=false中取第一个) - 写代码 → 跑测试 → 如果通过,更新
passes=true并追加日志 → 提交 - 如果失败,重试最多3次,仍失败则放弃并标记
blocked
状态图(面试时画出来,清晰展示流转条件):
注意:面试时强调“禁止跳转”——不允许从
Failed直接到Passed,必须经过InProgress重新执行。这防止Agent伪造测试结果。
考点五:Harness vs. 普通Swarm / AutoGen —— 到底区别在哪?
【⭐⭐⭐】市面上已有Multi-Agent框架(如AutoGen、CrewAI),为什么还要引入Harness?Harness额外解决了什么?**
参考答案
| 维度 | 传统Multi-Agent框架 | Harness Engineering |
|---|---|---|
| 环境抽象 | Agent直接操作文件系统、数据库,无沙箱 | 强制通过Environment API交互,可回滚、可审计 |
| 任务状态 | 依赖Agent自己汇报(容易谎报) | 由Harness主动轮询测试结果和Git diff |
| 失败处理 | 通常只重试当前Agent | 支持环境级回滚 + 任务重分配 |
| 进度持久化 | 依赖Agent输出的文本记录 | 结构化features.json + 自动化测试为唯一真理 |
| 适用规模 | 适合<10个步骤的线性任务 | 适合>50个功能点的长期项目(如构建整个微服务) |
一句话总结:Harness不是又一个Agent框架,而是 治理层 —— 它把每个Agent当作“不稳定但智能的工人”,通过环境隔离、测试守卫、状态机来保证整体工程的可控性。
最后送你的面试避坑指南
- 不要说“Harness就是马具” —— 这个比喻太浅。面试官要听的是:上下文管理、增量式任务、测试守卫、环境回滚。
- 一定要画图 —— 序列图或者流程图二选一。画得清晰比说得多更重要。
- 主动对比 —— 当被问“Harness怎么实现”时,主动提一句“这跟传统Agent框架不同,因为……”展示你的深度。
- 提一个真实踩坑案例 —— 比如“我们之前用AutoGen写爬虫,结果Agent自己删了requirements.txt,后来用Harness的只读挂载才解决”。面试官最爱听真实案例。
❝
如果这篇文章帮到了你,欢迎转发给正在准备大模型面试的朋友。
下一期预告:Tool Calling底层原理 —— 大模型怎么保证输出一定是合法JSON?约束解码的三种实现方式对比。