langgraph 中的人机回环

部署运行你感兴趣的模型镜像

     1.概述

        在使用langgraph创建工作流系列4:人机回环中对于人机回环进行了全面介绍,并且完整实现了工具调用时用户如何接入检查调用参数。本文对于与langgraph中的人机回环的使用模式和常见问题进行详细说明。

        在langgraph中的人机回环有三种模式:审批模式、修订模式和工具调用检查模式。

     2.审批模式

        如同OA工作流中的审批一样,在langgraph中借助中断可以是工作流进行审批,用户可以同意,也可以拒绝。在一个节点内部可以触发中断,用户对于中断时数据进行审批,同意和拒绝后分别走不通的路径,如下图所示:

        以下的例子中,借助大模型生成内容,针对生成的内容进行审批,如果满足用户的要求,则反馈同意,否则反馈拒绝,根据反馈结果进入到不同的下一节点。

        首先,导入必要的包和初始化大模型:

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.checkpoint.memory import InMemorySaver
from langgraph.types import Command, interrupt

llm = ChatOpenAI(
    model = 'deepseek-chat',
    api_key = "sk-*",
    base_url = "https://api.deepseek.com",
)

        创建图,一个chatbot节点,调用大模型生成内容,一个human_node节点,产生中断,a_node和b_node节点分别是审批同意和拒绝后进入的节点,具体代码如下:

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

graph_builder = StateGraph(State)

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

def a_node(state: State) -> State:
     return {"result": "approval"}

def b_node(state: State) -> State:
    return  {"result": "rejected"}


def human_node(state: State) -> Command[str]:
    action = interrupt({#产生中断。提示用于审批,并提供审批内容
        "question": "Do you approve the llm's output?  A---approve, Other---reject",
        "text_to_approve": state["messages"][-1].content}
    )
    if action == "A":
        return Command(goto="a_node")
    else:
        return Command(goto="b_node")        

checkpointer = InMemorySaver()
graph = (
    StateGraph(State)
    .add_node(chatbot)
    .add_node(a_node)
    .add_node(b_node)
    .add_node(human_node, destinations=('a_node', 'b_node'))
    .add_edge(START, "chatbot")
    .add_edge("chatbot", "human_node")
    .add_edge("a_node", END)  
    .add_edge("b_node",  END)
    .compile(checkpointer=checkpointer)
)

        绘制工作流图,确认图的正确性:

from IPython.display import Image, display

try:
    display(Image(graph.get_graph().draw_mermaid_png()))
except Exception:
    # This requires some extra dependencies and is optional
    pass

        调用图,创作一首关于友谊的7言诗,大模型生成诗后,在human_node内部产生中断:

config = {"configurable": {"thread_id": "1"}}
result =  graph.invoke({"messages": [{"role": "user", "content": "写一首关于友谊的7言诗"}]}, config=config)
print(result["__interrupt__"][0].value['question'])
print(result["__interrupt__"][0].value['text_to_approve'])

        中断内容如下:

Do you approve the llm's output?  A---approve, Other---reject
《赠别》
相知数载胜亲情,
患难时分见赤诚。
岁月沧桑人未老,
天涯海角总同行。

注:我的诗以友谊恒久为主题,通过“相知数载”、“患难见诚”等意象,展现岁月沉淀的真情。后两句以“人未老”、“总同行”形成时空张力,暗喻纵使沧海桑田、天涯相隔,挚友间心灵的相伴永不褪色。全诗承转自然,结句余韵悠长。

        用户审批后返回,从中断流程所在节点开始出继续执行:

result = graph.invoke(Command(resume="A"), config=config)
print(result['messages'])

        输出如下:

