· 2 min read · ← All posts
Ardan Labs Go Agents

Field notes from working through example 13 of Ardan Labs’ Ultimate AI course by Bill Kennedy and Florin Pățan (Apache 2.0). My fork: PratikDhanave/ai-training. Thank you Bill and Florin for teaching this material — the patterns in this post are derived from the course; the production reflections at the end are mine.

What the example teaches

An agent is a loop. The loop:

  1. Send messages + tool definitions to the LLM.
  2. LLM responds: either a final answer or a tool call.
  3. If tool call: execute the tool, append the result to messages, go to 1.
  4. If final answer: return it.

That’s it. Everything else (memory, planning, multi-agent coordination) is a refinement of this skeleton.

What it looks like

func RunAgent(ctx context.Context, llm LLM, tools []Tool, userMessage string) (string, error) {
    messages := []Message{
        {Role: "system", Content: systemPrompt},
        {Role: "user",   Content: userMessage},
    }

    for step := 0; step < maxSteps; step++ {
        resp, err := llm.Chat(ctx, messages, tools)
        if err != nil {
            return "", err
        }

        if resp.FinalAnswer != "" {
            return resp.FinalAnswer, nil
        }

        for _, call := range resp.ToolCalls {
            result, err := dispatch(tools, call)
            if err != nil {
                result = fmt.Sprintf("error: %v", err)
            }
            messages = append(messages,
                assistantToolCall(call),
                toolResult(call.ID, result),
            )
        }
    }

    return "", ErrMaxStepsReached
}

What I learned

The max-steps cap is load-bearing. Without it, a confused LLM can loop indefinitely. With it, you get bounded latency and bounded cost. 10-15 steps is a reasonable starting point for most workloads.

The system prompt does the work. The agent’s “intelligence” lives in the system prompt — what tools to use when, when to ask clarifying questions, when to stop. The loop is just plumbing.

Production connection

This is the literal shape of every agent in Genie’s agents/ directory. Adding governance policies, audit hooks, and budget limits doesn’t change the core loop; it wraps it. Reading this example was the moment “agents” stopped being mysterious.


Credit & reference. This post is field notes on example 13 from Ardan Labs’ Ultimate AI by Bill Kennedy + Florin Pățan, licensed Apache 2.0. The original example: cmd/examples/example13-agent-loop/. My fork with notes: PratikDhanave/ai-training. Highly recommend the course for anyone building AI applications in Go — the material is rigorous and the Kronk + yzma + llama.cpp pipeline gives you hardware-accelerated local inference end-to-end. Thank you, Bill and Florin.

← Back to all posts