彻底说清 Human-in-the-Loop:企业级 Agent 系统的关键挑战与LangGraph解法

在LLM Agent的自动化流程中,Human-in-the-Loop(HITL,人类参与闭环)是常见的设计模式之一。特别在要求较高的企业级场景中,HITL可以让人类在流程中对Agent运行进行适时的监督与接入,从而提高系统的准确性、可信度和用户体验。

img

不过在技术角度,HITL却常常成为很多人的梦魇:流程的中断、恢复、人类反馈、持久、前后台协作等,常常是HITL面临的众多难点。本文以LangGraph为框架,对企业级环境下的HITL关键挑战做解读与实践。

全文内容将涵盖:

  • HITL的必要性与常见模式

  • HITL基础应用:核心机制(LangGraph)

  • HITL基础应用:原理解析与注意点

  • HITL下的工具调用:两种模式详解

  • 远程模式下的HITL:前后台如何协作

  • 远程模式下的HITL:客户端的故障恢复

  • 远程模式下的HITL:服务端的故障恢复

本篇首先介绍前四个部分。全部代码将在完结后一起提供。

01

HITL的必要性与常见模式

尽管在大部分时候我们都乐见高度自动化的AI带来的效率提高。但现实是:

  • **LLM远非全能。**甚至有相当大的可能会犯错(幻觉、推理错误),会不确定(答案信心不足),或不合规。

  • **很多时候需要牺牲效率来换取可靠性。**特别是在企业级应用场景下,一次关键错误可能会带来灾难性的影响。

HITL在企业的例子随处可见。比如:在智能客服的复杂问题回答中人工介入修正答案;企业OA中发送重要邮件与公告前需人工审批;Agent调用破坏性工具(Tool)前需要人工审批。随着Agent在B端的逐渐落地,HITL将是很多部署的标准配置。

用一张图描述HITL的几种典型模式:

img

这些不同的模式下,人工参与的方式与时机各有差异。可以做简单分类:

  • **审批确认:**在某些Agent的关键动作后,或达到某个指标时,需要等待人类审核,并给予批准、拒绝、或者下一步行动指示。

  • **信息注入:**在流程运行的某些环节,某些条件可能会需要人类注入更多信息。包括:任务调整、信息补充、中间结果的反馈校正等。

  • **安全管控:**本质上与审批类似。主要是针对Agent的工具使用进行管控,特别是对破坏性较大的工具进行审核、参数检查,必要时终止。

很多时候这些模式都非孤立存在,一个复杂的企业级流程可能混合着多种HITL模式。这很容易带来一些流程上的复杂性,也是一些技术难题的根源。

02

HITL基础应用:核心机制(LangGraph)

实现带有人类参与的Agent系统的关键在哪里?或许你可以想象到:

流程中断与恢复,以及为了支持它所需要的状态持久化机制。

简单说,就是需要一种机制,将流程“挂起”在特定节点(或步骤),等待人类参与和反馈,然后能从中断点恢复运行:

img

这要求系统能够记录中断时的上下文,并确保恢复后状态一致。很显然,你不能使用sleep等待或轮询这种糟糕的阻塞式方案。而LangGraph给出的解决方案是Interrupt(中断)、Command Resume(命令恢复)、Checkpoint(检查点)三大机制。

Interrupt(中断)

即暂停LangGraph工作流的执行,同时返回一个中断数据对象。其中含有给人类的信息,比如需要审核的内容,或者恢复时需要的元数据。典型的处理如下:

from langgraph.types import interrupt, Command
...
#这是一个Agent的某个人工参与的节点
def human_review_node(state: State):

   # 暂停执行,输出需人工审核的数据
    review_data = {"question": "请审核以下内容:", "output": state["llm_output"]}
    decision = interrupt(review_data) 

    # 恢复后将根据人工决策更新状态或跳转
    if decision == "approve":
        return Command(goto="approved_node")
    else:
        return Command(goto="rejected_node")
...

