def get_agents(self, addr=True, agent_cls=None, as_coro=False):
        """Get agents from the slave environments.

        :param bool addr:
            If ``True``, returns only addresses of the agents, otherwise
            returns a :class:`Proxy` object for each agent.

        :param agent_cls:
            If specified, returns only agents that are members of that
            particular class.

        :param bool as_coro:
            If ``True``, returns a coroutine, otherwise runs the method in
            an event loop.

        :returns:
            A coroutine or list of :class:`Proxy` objects or addresses as
            specified by the input parameters.

        Slave environment managers are excluded from the returned list by
        default. Essentially, this method calls each slave environment
        manager's :meth:`creamas.mp.EnvManager.get_agents` asynchronously.

        .. note::

            Calling each slave environment's manager might be costly in some
            situations. Therefore, it is advisable to store the returned agent
            list if the agent sets in the slave environments are not bound to
            change.
        """
        async def slave_task(mgr_addr, addr=True, agent_cls=None):
            r_manager = await self.env.connect(mgr_addr, timeout=TIMEOUT)
            return await r_manager.get_agents(addr=addr, agent_cls=agent_cls)

        tasks = create_tasks(slave_task, self.addrs, addr, agent_cls)
        return run_or_coro(tasks, as_coro)