到目前为止,我们依赖一个包含一个条目(消息列表)的简单状态。虽然这个简单状态可以走得很远,但如果您想定义复杂的行为而不依赖于消息列表,您可以向状态添加额外的字段。

参考文档

官方文档参考

实践自定义状态

1.将键添加到状态中

在这里,我们将演示一个新场景,其中聊天机器人使用其搜索工具查找特定信息,并将其转发给人工进行审查。让聊天机器人研究一个实体的生日。我们将向状态添加namebirthday

from typing import Annotated

from typing_extensions import TypedDict

from langgraph.graph.message import add_messages

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

2.在工具内部更新状态

我们将在 human_assistance 工具内部填充状态键。这允许人工在信息存储到状态之前对其进行审查。我们将再次使用 Command,这次是从我们的工具内部发出状态更新。

# 导入所需模块和类型
from langchain_core.messages import ToolMessage # 工具调用结果消息类型
from langchain_core.tools import InjectedToolCallId, tool # 工具调用ID注入标记和工具装饰器
from langgraph.types import Command, interrupt # 状态更新命令和人工干预中断函数 @tool
def human_assistance(
name: str, birthday: str,
tool_call_id: Annotated[str, InjectedToolCallId]
) -> str:
"""请求人工协助验证和修正信息""" # 触发人工干预流程,传递待验证的姓名和生日信息
human_response = interrupt(
{
"question": "Is this correct?", # 询问信息是否正确
"name": name, # 待验证姓名
"birthday": birthday, # 待验证生日
},
) # 处理人工反馈结果
if human_response.get("correct", "").lower().startswith("y"):
# 信息正确时,直接使用原始数据
verified_name = name
verified_birthday = birthday
response = "Correct" # 标记信息正确
else:
# 信息错误时,获取人工修正后的数据
verified_name = human_response.get("name", name)
verified_birthday = human_response.get("birthday", birthday)
response = f"Made a correction: {human_response}" # 记录修正内容 # 构造状态更新数据
state_update = {
"name": verified_name, # 验证后的姓名
"birthday": verified_birthday, # 验证后的生日
"messages": [ToolMessage( # 封装工具调用结果消息
response,
tool_call_id=tool_call_id # 关联工具调用ID
)],
} # 返回状态更新命令,通知系统更新对话状态
return Command(update=state_update)

3. 提示聊天机器人

图的其余部分保持不变。

import os
# from langchain.chat_models import init_chat_model
from langchain_openai import ChatOpenAI
from langchain_tavily import TavilySearch from langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import StateGraph, START, END
from langgraph.prebuilt import ToolNode, tools_condition #环境变量设置,替换为你的API KEY
os.environ['TAVILY_API_KEY'] = 'TAVILY_API_KEY'
os.environ['ARK_API_KEY'] = 'API_KEY' tool = TavilySearch(max_results=2)
tools = [tool, human_assistance]
llm = ChatOpenAI(
base_url="https://ark.cn-beijing.volces.com/api/v3",
api_key=os.environ.get('ARK_API_KEY'),
model="doubao-1-5-pro-32k-250115" # 根据实际模型名称修改
)
llm_with_tools = llm.bind_tools(tools) def chatbot(state: State):
message = llm_with_tools.invoke(state["messages"])
assert len(message.tool_calls) <= 1
return {"messages": [message]} graph_builder = StateGraph(State)
graph_builder.add_node("chatbot", chatbot) tool_node = ToolNode(tools=tools)
graph_builder.add_node("tools", tool_node) graph_builder.add_conditional_edges(
"chatbot",
tools_condition,
)
graph_builder.add_edge("tools", "chatbot")
graph_builder.add_edge(START, "chatbot") memory = MemorySaver()
graph = graph_builder.compile(checkpointer=memory)

提示聊天机器人查找 LangGraph 库的“生日”(即发布时间),并在获取所需信息后引导聊天机器人使用 human_assistance 工具。通过在工具的参数中设置 name 和 birthday,你强制聊天机器人为这些字段生成建议。

user_input = (
"Can you look up when LangGraph was released? "
"When you have the answer, use the human_assistance tool for review."
)
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 Message =================================

