Movatterモバイル変換


[0]ホーム

URL:


Skip to main content
OurBuilding Ambient Agents with LangGraph course is now available on LangChain Academy!
Open In ColabOpen on GitHub

How to pass run time values to tools

📦Compatibility
The code in this guide requireslangchain-core>=0.2.21. Please ensure you have the correct packages installed.

You may need to bind values to atool that are only known at runtime. For example, the tool logic may require using the ID of the user who made the request.

Most of the time, such values should not be controlled by the LLM. In fact, allowing the LLM to control the user ID may lead to a security risk.

Instead, the LLM should only control the parameters of the tool that are meant to be controlled by the LLM, while other parameters (such as user ID) should be fixed by the application logic.

This how-to guide shows you how to prevent the model from generating certain tool arguments and injecting them in directly at runtime.

Using with LangGraph

If you're using LangGraph, please refer tothis how-to guidewhich shows how to create an agent that keeps track of a given user's favorite pets.

We can bind them to chat models as follows:

pip install -qU "langchain[google-genai]"
import getpass
import os

ifnot os.environ.get("GOOGLE_API_KEY"):
os.environ["GOOGLE_API_KEY"]= getpass.getpass("Enter API key for Google Gemini: ")

from langchain.chat_modelsimport init_chat_model

llm= init_chat_model("gemini-2.0-flash", model_provider="google_genai")

Hiding arguments from the model

We can use the InjectedToolArg annotation to mark certain parameters of our Tool, likeuser_id as being injected at runtime, meaning they shouldn't be generated by the model

from typingimport List

from langchain_core.toolsimport InjectedToolArg, tool
from typing_extensionsimport Annotated

user_to_pets={}


@tool(parse_docstring=True)
defupdate_favorite_pets(
pets: List[str], user_id: Annotated[str, InjectedToolArg]
)->None:
"""Add the list of favorite pets.

Args:
pets: List of favorite pets to set.
user_id: User's ID.
"""
user_to_pets[user_id]= pets


@tool(parse_docstring=True)
defdelete_favorite_pets(user_id: Annotated[str, InjectedToolArg])->None:
"""Delete the list of favorite pets.

Args:
user_id: User's ID.
"""
if user_idin user_to_pets:
del user_to_pets[user_id]


@tool(parse_docstring=True)
deflist_favorite_pets(user_id: Annotated[str, InjectedToolArg])->None:
"""List favorite pets if any.

Args:
user_id: User's ID.
"""
return user_to_pets.get(user_id,[])
API Reference:InjectedToolArg |tool

If we look at the input schemas for these tools, we'll see that user_id is still listed:

update_favorite_pets.get_input_schema().model_json_schema()
{'description': 'Add the list of favorite pets.',
'properties': {'pets': {'description': 'List of favorite pets to set.',
'items': {'type': 'string'},
'title': 'Pets',
'type': 'array'},
'user_id': {'description': "User's ID.",
'title': 'User Id',
'type': 'string'}},
'required': ['pets', 'user_id'],
'title': 'update_favorite_petsSchema',
'type': 'object'}

But if we look at the tool call schema, which is what is passed to the model for tool-calling, user_id has been removed:

update_favorite_pets.tool_call_schema.model_json_schema()
{'description': 'Add the list of favorite pets.',
'properties': {'pets': {'description': 'List of favorite pets to set.',
'items': {'type': 'string'},
'title': 'Pets',
'type': 'array'}},
'required': ['pets'],
'title': 'update_favorite_pets',
'type': 'object'}

So when we invoke our tool, we need to pass in user_id:

user_id="123"
update_favorite_pets.invoke({"pets":["lizard","dog"],"user_id": user_id})
print(user_to_pets)
print(list_favorite_pets.invoke({"user_id": user_id}))
{'123': ['lizard', 'dog']}
['lizard', 'dog']

But when the model calls the tool, no user_id argument will be generated:

tools=[
update_favorite_pets,
delete_favorite_pets,
list_favorite_pets,
]
llm_with_tools= llm.bind_tools(tools)
ai_msg= llm_with_tools.invoke("my favorite animals are cats and parrots")
ai_msg.tool_calls
[{'name': 'update_favorite_pets',
'args': {'pets': ['cats', 'parrots']},
'id': 'call_pZ6XVREGh1L0BBSsiGIf1xVm',
'type': 'tool_call'}]

Injecting arguments at runtime

If we want to actually execute our tools using the model-generated tool call, we'll need to inject the user_id ourselves:

from copyimport deepcopy

from langchain_core.runnablesimport chain


@chain
definject_user_id(ai_msg):
tool_calls=[]
for tool_callin ai_msg.tool_calls:
tool_call_copy= deepcopy(tool_call)
tool_call_copy["args"]["user_id"]= user_id
tool_calls.append(tool_call_copy)
return tool_calls


