掘金 人工智能 07月04日 14:28
LangGraph官方文档笔记(5)——自定义状态
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

文章介绍了如何在LangGraph中通过添加自定义键来扩展状态管理功能,实现更复杂的工作流。通过实际案例演示了如何在工具内部更新状态、利用human_assistance工具进行信息验证与修正,以及手动更新状态的方法。文章旨在帮助开发者更好地控制和管理LangGraph应用程序的状态。

🔑 **自定义状态键**:文章首先演示了如何在LangGraph的状态中添加自定义键,如'name'和'birthday',以存储特定信息,这使得状态可以不仅仅是消息列表,从而支持更复杂的操作。

🛠️ **工具内部更新状态**:文章重点介绍了在工具内部更新状态的方法。通过`human_assistance`工具,演示了如何触发人工干预流程,在信息被存储到状态之前进行审查和修正。工具可以返回`Command`,通知系统更新对话状态。

🔄 **手动更新状态**:文章还介绍了手动更新状态的功能,允许在任何时候(包括中断时)直接使用`graph.update_state`方法覆盖状态中的键。这提供了对应用程序状态的高度控制,方便灵活地修改状态信息。

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

参考文档

官方文档参考

实践自定义状态

1.将键添加到状态中

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

from typing import Annotatedfrom typing_extensions import TypedDictfrom langgraph.graph.message import add_messagesclass 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  # 状态更新命令和人工干预中断函数@tooldef 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_modelfrom langchain_openai import ChatOpenAIfrom langchain_tavily import TavilySearchfrom langgraph.checkpoint.memory import MemorySaverfrom langgraph.graph import StateGraph, START, ENDfrom langgraph.prebuilt import ToolNode, tools_condition#环境变量设置,替换为你的API KEYos.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_assistanceMade 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'}

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

原文地址:https://www.cnblogs.com/LiShengTrip/p/18924971

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

LangGraph 状态管理 自定义键 工具更新
相关文章