Can you look up when LangGraph was released? When you have the answer, use the human_assistance tool for review.
================================== Ai Message ================================== First, use the tavily_search tool to find out when LangGraph was released. Then, use the human_assistance tool to review the obtained information.
Tool Calls:
tavily_search (call_llt1sw4ifqhu46h92z6jc6o7)
Call ID: call_llt1sw4ifqhu46h92z6jc6o7
Args:
query: When was LangGraph released?
include_domains: None
exclude_domains: None
search_depth: None
include_images: None
time_range: None
topic: None
================================= Tool Message =================================
Name: tavily_search {"query": "When was LangGraph released?", "follow_up_questions": null, "answer": null, "images": [], "results": [{"title": "LangGraph 0.3 Release: Prebuilt Agents - blog.langchain.dev", "url": "https://blog.langchain.dev/langgraph-0-3-release-prebuilt-agents/", "content": "LangGraph 0.3 Release: Prebuilt Agents LangGraph 0.3 Release: Prebuilt Agents Over the past year, we’ve invested heavily in making LangGraph the go-to framework for building AI agents. Up to this point, we’ve had one higher level abstraction and it’s lived in the main langgraph package. We are also introducing a new set of prebuilt agents built on top of LangGraph, in both Python and JavaScript. LangGraph Supervisor: for getting started with a supervisor multi-agent architecture LangGraph Swarm: for getting started with a swarm multi-agent architecture We hope that this will foster a large collection of prebuilt agents built by the community. We hope the same will happen with LangGraph prebuilt agents.", "score": 0.27467275, "raw_content": null}, {"title": "Releases · langchain-ai/langgraph - GitHub", "url": "https://github.com/langchain-ai/langgraph/releases", "content": "Releases · langchain-ai/langgraph · GitHub * GitHub Copilot Write better code with AI * GitHub Advanced Security Find and fix vulnerabilities Search code, repositories, users, issues, pull requests... * update dockerfile generation logic, fix pip removal in wolfi * Remove dict subclasses used for values/updates stream chunks (#4816) * Merge branch 'langchain-ai:main' into fix-examples-link-readme Changes since prebuilt==0.2.1 * Add message state test * prebuilts hitl: fix branching logic + add structural snapshot tests (#4767) * sqlite: Add test for search with list filters (#4747) Changes since prebuilt==0.2.0 Changes since prebuilt==0.1.8 * prebuilts hitl: fix branching logic + add structural snapshot tests (#4767) * sqlite: Add test for search with list filters (#4747) * prebuilt: remove state_modifier (#4439) * fixing prebuilt tests", "score": 0.16426189, "raw_content": null}], "response_time": 1.8}
================================== Ai Message ================================== The search results did not directly indicate the release time of LangGraph. However, the information can be further verified by human assistance.
Tool Calls:
human_assistance (call_mbmtx7ovld4qgf4uty079oz6)
Call ID: call_mbmtx7ovld4qgf4uty079oz6
Args:
name: LangGraph
birthday: The release time could not be found in the search results.

我们再次触发了 human_assistance 工具中的 interrupt。在这种情况下,聊天机器人未能识别正确的日期,所以我们可以协助它:

human_command = Command(
resume={
"name": "LangGraph",
"birthday": "Jan 17, 2024",
},
) events = graph.stream(human_command, config, stream_mode="values")
for event in events:
if "messages" in event:
event["messages"][-1].pretty_print()

返回结果:

================================== Ai Message ==================================

The search results did not directly indicate the release time of LangGraph. However, the information can be further verified by human assistance.
Tool Calls:
human_assistance (call_mbmtx7ovld4qgf4uty079oz6)
Call ID: call_mbmtx7ovld4qgf4uty079oz6
Args:
name: LangGraph
birthday: The release time could not be found in the search results.
================================= Tool Message =================================
Name: human_assistance Made a correction: {'name': 'LangGraph', 'birthday': 'Jan 17, 2024'}
================================== Ai Message ================================== The release time of LangGraph, as corrected by human assistance, is January 17, 2024.

请注意,这些字段现在已反映在状态中:

snapshot = graph.get_state(config)

{k: v for k, v in snapshot.values.items() if k in ("name", "birthday")}

返回结果:

{'name': 'LangGraph', 'birthday': 'Jan 17, 2024'}

这使得下游节点(例如进一步处理或存储信息的节点)可以轻松访问这些信息。

手动更新状态

LangGraph 对应用程序状态提供了高度控制。例如,在任何时候(包括中断时),我们可以直接使用graph.update_state手动覆盖一个键。

graph.update_state(config, {"name": "LangGraph (library)"})

返回结果:

{'configurable': {'thread_id': '1',
'checkpoint_ns': '',
'checkpoint_id': '1f045d6d-9738-6a69-8006-0c42ead9b2f2'}}

如果我们调用 graph.get_state,可以看到新值已反映出来:

snapshot = graph.get_state(config)

{k: v for k, v in snapshot.values.items() if k in ("name", "birthday")}

返回结果:

{'name': 'LangGraph (library)', 'birthday': 'Jan 17, 2024'}

恭喜!您已向状态添加了自定义键,以便实现更复杂的工作流,并学习了如何从工具内部生成状态更新。

