Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Your First Agent

Let’s build a real agent — a task prioritizer that classifies items and presents them sorted by urgency.

Step 1: Scaffold the project

keel init task-prioritizer
cd task-prioritizer

This creates main.keel with a starter agent.

Step 2: Define your types

Replace main.keel with:

type Priority = low | medium | high | critical

type Task {
  title: str
  description: str
}

Types in Keel are either enums (a set of variants) or structs (named fields). The type checker ensures you handle all variants in when blocks.

Step 3: Write the classification task

task prioritize(task: Task) -> Priority {
  classify task.description as Priority considering [
    "blocks other people"        => critical,
    "has a deadline this week"   => high,
    "nice to have"               => low
  ] fallback medium
}

This sends the task description to the LLM with classification hints. The fallback medium ensures you always get a valid Priority — never none.

Step 4: Build the agent

agent Prioritizer {
  role "You help prioritize a task list"
  model "claude-sonnet"

  state {
    processed: int = 0
  }

  task run_batch(tasks: list[Task]) {
    for task in tasks {
      priority = prioritize(task)
      self.processed = self.processed + 1

      when priority {
        critical => notify user "🔴 CRITICAL: {task.title}"
        high     => notify user "🟠 HIGH: {task.title}"
        medium   => notify user "🟡 MEDIUM: {task.title}"
        low      => notify user "🟢 LOW: {task.title}"
      }
    }
    notify user "Processed {self.processed} tasks total"
  }

  every 1.hour {
    tasks = [
      {title: "Fix login bug", description: "Users can't log in, blocks the whole team"},
      {title: "Update README", description: "Nice to have, not urgent"},
      {title: "Deploy v2.0", description: "Release deadline is Friday"}
    ]
    run_batch(tasks)
  }
}

run Prioritizer

Step 5: Run it

KEEL_OLLAMA_MODEL=gemma4 keel run main.keel

Step 6: Type-check it

Before running, you can verify your code has no type errors:

keel check main.keel

If you forget a variant in a when block:

  × Type error
   ╭─[main.keel:25:5]
 24 │     when priority {
 25 │       critical => notify user "CRITICAL"
   ·       ─────────┬─────────
   ·                 ╰── Non-exhaustive match on Priority: missing high, medium, low
 26 │     }
   ╰────

Key takeaways

ConceptWhat it does
type Priority = low | medium | high | criticalDefines an enum — the type checker enforces exhaustive matching
classify text as TypeAI-powered classification into your enum
considering [...]Gives the LLM hints for each variant
fallback valueGuarantees a non-nullable result
when value { ... }Pattern matching — compiler checks all variants are covered
state { field: Type = default }Mutable agent state, accessed via self.field
every duration { ... }Scheduled recurring execution

Next: Language Guide →