DocumentationPricingLoginSign up

Getting Started

  • Introduction
  • Installation & Setup

Features

  • Modules
  • Platform
  • Recipes

Cluster

  • Details & Setup
  • Tasks, Actions & Agents
    • Tasks
    • Actions
    • Agents
    • Services
    • Sessions
    • Workers
    • Statuses
    • Monitoring
  • Assets & Files

API Reference

  • Command-Line Interface
  • Recipe Development
  • Recipes API

Tasks, Actions, Agents & Services

The main concepts in the app are tasks for annotation, actions for running jobs, agents for auto-annotation and services for apps and APIs. They can be created and managed in the web app, via the CLI or automatically by your coding assistant.


Tasks

Tasks are workflows that preprocess and queue up data for annotation or review and start the annotation server. They are created from a recipe, a Python function describing the workflow and its available settings. You can also think of a task as an instance of a given recipe with a specific configuration. Tasks can be created in the UI or via the CLI and once started, annotators will be able to connect to them and create annotations.

Annotate entitiesSTARTED

Named Entity Recognitionner
Annotations
512
Annotators
3
Agents
1

To create a new task, you can navigate to TasksNew task in the UI or use tasks create on the command line. The available settings are automatically converted into a web form and CLI arguments.

Command-line usage
$ellf

tasks

create

ner"Annotate entities"

--dataset "NER News"

--input "News Headlines"

--label PERSON,ORG,PRODUCT,LOCATION

--model.name en_core_web_trf

To start a task, you can run tasks start with the name or ID of the created task:

Starting the task
$ellf

tasks

start

"Annotate entities"

This will start the annotation server and will allow human annotators and annotation agents to connect and create data. Each time an annotator connects to the interface, a new session is created and the annotations and sessions can be viewed in the app. You can add annotators and agents in the UI or via users assign and agents assign. You can also provide annotation instructions that annotators can view in the app.

Overview of tasks in the app
Overview of tasks in the app
Overview of annotated data
Overview of annotated data

Annotations are saved into the provided dataset, which can then be used by other tasks and actions, e.g. to review the data or train a model, or exported to a file.

Read more

Annotation

Labelling data using Prodigy

Annotation Sessions

Grouping collected annotations

Task Recipes

Built-in workflows for tasks

Recipe Development

Build custom task recipes

Actions

Actions are workflows that execute any logic and exit. They’re created from a recipe, a Python function describing the workflow and its available settings. You can also think of an action as an instance of a given recipe with a specific configuration, similar to jobs running in a CI system like GitHub Actions. Actions can be created in the UI or via the CLI and have access to all resources on your cluster, so they can be used to train a model from your data, perform data analysis, trigger deployment or integrate Ellf with other tools and services.

Train a pipelineSTARTED

Train a spaCy pipelinetrain
Executions
42
Last execution
2 hours ago

To create a new action, you can navigate to ActionsNew action in the UI or use actions create on the command line. The available settings are automatically converted into a web form and CLI arguments.

Command-line usage
$ellf

actions

create

hello_world_action"My first action"

--n-lines 10

To start an action, you can run actions start with the name or ID of the created action:

Starting the action
$ellf

actions

start

"My first action"

This will create a new execution, run the code and save all output to the logs, which you can access via the Logs tab or actions logs. Actions can have many executions over time – for instance, for regular training runs, end-to-end testing, deployment or data import and export.

To check the status of a running action via your coding assistant and view a summary, you can use the monitoring module. If you’re using an action to train a model, Ellf is also able to analyze and interpret the logs via the model training module – for example to detect potential problems like overfitting and suggest solutions.

✳︎Claude Code: Checking on a training action
› /ellf-monitor How’s the NER training going?
⏺︎
Jobner-product-names-v2 (action)
Staterunning — step 800
Best score0.81 (ents_f) at step 720
Train loss0.52 (stable)
AlertsNone

Training looks healthy. The score has been improving steadily and there are no signs of overfitting or loss instability.

✳︎Claude Code: Detecting overfitting during training
› /ellf-train

My NER model for extracting company names and job titles from resumes has been training for a while. How’s it looking?

⚠ Overfitting detected — dev score declining while training loss continues to decrease (sustained over last 4 evaluation steps)
⏺︎