LangGraph官方文档笔记——5.自定义状态的更多相关文章

  1. docker官方文档笔记

    Docker在 CentOS7.X上运行.Docker可能在其他EL7的兼容版本中成功安装,但是官方并未进行测试,因此也不提供任何支持. 系统环境要求 docker必须运行在64-bit的系统上,对于 ...

  2. Vue官方文档笔记(二)

    23.$refs是什么东东? 通过在标签上设置ref属性,然后在Vue实例方法中可以通过$refs拿到这些标签,如: <input ref="input"> metho ...

  3. Vue官方文档笔记

    1.如何创建一个Vue实例对象? var vm = new Vue({ el: "#app", //标签id 或 标签类名 data:{ //双向绑定的数据 message: &q ...

  4. React官方文档笔记之快速入门

    快速开始 JSFiddle 我们建议在 React 中使用 CommonJS 模块系统,比如 browserify 或 webpack. 要用 webpack 安装 React DOM 和构建你的包: ...

  5. Spring 官方文档笔记---Bean

    In Spring, the objects that form the backbone of your application and that are managed by the Spring ...

  6. vue.js 2.0 官方文档学习笔记 —— 01. vue 介绍

    这是我的vue.js 2.0的学习笔记,采取了将官方文档中的代码集中到一个文件的形式.目的是保存下来,方便自己查阅. !官方文档:https://cn.vuejs.org/v2/guide/ 01. ...

  7. Vue2.0 官方文档学习笔记

    VUE2.0官方文档 基础部分: 1.VUE简介 Vue是一个基于MVVM的框架,其中M代表数据处理层,V代表视图层即我们在Vue组件中的html部分,VM即M和V的结合层,处理M层相应的逻辑数据,在 ...

  8. pm2 官方文档 学习笔记

    一.安装 1.安装 npm install pm2 -g 2.更新 npm install pm2 -g && pm2 update pm2 update 是为了刷新 PM2 的守护进 ...

  9. Effective Go(官方文档)笔记

    Effective Go(官方文档)笔记 自己主动局部变量提升(编译期完毕?):return &...; 内置函数: new/make copy, append delete range(这是 ...

  10. clang format 官方文档自定义参数介绍(中英文)

    官方文档:http://clang.llvm.org/docs/ClangFormatStyleOptions.html 中文 在代码中配置样式 当使用 clang::format::reformat ...

随机推荐

  1. 玩客云 OEC/OECT 笔记

    外观 内部 PCB正面 PCB背面 PCB背面 RK3566 1Gbps PHY 配置 OEC 和 OECT(OEC-turbo) 都是基于瑞芯微 RK3566/RK3568 的网络盒子, 没有HDM ...

  2. 初识protobuf

    protobuf的优点 性能方面 序列化后,数据大小可缩小3倍 序列化速度快 传输速度快 使用方面 使用简单:proto编译器自动进行序列化和反序列化 维护成本低:多平台只需要维护一套对象协议文件,即 ...

  3. [Python] 开发一个lychee相册命令行客户端以及python库pychee6

    有一段时间收集了不少的写真集和漫画,但是一直苦于没有很好的组织和储存的方法,直到我找到了LycheeOrg/Lychee ,它的图片组织形式非常适合存放写真集或者漫画,于是我尝试把图片都放上去.体验很 ...

  4. K8s新手系列之CronJob

    概述 官方文档:https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/cron-jobs/ CronJob控制器以 Job控制 ...

  5. Typora优化教程:如何使用回车键来实现「换行」而非「分段」(类似Obsidian)

    Typora优化教程:如何使用回车键来实现「换行」而非「分段」(类似Obsidian) 前言: 首先 在Typora中的默认设置中 按一下 回车键 会实现「分段」操作(中间空一行) 按一下 Shift ...

  6. ElasticSearch高可用部署

    简单说明 我们在部署ElasticSearch高可用集群时,要规划好集群的规模,每个节点的职责,规划好后续的水平扩展方案,再进行部署. 核心概念 Cluster:集群,由一个或多个 Elasticse ...

  7. 构建RPM之SPEC详解

    一.简单说明 在centos/rhel的系统使用中,我们会涉及自己构建一些rpm包在centos/rhel的系统中进行安装,这里涉及rpm打包环境的部署.SPEC文件的编写相关,下面我们具体进行说明. ...

  8. flink基础之window

    flink会把数据分成不同的窗口,然后进行汇总和统计. flink的窗口分为timeWindow, countWindow, sessionWindow, gapWindow. timeWindow分 ...

  9. 袋鼠云数栈UI5.0体验升级背后的故事:可用性原则与交互升级

    最近,我们袋鼠云的UED部⻔小伙伴们,不声不响地⼲了⼀件⼤事--升级了全新设计语言「数栈UI5.0」. 众所周知,用户在使用产品时,是一个动态的过程,用户和产品之间进行交互的可用性,能否让用户愉悦.快 ...

  10. ArkUI-X案例解析

    目前,已经有按照方案完成整体改造的4个Sample作为完整案例. 应用描述 链接 鸿蒙世界 HMOSWorld 溪村小镇 OxHornCampus 音乐专辑 MusicHome 购物应用 MultiS ...