Agents never control other agents. Aside from supporting technology (PuppetDB, an ENC if you have one, a database to back PuppetDB), yeah, a master and N agents is the gist of it.
There are some docs online (see specifically the "Tuning and Scaling" section of the Puppet Documentation Index,
https://docs.puppetlabs.com/puppet/#tuning-and-scaling ) about scaling, and a search of the mailing list archives (as well as Google - there have been quite a few blog posts on this) should help turn up other options and experiences.
Off the top of my head, I believe there are generally two paradigms used: either clustering/HA for your masters, generally load-balanced from what I gather, or (what I do) splitting up agents between different masters (by location, or network, or dev/test/prod). My current infrastructure is made up of ~450 nodes which are served by three masters - dev, test/QA and prod. We run every 30 minutes, via mcollective with a set concurrency. The masters are VMs, running on the same physical hosts as PuppetDB and its PostgreSQL instance, so I'm quite confident that I could scale each one to a few thousand nodes before I have to worry about overloading one host. In addition, since we split dev, test/QA and prod masters, we can deploy module changes (and puppet/puppetdb/etc. upgrades) to the dev environment, validate there, promote to test/QA, validate there, and then promote to prod.