OllamaCLI icon
SlackIncomingWebhook icon
Schedule icon

Batch Ticket Classification with a Local Ollama Model

Classify batches of tickets or logs with a local Ollama model in Kestra. One task loops over every line, writes a CSV artifact, and reports counts to Slack.

Categories
AI

Nightly triage is the classic case where cloud LLMs are hardest to justify: hundreds of items, each containing customer text you would rather not send to a third party, multiplied by per-token pricing. This blueprint runs the whole batch through one io.kestra.plugin.ollama.cli.OllamaCLI task instead. A small shell loop inside commands feeds each line of the input file to a local model, collects one label per line into a CSV, and the model loads into memory once for the entire batch rather than once per item.

How it works

  1. classify_batch receives the ticket list as an inline inputFiles entry, one ticket per line.
  2. The first command is a while read loop: for each line, ollama run {{ inputs.model }} gets a prompt that names the three allowed categories and demands only the category name back, and the result is appended to classified.csv next to the quoted ticket text.
  3. The second command counts the CSV lines with wc -l and prints the count through Kestra's ::{"outputs": {...}}:: protocol, exposing it as {{ outputs.classify_batch.vars.classified_count }}.
  4. outputFiles uploads classified.csv to internal storage as a downloadable execution artifact.
  5. enableModelCaching: true persists the model between nightly runs, so the batch starts classifying immediately instead of re-downloading the model.
  6. notify posts the count to Slack and points at the artifact; the errors block alerts on failure. A disabled-by-default Schedule trigger runs the triage nightly at 01:00.

What you get

  • Batch economics: one model load amortized over every item, zero API cost, zero data egress.
  • A CSV artifact pairing each ticket with its label, ready for spreadsheets, BI tools, or a warehouse load.
  • The classified count as a typed output for notifications, thresholds, or downstream conditions.
  • A constrained prompt pattern, fixed label set, answer-only instruction, that keeps model output machine-usable.

Who it's for

  • Support teams labeling the day's queue overnight without sharing customer text with an API provider.
  • SRE and platform teams triaging log lines or alerts into buckets on a schedule.
  • Anyone with a classify-many-small-things job where per-item API calls are too slow or too expensive.

Why orchestrate this with Kestra

A cron job running this loop would work until the night it does not, and nobody would know which line broke or how many items were labeled. Kestra wraps the same shell loop with an input file it versions, an artifact it stores, a count it types, a schedule it owns, and an alert that fires when the batch dies at 01:00 instead of a silent empty CSV at 09:00.

Prerequisites

  • The default containerImage runs Ollama inside Docker, so the Kestra worker needs access to a Docker daemon. On self-hosted workers that already have Ollama installed locally, set the task's taskRunner to Process to use the local install directly.
  • A model small enough that per-line latency times batch size fits your window; llama3.2 handles short labels quickly on CPU.
  • A Slack incoming webhook.

Secrets

  • SLACK_WEBHOOK_URL: Slack incoming webhook URL.

Quick start

  1. Add the SLACK_WEBHOOK_URL secret to your Kestra namespace.
  2. Execute the flow; Slack should report 4 classified tickets, and classified.csv should pair each sample line with bug, billing, or feature.
  3. Replace the inline tickets.txt with a real export and set disabled: false on the nightly trigger.

How to extend

  • Feed the batch from a real source: map a database export, an S3 object, or a previous task's output file into inputFiles instead of the inline sample.
  • Change the category list in the prompt to your own taxonomy; keep the reply-with-only-the-label instruction.
  • Load the CSV into DuckDB or Postgres afterward and trend label volumes over time.
  • For per-field extraction instead of a single label, see the Ollama structured extraction blueprint.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.