LangGraph篇-人机交互

Human-in-the-loop(人机交互)

人机交互 (或称"在循环中")工作流将人类输入整合到自动化过程中,在关键阶段允许决策、验证或修正。这在基于 LLM 的应用中尤其有用,因为基础模型可能会产生偶尔的不准确性。在合规、决策或内容生成等低误差容忍场景中,人类的参与通过允许审查、修正或覆盖模型输出来确保可靠性。

使用案例

基于 LLM 应用中的人机交互工作流的关键使用案例包括:

  1. 🛠️ 审查工具调用:人类可以在工具执行之前审查、编辑或批准 LLM 请求的工具调用。
  2. ✅ 验证 LLM 输出:人类可以审查、编辑或批准 LLM 生成的内容。
  3. 💡 提供上下文:使 LLM 能够明确请求人类输入以进行澄清或提供额外细节,或支持多轮对话。

interrupt

interrupt函数 在 LangGraph 中通过在特定节点暂停图形、向人类展示信息以及使用他们的输入恢复图形,从而启用人工干预工作流。该函数对于批准、编辑或收集额外输入等任务非常有用。interrupt函数Command 对象结合使用,以人类提供的值恢复图形。

ini 复制代码
from langgraph.types import interrupt

def human_node(state: State):
    value = interrupt(
        # 任何可序列化为 JSON 的值,供人类查看。
        # 例如,一个问题、一段文本或状态中的一组键
       {
          "text_to_revise": state["some_text"]
       }
    )
    # 使用人类的输入更新状态或根据输入调整图形。
    return {
        "some_text": value
    }

graph = graph_builder.compile(
    checkpointer=checkpointer # `interrupt` 工作所需
)

# 运行图形直到遇到中断
thread_config = {"configurable": {"thread_id": "some_id"}}
graph.invoke(some_input, config=thread_config)

# 用人类的输入恢复图形
graph.invoke(Command(resume=value_from_human), config=thread_config)
arduino 复制代码
{'some_text': '编辑后的文本'}

Warning

中断非常强大且易于使用。然而,尽管它们在开发者体验上可能类似于 Python 的 input() 函数,但重要的是要注意,它们不会自动从中断点恢复执行。相反,它们会重新运行使用中断的整个节点。 因此,中断通常最好放置在节点的开头或一个专用的节点中。请阅读 从中断恢复 部分以获取更多细节。

完整代码

要求

要在图形中使用 interrupt,您需要:

  1. 指定一个检查点,以在每一步后保存图形状态。
  2. 在适当位置调用 **** interrupt()。有关示例,请参见 设计模式 部分。
  3. 使用 **** 线程 ID ****运行图形 ,直到触发 interrupt
  4. 使用 **** invoke / ainvoke / stream / astream ****恢复执行 (见 Command原语)。

设计模式

您通常可以采取三种不同的行动来实现人工干预工作流:

  1. 批准或拒绝 :在关键步骤之前暂停图形,例如 API 调用,以审查和批准该操作。如果拒绝该操作,您可以阻止图形执行该步骤,并可能采取替代行动。此模式通常涉及根据人类的输入路由图形。
  2. 编辑图形状态 :暂停图形以审查和编辑图形状态。这对于纠正错误或使用额外信息更新状态非常有用。此模式通常涉及使用人类的输入更新状态。
  3. 获取输入 :在图形的特定步骤明确请求人类输入。这对于收集额外信息或上下文以帮助代理的决策过程或支持多轮对话非常有用。

下面我们展示可以使用这些行动实现的不同设计模式。

批准或拒绝

根据人类的批准或拒绝,图形可以继续执行操作或采取替代路径。

在关键步骤之前暂停图形,例如 API 调用,以审查和批准该操作。如果拒绝该操作,您可以阻止图形执行该步骤,并可能采取替代行动。

python 复制代码
from typing import Literal
from langgraph.types import interrupt, Command

def human_approval(state: State) -> Command[Literal["some_node", "another_node"]]:
    is_approved = interrupt(
        {
            "question": "这是正确的吗?",
            # 展示应由人类审查和批准的输出。
            "llm_output": state["llm_output"]
        }
    )

    if is_approved:
        return Command(goto="some_node")
    else:
        return Command(goto="another_node")

# 将节点添加到图形中的适当位置并连接到相关节点。
graph_builder.add_node("human_approval", human_approval)
graph = graph_builder.compile(checkpointer=checkpointer)

# 在运行图形并触发中断后,图形将暂停。
# 用批准或拒绝恢复。
thread_config = {"configurable": {"thread_id": "some_id"}}
graph.invoke(Command(resume=True), config=thread_config)

请参见 如何审查工具调用 获取更详细的示例

添加断点

在某些节点执行之前或之后设置断点通常很有用。这可以用来在继续之前等待人工批准。当您"编译"图形时,可以设置这些断点。您可以在节点执行之前 (使用interrupt_before)或节点执行之后 (使用interrupt_after)设置断点。

使用断点时,您必须 使用检查点。这是因为您的图形需要能够恢复执行。

为了恢复执行,您可以使用 None 作为输入调用您的图。

