跳到内容

如何向工具传递配置

前提条件

本指南假定您熟悉以下内容

在运行时,您可能需要向工具传递值,例如用户 ID。出于安全原因,这些值应由应用程序逻辑设置,而不是由 LLM 控制。LLM 应只管理其预期的参数。

LangChain 工具使用 Runnable 接口,其中 invoke 等方法通过带有 RunnableConfig 类型注解的 config 参数接受运行时信息。

在下面的示例中,我们将设置一个代理,该代理带有管理用户最喜欢的宠物(添加、读取和删除条目)的工具,同时通过应用程序逻辑固定用户 ID,并让聊天模型控制其他参数。

设置

首先,让我们安装所需的软件包并设置 API 密钥

pip install --quiet -U langgraph langchain_anthropic
import getpass
import os


def _set_env(var: str):
    if not os.environ.get(var):
        os.environ[var] = getpass.getpass(f"{var}: ")


_set_env("ANTHROPIC_API_KEY")

设置 LangSmith 以进行 LangGraph 开发

注册 LangSmith 可以快速发现问题并提高 LangGraph 项目的性能。LangSmith 允许您使用跟踪数据来调试、测试和监控使用 LangGraph 构建的 LLM 应用程序 — 在此处了解更多入门信息。

定义工具和模型

配置类型注解

每个工具函数都可以接受一个 config 参数。为了使配置正确传递给函数,您必须始终为您的 config 参数添加 RunnableConfig 类型注解。例如

def my_tool(tool_arg: str, config: RunnableConfig):
    ...

API 参考:tool | RunnableConfig | ToolNode

from typing import List

from langchain_core.tools import tool
from langchain_core.runnables.config import RunnableConfig

from langgraph.prebuilt import ToolNode

user_to_pets = {}


@tool(parse_docstring=True)
def update_favorite_pets(
    # NOTE: config arg does not need to be added to docstring, as we don't want it to be included in the function signature attached to the LLM
    pets: List[str],
    config: RunnableConfig,
) -> None:
    """Add the list of favorite pets.

    Args:
        pets: List of favorite pets to set.
    """
    user_id = config.get("configurable", {}).get("user_id")
    user_to_pets[user_id] = pets


@tool
def delete_favorite_pets(config: RunnableConfig) -> None:
    """Delete the list of favorite pets."""
    user_id = config.get("configurable", {}).get("user_id")
    if user_id in user_to_pets:
        del user_to_pets[user_id]


@tool
def list_favorite_pets(config: RunnableConfig) -> None:
    """List favorite pets if asked to."""
    user_id = config.get("configurable", {}).get("user_id")
    return ", ".join(user_to_pets.get(user_id, []))


tools = [update_favorite_pets, delete_favorite_pets, list_favorite_pets]

在我们的示例中,我们将使用 Anthropic 的一个小聊天模型。

API 参考:ChatAnthropic | StateGraph | ToolNode

from langchain_anthropic import ChatAnthropic
from langgraph.graph import StateGraph, MessagesState
from langgraph.prebuilt import ToolNode


model = ChatAnthropic(model="claude-3-5-haiku-latest")

ReAct 代理

让我们设置 ReAct 代理 的图实现。这个代理接受一些查询作为输入,然后重复调用工具,直到有足够的信息来解决查询。我们将使用预构建的 create_react_agent 和我们刚刚定义的带有工具的 Anthropic 模型。注意:工具是通过 create_react_agent 实现中的 model.bind_tools 自动添加到模型中的。

API 参考:create_react_agent

from langgraph.prebuilt import create_react_agent
from IPython.display import Image, display

graph = create_react_agent(model, tools)

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

使用它!

API 参考:HumanMessage

from langchain_core.messages import HumanMessage

user_to_pets.clear()  # Clear the state

print(f"User information prior to run: {user_to_pets}")