Your best model was saved at step 1,600 with 0.79 F1 (COMPANY 0.85, JOB_TITLE 0.71). After that, training loss keeps dropping but dev scores are going down — the model is memorizing your training data. JOB_TITLE is the weaker label. Checking your data: you have 312 COMPANY examples but only 87 for JOB_TITLE. That’s likely not enough for reliable generalization. I’d recommend:

  1. Annotate more JOB_TITLE examples — target at least 150
  2. Increase dropout from 0.1 to 0.3 in the next run
  3. Use model-best from this run as your current baseline

Want me to set up an annotation task to collect more JOB_TITLE examples?

Read more

Action Recipes

Built-in workflows for actions

Recipe Development

Build custom action recipes

Agents

Agents are autonomous workers and annotators that can be assigned to tasks. They’re created from a recipe, a Python function describing the agent’s intended behavior, its available settings and the type of work it’s specialized for. Agents are typically powered by LLMs and can use models running on the cluster or access them via APIs. When assigned to an annotation task, an agent will run in the background and automatically create annotated data in its own dataset.

Auto-labeler for NERANNOTATING

Gemini Annotation Agentgemini_agent
Tasks
2
Annotations
1204

To create a new agent, you can navigate to AgentsNew agent in the UI or use agents create on the command line. The available settings are automatically converted into a web form and CLI arguments. If API keys are required, you can use Ellf’s built-in secrets feature.

Command-line usage
$ellf

agents

create

gemini_agent"My first agent"

--model gemini-2.0-flash

--api-key GEMINI_API_KEY

To start an agent, you can run agents start with the name or ID of the created agent:

Starting the agent
$ellf

agents

start

"My first agent"

Once started, the agent will automatically discover its assigned task servers, fetch tasks, annotate them using the logic defined in the recipe, and submit the results. If a task has annotation instructions defined, the agent is also able to use them, in addition to its own guidelines.

Each agent runs in its own session and creates annotations in the task’s dataset, just like a human annotator would. While an agent is running, the app shows its status as ANNOTATING when it is working on a task, and IDLE when it is running but has had nothing to annotate for the last few minutes. An idle agent is still assigned and will pick up new examples as soon as a task has them. To stop an agent automatically once it runs out of work, set its idle shutdown time – the built-in agents have it under Advanced settings.

Classification agentIDLE

Hugging Face LLM Agenthf_llm_agent
Tasks
1
Annotations
500

You can assign agents to tasks via AgentAdd to tasks or TaskAdd agents in the UI or using agents assign on the CLI.

Assigning the agent to a task
$ellf

agents

assign

--task "Annotate entities"

To unassign an agent, you can remove it from a task in the UI or via agents unassign. This will only remove the assignment and keep all annotations the agent has created.

Agents support three optional settings that control their runtime behavior: poll_interval sets how frequently the agent checks for new tasks (in seconds), idle_shutdown_seconds shuts the agent down once none of its tasks has had anything to annotate for that many seconds, even if the tasks are still running, and icon customizes the avatar used to attribute annotations created by agents in the app, to make it easier to tell them apart.

Annotations with custom avatars for agents

These are defined as parameters in the agent recipe and can be configured when creating the agent. For details on building your own agent recipes, see the recipe development guide and the @agent_recipe API reference.

Use Ellf to iterate on label scheme

To make the most of annotation agents, its crucial to have a well-defined and consistent label scheme. You can use Ellf’s project planning and data annotation modules to guide you through the process, before starting an annotation agent or incorporating human annotators.

Read more

Agent Recipes

Built-in workflows for agents

Recipe Development

Build custom agent recipes

Services

Services are long-running background processes like REST or MCP apps and APIs that can also be used by your coding assistant, or tasks, actions and agents in Ellf. They’re created from a recipe, a Python function describing the setup and its available settings. Services can also expose web apps, so you can use them to host demos, dashboards or other custom apps and tools on your cluster.

Generate PatternsSTARTED

Pattern Generation MCP Serverpattern_gen
Uptime
3 days
Last updated
3 days ago

To create a new service, you can navigate to ServicesNew service in the UI or use services create on the command line. The available settings are automatically converted into a web form and CLI arguments.

Command-line usage
$ellf

services

create

annotation_dashboard"My first service"

--dataset "NER News"

To start a service, you can run services start with the name or ID of the created service:

Starting the service
$ellf

services

start