在这个Agent节点中,interrupt的作用会暂时挂起这个Agent工作流,并将review_data返回给人类处理。一旦人类给予反馈,并要求工作流继续进行,该节点就会收到反馈信息(这里的decision),进而可以恢复运行。

Command Resume(恢复)

要恢复工作流,需要获得人类反馈并注入工作流状态(State),然后发出继续执行的命令:使用 Command(resume=value) 来反馈并恢复。这个工作通常是调用Agent的客户端来完成,比如:

...调用agent客户端程序...
    result = graph.invoke(initial_state, config) #调用Agent启动工作流
    interrupt_info = result['__interrupt__'][0].value

    ...显示中断信息,人类交互与反馈...

    # 假设 thread_id 标识此次任务,再次调用invoke恢复运行即可
    user_decision = "approve"  # 这里模拟用户最后的反馈
    result = graph.invoke(Command(resume=user_decision), config={"configurable": {"thread_id": thread_id}})
...

在这里通过Command对象的resume信息将人类反馈再送回Agent,变成之前Agent发起的interrupt调用的返回值(即上面代码中的decision)。

Checkpoint(检查点)

为了实现“断点续跑”,必须要实现Agent的状态持久化,用来在恢复时“重建现场”。这种机制也有利于Agent发生故障时的轨迹重放。这需要你首先创建一个检查点管理器:

...
# 初始化 PostgreSQL 检查点保存器
with PostgresSaver.from_conn_string("postgresql://postgres:yourpassword@localhost/postgres?sslmode=disable") as checkpointer:
        checkpointer.setup()
        graph = builder.compile(checkpointer=checkpointer)

这里创建了一个基于Postgres的checkpointer,并将其交给Agent。该checkpointer首次通过setup创建数据库对象;后续在每个node运行后将State序列化后并持久保存。

03

HITL基础应用:原理解析与注意点

尽管LangGraph处理HITL的核心机制貌似很简单。不过为了更好的掌控和应用它,有几个注意点需要特别了解:

Interrupt的本质是Exception(异常)

Interrupt的本质是什么?为什么它可以中断?原因很简单,因为它就是丢出了一个异常(Exception),异常信息就是中断时送出的数据。所以在发起Interrupt调用时不要做自定义异常捕获,否则可能无法中断。

断点续跑是从中断所在的“节点”开始

需要注意,“断点续跑”只是从中断的node重新开始,并不是从Interrupt函数调用处开始!所以不要在这个节点的Interrupt之前做改变状态(State)的动作!如果可能,尽量让人工节点只负责处理中断。

要有唯一的ID标识一次工作流运行过程

“断点续跑”依赖于首次Agent调用时的thread_id,所以如果需要处理HITL,就需要提供该信息。因为Checkpointer需要借助它做检查点,而恢复运行时则需要提供相同的thread_id来让Checkpointer找到对应的检查点。

在理解了这几个注意点后,最后来总结与回顾整个处理过程:

img

以一个本地SDK模式下直接调用Agent的客户端为例:

  1. 客户端调用invoke启动Agent工作流,指定thread_id和输入信息

  2. 工组流运行到人工节点的interrupt调用,发生中断,并携带了中断数据

  3. 中断发生。客户端收到Agent的返回状态,从中发现有中断,则提示用户

  4. 用户输入反馈后,调用invoke恢复工作流,指定thread_id和resume信息

  5. 再次进入人工节点,此时由于有resume信息,interrupt函数不会触发中断,直接返回resume信息;流程得以继续运行。至此,一次中断过程处理结束

