· Agent engineering

Lessons from Scaling to 1,000 Agents—and Making Them Productive

Sixteen lessons on focus, coordination, execution, and recovery for an agent fleet.

Disclaimer: The ideas and analysis presented in this article are based on publicly available technical information, first-principles reasoning, and the author’s personal experience in HPC and distributed systems architecture. The content reflects personal technical exploration and architectural thinking only, and does not represent the views, strategies, products, or business interests of the author’s employer or any affiliated organization. All rights reserved by the author.

Starting 1,000 agents is one thing. Making them productive—working together, completing useful tasks, and recovering from failures—is where the engineering begins.

After intensive experiments with coding, research, and writing—using individual agents, persistent roles, loops, graphs, and combinations of them—I keep coming back to one principle:

Give agents room to reason. Give the runtime clear rules to execute and recover.

These are my 16 lessons so far.

1. Build for agents that keep getting smarter.

Treat agents as capable collaborators. Before adding another component, ask whether an agent with clear instructions can handle the work.

Be selective about small tricks and workarounds. A limitation in today’s Codex or Claude may become a built-in capability in a future release. Solve immediate problems when necessary, but avoid building your architecture around temporary weaknesses.

Invest in the framework, stability, and unresolved problems you expect to matter for months or years. Keep simplifying as agent capabilities improve.

2. Engineer the guidance for each role.

Give each agent a clear purpose, relevant context, boundaries, and completion criteria.

A capable agent can still spend considerable effort solving the wrong problem. At scale, unclear instructions multiply that waste. Help agents focus their intelligence on a specific outcome.

3. Make skills progressively discoverable.

Give agents a focused scope and let them discover and load relevant skills when needed.

Loading every instruction into every agent adds noise and consumes context. Make the right guidance accessible at the right moment.

4. Centralize tool access through an MCP gateway.

Use a shared gateway to aggregate tools, manage connections, and enforce access by role.

Each agent can connect to the gateway instead of managing its own collection of backend integrations. Keep tool discovery relevant to the agent’s current work.

5. Keep agent communication simple.

Our everyday messaging often runs through shared services. Agent communication can follow the same pattern.

A coordination service exposed through MCP can provide messaging, task handoffs, and status retrieval. The service behind MCP owns delivery and persistence. Introduce more complex communication infrastructure when the workload justifies it.

6. Separate events from conversations.

Events record execution facts for retrieval, debugging, and audit. Conversations carry shared context.

Encourage agents to communicate their plans, key rationale, uncertainties, and results. Other agents need enough context to coordinate, challenge assumptions, and continue the work.

7. Keep conversation history retrievable.

Preserve discussions by task, project, or thread so agents can retrieve relevant decisions, assumptions, and unresolved questions.

A reliable handoff should carry the objective, usable results, supporting evidence, and what remains unfinished. The next agent should be able to continue without rediscovering everything.

8. Let agents propose graph fan-out.

An agent can decide which specialist—or specialists—should act next based on what it discovers.

The scheduler validates and executes those branches within dependencies, permissions, and resource limits. Let the graph evolve with the work while keeping execution explicit.

9. Parallelize only where it helps.

Use a pool of specialized agents for work that benefits from parallel execution.

Every branch adds coordination, context, and reconciliation costs. Unnecessary fan-out creates unnecessary work and divergence. Give each branch a clear contribution to the final result.

10. Let the scheduler control loops.

Agents can recommend another iteration and explain what needs improvement.

The scheduler controls continuation, retries, correction steps, and fallbacks through explicit conditions and stopping limits. An agent’s decision to keep working should become a bounded execution request.

11. Build a review pool.

Use a shared pool of reviewers instead of assigning a dedicated reviewer to every worker.

Route reviews by expertise and workload. Preserve enough independence for reviewers to question the original approach, and give them concrete results and acceptance criteria to examine.

12. Scope voting and decision gates to the domain.

When agents disagree, involve agents with expertise relevant to the question.

Define who can review, vote, or approve that class of decision. A larger vote alone does not establish correctness. Use evidence, tests, and domain-specific validation to resolve divergent directions.

13. Scale useful concurrency.

A fleet of 1,000 agents does not require 1,000 simultaneous model calls.

Match active work to model capacity, tool limits, and available compute. Measure completed work, quality, latency, and cost. A busy fleet is productive only when its activity advances useful outcomes.

14. Make progress observable.

Store structured JSON events in a database and connect them through task, agent, and execution IDs.

You should be able to see what is running, what is blocked, what failed, and which tasks have actually completed. At scale, reading conversations is insufficient for understanding execution.

15. Preserve raw events.

Keep the original execution events behind your monitoring views and summaries.

They provide the evidence needed to investigate failures, reconstruct sequences, and audit behavior. A summary is useful until the detail it omitted becomes the detail you need.

16. Design for scheduler recovery.

Persist task states and checkpoints so a restart can resume unfinished work.

Account for the awkward case where an action succeeds but its completion is never recorded. Durable task IDs and idempotent operations help prevent recovery from repeating completed work.

The deeper lesson is that the baseline keeps moving.

We develop agent frameworks to turn AI capability into stable, dependable work. But the agent inside the framework keeps getting smarter.

As agents improve, they may directly handle planning, coordination, and correction that previously required custom engineering. Some mechanisms we carefully build today may become unnecessary tomorrow.

Our framework therefore has to keep earning its place. What reliability does it provide beyond what the agent can already accomplish on its own?

This changes how I think about competition. Alongside other developers and companies, we are racing against the growing capabilities of the agents themselves. Each major advance gives everyone a new baseline to build from. Resources and experience differ, but everyone must reconsider where their engineering adds value.

My working assumption is that agents will keep becoming more capable. Our job is to help them focus, hand off dependable work, and operate within a system that can verify results and recover from failure.

That is how I am approaching 1,000 agents and beyond: build an architecture that becomes more useful as the agents become more intelligent.

Most importantly, stay humble and take a rest when you can! That’s what I’ve learned from working with an agent fleet.