"My first service"

Once a service is running, you can use the web UI or services url command to get its bearer-token-authenticated URL. This mints a fresh 90-day token and formats it together with the service’s public URL, ready to drop into an MCP client config or curl invocation.

Getting the service URL and token
$ellf

services

url

"My first service"
✔ URL:         https://yourorg.ellf.run/services/3f2a.../
  Token:       eyJhbGciOiJSUzI1NiIsInR5cCI6IkpX...
  Expires at:  2026-09-23T11:04:00+00:00
  Try it:      curl -H 'Authorization: Bearer eyJhbGc…' https://yourorg.ellf.run/services/3f2a.../

The URL stays stable across stop/start cycles, so an MCP client config that points at it keeps working even after the service is restarted. If a token ever leaks, services rotate-token mints a fresh one without printing the URL again. Existing tokens stay valid until they expire.

Opening a service in the browser

Services built for people rather than machines – dashboards, demos, notebook servers – can be declared with auth="session" in their recipe. For these, the service page in the web UI shows an Open in browser button while the service is running: click it and the service opens in a new tab. Access is limited to logged-in members of the service’s project, and visiting the service URL directly (e.g. from a bookmark) redirects you through the app to sign in first. Bearer tokens keep working alongside, so the same service can also be called by machines.

Connecting an MCP client

For a service that exposes an MCP server (like the built-in pattern generation service), drop the URL and token into your MCP client config. The exact file depends on the client, but the shape is the same – a streamable-HTTP server with the bearer token as a header:

MCP client config
{
  "mcpServers": {
    "pattern-gen": {
      "url": "https://yourorg.ellf.run/services/3f2a.../mcp",
      "headers": {
        "Authorization": "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpX..."
      }
    }
  }
}

Your coding assistant can then call the service’s tools directly. Because the cluster enforces authentication for you, a request without a valid token is rejected before it ever reaches the recipe.

End to end service setup and usage

To create a new service, you can use the services create command or click New service in the web app. If you’ve created a service with --no-start, you can also run services start to start it manually. To build your own service – an MCP server, REST API, or a browser app like a dashboard – see the service recipe guide and the @service_recipe API reference.

1. Create the service from a recipe (and start it)
$ellf

services

create

pattern_gen"Pattern server"

--api-key GEMINI_API_KEY

2. Get the stable URL + a 90-day token to use in MCP client config
$ellf

services

url

"Pattern server"
3. Stop service when you're done to release worker
$ellf

services

stop

"Pattern server"

Use Ellf to integrate your existing apps for you

Services are a great way to integrate apps like dashboards that have access to data and model resources on your cluster, or to set up webhooks for other tools and platforms. If you’ve connected Ellf to your coding assistant, it will become proficient at recipe development and the Python API, and can implement these integrations for you.

Read more

Service Recipes

Built-in workflows for services

Recipe Development

Build custom service recipes

Annotation sessions

Once a task is running, annotators with access to it can navigate to it in their dashboard and open the annotation app. You’ll be able to see their work and monitor the activity as it happens. You can also click the Annotate now button on the task page to annotate yourself. A session counts every time a user opens the annotation UI, until they navigate away from it. This means that the same user can start multiple sessions over time and create annotations during those sessions.

Task overview page in the app
Task overview page in the app

To exclude a whole session, e.g. if an annotator misunderstood the guidelines, use the session menu or sessions exclude CLI. This takes all of the session’s examples out of the task’s active data and serves their questions to annotators again. The examples still count as the annotator’s work and you can put them back at any time.

The total annotation duration you see for a task is the sum of the time spent annotating by all annotators and agents across their sessions. Time counts while an annotator is active, and while an agent is ANNOTATING and not IDLE. Short pauses are included, but a stretch of more than five minutes with no activity is left out.

Ellf shows you the cumulative annotation duration for each task, individual sessions and individual annotators and agents within a task. You can also see the total annotation duration for each user in the SettingsMembers tab or users info.

Ellf will start a new session when a user opens the annotation UI. When to close it can be tricky if the user doesn’t explicitly exit the app: we want to account for periods of inactivity, like short breaks or annotation decisions that take a longer time to complete, but eventually, the session needs to be closed so the queue of examples can be “released” to other annotators. This is why Ellf allows for longer inactivity before a session times out.

