当前位置: 首页 > news >正文

使用langgraph创建工作流系列4:人机回环

        到目前为止chatbot的工作流都是用户输入后等待应答,但有些情况下需要人工干预:

        1)因为大模型本身不是可靠的,基于大模型的智能体也是不可靠的,需要人工输入以完成符合要求的任务

        2)在工作流执行过程中,需要人工审核、修改等操作

        在智能体语境下的人工干预也成为人机回环(human-in-the-loop)。langgraph的持久化层借助检查点支持人机回环的工作流。

        在工作流执行过程中,在节点内部调用interrupt将暂停工作流的执行,用户完成处理后,可以从暂停点回复执行,并且可以获得用户输入的数据。

        本文仍基于使用langgraph创建工作流系列3:增加记忆-CSDN博客中的chatbot构建人机回环的chatbot。

        1.增加工具

from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
from langchain_openai import ChatOpenAI

from langgraph.prebuilt import ToolNode, tools_condition#支持工具调用

from langgraph.types import Command, interrupt#引入Command和interrupte支持人机回环

class State(TypedDict):
    messages: Annotated[list, add_messages]

graph_builder = StateGraph(State)


llm = ChatOpenAI(
    model = 'qwen-plus',
    api_key = "sk-27cd7fd64e5a4c82a71f879efaebc40e",
    base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1")

#新增加支持人机回环的工具

@tool def human_assistance(query: str) -> str:

    """请求用户输入"""

    human_response = interrupt({"query": query})

    return human_response["data"]

tools = [human_assistance]

llm_with_tools = llm.bind_tools(tools)

tool_node = ToolNode(tools=tools) #生成工具节点

graph_builder.add_node("tools", tools) #把工具节点增加到工作流图中

def chatbot(state: State):
    return {"messages": [llm.invoke(state["messages"])]}

graph_builder.add_node("chatbot", chatbot)

graph_builder.add_conditional_edges( "chatbot", tools_condition, )
graph_builder.add_edge(START, "chatbot")
graph_builder.add_edge("chatbot", END)
graph = graph_builder.compile(checkpointer=memory)

        2.触发用户介入

        输入一个问题,触发用户介入,也就是调用新增的human_assistant方法。

user_input = "I need some expert guidance for building an AI agent. Could you request assistance for me?"
config = {"configurable": {"thread_id": "1"}}

events = graph.stream(
    {"messages": [{"role": "user", "content": user_input}]},
    config,
    stream_mode="values",
)
for event in events:
    if "messages" in event:
        event["messages"][-1].pretty_print()

        返回数据如下。可见大模型指示调用human_assiatant,调用参数为原始问题。

================================ Human Message =================================

I need some expert guidance for building an AI agent. Could you request assistance for me?
================================== Ai Message ==================================
Tool Calls:
  human_assistance (call_44b1fdebb102451faf8151)
 Call ID: call_44b1fdebb102451faf8151
  Args:
    query: I need some expert guidance for building an AI agent. Could you request assistance for me?
 

        查看工作流下一个节点:

snapshot = graph.get_state(config)
snapshot.next

        输出为('tools",),可见工作流暂停在tools节点,也就是要调用human_assistant。等待用户介入:

('tools',)

        3.模拟用户输入,恢复工作流执行

        用用户输入构造一个Command对象,然后用Command作为参数调用graph.stream

#这里的Command对象很简单,可以根据实际需要构造

human_response = ( "We, the experts are here to help! We'd recommend you check out LangGraph to build your agent." " It's much more reliable and extensible than simple autonomous agents." )

#用用户输入包装一个Command对象,设置resume

human_command = Command(resume={"data": human_response})

events = graph.stream(human_command, config, stream_mode="values")

for event in events:

    if "messages" in event: event["messages"][-1].pretty_print()

        基于用户输出chatbot调用大模型后的输出如下:

================================== Ai Message ==================================
Tool Calls:
  human_assistance (call_44b1fdebb102451faf8151)
 Call ID: call_44b1fdebb102451faf8151
  Args:
    query: I need some expert guidance for building an AI agent. Could you request assistance for me?
================================= Tool Message =================================
Name: human_assistance

We, the experts are here to help! We'd recommend you check out LangGraph to build your agent. It's much more reliable and extensible than simple autonomous agents.

http://www.xdnf.cn/news/1448353.html

相关文章:

  • 面试复习题-Flutter
  • 论文介绍:“DUSt3R”,让 3D 视觉从“繁琐”走向“直观”
  • Swift 解法详解:LeetCode 370《区间加法》
  • 《网络安全实战:CC攻击(应用层)与DDoS攻击(网络层)的底层逻辑与防御体系》​
  • 分发饼干——很好的解释模板
  • 从“看见”到“行动”:一场机器视觉与机器人的软硬件共舞
  • 把本地win11系统打包成镜像并安装到vmware中
  • Springboot3+SpringSecurity6Oauth2+vue3前后端分离认证授权-授权服务
  • FastVLM:高效视觉编码助力视觉语言模型突破高分辨率效率瓶颈
  • LeNet-5:卷积神经网络的奠基之作
  • 0903 C++类的运算符重载、静态成员与继承
  • 前端-安装VueCLI
  • 【ARM嵌入式汇编基础】-数据处理指令(三)
  • OpenHarmony Ability“全家桶”彻底拆解:从UIAbility到ExtensionAbility一文说清楚
  • LeetCode 1537.最大得分
  • 残差连接的概念与作用
  • 蓝桥杯算法之基础知识(6)
  • Netty从0到1系列之Channel
  • 【 线段树】P12347 [蓝桥杯 2025 省 A 第二场] 栈与乘积|普及+
  • 基于 HTML、CSS 和 JavaScript 的智能图像灰度直方图分析系统
  • HTML全屏功能实现汇总
  • npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR!
  • 求单源最短路(Dijkstra 算法-迪杰斯特拉算法,SPFA)
  • 【Unity基础】两个关于UGUI中Text对非英文字体支持的问题
  • SpringAI应用开发面试全流程:技术原理、架构优化与企业场景解析
  • 复写零(双指针)
  • JavaScript学习最后一章节(小练习)
  • 如何解决虚拟机网络连接问题:配置固定 IP 篇
  • Spring Authorization Server 1.5.2 使用YML配置的方式,最常用法总结
  • 【算法--链表】141.环形链表(通俗讲解链表中是否有环)