Back to Go Micro

Agents for Services: A New Model for Microservices

internal/website/blog/15.md

5.26.07.9 KB
Original Source

Agents for Services: A New Model for Microservices

June 4, 2026 • Asim Aslam

Microservices solved monolithic code. Split it into small, independent units. But we centralised the intelligence — one agent, one brain, managing everything. That's just a different kind of monolith.

What if every service had its own agent? Not embedded in the service. Created separately, assigned to manage it. The service is the capability. The agent is the intelligence.

The Problem with One Agent

Right now, micro chat is a single agent. It discovers every service in the registry, sees every endpoint, and orchestrates across all of them. You ask it a question and it figures out which service to call.

This works for small systems. Two or three services, a dozen endpoints — one agent can handle it. But it doesn't scale the way microservices are supposed to scale.

A single agent managing ten services is like one person running ten departments. They know a little about everything and a lot about nothing. They can't hold the full context of each domain. They make shallow decisions because they're spread too thin.

This is the same centralisation problem that microservices were designed to solve. We distributed the services but centralised the intelligence.

An Agent Per Service

What if each service had its own agent? Not inside the service — separate from it, but created to manage it.

The service is the capability. It has endpoints, stores data, handles requests. It doesn't know or care whether an agent exists.

The agent is the intelligence. It knows the service's domain deeply — what the endpoints do, how they relate, what the edge cases are, when to use which operation. It makes decisions about its service the way a domain expert would.

You (the creator)
  └── Agent: task-agent
  │     └── Service: task
  └── Agent: project-agent
  │     └── Service: project
  └── Agent: notification-agent
        └── Service: notification

When you talk to the system, you don't talk to the services. You don't even talk to a single central agent. Your message reaches the right agent — the one responsible for that domain — and it handles it using its service.

Multi-Service Agents

Some agents manage more than one service. A "project management agent" might oversee both the task service and the project service because they're part of the same domain. It understands how projects contain tasks, how task completion affects project progress, how to coordinate across both.

You
  └── Agent: project-management
  │     ├── Service: task
  │     └── Service: project
  └── Agent: communication
        ├── Service: notification
        └── Service: email

The agent boundaries don't have to match the service boundaries. A service is a technical unit — one concern, one data store, one set of endpoints. An agent is a domain unit — it might span multiple services because the domain spans them.

This is the separation that matters: services are about capability, agents are about intelligence.

How They Communicate

Agents are services. They communicate via standard RPC — the same way every service in the system communicates. An agent has a proto-defined Agent.Chat endpoint that any other agent or client can call.

When the project management agent needs to notify someone, the router dispatches to the communication agent via RPC. Each agent handles its domain.

> Reschedule all of Alice's tasks to next week and let her know

  [project-management] Rescheduling 3 tasks for Alice...
  [project-management] → task.Update(id: "t1", due: "2026-06-11")
  [project-management] → task.Update(id: "t2", due: "2026-06-12")
  [project-management] → task.Update(id: "t3", due: "2026-06-13")
  [project-management] Notifying communication agent...
  [communication] Sending schedule change email to Alice...
  [communication] → notification.Create(user: "alice", message: "3 tasks rescheduled")
  [communication] → email.Send(to: "[email protected]", subject: "Tasks rescheduled")

Each agent handles its domain. The user sees one conversation. Underneath, multiple agents are collaborating, each using their own services.

What Agents Do

An agent isn't just a router to endpoints. It has responsibilities:

Functional — it's the intelligent interface to its services. It knows which endpoint to call, in what order, with what parameters. It handles the "how" so the user only needs to express the "what."

Evolutionary — it can grow its services. If the task agent realises it needs a "recurring tasks" capability that doesn't exist, it can generate a new endpoint or a new service. The agent evolves the system based on what users need.

Operational — it monitors its services. Health checks, error rates, log patterns. If the task service starts failing, the task agent notices and can act — restart it, alert the operator, degrade gracefully.

These layers build on each other. Functional is where we start. Evolutionary is what makes the system grow. Operational is what makes it production-ready.

The Service Stays Simple

This is the critical point: the service doesn't change. It's still a Go struct with methods. It still registers with the registry. It still stores data in the store. It still communicates via RPC.

go
func main() {
    service := micro.New("task")
    service.Handle(new(TaskHandler))
    service.Run()
}

The agent is a separate entity, created by the operator — or by micro run --prompt — to manage that service. The service has no dependency on the agent. You can run services without agents. You can swap agents without touching services. You can have one agent managing three services, or three agents managing one service from different angles.

The service is the body. The agent is the mind assigned to it.

What This Looks Like in Micro

The pieces already exist:

  • Registry — agents register as services with a proto-defined Agent.Chat endpoint. No special metadata hacks — they're real services.
  • RPCmicro chat calls agents via standard RPC. Agents call services via standard RPC. Agent-to-agent communication is just RPC. One protocol for everything.
  • Store — agents persist memory (conversation history, learned context) across restarts.
  • micro chat — discovers agents from the registry and routes to the right one based on intent.
  • micro run --prompt — generates services and an agent as a pair. Everything starts together.

The framework was built for distributed systems. Agents are just the next thing we distribute.

The Bigger Picture

Microservices solved the problem of monolithic code — split it into small, independent units that can evolve separately. But they created a new problem: how do the pieces coordinate?

We tried solving coordination with code — service-to-service calls, sagas, choreography, orchestration engines. Each solution added complexity. The coordination layer became harder to build than the services themselves.

Agents solve coordination differently. They don't coordinate through code. They coordinate through understanding. An agent that manages the project domain understands what "reschedule Alice's tasks" means. It doesn't need a workflow definition or a saga pattern. It just knows.

And when you have multiple agents, each understanding their domain, the system coordinates itself. Not through service-to-service calls. Not through a central orchestrator. Through distributed intelligence.

That's the model. Services for capability. Agents for intelligence. The framework connects them.

bash
micro run --prompt "task management system"
micro chat
> What's overdue this week?

The agent for your services answers. Not because you wired it up. Because the system understands what you built.


Go Micro is open source. Star us on GitHub, join the Discord, or read the docs.