[HumanMessage(content='写一首关于友谊的7言诗', additional_kwargs={}, response_metadata={}, id='b36e200b-036a-42ba-b343-6d069768622c'), AIMessage(content='《赠别》\n相知数载胜亲情,\n患难时分见赤诚。\n岁月沧桑人未老,\n天涯海角总同行。\n\n注:我的诗以友谊恒久为主题,通过“相知数载”、“患难见诚”等意象,展现岁月沉淀的真情。后两句以“人未老”、“总同行”形成时空张力,暗喻纵使沧海桑田、天涯相隔,挚友间心灵的相伴永不褪色。全诗承转自然,结句余韵悠长。', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 109, 'prompt_tokens': 12, 'total_tokens': 121, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 0}, 'prompt_cache_hit_tokens': 0, 'prompt_cache_miss_tokens': 12}, 'model_name': 'deepseek-chat', 'system_fingerprint': 'fp_ffc7281d48_prod0820_fp8_kvcache', 'id': '61b5d1b1-aa34-4206-8df0-5e03906206b5', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None}, id='run--faa1877e-021f-4aed-a59c-6be42918842d-0', usage_metadata={'input_tokens': 12, 'output_tokens': 109, 'total_tokens': 121, 'input_token_details': {'cache_read': 0}, 'output_token_details': {}})]

      3.修订模式

        采用修订模式时,用户接入对于内容进行检查,还可以对内容进行修改补充。该模式下,在一个节点内部产生中断,由用户对内容进行修订,从中断返回并完成处理后进入下一节点,具体如下图所示:

        以下的例子中,借助大模型生成内容,针对生成的内容进行审批,如果满足用户的要求,则反馈同意,否则反馈拒绝,根据反馈结果进入到不同的下一节点。

       首先创建图,intent_recognition根据用户输入进行意图识别,human_node产生中断,让用户修改意图,next_node仅输出修改后的意图用以说明问题,具体代码如下:

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

graph_builder = StateGraph(State)

def intent_recognition(state: State) ->State:
    prompt = f"""
    根据用户输入分析用户的意图类型,返回以下之一:
    - make: 用户想制作电子印章
    - manage: 用户想对印章进行管理,比如对印章冻结、解冻、注销、续期和变更
    - grant: 用户想把印章授权给其他用户管理管理或使用
    — consult: 用户想咨询印章相关的业务知识或技术知识
    — chat: 其他
    用户输入{state['messages']}
    """
    return {'intent': llm.predict(prompt)}

def next_node(state: State) -> State:
    print(f"✅ Using edited intent: {state['intent']}")
    return state    

def human_node(state: State) -> dict:
    result = interrupt({
        "task": "Please review and edit the recognition intent if necessary.",
        "intent_to_review": state["intent"]}
    )
    return {"intent": result['edited_intent']}

checkpointer = InMemorySaver()
graph = (
    StateGraph(State)
    .add_node(intent_recognition)
    .add_node(next_node)
    .add_node(human_node)
    .add_edge(START, "intent_recognition")
    .add_edge("intent_recognition", "human_node")
    .add_edge("human_node", "next_node")  
    .add_edge("next_node",  END)
    .compile(checkpointer=checkpointer)
)

        绘制工作流图,确认工作流正确性:

from IPython.display import Image, display

try:
    display(Image(graph.get_graph().draw_mermaid_png()))
except Exception:
    # This requires some extra dependencies and is optional
    pass

        调用图,具体代码如下:

config = {"configurable": {"thread_id": "1"}}
user_input = "我的印章要过期了"

result =  graph.invoke({"messages": [{"role": "user", "content": user_input}]}, config=config)
print(result["__interrupt__"][0].value['task'])
print(result["__interrupt__"][0].value['intent_to_review'])

        输出断点信息如下:

Please review and edit the recognition intent if necessary.
根据用户输入内容"我的印章要过期了",分析用户意图类型为:

**manage**

理由:用户提到印章即将过期,这属于印章生命周期管理中的续期相关操作,符合"对印章进行管理,比如对印章冻结、解冻、注销、续期和变更"的范畴。

        再次调用,输入修改后的信息,并从中断返回,具体代码如下:

