精通LangGraph-Tools call-05

文摘   2025-01-19 10:00   四川  
如何通过tool更新graph state
一种常见用例是从工具内部更新graph state。例如,在客户支持应用程序中,可能希望在对话开始时查找客户帐号或 ID。
要从工具更新graph state,可以从tool返回 Command(update={"my_custom_key": "foo", "messages": [...]}):
@tooldef lookup_user_info(tool_call_id: Annotated[str, InjectedToolCallId], config: RunnableConfig):    """使用此工具查找用户信息,以便更好地回答他们的问题。"""    user_info = get_user_info(config)    return Command(        update={            # 更新状态键            "user_info": user_info,            # 更新消息历史记录            "messages": [ToolMessage("成功查找用户信息", tool_call_id=tool_call_id)]        }    )

定义tool
首先,让我们定义用于查找用户信息的工具。我们将使用一个简单的实现,即使用字典简单地查找用户信息:
USER_INFO = [    {"user_id""1""name""张三""location""北京"},    {"user_id""2""name""李四""location""成都"},]USER_ID_TO_USER_INFO = {info["user_id"]: info for info in USER_INFO}from langgraph.prebuilt.chat_agent_executor import AgentStatefrom langgraph.types import Commandfrom langchain_core.tools import toolfrom langchain_core.tools.base import InjectedToolCallIdfrom langchain_core.messages import ToolMessagefrom langchain_core.runnables import RunnableConfigfrom typing_extensions import Any, Annotatedclass State(AgentState):    # 由工具更新    user_info: dict[str, Any]@tooldef lookup_user_info(    tool_call_id: Annotated[str, InjectedToolCallId], config: RunnableConfig):    """使用此工具查找用户信息,以便更好地回答他们的问题。"""    user_id = config.get("configurable", {}).get("user_id")    if user_id is None:        raise ValueError("请提供用户ID")    if user_id not in USER_ID_TO_USER_INFO:        raise ValueError(f"未找到用户'{user_id}'")    user_info = USER_ID_TO_USER_INFO[user_id]    return Command(        update={            # 更新状态键            "user_info": user_info,            # 更新消息历史            "messages": [                ToolMessage(                    "成功查找用户信息", tool_call_id=tool_call_id                )            ],        }    )
定义prompt
现在让我们加点料:在状态从工具更新后,我们将根据状态值对用户做出不同的响应。
为了实现这一点,让我们定义一个函数,该函数将根据图形状态动态构建系统提示。每次调用 LLM 时都会调用它,并且函数输出将传递给 LLM:
def state_modifier(state: State):    user_info = state.get("user_info")    if user_info is None:        return state["messages"]    system_msg = (        f"用户名是{user_info['name']}。用户住在{user_info['location']}"    )    return [{"role""system""content": system_msg}] + state["messages"]
定义graph
from langgraph.prebuilt import create_react_agentfrom langchain_ollama import ChatOllamaimport base_confmodel = ChatOllama(base_url=base_conf.base_url, model=base_conf.model_name, temperature=0)agent = create_react_agent(    model,    # 传递可以更新状态的工具    [lookup_user_info],    state_schema=State,    # 传递动态提示函数    state_modifier=state_modifier,)for chunk in agent.stream(    {"messages": [("user""我是用户,这周我该做什么?")]},    # provide user ID in the config    {"configurable": {"user_id""1"}},):    print(chunk)    print("\n")
输出:
{'agent': {'messages': [AIMessage(content='', additional_kwargs={}, response_metadata={'model''qwen2.5:7b''created_at''2025-01-08T06:39:47.488317Z''done'True'done_reason''stop''total_duration'3534691667'load_duration'22909042'prompt_eval_count'162'prompt_eval_duration'799000000'eval_count'60'eval_duration'2710000000'message': Message(role='assistant', content='', images=None, tool_calls=None)}, id='run-3909aefc-f875-49f6-952e-9f24290f3780-0', tool_calls=[{'name''lookup_user_info''args': {}, 'id''17f1dc87-07fd-4261-8c35-f554fbce7fcd''type''tool_call'}], usage_metadata={'input_tokens'162'output_tokens'60'total_tokens'222})]}}

{'tools': {'user_info': {'user_id''1''name''张三''location''北京'}, 'messages': [ToolMessage(content='成功查找用户信息', name='lookup_user_info'id='45207262-0344-41a4-a28d-ce33a4927d44', tool_call_id='17f1dc87-07fd-4261-8c35-f554fbce7fcd')]}}

{'agent': {'messages': [AIMessage(content='您好!根据您的个人信息,您最近在学习编程。如果您愿意的话,这周您可以尝试完成一些小项目来巩固所学知识,或者参加在线课程进一步提升技能。此外,您还可以阅读相关书籍或文章以拓宽视野。\n\n另外,您还提到了对摄影感兴趣。如果时间允许,您可以利用周末的时间去户外拍摄风景照片,提高自己的摄影技巧。\n\n当然,这些建议仅供参考,您可以根据个人兴趣和实际情况进行调整。希望这些建议能帮助到您!', additional_kwargs={}, response_metadata={'model''qwen2.5:7b''created_at''2025-01-08T06:39:53.329455Z''done'True'done_reason''stop''total_duration'5823573375'load_duration'9685875'prompt_eval_count'194'prompt_eval_duration'854000000'eval_count'108'eval_duration'4957000000'message': Message(role='assistant', content='您好!根据您的个人信息,您最近在学习编程。如果您愿意的话,这周您可以尝试完成一些小项目来巩固所学知识,或者参加在线课程进一步提升技能。此外,您还可以阅读相关书籍或文章以拓宽视野。\n\n另外,您还提到了对摄影感兴趣。如果时间允许,您可以利用周末的时间去户外拍摄风景照片,提高自己的摄影技巧。\n\n当然,这些建议仅供参考,您可以根据个人兴趣和实际情况进行调整。希望这些建议能帮助到您!', images=None, tool_calls=None)}, id='run-984dfe37-7aa0-4133-bd20-ccf92cef88dc-0', usage_metadata={'input_tokens'194'output_tokens'108'total_tokens'302})]}}
当然了,你还可以试着把{"configurable": {"user_id": "1"}}改为2试试。
可以看到,我们的tool实际上充当了一个修改 state 状态的 node。

半夏决明
读书,摄影,随笔
 最新文章