LangGraph官方文档笔记——5.自定义状态
到目前为止,我们依赖一个包含一个条目(消息列表)的简单状态。虽然这个简单状态可以走得很远,但如果您想定义复杂的行为而不依赖于消息列表,您可以向状态添加额外的字段。
参考文档
实践自定义状态
1.将键添加到状态中
在这里,我们将演示一个新场景,其中聊天机器人使用其搜索工具查找特定信息,并将其转发给人工进行审查。让聊天机器人研究一个实体的生日。我们将向状态添加name和birthday键
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.自定义状态的更多相关文章
- docker官方文档笔记
Docker在 CentOS7.X上运行.Docker可能在其他EL7的兼容版本中成功安装,但是官方并未进行测试,因此也不提供任何支持. 系统环境要求 docker必须运行在64-bit的系统上,对于 ...
- Vue官方文档笔记(二)
23.$refs是什么东东? 通过在标签上设置ref属性,然后在Vue实例方法中可以通过$refs拿到这些标签,如: <input ref="input"> metho ...
- Vue官方文档笔记
1.如何创建一个Vue实例对象? var vm = new Vue({ el: "#app", //标签id 或 标签类名 data:{ //双向绑定的数据 message: &q ...
- React官方文档笔记之快速入门
快速开始 JSFiddle 我们建议在 React 中使用 CommonJS 模块系统,比如 browserify 或 webpack. 要用 webpack 安装 React DOM 和构建你的包: ...
- Spring 官方文档笔记---Bean
In Spring, the objects that form the backbone of your application and that are managed by the Spring ...
- vue.js 2.0 官方文档学习笔记 —— 01. vue 介绍
这是我的vue.js 2.0的学习笔记,采取了将官方文档中的代码集中到一个文件的形式.目的是保存下来,方便自己查阅. !官方文档:https://cn.vuejs.org/v2/guide/ 01. ...
- Vue2.0 官方文档学习笔记
VUE2.0官方文档 基础部分: 1.VUE简介 Vue是一个基于MVVM的框架,其中M代表数据处理层,V代表视图层即我们在Vue组件中的html部分,VM即M和V的结合层,处理M层相应的逻辑数据,在 ...
- pm2 官方文档 学习笔记
一.安装 1.安装 npm install pm2 -g 2.更新 npm install pm2 -g && pm2 update pm2 update 是为了刷新 PM2 的守护进 ...
- Effective Go(官方文档)笔记
Effective Go(官方文档)笔记 自己主动局部变量提升(编译期完毕?):return &...; 内置函数: new/make copy, append delete range(这是 ...
- clang format 官方文档自定义参数介绍(中英文)
官方文档:http://clang.llvm.org/docs/ClangFormatStyleOptions.html 中文 在代码中配置样式 当使用 clang::format::reformat ...
随机推荐
- 玩客云 OEC/OECT 笔记
外观 内部 PCB正面 PCB背面 PCB背面 RK3566 1Gbps PHY 配置 OEC 和 OECT(OEC-turbo) 都是基于瑞芯微 RK3566/RK3568 的网络盒子, 没有HDM ...
- 初识protobuf
protobuf的优点 性能方面 序列化后,数据大小可缩小3倍 序列化速度快 传输速度快 使用方面 使用简单:proto编译器自动进行序列化和反序列化 维护成本低:多平台只需要维护一套对象协议文件,即 ...
- [Python] 开发一个lychee相册命令行客户端以及python库pychee6
有一段时间收集了不少的写真集和漫画,但是一直苦于没有很好的组织和储存的方法,直到我找到了LycheeOrg/Lychee ,它的图片组织形式非常适合存放写真集或者漫画,于是我尝试把图片都放上去.体验很 ...
- K8s新手系列之CronJob
概述 官方文档:https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/cron-jobs/ CronJob控制器以 Job控制 ...
- Typora优化教程:如何使用回车键来实现「换行」而非「分段」(类似Obsidian)
Typora优化教程:如何使用回车键来实现「换行」而非「分段」(类似Obsidian) 前言: 首先 在Typora中的默认设置中 按一下 回车键 会实现「分段」操作(中间空一行) 按一下 Shift ...
- ElasticSearch高可用部署
简单说明 我们在部署ElasticSearch高可用集群时,要规划好集群的规模,每个节点的职责,规划好后续的水平扩展方案,再进行部署. 核心概念 Cluster:集群,由一个或多个 Elasticse ...
- 构建RPM之SPEC详解
一.简单说明 在centos/rhel的系统使用中,我们会涉及自己构建一些rpm包在centos/rhel的系统中进行安装,这里涉及rpm打包环境的部署.SPEC文件的编写相关,下面我们具体进行说明. ...
- flink基础之window
flink会把数据分成不同的窗口,然后进行汇总和统计. flink的窗口分为timeWindow, countWindow, sessionWindow, gapWindow. timeWindow分 ...
- 袋鼠云数栈UI5.0体验升级背后的故事:可用性原则与交互升级
最近,我们袋鼠云的UED部⻔小伙伴们,不声不响地⼲了⼀件⼤事--升级了全新设计语言「数栈UI5.0」. 众所周知,用户在使用产品时,是一个动态的过程,用户和产品之间进行交互的可用性,能否让用户愉悦.快 ...
- ArkUI-X案例解析
目前,已经有按照方案完成整体改造的4个Sample作为完整案例. 应用描述 链接 鸿蒙世界 HMOSWorld 溪村小镇 OxHornCampus 音乐专辑 MusicHome 购物应用 MultiS ...