ini 复制代码
# Initial run of graph
graph.invoke(inputs, config=config)

# Let's assume it hit a breakpoint somewhere, you can then resume by passing in None
graph.invoke(None, config=config)

有关如何添加断点的完整演练,请参阅本指南

人机交互 (HIL) 在 代理系统 中至关重要。 断点 是一种常见的 HIL 交互模式,允许图在特定步骤停止并寻求人为批准后再继续执行(例如,对于敏感操作)。

断点建立在 LangGraph 检查点 之上,检查点在每个节点执行后保存图的状态。 检查点保存在 线程 中,这些线程保存图状态,并且可以在图执行完成后访问。 这使得图执行可以在特定点暂停,等待人为批准,然后从最后一个检查点恢复执行。

让我们看看它的基本用法。

下面,我们做两件事

  1. 我们使用 interrupt_before 指定步骤,来指定 断点
  2. 我们设置一个检查点来保存图的状态。
python 复制代码
#示例:breakpoints_case.py
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.checkpoint.memory import MemorySaver
from IPython.display import Image, display


class State(TypedDict):
    input: str


def step_1(state):
    print("---Step 1---")
    pass


def step_2(state):
    print("---Step 2---")
    pass


def step_3(state):
    print("---Step 3---")
    pass


builder = StateGraph(State)
builder.add_node("step_1", step_1)
builder.add_node("step_2", step_2)
builder.add_node("step_3", step_3)
builder.add_edge(START, "step_1")
builder.add_edge("step_1", "step_2")
builder.add_edge("step_2", "step_3")
builder.add_edge("step_3", END)

# Set up memory
memory = MemorySaver()

# Add
graph = builder.compile(checkpointer=memory, interrupt_before=["step_3"])

# 将生成的图片保存到文件
graph_png = graph.get_graph().draw_mermaid_png()
with open("breakpoints_case.png", "wb") as f:
    f.write(graph_png)

我们为检查点创建一个 线程 ID

我们运行到步骤 3,如 interrupt_before 中定义。

在用户输入/批准后,我们恢复执行,方法是用 None 调用图。

python 复制代码
#示例:breakpoints_add.py
from typing import TypedDict
from langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import StateGraph, START, END

class State(TypedDict):
    input: str

def step_1(state):
    print("---Step 1---")
    pass

def step_2(state):
    print("---Step 2---")
    pass

def step_3(state):
    print("---Step 3---")
    pass

builder = StateGraph(State)
builder.add_node("step_1", step_1)
builder.add_node("step_2", step_2)
builder.add_node("step_3", step_3)
builder.add_edge(START, "step_1")
builder.add_edge("step_1", "step_2")
builder.add_edge("step_2", "step_3")
builder.add_edge("step_3", END)

# Set up memory
memory = MemorySaver()

# Add
graph = builder.compile(checkpointer=memory, interrupt_before=["step_3"])

# Input
initial_input = {"input": "hello world"}

# Thread
thread = {"configurable": {"thread_id": "1"}}

# 运行graph,直到第一次中断
for event in graph.stream(initial_input, thread, stream_mode="values"):
    print(event)

user_approval = input("Do you want to go to Step 3? (yes/no): ")

if user_approval.lower() == "yes":
    # If approved, continue the graph execution
    for event in graph.stream(None, thread, stream_mode="values"):
        print(event)
else:
    print("Operation cancelled by user.")
css 复制代码
{'input': 'hello world'}
---Step 1---
    ---Step 2---
相关推荐
深圳多奥智能一卡(码、脸)通系统8 分钟前
智能二维码QR\刷IC卡\人脸AI识别梯控系统功能设计需基于模块化架构,整合物联网、生物识别、权限控制等技术,以下是多奥分层次的系统设计框架
人工智能·门禁·电梯门禁·二维码梯控·梯控·电梯
批量小王子11 分钟前
2025-08-19利用opencv检测图片中文字及图片的坐标
人工智能·opencv·计算机视觉
没有梦想的咸鱼185-1037-16631 小时前
SWMM排水管网水力、水质建模及在海绵与水环境中的应用
数据仓库·人工智能·数据挖掘·数据分析
即兴小索奇1 小时前
【无标题】
人工智能·ai·商业·ai商业洞察·即兴小索奇
国际学术会议-杨老师1 小时前
2025年计算机视觉与图像国际会议(ICCVI 2025)
人工智能·计算机视觉
欧阳小猜2 小时前
深度学习②【优化算法(重点!)、数据获取与模型训练全解析】
人工智能·深度学习·算法
fsnine2 小时前
深度学习——神经网络
人工智能·深度学习·神经网络
有Li2 小时前
CXR-LT 2024:一场关于基于胸部X线的长尾、多标签和零样本疾病分类的MICCAI挑战赛|文献速递-深度学习人工智能医疗图像
论文阅读·人工智能·算法·医学生
的小姐姐2 小时前
AI与IIOT如何重新定义设备维护系统?_璞华大数据Hawkeye平台
大数据·人工智能
arron88992 小时前
(双类别检测:电动车 + 头部,再对头部分类)VS 单类别检测 + ROI 分类器 方案
人工智能