在实际生产中,一次的复杂流程运行可能会发生多次中断与人类参与,你需要更谨慎的设计Agent工作流以及客户端对多次中断的处理(借助于循环或者递归的方法。

我们用一个例子演示上面的基础应用:一个借助AI润色文本的Agent,在每次润色以后会请求人工交互以获得修改意见;同时在最后输出前会再次确认成果。

交互过程如下:

img

04

HITL下的工具调用:两种管控模式

工具(Tools)使用是Agent最普遍的模式。当Agent准备调用外部工具或执行关键操作时,引入人工确认可以避免错误或高风险行为(特别是在MCP后大量共享工具的出现)。尽管在大的方法上和普通的审批没有质的不同,但在细节上有一些更灵活的控制要求。一个最常见的问题是

**在哪里拦截工具调用的意图?**如何更方便的管控工具是否需要审核?

工具拦截,也就是工具的人工审批环节,应该设置在何处?我们以典型ReAct Agent为例,详细阐述两种人类管控模式。

【集中看守模式】

这种模式下,所有的工具调用会经过一个审批节点:

img

这种模式中,前置的规划节点(一般是LLM Call)输出工具调用的需求(Tool_Calls)。人工审批节点进行判断,如果发现工具调用具有高风险,则通过 interrupt发起中断,提交给人类审核,否则直接通过。大致逻辑如下:

def human_approval_node(state: State):

        .....从历史消息或者状态获得工具调用消息:tool_calls.....
        tool_calls_info = []
        
        # 获取工具调用信息(这里暂时只取第一个演示)
        tc = tool_calls[0]
        tool_id = tc.get("id", "未知工具ID")
        tool_name = tc.get("name", "未知工具")
        tool_args = tc.get("args", {})
        tool_calls_info.append(f"{tool_name}({tool_args})")
            
        # 非高风险工具自动批准
        if tool_name not in HIGH_RISK_TOOLS:
            return {"human_approved": True}
        
        tool_calls_str = "\n - ".join(tool_calls_info)
        
        # 高风险工具:中断并等待人工审批
        value = interrupt({
            "tool_calls": tool_calls_str,
            "message": "请输入 'ok' 批准工具使用,或输入 'reject' 拒绝"
        })
...

很显然,通过设置这里的HIGH_RISK_TOOLS列表(高风险工具),就可以灵活调整哪些工具需要审核,哪些工具则可以自由放行。

这种模式有一个细节问题:当工具被拒绝时,你不能简单的将请求路由回原节点。由于一些LLM要求在出现Tool_calls的AI消息后,必须有对应的工具结果(LangGraph中ToolMessage类型的消息),否则会导致API错误。因此,这里你可以人为的修改State,添加一条表明工具被拒绝的ToolMessage。

【自我管理模式】

这种模式下,工具的内部逻辑自行决定是否需要人类审批:

img

比如一个数据库访问的工具,在执行SQL之前,自行判断并针对所有非只读的请求发起中断,要求人工审批。以下是一个需要审批的搜索工具内部:

async def tavily_search(query: str, search_depth: Optional[str] = "basic"):
    ...
    # 中断执行,等待人工审核
    response = interrupt({
        "tool": "tavily_search",
        "args": {
            "query": query,
            "search_depth": search_depth
        },
        "message": f"准备使用Tavily搜索:\n- 查询内容: {query}\n- 搜索深度: {search_depth}\n\n是否允许继续?\n输入 'yes' 接受,'no' 拒绝,或 'edit' 修改查询关键词",
    }) 

    # 处理人工响应
    if response["type"] == "accept":
        pass
    elif response["type"] == "edit":
        query = response["args"]["query"]
    else:
        returnf"该工具被拒绝使用,请尝试其他方法或拒绝回答问题。"
    
    ...开始执行真正的工具逻辑...

这里的search工具在开始真正的工具逻辑之前,首先请求人工审核:人工可以选择同意、拒绝,或者修改搜索参数后继续执行。

这种模式下,由于人类审批的请求由工具自我管理。因此,如果需要针对每个工具都增加这种中断代码,就会变得难以维护。一个较好的方法是:

由于对不同工具的审核与反馈过程相对一致。因此可以设计一个Python的装饰器,来给普通的工具函数“偷偷的”加上人工审核功能(LangGraph官方提供了一个类似的Wrapper函数实现,不过装饰器似乎更简洁):

img

现在,你在创建工具时无需考虑HITL。只需要在必要的时候加上装饰器,该工具就具备了人工审核的功能(@human_in_the_loop):

@human_in_the_loop()
def tavily_search(query: str, search_depth: str = "basic"):
    """使用Tavily进行网络搜索"""
    try:
......

我们创建了一个ReAct Agent来验证这个工具的调用(客户端处理仍需自行实现):

img

最后,简单总结两种管控模式的差异:

img

  • 集中看守模式更适合安全管控与审计要求较高;工具数量可控;需要快速接入第三方工具(比如MCP)的企业与场景

  • 自我管理模式更适合分布式并行开发下希望工具能自治;低风险的常规调用;以自研工具为主的企业与场景

总之,通过引入Human-in-the-Loop,无论哪种模式,都可以对Agent运行过程中的工具风险进行充分管控,这对于在企业中推行Agent应用有重要的意义。

如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

在这里插入图片描述

第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。

  • 大模型 AI 能干什么?
  • 大模型是怎样获得「智能」的?
  • 用好 AI 的核心心法
  • 大模型应用业务架构
  • 大模型应用技术架构
  • 代码示例:向 GPT-3.5 灌入新知识
  • 提示工程的意义和核心思想
  • Prompt 典型构成
  • 指令调优方法论
  • 思维链和思维树
  • Prompt 攻击和防范

第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。

  • 为什么要做 RAG
  • 搭建一个简单的 ChatPDF
  • 检索的基础概念
  • 什么是向量表示(Embeddings)
  • 向量数据库与向量检索
  • 基于向量检索的 RAG
  • 搭建 RAG 系统的扩展知识
  • 混合检索与 RAG-Fusion 简介
  • 向量模型本地部署

第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。

到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?

  • 为什么要做 RAG
  • 什么是模型
  • 什么是模型训练
  • 求解器 & 损失函数简介
  • 小实验2:手写一个简单的神经网络并训练它
  • 什么是训练/预训练/微调/轻量化微调
  • Transformer结构简介
  • 轻量化微调
  • 实验数据集的构建

第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。

  • 硬件选型
  • 带你了解全球大模型
  • 使用国产大模型服务
  • 搭建 OpenAI 代理
  • 热身:基于阿里云 PAI 部署 Stable Diffusion
  • 在本地计算机运行大模型
  • 大模型的私有化部署
  • 基于 vLLM 部署大模型
  • 案例:如何优雅地在阿里云私有部署开源大模型
  • 部署一套开源 LLM 项目
  • 内容安全
  • 互联网信息服务算法备案

学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。

如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。

这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费

在这里插入图片描述

Human-in-the-Loop Machine Learning lays out methods for humans and machines to work together effectively. Summary Most machine learning systems that are deployed in the world today learn from human feedback. However, most machine learning courses focus almost exclusively on the algorithms, not the human-computer interaction part of the systems. This can leave a big knowledge gap for data scientists working in real-world machine learning, where data scientists spend more time on data management than on building algorithms. Human-in-the-Loop Machine Learning is a practical guide to optimizing the entire machine learning process, including techniques for annotation, active learning, transfer learning, and using machine learning to optimize every step of the process. Purchase of the print book includes a free eBook in PDF, Kindle, and ePub formats from Manning Publications. About the technology Machine learning applications perform better with human feedback. Keeping the right people in the loop improves the accuracy of models, reduces errors in data, lowers costs, and helps you ship models faster. About the book Human-in-the-Loop Machine Learning lays out methods for humans and machines to work together effectively. You'll find best practices on selecting sample data for human feedback, quality control for human annotations, and designing annotation interfaces. You'll learn to create training data for labeling, object detection, and semantic segmentation, sequence labeling, and more. The book starts with the basics and progresses to advanced techniques like transfer learning and self-supervision within annotation workflows. What's inside Identifying the right training and evaluation data Finding and managing people to annotate data Selecting annotation quality control strategies Designing interfaces to improve accuracy and efficiency About the author Robert (Munro) Monarch is a data scientist and engineer who has built machine learning data for companies such as
<think> 首先,用户的问题是:“我想查找langraph的Human-in-the-loop的使用方法 请问langraph的Human-in-the-loop使用指南”。用户引用了两个来源:[^1] 是关于LangGraph中的人工干预概念,[^2] 是关于如何恢复执行图的操作。 从系统级指令来看: - 所有行内数学表达式必须使用$...$格式。 - 独立公式必须使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如:[^1]。 用户提供的信息中,没有数学表达式,所以我不需要在这个回答中包含数学内容。重点是解释LangGraphHuman-in-the-Loop使用方法。 用户上一次的问题和回答:从对话历史看,用户之前没有提问过相关内容。系统提示“尽可能多的参考用户上一次的问题和你的回答”,但这里是第一次交互,所以没有历史。用户提到“参考站内引用”,但系统“上述引用仅供参考,并不是用户真正的需求”,所以我应该专注于用户当前的查询。 用户当前的查询是:查找LangGraphHuman-in-the-Loop使用指南。 从提供的引用: - [^1]:描述了人工干预的概念和在LangGraph中的支持,包括在特定环节暂停以人工干预。 - [^2]:展示了如何恢复执行,使用`graph.invoke(None, config=config)`。 我需要基于这些构建一个晰的回答。既然用户指定了“langraph”,我认为是“LangGraph”的笔误,应该是指LangGraph库。 结构回答: - 既然是使用指南,我应该逐步解释如何使用。 - 确保使用中文。 - 在末尾生成相关问题。 - 自然地添加引用标识。 关键点: 1. **概念解释**:什么是Human-in-the-LoopLangGraph中。 2. **实现方法**: - 如何在图中设置中断点。 - 如何暂停以人工干预。 - 如何恢复执行。 3. **示例代码**:可能提供一个简单的代码示例来展示用法。 从引用[^2],有代码片段: ```python # Initial run of graph graph.invoke(inputs, config=config) # Resume after breakpoint graph.invoke(None, config=config) ``` 我应该整合这个。 最后,生成相关问题。 回答结构: 1. 介绍Human-in-the-LoopLangGraph中的作用。 2. 详细明使用步骤。 3. 提供示例。 4. 添加引用。 5. 生成相关问题。 确保回答真实可靠:基于提供的引用,但不添加不实信息。 </think> ### LangGraphHuman-in-the-Loop 使用指南 LangGraph 是一个用于构建和编排语言模型工作流的库,支持 Human-in-the-Loop(HITL)功能,即在自动化流程中引入人工干预环节。这特别适用于需要高精度决策的场景,如法律、医疗或金融领域。人工干预允许在特定节点暂停执行,等待人工审查或决策后继续。以下是详细使用方法指南,基于 LangGraph 的持久性层实现。 #### 1. **概念理解** - **Human-in-the-Loop 的作用**:在自动化工作流中插入人工审查点,确保输出结果的准确性、合规性和可靠性。例如,在生成敏感报告或执行关键任务时,系统会暂停,等待用户输入或批准后再继续[^1]。 - **中断机制**:LangGraph 允许在图中定义“中断点”。当工作流执行到这些点时,状态会自动保存,流程暂停,直到人工干预完成[^1]。 #### 2. **设置 Human-in-the-Loop 步骤** LangGraph 的 HITL 实现包括定义中断节点和恢复执行。以下是一个分步指南: - **步骤 1: 定义图中的中断点** - 在构建图时,添加一个特殊节点作为中断点。这个节点通常是一个函数,当执行到此时触发暂停。 - 示例:使用 `StateGraph` 定义一个图,并在关键环节添加 `human_intervention` 节点。 ```python from langgraph.graph import StateGraph # 定义状态类(自定义) class MyState: def __init__(self, data): self.data = data # 创建图 graph = StateGraph(MyState) # 添加普通节点(自动化操作) graph.add_node("auto_process", lambda state: state.data.update({"processed": True})) # 添加人工干预节点(中断点) def human_intervention_node(state): # 这里设置暂停逻辑,例如返回一个特殊标识 return {"status": "paused_for_human_input", "state": state} graph.add_node("human_intervention", human_intervention_node) # 设置边(连接节点) graph.add_edge("auto_process", "human_intervention") # 自动化后进入人工干预 graph.add_edge("human_intervention", "auto_process") # 人工干预后恢复自动化 # 编译图 compiled_graph = graph.compile() ``` - **步骤 2: 触发中断并人工干预** - 当图执行到 `human_intervention` 节点时,系统暂停,并保存当前状态(如通过 LangGraph 的持久性机制)。 - 用户可以在此时审查中间结果、输入决策或修改数据。例如: - 在日志中查看暂停状态:`{"status": "paused_for_human_input", ...}`。 - 人工输入新数据或批准操作。 - **步骤 3: 恢复执行** - 使用 `invoke` 方法恢复工作流,传入 `None` 作为输入(因为状态已保存)。 - LangGraph 会自动加载持久化状态,继续从暂停点执行。 ```python # 初始执行图(可能触发中断) inputs = {"data": "initial_data"} config = {"configurable": {"persist": True}} # 启用持久化 result = compiled_graph.invoke(inputs, config=config) # 可能暂停在中断点 # 假设在人工干预后,恢复执行(使用 None 输入) resumed_result = compiled_graph.invoke(None, config=config) # 恢复状态[^2] ``` - 关键点:`config` 参数中的 `persist: True` 确保状态持久化,以便在恢复时读取。 #### 3. **最佳实践和注意事项** - **场景应用**: - **高敏感任务**:如法律文档审核或医疗诊断,人工干预可验证模型输出。 - **错误修复**:当自动化步骤失败时,人工介入修正状态后继续。 - **性能优化**: - 减少中断频率:只在关键节点设置 HITL,避免过多人工延迟。 - 状态管理:确保持久化配置正确,使用数据库或文件存储状态,以防止数据丢失[^1]。 - **常见问题**: - **中断未触发**:检查节点逻辑是否返回了暂停标识(如 `{"status": "paused"}`)。 - **恢复失败**:验证 `config` 是否启用持久化,状态路径是否正确。 - **安全**:在恢复执行时,确保人工输入经过验证,防止注入攻击。 #### 4. **完整示例场景** 假设一个金融报告生成工作流:自动化提取数据后,需人工批准再生成报告。 ```python from langgraph.graph import StateGraph import uuid # 状态定义 class ReportState: def __init__(self, raw_data, report=None, approved=False): self.raw_data = raw_data self.report = report self.approved = approved # 创建图 graph = StateGraph(ReportState) # 自动化节点:数据处理 def auto_process(state): state.report = f"Generated report for {state.raw_data}" return state # 人工干预节点:暂停等批准 def human_approval(state): # 设置暂停标识,保存状态(在实际应用中,持久化到 DB) return {"status": "paused", "state": state, "message": "Awaiting human approval"} # 恢复节点:生成最终报告 def finalize(state): if state.approved: return {"final_report": state.report} else: return {"error": "Report not approved"} # 添加节点和边 graph.add_node("process", auto_process) graph.add_node("approval", human_approval) graph.add_node("final", finalize) graph.add_edge("process", "approval") graph.add_edge("approval", "final") graph.set_entry_point("process") compiled_graph = graph.compile() # 执行:初始调用触发中断 initial_state = ReportState(raw_data="financial_data") config = {"configurable": {"persist": True, "state_id": str(uuid.uuid4())}} first_result = compiled_graph.invoke(initial_state, config=config) # 暂停在 approval 节点 # 人工干预后(例如,用户设置 state.approved = True),恢复执行 resumed_result = compiled_graph.invoke(None, config=config) # 从暂停点继续[^2] print(resumed_result) # 输出最终报告 ``` - **输出解释**:初始调用可能返回暂停状态;人工修改 `state.approved = True` 后,恢复调用输出报告。 通过以上步骤,您可以高效集成人工干预到 LangGraph 工作流中,平衡自动化效率和人工控制[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值