高级功能

人机交互

实现 Human-in-the-loop (HITL) 工作流,如审批、修改和澄清

📚 学习目标

学完这篇文章后,你将能够:

  • 使用 interrupt 暂停 Graph 执行
  • 使用 Command 恢复执行并注入用户反馈
  • 实现审批(Approval)和编辑(Editing)模式

前置知识

在开始学习之前,建议先阅读:


1️⃣ 什么是 Human-in-the-loop?

全自动的 AI 有时不可靠。我们需要人在关键节点介入:

  • 审批:AI 想发送邮件,人审批 "同意" 或 "拒绝"。
  • 修改:AI 写了草稿,人想在发布前 "润色" 一下。
  • 澄清:AI 没听懂,回头问人 "你是这个意思吗?"。

LangGraph 的 interrupt 机制让这一切变得简单。


2️⃣ 核心机制:interrupt & Command

暂停 (interrupt)

在节点内部调用 interrupt 函数。Graph 会停在这里,并保存状态(需配置 checkpointer)。

import { interrupt } from "@langchain/langgraph";

const humanReviewNode = async (state) => {
  // 暂停执行,把 value 返回给主程序(方便前端展示)
  const userFeedback = await interrupt("Please approve this action");
  
  // 恢复后,userFeedback 就是用户传进来的值
  return { feedback: userFeedback };
};

恢复 (Command)

用户在前端操作后,我们再次调用 Graph,这次带上 Command 对象。

import { Command } from "@langchain/langgraph";

// 第一次运行:遇到 interrupt 暂停
await app.invoke(inputs, config);

// ... 等待用户操作 ...
// 用户批准了
const userInput = "Approved";

// 第二次运行:恢复执行
// resume 的值会被传给 interrupt 函数的返回值
await app.invoke(new Command({ resume: userInput }), config);

3️⃣ 常见模式

审批模式 (Approval)

先生成,再审批,最后执行。

const step1 = (state) => ({ draft: "Generated Content" });

const approval = async (state) => {
  const decision = await interrupt({ 
    type: "approval", 
    content: state.draft 
  });
  
  if (decision === "reject") {
    // 可以抛错,或者路由到修改节点
    throw new Error("Rejected by user");
  }
  return { status: "approved" };
};

const execute = (state) => {
    // 只有批准后才会执行到这里
    console.log("Executing:", state.draft);
};

编辑模式 (Editing)

AI 生成 -> 人修改 -> 确认。

这其实可以通过更新 State 来实现。在恢复时,不仅传入 resume 值,还可以直接 update 状态。

// 直接更新状态中的 draft 字段
await app.updateState(config, { draft: "Human Edited Content" });
// 然后恢复
await app.invoke(new Command({ resume: "continue" }), config);

💡 练习题

  1. 实战题:构建一个 "敏感操作执行器"。
    • 节点 A: 接收用户指令(如 "删除数据库")。
    • 节点 B: 检测到敏感词 "删除",触发 interrupt,询问 "你确定吗?"。
    • 恢复:
      • 如果用户输入 "yes",执行操作。
      • 如果用户输入 "no",返回 "操作取消"。

📚 参考资源

官方文档


✅ 总结

本章要点

  • Checkpointer 是必须的:没有持久化,暂停后就找不回上下文了。
  • interrupt 像是一个异步断点,只有收到 Command 才会继续。
  • UX 设计:前端需要适配这种暂停/恢复的逻辑,给用户展示待办任务。

下一步:除了保存对话,如何让 AI 记住用户的长期偏好?学习记忆管理

登录以继续阅读

解锁完整文档、代码示例及更多高级功能。

立即登录

On this page