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---
相关推荐
咸蛋-超人35 分钟前
火山引擎TTS使用体验
人工智能·语音识别·火山引擎
jieshenai37 分钟前
MTEB:基于 Embedding 的文本分类评估与实战解析
人工智能·分类·embedding
京东零售技术1 小时前
GAITC2025|张科:端云一体大模型推理应用实战
人工智能
Gyoku Mint1 小时前
机器学习×第十二卷:回归树与剪枝策略——她剪去多余的分支,只保留想靠近你的那一层
人工智能·算法·机器学习·数据挖掘·pycharm·回归·剪枝
小鬼难缠z1 小时前
HomeLab的反代之神,还得是香香的IPv6
程序员
redreamSo1 小时前
AI Daily | AI日报:摩尔线程冲刺国产GPU第一股; KAIST公布HBM4关键特性及长期路线图; 北京AIGC创投会推动文旅与AI融合
程序员·aigc·资讯
xiaoxiaoxiaolll1 小时前
5G光网络新突破:<Light: Science & Applications>报道可适应环境扰动的DRC实时校准技术
人工智能·学习
资讯分享周2 小时前
2025 MWC 上海盛大开幕,聚焦AI、5G-Advanced及开放API
人工智能·5g
快起来别睡了2 小时前
大模型工作流解析:从输入到输出的详细拆解
程序员
后端小肥肠2 小时前
让Mermaid听懂人话:用Coze空间+MCP一句话搞定所有业务图
人工智能·coze·mcp