inputs = {"messages": [HumanMessage(content="my favorite pets are cats and dogs")]}
for chunk in graph.stream(
    inputs, {"configurable": {"user_id": "123"}}, stream_mode="values"
):
    chunk["messages"][-1].pretty_print()

print(f"User information after the run: {user_to_pets}")
User information prior to run: {}
================================ Human Message =================================

my favorite pets are cats and dogs
================================== Ai Message ==================================

[{'text': "I'll help you update your favorite pets using the `update_favorite_pets` function.", 'type': 'text'}, {'id': 'toolu_015jtecJ4jnosAfXEC3KADS2', 'input': {'pets': ['cats', 'dogs']}, 'name': 'update_favorite_pets', 'type': 'tool_use'}]
Tool Calls:
  update_favorite_pets (toolu_015jtecJ4jnosAfXEC3KADS2)
 Call ID: toolu_015jtecJ4jnosAfXEC3KADS2
  Args:
    pets: ['cats', 'dogs']
================================= Tool Message =================================
Name: update_favorite_pets

null
================================== Ai Message ==================================

Great! I've added cats and dogs to your list of favorite pets. Would you like to confirm the list or do anything else with it?
User information after the run: {'123': ['cats', 'dogs']}

API 参考:HumanMessage

from langchain_core.messages import HumanMessage

print(f"User information prior to run: {user_to_pets}")

inputs = {"messages": [HumanMessage(content="what are my favorite pets")]}
for chunk in graph.stream(
    inputs, {"configurable": {"user_id": "123"}}, stream_mode="values"
):
    chunk["messages"][-1].pretty_print()

print(f"User information prior to run: {user_to_pets}")
User information prior to run: {'123': ['cats', 'dogs']}
================================ Human Message =================================

what are my favorite pets
================================== Ai Message ==================================

[{'text': "I'll help you check your favorite pets by using the list_favorite_pets function.", 'type': 'text'}, {'id': 'toolu_01EMTtX5WtKJXMJ4WqXpxPUw', 'input': {}, 'name': 'list_favorite_pets', 'type': 'tool_use'}]
Tool Calls:
  list_favorite_pets (toolu_01EMTtX5WtKJXMJ4WqXpxPUw)
 Call ID: toolu_01EMTtX5WtKJXMJ4WqXpxPUw
  Args:
================================= Tool Message =================================
Name: list_favorite_pets

cats, dogs
================================== Ai Message ==================================

Based on the results, your favorite pets are cats and dogs.

Is there anything else you'd like to know about your favorite pets, or would you like to update the list?
User information prior to run: {'123': ['cats', 'dogs']}

print(f"User information prior to run: {user_to_pets}")

inputs = {
    "messages": [
        HumanMessage(content="please forget what i told you about my favorite animals")
    ]
}
for chunk in graph.stream(
    inputs, {"configurable": {"user_id": "123"}}, stream_mode="values"
):
    chunk["messages"][-1].pretty_print()

print(f"User information prior to run: {user_to_pets}")
User information prior to run: {'123': ['cats', 'dogs']}
================================ Human Message =================================

please forget what i told you about my favorite animals
================================== Ai Message ==================================

[{'text': "I'll help you delete the list of favorite pets. I'll use the delete_favorite_pets function to remove any previously saved list.", 'type': 'text'}, {'id': 'toolu_01JqpxgxdsDJFMzSLeogoRtG', 'input': {}, 'name': 'delete_favorite_pets', 'type': 'tool_use'}]
Tool Calls:
  delete_favorite_pets (toolu_01JqpxgxdsDJFMzSLeogoRtG)
 Call ID: toolu_01JqpxgxdsDJFMzSLeogoRtG
  Args:
================================= Tool Message =================================
Name: delete_favorite_pets

null
================================== Ai Message ==================================

The list of favorite pets has been deleted. If you'd like to create a new list of favorite pets in the future, just let me know.
User information prior to run: {}

评论