/zh/posts/human-facing-ai-harness-notes

面向人的 AI Harness 设计笔记

EN

我不认为 AI 最有意思的用途是替代一个人在键盘前操作。更好的用途,是拓展一个人可以观察、比较和推理的认知面。

这对非技术人员尤其重要。技术人员本来就可以用脚本、prompt、日志、git、终端和 review 习惯把 AI 包起来。非技术人员看到的通常只有聊天框。如果模型卡住、重复、隐藏不确定性,或者忘记任务,用户几乎没有抓手。

AI harness 改变的是这种关系。它不是另一个 agent,而是 agent 外面的框架:任务板、循环、日志、停止条件、进度表面,以及人可以介入的位置。

1. AI 应该拓展认知面

当我说 AI 拓展认知时,我不是说它替我做决定。我说的是,它能让我同时看到问题的更多部分。

一个好的 AI 工作流,应该帮助人看到:

  • 当前目标是什么
  • 已经尝试过什么
  • 改动了什么
  • 什么失败了
  • 系统哪里不确定
  • 哪里需要人做决定
  • 当前状态有什么证据

这和让模型显得自信不一样。自信很便宜。一个可见的思考表面更有价值。

对于非技术人员来说,这个表面不能是“打开终端去看 JSON 日志”。它必须是一份小的操作契约:这些是任务,这是当前轮次,这是发生了什么,这是为什么停止。

2. Harness 不是 Agent

第一个设计边界很重要:

agent = the system that reasons and acts
harness = the system that frames, runs, observes, and stops the agent

Harness 不应该试图变成更聪明的模型。它不应该拥有产品方向,也不应该假装自己深入理解每个任务。

它的职责更窄:

  • 给 agent 一个任务
  • 用可重复的方式调用 agent
  • 记录发生了什么
  • 判断是否有进展
  • 在循环变得浪费之前停止
  • 给人一个有用的总结

这种分离能让工具保持诚实。如果模型是大脑,harness 更像桌子、笔记本、计时器、检查清单和录音机。

3. 非技术人员需要任务板,不只是 Prompt 框

Prompt 框很灵活,但也很滑。任务板表达力没那么强,但它能产生抓手。

对非技术人员来说,核心输入应该更接近这样:

- [ ] Draft the landing page copy
- [ ] Compare the three strongest positioning options
- [ ] Rewrite the pricing FAQ in a calmer tone
- [ ] Mark anything that needs my decision as HUMAN

用户不需要知道模型是怎么被调用的。他们需要知道如何描述工作、看到进展、纠正方向。

任务板给 harness 一个简单事实源:

function nextTask(board):
for task in board:
if task is unchecked:
return task
return null

这应该保持朴素。任务格式越复杂,用户在真正使用工具前要学的东西就越多。

4. 用新轮次,而不是一条无尽会话

长 AI 会话一开始很方便,直到它变浑浊。旧假设留在上下文里,失败尝试也留在旁边。模型可能沿着一个已经混乱的状态继续,因为那个状态仍然在对话里。

Harness 可以改用轮次:

function runLoop(board):
while true:
task = nextTask(board)

if task is null:
stop("done")

context = buildContext(board, task, previousEvidence)
result = runAgentOnce(context)
evidence = capture(result)

updateBoardIfTaskCompleted(board, result)
recordRound(task, evidence)

if needsHuman(board, evidence):
stop("blocked_by_human")

每一轮都给 agent 一个当前任务和规则的干净视图。Harness 负责把耐用事实带到下一轮,而不是把整段对话雾气都带过去。

对非技术人员来说,这很有用,因为系统可以用轮次解释工作:

Round 1: drafted options
Round 2: compared tradeoffs
Round 3: stopped because a human decision is needed

这比一整段长聊天记录容易理解得多。

5. 进展必须可观察

如果人看不出 AI 是否在推进,就无法监督它。

Harness 应该暴露一小组状态:

  • running
  • waiting
  • done
  • failed
  • blocked by human
  • stopped because no progress was detected