inject_user_id.invoke(ai_msg)
API Reference:chain
[{'name': 'update_favorite_pets',
'args': {'pets': ['cats', 'parrots'], 'user_id': '123'},
'id': 'call_pZ6XVREGh1L0BBSsiGIf1xVm',
'type': 'tool_call'}]

And now we can chain together our model, injection code, and the actual tools to create a tool-executing chain:

tool_map={tool.name: toolfor toolin tools}


@chain
deftool_router(tool_call):
return tool_map[tool_call["name"]]


chain= llm_with_tools| inject_user_id| tool_router.map()
chain.invoke("my favorite animals are cats and parrots")
[ToolMessage(content='null', name='update_favorite_pets', tool_call_id='call_oYCD0THSedHTbwNAY3NW6uUj')]

Looking at the user_to_pets dict, we can see that it's been updated to include cats and parrots:

user_to_pets
{'123': ['cats', 'parrots']}

Other ways of annotating args

Here are a few other ways of annotating our tool args:

from langchain_core.toolsimport BaseTool
from pydanticimport BaseModel, Field


classUpdateFavoritePetsSchema(BaseModel):
"""Update list of favorite pets"""

pets: List[str]= Field(..., description="List of favorite pets to set.")
user_id: Annotated[str, InjectedToolArg]= Field(..., description="User's ID.")


@tool(args_schema=UpdateFavoritePetsSchema)
defupdate_favorite_pets(pets, user_id):
user_to_pets[user_id]= pets


update_favorite_pets.get_input_schema().model_json_schema()
API Reference:BaseTool
{'description': 'Update list of favorite pets',
'properties': {'pets': {'description': 'List of favorite pets to set.',
'items': {'type': 'string'},
'title': 'Pets',
'type': 'array'},
'user_id': {'description': "User's ID.",
'title': 'User Id',
'type': 'string'}},
'required': ['pets', 'user_id'],
'title': 'UpdateFavoritePetsSchema',
'type': 'object'}
update_favorite_pets.tool_call_schema.model_json_schema()
{'description': 'Update list of favorite pets',
'properties': {'pets': {'description': 'List of favorite pets to set.',
'items': {'type': 'string'},
'title': 'Pets',
'type': 'array'}},
'required': ['pets'],
'title': 'update_favorite_pets',
'type': 'object'}
from typingimport Optional, Type


classUpdateFavoritePets(BaseTool):
name:str="update_favorite_pets"
description:str="Update list of favorite pets"
args_schema: Optional[Type[BaseModel]]= UpdateFavoritePetsSchema

def_run(self, pets, user_id):
user_to_pets[user_id]= pets


UpdateFavoritePets().get_input_schema().model_json_schema()
{'description': 'Update list of favorite pets',
'properties': {'pets': {'description': 'List of favorite pets to set.',
'items': {'type': 'string'},
'title': 'Pets',
'type': 'array'},
'user_id': {'description': "User's ID.",
'title': 'User Id',
'type': 'string'}},
'required': ['pets', 'user_id'],
'title': 'UpdateFavoritePetsSchema',
'type': 'object'}
UpdateFavoritePets().tool_call_schema.model_json_schema()
{'description': 'Update list of favorite pets',
'properties': {'pets': {'description': 'List of favorite pets to set.',
'items': {'type': 'string'},
'title': 'Pets',
'type': 'array'}},
'required': ['pets'],
'title': 'update_favorite_pets',
'type': 'object'}
classUpdateFavoritePets2(BaseTool):
name:str="update_favorite_pets"
description:str="Update list of favorite pets"

def_run(self, pets: List[str], user_id: Annotated[str, InjectedToolArg])->None:
user_to_pets[user_id]= pets


UpdateFavoritePets2().get_input_schema().model_json_schema()
{'description': 'Use the tool.\n\nAdd run_manager: Optional[CallbackManagerForToolRun] = None\nto child implementations to enable tracing.',
'properties': {'pets': {'items': {'type': 'string'},
'title': 'Pets',
'type': 'array'},
'user_id': {'title': 'User Id', 'type': 'string'}},
'required': ['pets', 'user_id'],
'title': 'update_favorite_petsSchema',
'type': 'object'}
UpdateFavoritePets2().tool_call_schema.model_json_schema()
{'description': 'Update list of favorite pets',
'properties': {'pets': {'items': {'type': 'string'},
'title': 'Pets',
'type': 'array'}},
'required': ['pets'],
'title': 'update_favorite_pets',
'type': 'object'}

[8]ページ先頭

©2009-2025 Movatter.jp