The annotation app will periodically save in the background, while keeping the most recent annotations on the client only to make it easy to undo previous decisions, without causing conflicts with the database or model in the loop. To ensure data privacy, no annotations are persisted in the browser’s local storage.

If a session times out or the user exits without saving, the queue of examples and most recent annotations are released again so other annotators can work on them, if Prodigy is configured to divide data up between annotators. When the annotator resumes, a new session will be started. If the internet connection was interrupted and the browser tab is still open, they’ll be able to submit their unsaved annotations via the save button or CMD+S once they’re connected again.

When an agent is running, it will regularly check the tasks it’s assigned to for new examples to annotate. This is especially useful if the task’s source is dynamic, e.g. if it fetches live data from an external database. If an agent is currently annotating, it will create a new session and show up with a “ live” marker in the app and as ANNOTATING in the tasks and agents overview.

If no new examples arrive for 5 minutes, the agent is shown as idle but keeps checking for work. When new examples become available, it picks them up and continues in the same session. To shut the agent down automatically instead, you can use the idle_shutdown_seconds setting of agents that expose it or add it to your agent recipes. The agent then stops once none of its tasks has had anything to annotate for that long, even if the tasks are still running. A value of 0 keeps it running until you stop it.

Read more

Annotation

Labelling data using Prodigy

Datasets

Annotated data in the database

Workers

Task, actions, agents and services can have different cloud hardware requirements and may require a high-performance CPU or GPU to run or train machine learning models. When starting a job, you can customize the worker class to be used so that the cluster can provision the required workers. For example, you can change the worker used by an action by clicking the arrow on the Start action button or by setting the --worker-class argument on the CLI.

Selecting a worker
$ellf

actions

start

"My first action"--worker-class gpu

By default, the cluster is set up to provide the workers base, small, medium and gpu. See the cluster documentation for more details on their specs and how to define custom workers.


Job statuses

Tasks, actions, agents and services all report a status that tells you where the job currently is in its lifecycle. It’s shown next to the job’s name in the app, and you can filter the overview pages by it.

STARTEDThe job is running. For tasks, this means the annotation app is ready to use.
ANNOTATINGAgents: the agent is running and currently annotating examples.
IDLEAgents: the agent is running but there are no new examples right now.
STARTINGTasks: the job and annotation app are starting up, but not ready yet.
STOPPINGThe job is shutting down after stopping it in ClusterJobs.
NOT_FOUNDThe job doesn’t exist on the cluster, usually because it hasn’t been started yet.
STOPPEDThe job was stopped from the app or via the CLI.
COMPLETEThe job finished successfully, the typical end state of an action.
PENDINGThe job is waiting to be scheduled, e.g. while a new worker is provisioned.
BLOCKEDThe cluster can’t start the job, e.g. if no node has resources for the worker.
CRASHINGThe job is running but unhealthy, e.g. because it keeps crashing on startup.
FAILEDThe job exited with an error and won’t recover on its own.

If a job is BLOCKED, CRASHING or FAILED, the job page shows an alert with the reason reported by the cluster, e.g. that the job ran out of memory or was evicted from its node, together with a hint on how to fix it. The monitoring module can also help you diagnose the problem from your coding assistant.


Monitoring and observability

The monitoring module lets you check in on the status of your running tasks, actions, agents and services. It can report scores and potential problems for actions like model training, task state, progress and activity for annotation tasks and annotation agents, as well as the overall cluster health.

✳︎Claude Code: Checking on a training action
› /ellf-monitor How’s the NER training going?
⏺︎
Jobner-product-names-v2 (action)
Staterunning — step 800
Best score0.81 (ents_f) at step 720
Train loss0.52 (stable)
AlertsNone

Training looks healthy. The score has been improving steadily and there are no signs of overfitting or loss instability.

For each task, action, agent or service, you can also view the log output in the Logs tab or on the CLI via tasks logs, actions logs, agents logs and services logs. In custom recipes, you can use Python’s logging utility or regular print statements to add entries to the logs.

Read next
Assets & Files

from the makers of spaCy and Prodigy

Navigation

  • Home
  • Documentation

Platform

  • Pricing
  • Free Trial

Use Cases

  • Prodigy
  • Universities

Resources

  • Case Studies
  • Blog
LoginTerms & ConditionsPrivacy PolicyImprint© 2026 Explosion