Build a first project
This page builds a small support-triage project from empty templates. The AI reads a support ticket and sorts it into the right category, and a grader checks its answer. It ends up the same shape as the finished support queue project, so you can compare your work with it at any point.
Prefer to start from the finished project? Download it and follow the support queue tutorial instead.
You need Plural installed; see Install.
Create the project
A project is the folder that holds everything you build.
plural project init support-queuecd support-queueThis works offline. It creates project.yaml, plural.lock, pyproject.toml, README.md, and a .gitignore that leaves out .plural/, where Plural keeps the records of your runs and other local state. Commit plural.lock; Plural updates it when you push.
Scaffold the resources
Each building block gets its own template. You will create five:
- an Environment called
support-queue: the world, a help desk with tickets, - a Verifier called
correct-category: the grader, which checks the category, - a Task called
ticket-1: one assignment, a single ticket to sort, - a Benchmark called
support-triage: the exam, which groups the Tasks, and - an Agent called
careful: the contestant, a model plus its instructions.
plural env init support-queue --python --bareplural verifier init correct-categoryplural task init ticket-1 --environment support-queue --verifier correct-categoryplural benchmark init support-triageplural benchmark add ticket-1 --benchmark support-triageplural agent init careful --model openai/gpt-5.6-lunaEach init command writes one folder, such as environments/support-queue/ or tasks/ticket-1/, and marks every place you must fill in with PLURAL-TODO:
environments/support-queue/environment.py: the App. What it holds (its State), the moves it can make (its@actionmethods), and what each move returns, which is all the AI sees. Keep the answers on State, never in what an action returns. Mark the fields a Task sets withinitial().environments/support-queue/README.md: what the world is and how to use it.verifiers/correct-category/verify.py: compare how things ended with what the Task asked for, and return a score from 0 to 1 with evidence.tasks/ticket-1/instruction.md: what the AI must accomplish, in plain language. Set the Task's starting State underinitial_stateintask.yaml.benchmarks/support-triage/benchmark.yamland itsREADME.md: thepurpose, and what a score means inscoring.description.
Also write the Agent's instructions in agents/careful/agent.yaml. The Agent has no harness, so it plays with native, Plural's built-in tool loop.
The finished files in the support queue tutorial show one way to fill in each of these.
Good to know: The new Environment uses thelocalruntime, which runs it as a subprocess on your machine. That needs no setup, and it is not a sandbox. To keep the AI's world in a sealed container, setruntime.provider: docker; see Runtimes.
Validate and run
Check your work, preview the run, run it, and look at the result:
plural benchmark validate support-triageplural run --benchmark support-triage --agent careful --dry-runplural run --benchmark support-triage --agent carefulplural job show <job-id>validatechecks a resource and everything it depends on, and lists everyPLURAL-TODOyou left unfinished. Unfinished places don't stop a local run, butpushand--recordrefuse them.--dry-runshows the plan without running anything.- The real run calls the model through the Plural gateway, so it needs a Plural API key (
plural auth login,plural auth login --api-key-stdin, orPLURAL_API_KEY). The run prints the Job id to pass toplural job show.
To run without any credential, add a Harness that calls no model and an Agent with auth: none, like the scripted Agent in the finished project.
Next steps
To add more tickets, repeat plural task init and plural benchmark add, or list them as cases and write them all with plural task cases.
When you want to see runs in the web app, register the project with plural project init support-queue --push and add --record to plural run. The support queue tutorial covers both. Pushing never makes anything public.