它还应该暴露刚好足够的实时细节:

  • 当前任务
  • 当前轮次
  • 已耗时长
  • 最近可见动作
  • 已完成任务数
  • 停止原因

伪代码:

status = {
runId,
currentTask,
round,
completedTasks,
totalTasks,
state,
lastEvent,
exitReason
}

renderStatus(status):
show progress
show current task
show last event
show stop reason if finished

这不只是给开发者看的。非技术人员更需要它,因为他们没有太多其他工具去推断发生了什么。

6. 停止条件是产品功能

AI 系统需要刹车。

Harness 应该在这些情况下停止:

  • 所有任务完成
  • 模型连续失败
  • 某一轮运行太久
  • 同一个任务没有进展
  • 任务明确需要人输入
  • 已经有另一个 run 在使用当前 workspace

最重要的停止条件是没有进展。模型可以一直输出文字,但那不代表它在帮忙。

function detectProgress(before, after):
if checkedTaskCount(after.board) > checkedTaskCount(before.board):
return true

if visibleArtifactsChanged(before, after):
return true

return false

if detectProgress(before, after):
stallCount = 0
else:
stallCount += 1

if stallCount >= limit:
insertHumanTask("The loop stopped because no progress was detected.")
stop("blocked_by_human")

这是 harness 变得更像人的地方。它不会让用户事后才发现浪费。它会停下来,要求一个决定。

7. 人类接管应该内建

对非技术人员来说,“AI 卡住了”不应该等于“系统坏了”。

它应该表示:

The current task needs your decision.
Here is what happened.
Here are the options.
Here is the smallest thing you need to answer.

Harness 可以把它表示成一个人类任务:

- [ ] HUMAN: Choose whether the homepage should emphasize speed or trust.
- [ ] Rewrite the homepage based on that decision.

这样人的部分就显式存在了。它也能防止 agent 假装自己可以解决一个本来属于用户的产品决策。

我喜欢这个点,因为它尊重两边。AI 可以扩大选项空间,人仍然选择方向。

8. 证据比 Transcript 数量更重要

完整 transcript 经常太多。真正有用的证据链应该更小、更结构化。

对每一轮,我想知道:

  • 哪个任务是活跃任务
  • 给 agent 的输入是什么
  • agent 产出了什么
  • 改动了什么
  • 任务有没有被标记完成
  • 有没有错误
  • 下一步交接应该说什么

伪代码:

roundRecord = {
taskId,
roundNumber,
startedAt,
finishedAt,
resultState,
changedArtifacts,
summary,
error,
nextAction
}

用户不应该被迫读完每个原始事件。但 harness 应该留下足够证据,让未来的用户、维护者或 agent 可以复原工作。

这也是 AI 拓展认知的一种方式:它留下的是地图,而不只是答案。

9. Provider 应该可替换

不同 AI 工具擅长不同事情。Harness 不应该把自己锁死在某一个 provider 的性格里。

接口可以很简单:

interface Provider:
checkAvailable()
runOnce(prompt, outputTarget)
collectEvidence()
diagnoseFailure()

循环不需要知道 provider 是 Claude、Codex、Gemini,还是别的东西。它只需要一个稳定契约:

prompt in
events out
evidence copied
failure diagnosed

对非技术人员来说,选择 provider 应该像选择引擎,而不是重写工作流。

10. 部署形状要小

如果 harness 是给非技术人员用的,安装方式很重要。

运行形状越小,越容易被信任:

  • 一个本地目录
  • 一个任务文件
  • 一个提示文件
  • 一个私有配置文件
  • 一个运行命令
  • 一个状态命令
  • 一个观察命令

心智模型最好能放进一句话里:

Put the harness in a workspace, write tasks, choose a provider, run the loop, watch progress, answer HUMAN tasks when needed.

这仍然不是“零学习”。但它是可以学会的。

我现在的规则

对于面向人的 AI harness,我的规则是:

make AI work inspectable enough for non-technical supervision

目标不是把机器藏起来。目标是给人一个更大、更平静的思考表面:任务、轮次、证据、停止原因和人类决策都在同一个框架里。