edited_intent = "make"
resumed_result = graph.invoke(
    Command(resume={"edited_intent": edited_intent}),
    config=config
)
print(resumed_result)

        输出如下:

✅ Using edited intent: make
{'messages': [HumanMessage(content='我的印章要过期了', additional_kwargs={}, response_metadata={}, id='e27e0f9f-9b34-4303-91f7-4934e991626e')], 'intent': 'make'}

      4.工具调用检查模式

        本模式具体实现可参考基于Agent Chat UI实现人机回环1-检查工具调用,此处不再赘述。

      5.DEBUG图

         interrupt可用于在图代码执行过程中设置断点,正如通用的DEBUG工具一样。可以在一个几点执行前后设置断点。可以在创建图时设置好断点,也可以在调用图时设置断点。

        如下代码在node_a节点前设置断点,同时在node_b节点执行后设置断点。

      5.1创建图时设置断点      

graph = graph_builder.compile( 
    interrupt_before=["node_a"], 
    interrupt_after=["node_b"], 
    checkpointer=checkpointer, 
)

config = {
    "configurable": {
        "thread_id": "some_thread"
    }
}

graph.invoke(inputs, config=thread_config) 

graph.invoke(None, config=thread_config) 

        5.2调用图时设置断点

config = {
    "configurable": {
        "thread_id": "some_thread"
    }
}graph.invoke(inputs,     
             interrupt_before=["node_a"], 
             interrupt_after=["node_b"], 
             config=config) graph.invoke(None, config=config) 

您可能感兴趣的与本文相关的镜像

ComfyUI

ComfyUI

AI应用
ComfyUI

ComfyUI是一款易于上手的工作流设计工具,具有以下特点:基于工作流节点设计,可视化工作流搭建,快速切换工作流,对显存占用小,速度快,支持多种插件,如ADetailer、Controlnet和AnimateDIFF等

### Simulink 中回环函数的使用方法 #### 什么是回环函数? 在 MATLAB 的 Simulink 环境中,回环(Loop)通常指的是反馈控制系统中的闭环部分。Simulink 提供了多种方式来构建和模拟这些系统,其中包括使用特定模块创建反馈路径。 #### 创建基本的回环结构 为了创建一个简单的回环,在 Simulink 中可以按照如下方式进行: 1. **启动 Simulink 并新建模型** 打开 MATLAB 后通过命令窗口输入 `simulink` 或者点击主页选项卡下的 "Simulink" 图标进入 Simulink 库浏览器;随后选择 File -> New -> Model 来开启一个新的空白画布[^1]。 2. **添加必要的组件** - 添加信号源:从 Sources 类目下拖拽 Step 模块到工作区作为系统的输入。 - 加入控制器:依据具体需求设计 PID 控制器或其他类型的调节装置。 - 插入被控对象:根据实际物理过程或数学描述定义 Plant (Process) 部分。 - 设置测量输出:利用 Scope 查看结果或者 To Workspace 存储数据以便后续分析。 3. **连接各部件形成闭合路径** 将上述各个组成部分依次相连构成完整的负反馈架构。特别注意的是,对于 S 函数的应用场景,可以通过编写自定义 C/C++/MATLAB 文件来扩展功能,并将其嵌入至现有框架内完成更复杂的运算逻辑处理。 4. **配置参数与运行仿真** 对于每一个加入的元件都需要合理设定内部属性以匹配预期行为模式。完成后保存项目并执行 Simulation 菜单项下的 Start 功能键触发整个流程运转直至结束时刻到来为止。 ```matlab % 运行已建立好的 simulink 模型 'myModel' open_system('myModel'); set_param(gcs,'SimulationCommand','start'); waitforbuttonpress; close_system(gcf); ``` 5. **观察结果** 利用之前提到过的观测工具比如 Scope 实时监控波形变化趋势,亦或是借助其他图形化界面呈现手段辅助理解最终成效如何。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值