Back to Go Micro

From Chat to Flows: What If Your Services Could Orchestrate Themselves?

internal/website/blog/9.md

5.23.08.8 KB
Original Source

From Chat to Flows: What If Your Services Could Orchestrate Themselves?

May 29, 2026 • By the Go Micro Team

We shipped micro chat recently — an interactive terminal where you talk to your services through an LLM. You say "list all users over 30 and send each a welcome email," and the model figures out which services to call, in what order, with what arguments.

It works. But it's interactive and ephemeral. You type a prompt, get a result, move on. What if you could save that prompt as a flow and trigger it from an event?

This post explores that idea. We're not shipping anything yet — we're thinking out loud about where the intersection of microservices, MCP, and LLMs could go.

What We Have Today

Go Micro already has the building blocks:

  • Services as tools: every endpoint is discoverable via MCP with typed schemas
  • ai/tools: programmatic discovery and execution — tools.FromRegistry(reg) gives you the tool list, tools.Handler(client) executes RPCs
  • ai.History: multi-turn conversation state so the LLM has context across steps
  • micro chat: the interactive agent loop that ties it together
  • Broker/events: pub/sub for async communication between services

The gap is between "I can interactively ask an LLM to orchestrate my services" and "I can define a persistent, event-driven workflow that does it automatically."

The Flow Concept

Imagine you could define a flow like this:

yaml
name: onboard-user
trigger: events.user.created
prompt: |
  A new user was just created: {{.event.data}}.
  1. Send them a welcome email via the email service
  2. Create a default workspace via the workspace service
  3. If they're on an enterprise plan, assign them to the enterprise onboarding queue
  4. Log everything via the audit service

When a user.created event fires, the flow engine:

  1. Discovers available services from the registry
  2. Builds the tool list from their endpoints
  3. Feeds the event data + prompt to an LLM
  4. The LLM decides which tools to call, in what order, with what arguments
  5. The engine executes the RPCs, feeds results back, and lets the LLM continue until done
  6. The flow result is logged/stored for observability

This is essentially micro chat but triggered by an event instead of a human, with the prompt pre-defined instead of typed interactively.

How It Compares to Traditional Orchestration

Step Functions / TemporalLLM Flow
DefinitionState machine in JSON/YAMLNatural language prompt
BranchingExplicit if/else statesLLM decides based on context
Error handlingRetry policies, catch blocks"If this fails, try X instead"
New serviceUpdate the state machineLLM discovers it automatically
Determinism100% reproducibleProbabilistic (same prompt, slightly different execution)
CostCompute onlyCompute + LLM tokens per flow
DebuggingStep-by-step state traceConversation log

The tradeoff is clear: traditional orchestration is deterministic but rigid. LLM flows are flexible but probabilistic.

For a payment processing pipeline, you want Step Functions. For "onboard this user and do whatever makes sense based on their plan," an LLM flow could be genuinely better — it adapts to new services without code changes.

What This Would Look Like in Go Micro

The simplest version is just micro chat with a saved prompt and a trigger:

go
flow := ai.NewFlow("onboard-user",
    ai.WithTrigger("events.user.created"),
    ai.WithPrompt(`A new user was created: {{.Data}}.
        Send welcome email, create workspace, 
        assign to enterprise queue if enterprise plan.`),
    ai.WithProvider("atlascloud"),
    ai.WithAPIKey(key),
)

// Register with the service
service := micro.New("flow-runner")
flow.Register(service)
service.Run()

Under the hood, Flow would:

  1. Subscribe to the broker topic
  2. On each event, create an ai.History with the prompt + event data
  3. Call history.Generate() in a loop until the LLM stops requesting tool calls
  4. Log the full conversation for audit

The building blocks already exist. ai.History manages the conversation. ai/tools discovers and executes services. The broker delivers events. A Flow just connects them.

Why We Haven't Built It Yet

Three honest reasons:

1. Non-determinism is dangerous for workflows. If you run the same flow twice with the same input, the LLM might call tools in a different order or skip a step. For many workflows, that's a bug, not a feature. We'd need guardrails: required steps, validation, output schemas.

2. Cost unpredictability. Each flow execution costs LLM tokens. A complex flow with 5 tool calls might cost $0.01. At 10,000 events per day, that's $100/day just for orchestration. Traditional orchestrators cost effectively nothing per execution.

3. Scope creep. Go Micro is a microservices framework, not a workflow engine. Adding persistent flow state, retry logic, dead letter queues, and flow versioning is a big commitment. Temporal exists. Step Functions exist. We should be honest about where the framework ends and the platform begins.

Where It Makes Sense

Despite those caveats, there are use cases where this is genuinely better than traditional orchestration:

  • Ops automation: "When a service health check fails, investigate by checking logs, recent deployments, and related services, then post a summary to Slack." This is inherently fuzzy — you don't know which tools you'll need until you see what's wrong.

  • Customer support flows: "A customer filed a ticket about a billing issue. Look up their account, check recent invoices, and draft a response." The flow adapts to what it finds.

  • Data pipeline glue: "New CSV uploaded. Parse it, validate the schema, create records in the appropriate service, and report any errors." The LLM handles schema variations that would break a rigid pipeline.

  • Development workflows: "Run the test suite, analyze failures, check if they're flaky, and create issues for real failures." This is micro chat for CI.

What You Can Do Today

You don't need a flow engine to get most of this value. The ai/tools package already gives you programmatic access:

go
set := tools.New(service.Registry())
discovered, _ := set.Discover()

m := ai.New("atlascloud",
    ai.WithAPIKey(key),
    ai.WithToolHandler(set.Handler(service.Client())),
)

hist := ai.NewHistory("You are a service orchestrator.", 50)

// React to an event
broker.Subscribe("user.created", func(e broker.Event) error {
    prompt := fmt.Sprintf("New user created: %s. Send welcome email and create workspace.", string(e.Message().Body))
    resp, _ := hist.Generate(ctx, m, prompt, discovered)
    log.Infof("Flow result: %s", resp.Answer)
    hist.Reset() // fresh history for next event
    return nil
})

That's ~15 lines. No flow engine, no YAML, no new abstractions. Just a broker subscription that feeds events into the LLM with your services as tools.

If that pattern proves useful in practice — if people are writing those 15 lines over and over — then there's a case for a Flow primitive. But we'd rather see the usage pattern emerge naturally than design it speculatively.

We Want Your Feedback

This is an open question, not an announcement. If you're building with Go Micro and thinking about service orchestration:

  • Would you use an LLM-powered flow engine? For what?
  • What guardrails would you need? (Required steps? Output validation? Cost limits?)
  • Would you rather have a YAML-based DSL or a Go API?
  • Is this a framework feature or a separate tool?

Open an issue on GitHub or reach out. We're genuinely curious what the community thinks.

The Bigger Picture

The thesis behind Go Micro's AI-native direction is that services should be composable by agents, not just by code. MCP made services discoverable. ai/tools made them callable. micro chat made them interactive. Flows would make them orchestratable.

Each layer builds on the previous one. And at each layer, the question is the same: does this belong in the framework, or is it better left to the user? So far, we've been conservative — ai/tools is 150 lines, History is 80, micro chat is 170. Small, composable building blocks rather than a big orchestration framework.

We think that's the right approach. But we're watching to see if the community says otherwise.


Go Micro is an open source framework for distributed systems development. Star us on GitHub.

<div class="post-nav"> <div><a href="/blog/8">&larr; Atlas Cloud Sponsors Go Micro</a></div> <div><a href="/blog/">All Posts</a></div> </div>