第 8 章 · Human-in-the-Loop:把「人」插进协调链路
一句话结论:多 agent 协调的最高效做法,不是「全自动」,而是在最关键、最不可逆的那一步插入一个「人」——让机器干它能干好的,把「方向对不对」这个机器最不可靠的判断,交给人来兜底。DeerFlow 1.x 把这个人机接口精准地放在了 Planner 之后、执行之前。
1. 为什么「全自动」很诱人,但很危险
「让 agent 自己从头跑到尾,出报告」听起来很爽。但结合第 3 章的结论我们知道:Plan 契约管得住「怎么执行」,管不住「计划本身对不对」。
如果计划错了(方向偏了、漏了关键点),agent 会很高效地执行一个错误的计划——跑几十分钟,搜了一堆,最后产出一份「很漂亮但答非所问」的报告。浪费的不只是 token,是几十分钟的墙钟时间和用户对系统的信任。
2. 思考的分叉:人该插在哪一步?
人的判断是宝贵的、稀缺的(用户不可能一直盯着),所以「在哪插人」是一个精心权衡:
方向 A:全程人工审批(每一步都问)。
- 代价:烦死用户,agent 失去了「自动化」的意义。
方向 B:完全不插人(全自动)。
- 代价:计划错了就全盘皆输,且用户无法在早期纠正方向。
方向 C:只在「最关键的一次分叉」插人(计划定稿后、大规模执行前)。
- 代价:用户还是要花几秒钟看一次计划;但换来的是「在方向错误的代价还很小的时候,就能拦住」。
为什么 DeerFlow 选 C:
- 因为「计划 → 执行」这一跳,是整条链路上杠杆最高、可逆性最低的一步。
- 杠杆最高:计划决定后面所有执行的方向,改计划等于改了所有后续工作。
- 可逆性最低:一旦开始大规模执行(几十次搜索、几十分钟跑代码),再回头改计划的成本极高。
- 在「杠杆最高 + 可逆性最低」的点插人,是用最小的人工成本,换取最大的纠错收益。这是人机协作的黄金法则。
类比:装修房子,你会在「施工图定稿」这个点让业主确认一次,而不是让工人每敲一块砖都来问一次。因为施工图决定了后面所有工序的方向,而一旦开工,改图代价巨大。在人机协作里,找到那个「杠杆最高、可逆性最低」的决策点插人,就是最优解。
3. 伪代码:一个人机闸门的三种状态
DeerFlow 1.x 的 human_feedback 节点,本质是一个可中断的闸门,用户有三种回应:
def human_feedback_node(state):
plan = state["plan"]
decision = interrupt_and_ask_user(plan) # 暂停,把计划给用户看
if decision == ACCEPTED: # ① 用户说「就按这个来」
return {"approved": True}
elif decision == EDIT_PLAN: # ② 用户用自然语言改计划
state["feedback"] = decision.edit # 把用户的修改意见存下来
return {"approved": False, "loop_back": "planner"} # 回头重新规划
# ③ auto-accept:用户开了「自动接受」,跳过人工,直接执行
def should_pause_for_human(state):
if config.auto_accept: # 用户配置了自动接受
return "accept"
return "review" # 否则进人工闸门三种状态拆开看,藏着三个层次的设计:
- ACCEPTED:用户确认计划。这是最朴素的「人点头」。
- EDIT_PLAN:用户用自然语言改计划,而不是改代码。这是关键——用户不需要懂 Pydantic,直接说「把『竞争对手分析』也加进去」,系统把它转回 Planner 重新规划。自然语言是人和机器之间最自然的「协调接口」。
- auto-accept:允许用户主动放弃这个闸门。这很重要——「插人」应该是一个可选的、用户可关的开关,而不是强制的。用户对某个任务很有把握,可以一键跳过。
4. 人机协作的深层逻辑:为什么要「可中断」
这个闸门背后,是 LangGraph 状态图的又一个杀手锏——checkpoint(检查点)支持「中断 + 恢复」:
# interrupt 不是「卡住等用户」,而是「把状态存盘,进程可以先挂起」
# 用户随时回来,从「计划待确认」这个现场继续这比「一个阻塞的 input()」高级得多:
input()是同步阻塞——进程卡死等输入,超时、重启、用户离开都处理不了。interrupt + checkpoint是异步挂起 + 持久恢复——系统把「当前卡在哪一步」存盘,用户几分钟后、甚至几小时后回来,都能从现场继续。
对长任务 agent 来说,这个区别是生死之差。 深度研究要跑几十分钟,用户不可能全程守着,也不可能在一个阻塞输入上干等。可中断 + 可恢复,让人机协作从「你必须实时在线」变成「你想什么时候介入都行」。
一个更深的洞察:「人机协调」和「agent 之间的协调」用的是同一套基础设施(状态图 + checkpoint)。 人,本质上也是协调链路里的一个「特殊角色」——一个「有最终判断权、但响应速度不可预测」的角色。把人也建模成状态图里的一个节点,人机协作就自然融入了整个协调框架,而不是一个割裂的「弹窗」。
思考题
Q:为什么「人机闸门」默认放在 Planner 之后,而不是放在 Reporter 之后(即「报告写好了再让人确认」)?后者不是更保险吗——连最终结果都确认了。
参考答案:
因为「放哪」要同时看纠错杠杆和纠错成本:
- 放 Planner 之后:改的是「方向」,杠杆最大——改一处计划,影响所有后续执行;而且此时还没投入执行成本,改起来最便宜。
- 放 Reporter 之后:虽然连结果都把关了,但如果方向一开始就错,你已经白跑了几十分钟才发现,纠错成本极高;而且「报告写错了」往往是「方向错了」的果,盯着果不如在因上拦。
一个常用的框架是**「双闸门」**——关键方向确认放前(Planner 后),最终交付确认放后(Reporter 后),中间全自动。但如果你只能选一个,放前面性价比最高,因为「在错误还很便宜的时候拦住它」永远优于「在错误已经很贵的时候发现它」。
这也呼应了一句工程箴言:越早发现错误,代价越低。 人机协作的闸门位置,本质是在「错误成本曲线」上找那个「成本即将陡增」的点。