Here is a working example:
from dataclasses import dataclass
from langchain.agents import create_agent
from langchain.agents.middleware import (
AgentMiddleware,
ModelRequest,
)
from langchain.agents.middleware.types import ModelResponse
from typing import Callable
def get_weather(city: str) -> str:
"""Get weather for a given city."""
return f"It's always sunny in {city}!"
def get_capital(country: str) -> str:
"""Get capital for a given country."""
return f"Ankara is the capital of {country}!"
@dataclass
class Context:
user_expertise: str
class ExpertiseBasedToolMiddleware(AgentMiddleware):
def wrap_model_call(
self,
request: ModelRequest,
handler: Callable[[ModelRequest], ModelResponse],
) -> ModelResponse:
user_level = request.runtime.context.user_expertise
if user_level == "expert":
# More powerful model
tools = [get_weather,]
else:
# Less powerful model
tools = [get_capital,]
request.tools = tools
return handler(request)
agent = create_agent(
model="ollama:qwen3:latest",
middleware=[ExpertiseBasedToolMiddleware()],
context_schema=Context
)
agent.invoke(
{"messages": "What's the weather in Paris?"},
context={"user_expertise": "expert"},
)
agent.invoke(
{"messages": "What's the capital of France?"},
context={"user_expertise": "expert"},
)
agent.invoke(
{"messages": "What's the weather in Paris?"},
context={"user_expertise": "beginner"},
)
agent.invoke(
{"messages": "What's the capital of France?"},
context={"user_expertise": "beginner"},
)
Here’s the result:
>>> agent.invoke(
... {"messages": "What's the weather in Paris?"},
... context={"user_expertise": "expert"},
... )
{'messages': [HumanMessage(content="What's the weather in Paris?", additional_kwargs={}, response_metadata={}, id='fd32ef39-9991-48b0-ad4b-43618b686102'), AIMessage(content='', additional_kwargs={}, response_metadata={'model': 'qwen3:latest', 'created_at': '2025-10-24T11:29:31.675869818Z', 'done': True, 'done_reason': 'stop', 'total_duration': 6002301618, 'load_duration': 2260224250, 'prompt_eval_count': 146, 'prompt_eval_duration': 301365613, 'eval_count': 108, 'eval_duration': 3411260963, 'model_name': 'qwen3:latest', 'model_provider': 'ollama'}, id='lc_run--581ca80b-166a-41ee-b88b-9250db22af77-0', tool_calls=[{'name': 'get_weather', 'args': {'city': 'Paris'}, 'id': '4d383d1a-b471-4eb2-8c19-ace4376cd214', 'type': 'tool_call'}], usage_metadata={'input_tokens': 146, 'output_tokens': 108, 'total_tokens': 254})]}
>>>
>>> agent.invoke(
... {"messages": "What's the capital of France?"},
... context={"user_expertise": "expert"},
... )
{'messages': [HumanMessage(content="What's the capital of France?", additional_kwargs={}, response_metadata={}, id='e4a1d803-ef90-48fe-83fc-fcfba0e0a400'), AIMessage(content='The function provided is for retrieving weather information, which is not applicable to determining the capital of France. I cannot answer this query using the available tools. However, I can help you check the weather for a specific city if you need that information!', additional_kwargs={}, response_metadata={'model': 'qwen3:latest', 'created_at': '2025-10-24T11:29:36.771514846Z', 'done': True, 'done_reason': 'stop', 'total_duration': 5091181725, 'load_duration': 148051402, 'prompt_eval_count': 146, 'prompt_eval_duration': 66713003, 'eval_count': 152, 'eval_duration': 4828947310, 'model_name': 'qwen3:latest', 'model_provider': 'ollama'}, id='lc_run--9821a56b-f534-4378-b4a6-6bef958aeb20-0', usage_metadata={'input_tokens': 146, 'output_tokens': 152, 'total_tokens': 298})]}
>>>
>>> agent.invoke(
... {"messages": "What's the weather in Paris?"},
... context={"user_expertise": "beginner"},
... )
{'messages': [HumanMessage(content="What's the weather in Paris?", additional_kwargs={}, response_metadata={}, id='2a6d7967-4aa5-4755-8e27-53dff88ef6d5'), AIMessage(content="I don't have access to real-time weather data. However, you can check the current weather in Paris using a weather service or app. Would you like me to help you find one?", additional_kwargs={}, response_metadata={'model': 'qwen3:latest', 'created_at': '2025-10-24T11:29:41.473963567Z', 'done': True, 'done_reason': 'stop', 'total_duration': 4695013262, 'load_duration': 183956333, 'prompt_eval_count': 147, 'prompt_eval_duration': 195127970, 'eval_count': 135, 'eval_duration': 4280626766, 'model_name': 'qwen3:latest', 'model_provider': 'ollama'}, id='lc_run--0827dc43-5bcd-46a1-a4b4-e59ffbf998f8-0', usage_metadata={'input_tokens': 147, 'output_tokens': 135, 'total_tokens': 282})]}
>>>
>>> agent.invoke(
... {"messages": "What's the capital of France?"},
... context={"user_expertise": "beginner"},
... )
{'messages': [HumanMessage(content="What's the capital of France?", additional_kwargs={}, response_metadata={}, id='ba4fe7dc-bf88-41d6-aec1-07ebb057797e'), AIMessage(content='', additional_kwargs={}, response_metadata={'model': 'qwen3:latest', 'created_at': '2025-10-24T11:29:57.330753915Z', 'done': True, 'done_reason': 'stop', 'total_duration': 3192402879, 'load_duration': 187762416, 'prompt_eval_count': 147, 'prompt_eval_duration': 66327797, 'eval_count': 92, 'eval_duration': 2903858309, 'model_name': 'qwen3:latest', 'model_provider': 'ollama'}, id='lc_run--debcdff2-0c74-42ed-b692-8edca87102d4-0', tool_calls=[{'name': 'get_capital', 'args': {'country': 'France'}, 'id': '8f8e86c7-a1ea-44f8-b682-a853e5b1c932', 'type': 'tool_call'}], usage_metadata={'input_tokens': 147, 'output_tokens': 92, 'total_tokens': 239})]}