官方文档分为两部分
过滤预注册的工具
工具已经注册了,可以动态过滤
state 方式
python
from langchain.agents import create_agent
from langchain.agents.middleware import wrap_model_call, ModelRequest, ModelResponse
from typing import Callable
@wrap_model_call
def state_based_tools(
request: ModelRequest,
handler: Callable[[ModelRequest], ModelResponse]
) -> ModelResponse:
"""Filter tools based on conversation State."""
# Read from State: check if user has authenticated
state = request.state
is_authenticated = state.get("authenticated", False)
message_count = len(state["messages"])
# Only enable sensitive tools after authentication
if not is_authenticated:
tools = [t for t in request.tools if t.name.startswith("public_")]
request = request.override(tools=tools)
elif message_count < 5:
# Limit tools early in conversation
tools = [t for t in request.tools if t.name != "advanced_search"]
request = request.override(tools=tools)
return handler(request)
agent = create_agent(
model="gpt-5.5",
tools=[public_search, private_search, advanced_search],
middleware=[state_based_tools]
)
store 方式
python
from dataclasses import dataclass
from langchain.agents import create_agent
from langchain.agents.middleware import wrap_model_call, ModelRequest, ModelResponse
from typing import Callable
from langgraph.store.memory import InMemoryStore
@dataclass
class Context:
user_id: str
@wrap_model_call
def store_based_tools(
request: ModelRequest,
handler: Callable[[ModelRequest], ModelResponse]
) -> ModelResponse:
"""Filter tools based on Store preferences."""
user_id = request.runtime.context.user_id
# Read from Store: get user's enabled features
store = request.runtime.store
feature_flags = store.get(("features",), user_id)
if feature_flags:
enabled_features = feature_flags.value.get("enabled_tools", [])
# Only include tools that are enabled for this user
tools = [t for t in request.tools if t.name in enabled_features]
request = request.override(tools=tools)
return handler(request)
agent = create_agent(
model="gpt-5.5",
tools=[search_tool, analysis_tool, export_tool],
middleware=[store_based_tools],
context_schema=Context,
store=InMemoryStore()
)
context方式
python
from dataclasses import dataclass
from langchain.agents import create_agent
from langchain.agents.middleware import wrap_model_call, ModelRequest, ModelResponse
from typing import Callable
@dataclass
class Context:
user_role: str
@wrap_model_call
def context_based_tools(
request: ModelRequest,
handler: Callable[[ModelRequest], ModelResponse]
) -> ModelResponse:
"""Filter tools based on Runtime Context permissions."""
# Read from Runtime Context: get user role
if request.runtime is None or request.runtime.context is None:
# If no context provided, default to viewer (most restrictive)
user_role = "viewer"
else:
user_role = request.runtime.context.user_role
if user_role == "admin":
# Admins get all tools
pass
elif user_role == "editor":
# Editors can't delete
tools = [t for t in request.tools if t.name != "delete_data"]
request = request.override(tools=tools)
else:
# Viewers get read-only tools
tools = [t for t in request.tools if t.name.startswith("read_")]
request = request.override(tools=tools)
return handler(request)
agent = create_agent(
model="gpt-5.5",
tools=[read_data, write_data, delete_data],
middleware=[context_based_tools],
context_schema=Context
)
运行时注册工具
工具没注册,动态添加并且注册
python
from langchain.tools import tool
from langchain.agents import create_agent
from langchain.agents.middleware import AgentMiddleware, ModelRequest, ToolCallRequest
# A tool that will be added dynamically at runtime
@tool
def calculate_tip(bill_amount: float, tip_percentage: float = 20.0) -> str:
"""Calculate the tip amount for a bill."""
tip = bill_amount * (tip_percentage / 100)
return f"Tip: ${tip:.2f}, Total: ${bill_amount + tip:.2f}"
class DynamicToolMiddleware(AgentMiddleware):
"""Middleware that registers and handles dynamic tools."""
def wrap_model_call(self, request: ModelRequest, handler):
# Add dynamic tool to the request
# This could be loaded from an MCP server, database, etc.
updated = request.override(tools=[*request.tools, calculate_tip])
return handler(updated)
def wrap_tool_call(self, request: ToolCallRequest, handler):
# Handle execution of the dynamic tool
if request.tool_call["name"] == "calculate_tip":
return handler(request.override(tool=calculate_tip))
return handler(request)
agent = create_agent(
model="gpt-5.5",
tools=[get_weather], # Only static tools registered here
middleware=[DynamicToolMiddleware()],
)
# The agent can now use both get_weather AND calculate_tip
result = agent.invoke({
"messages": [{"role": "user", "content": "Calculate a 20% tip on $85"}]
})