Centraltec

AI DevelopmentAI Consulting

Multi-agent workflows in Cursor: a tutorial built around one example

How to coordinate several AI agents in Cursor: rules, subagents, worktrees and cloud agents – explained step by step on an audit log feature, with a focus on context and token usage.

Illustration: several AI agents working in parallel on one codebase

A single AI agent gets surprisingly far in a small codebase. In a mature project that breaks down at some point: the agent searches files, reads test output, tries variants – and eventually the context window is full. Answers get vaguer, the agent forgets earlier decisions, and every further step costs more.

Multi-agent development is the answer to that. Several agents share one task, each with its own context. One expectation is worth correcting right away: the main benefit is context isolation, not speed. Five parallel agents consume roughly five times the tokens of a single agent, and on simple tasks they are even slower, because each one starts from zero. (Cursor Docs)

This tutorial walks through a complete workflow, using an example close to typical projects.

The example: an audit log for a customer portal

The starting point is an existing customer portal: Next.js on the front end, FastAPI on the back end, PostgreSQL as the database, around 60,000 lines of code. The business side wants an audit-proof log: every write action is recorded, administrators see a filterable table, and auditors can export the data as CSV.

The task splits into four parts that need very different amounts of context:

This split is exactly why several agents pay off here. Research produces a lot of intermediate material nobody needs later. Back end and front end touch separate files. The review should be done by someone who did not write the code.

Why one agent alone hits a wall

Before starting, it is worth looking at the context ring – the circular indicator next to the input field. Clicking it opens a breakdown of how the context window is currently filling up. Cursor distinguishes between system prompt, tool definitions, rules, skills, MCP servers, subagent descriptions, summarised earlier turns and the running conversation, among others. (Cursor Docs)

What matters is which parts grow. The system prompt and tool definitions are largely constant. Rules and MCP catalogues are configured once – but they then cost tokens on every request. What really explodes is the conversation itself: every search result, every file read, every test output stays in context.

When space runs short, Cursor automatically compresses older parts of the conversation into a summary (compaction). That saves the session but costs detail. It is better not to let the context fill up in the first place.

Step 1: rules as the shared foundation

Every subagent starts with an empty context. It knows neither the previous conversation nor the project conventions. Anything all agents must know therefore belongs in rules, not in the chat.

Project rules live as .mdc files under .cursor/rules/. Only this extension is recognised; a .md file in the same folder is ignored by Cursor because it has no frontmatter. For plain markdown, AGENTS.md is the intended place. (Cursor Docs)

For our example, the back end needs a rule that only applies to back end files:

---
description: Conventions for FastAPI endpoints and Alembic migrations
globs: backend/**/*.py, backend/alembic/**
alwaysApply: false
---

# Back end conventions

- Every endpoint gets a Pydantic response model, never a bare dict.
- Migrations are generated with `alembic revision --autogenerate` and then
  reviewed by hand. Never edit a migration directly after it has been
  deployed.
- Write endpoints go through `require_role("admin")`.

Which rule type this becomes follows from the combination of the three frontmatter fields:

Three details that regularly cause trouble in practice:

Multiple glob patterns are separated by commas, not by line breaks or array syntax: globs: docs/**/*.md, docs/**/*.mdx.

A file mention inside a rule does not inline its content. Writing @migration-template.sql in a rule only tells the agent where to look. It reads the file when it needs it. That saves tokens, but it also means anything that must always apply belongs directly in the rule body.

alwaysApply: true is expensive. These rules land in every single request, including every subagent. Cursor recommends keeping rules under 500 lines and splitting large rule sets. In our example only a small always-rule with project structure and the test command remains; everything domain-specific hangs off globs.

On top of that there is AGENTS.md – plain markdown in the project root and additionally in subfolders. Nested files are combined with their parents, with the more specific one taking precedence. For our portal there is a general AGENTS.md in the root plus one each in frontend/ and backend/.

Two limitations are worth knowing: user rules do not apply to Inline Edit via Cmd+K, and project rules from .cursor/rules/ do not apply to Bugbot runs – Bugbot reads .cursor/BUGBOT.md.

Step 2: plan first, delegate second

Shift+Tab switches from the input field into Plan Mode. Cursor asks clarifying questions, researches the codebase and produces a plan you refine in the chat or as a markdown file. By default, plans are stored in the home directory; "Save to workspace" puts them into the project instead. (Cursor Docs)

For multi-agent work this step is not optional, it is the precondition. The plan is the only artefact all subagents share – each one receives the relevant excerpt in its prompt. Without a plan you describe the same task four times in prose and get four slightly different interpretations.

A useful pattern from the documentation: if an agent built the wrong thing, it is often more effective to discard the changes and sharpen the plan than to steer a running agent.

Step 3: offload the research

Research has the worst ratio of effort to lasting value. Twenty files get read, three of them are relevant – the rest clogs the context. That is exactly what the built-in Explore subagent is for; it runs on a faster model by default and can perform many searches in parallel. (Cursor Docs)

Call it explicitly rather than hoping the main agent delegates:

Use three Explore subagents in parallel:

1. Find every place where write requests pass through middleware.
   Return file paths, function names and the middleware order.
2. Describe how Alembic migrations are organised in this repo: location,
   naming convention, how they run during deployment.
3. Find the existing table components in the front end including filtering
   and pagination. Return paths and props signatures.

Summarise in at most 15 lines per agent. No code excerpts.

Three things happen here deliberately. The agents run simultaneously, because the main agent sends several calls in one message. Each works in its own context window and returns only its final message – the twenty files it read stay with it. And the length limit in the prompt is not a style preference but cost control: whatever comes back is paid for in the main context.

Because subagents start without prior knowledge, the prompt must contain everything needed. "Continue as discussed" does not work. Every run returns an agent ID, which lets you resume a subagent later without it exploring everything again.

Step 4: work in parallel – but not in the same directory

Here comes the trap that ruins most first multi-agent attempts: by default, subagents share the main agent's working directory. Two agents writing at the same time overwrite each other.

Isolation has to be requested explicitly. Each agent then gets its own git worktree – a second working directory of the same repository on its own branch – or, in the cloud case, its own virtual machine.

In the editor, worktrees are driven by slash commands: /worktree runs the rest of the chat in a separate checkout, /apply-worktree brings the changes back into the main folder, /delete-worktree cleans up. There is also /best-of-n, which runs the same task across several models – each run in its own worktree, for comparison rather than automatic merging. (Cursor Docs)

For a fresh worktree to be immediately usable it needs a setup step, defined in .cursor/worktrees.json:

{
  "setup-worktree-unix": [
    "pnpm install --frozen-lockfile",
    "cp $ROOT_WORKTREE_PATH/.env.local .env.local",
    "uv sync --project backend"
  ]
}

The $ROOT_WORKTREE_PATH variable points at the main checkout – handy for copying local configuration files that are not in the repository. The documentation explicitly warns against sharing dependencies via symlinks; that damages the main worktree. Use fast package managers such as pnpm, bun or uv instead.

For our audit log this means the back end agent and the front end agent run in separate worktrees, on separate branches. The main agent merges the results.

If you prefer to stay in the editor, /multitask lets several asynchronous subagents work at once instead of queueing your requests. From a finished plan there is a Build in Parallel button: independent steps start simultaneously, dependent ones stay in order. Full worktree management with a user interface lives in the Agents Window, reachable via Cmd+Shift+P and "Open Agents Window".

Step 5: define your own subagents

For recurring roles, a custom subagent type pays off. These are markdown files with frontmatter under .cursor/agents/ in the project, or ~/.cursor/agents/ for all projects. Project takes precedence over user. (Cursor Docs)

For the audit log we set up a reviewer that explicitly must not change anything:

---
name: migration-reviewer
description: Reviews Alembic migrations for backward compatibility. Always
  use when a migration has been created or changed.
model: inherit
readonly: true
---

You review database migrations in a running system.

Check in this order:
1. Can the migration run without locking a large table? Name the offending
   line if not.
2. Is a downgrade implemented and correct?
3. Can the old and new application version run against this schema at the
   same time?
4. Are columns dropped or renamed? That is only acceptable in two steps.

Answer with a list of findings, each with file, line, severity and a
suggestion. Do not make changes.

The key frontmatter fields are name (lowercase and hyphens), description (controls when work is delegated automatically), model (inherit or a model ID), readonly and is_background. The model accepts parameters in square brackets, for example a larger context window via [context=300k].

readonly: true is more than a safety measure. A reviewer that cannot fix things reports problems instead of quietly overwriting them – and the decision stays with you. Invoke it with /migration-reviewer or simply by describing the task. To skip the file format entirely, use the built-in /create-subagent skill.

For the distinction: a subagent pays off when you need separate context, parallelism or independent verification. A skill is the better choice for a repeatable one-off action that does not need its own context window.

Step 6: cloud agents for anything long-running

Cloud agents – formerly background agents – run in isolated virtual machines on Ubuntu, with a cloned repository, installed dependencies and network access. They work on their own branch and push the result as a pull request. (Cursor Docs)

You can start them from the desktop client via the dropdown under the input field, via cursor.com/agents, from the iOS app, with @cursor in Slack, as a comment on a GitHub or Bitbucket pull request, from Linear, or through the API. This requires an account admin to have connected source control, and a plan that includes cloud agents – the free tiers do not.

The environment is described in .cursor/environment.json:

{
  "install": "pnpm install --frozen-lockfile && uv sync --project backend",
  "start": "sudo service postgresql start",
  "terminals": [
    { "name": "api", "command": "uv run uvicorn app.main:app --reload" },
    { "name": "web", "command": "pnpm dev" }
  ]
}

The install command runs on every build and must therefore be idempotent. Only the disk state is preserved – running processes, exported shell variables and in-memory caches do not survive the build. As an alternative to the install step, a Dockerfile or a snapshot can be referenced.

In our example a cloud agent takes the thankless work: run the existing 340 tests against the new schema, fix the fallout, test the migration against a copy of the database. That takes time, but it blocks neither a local agent nor a local machine.

Two capabilities are particularly worthwhile. Cloud agents attach artifacts to the pull request – screenshots, videos, logs – so you can see how the agent verified its work. And through subscriptions an agent ends its turn and wakes up when an event arrives: a CI result, a comment on the pull request, a Slack reply.

Differences from local agents worth planning for: hooks only work as command-based hooks from .cursor/hooks.json in the repository, not from the user directory. MCP servers come from the team configuration, not from your local session. Personal skills are only transferred when "Sync Skills for Cloud Agents" is enabled – putting skills under .cursor/skills/ in the repository is more reliable.

Step 7: minimising tokens

The levers differ in impact. In this order they pay off:

1. Isolate context instead of sharing it. The biggest lever. Research, test runs and debugging produce a lot of intermediate material. If that lands in a subagent, you pay for it once – and not again in every further step of the main conversation.

2. Limit what comes back. A subagent returns exactly one final message. How long it is depends on the prompt. "At most 15 lines, no code excerpts" is a cost decision.

3. Attach rules correctly. Anything that does not truly always apply gets globs instead of alwaysApply: true. A 300-line rule riding along on every request costs more over a working day than the rest of the setup combined.

4. Match model and context window to the task. Searching and routine work run well on fast models; deep reasoning needs the stronger one. A large context is not a default but a deliberate per-task decision – previously via Max Mode, today via the choice of context window size or parameters such as [context=300k].

5. Attach deliberately or not at all. @ mentions for files and folders only pay off when you actually know the relevant files. If that is unclear, leave them out – the agent's own search usually finds less material, but more fitting material. Available are files and folders, @Terminals, @Chats, git diffs via @Commit and @Branch, and @Browser.

6. Side chats for interim questions. /side or Shift+Cmd+S opens a side thread that uses the main history as hidden background without lengthening the main transcript. You pull the result back with an @ mention.

7. Exclude ballast. .cursorignore uses .gitignore syntax and keeps files out of agent, tab, inline edit and @ mentions. One limitation to know: the agent's terminal and MCP tools cannot be reliably blocked by it – so the file is not a security boundary.

And the most important lever is a negative one: do not parallelise what is cheaper sequentially. For a change across two files, a single agent is faster and cheaper than three coordinated ones.

Common mistakes

The subagent knows nothing. It starts with empty context. References to "the file from earlier" go nowhere. Every prompt has to stand on its own.

Two agents, one working directory. Without explicitly requested isolation, parallel subagents write into the same checkout.

Parallelism as a reflex. Five agents cost five times as much. That pays off for separate work areas – not for a small change.

Rules as a documentation dump. Rules are not a wiki. Cursor explicitly recommends not copying entire style guides into them – that is what the linter is for – and creating a rule only once the agent repeatedly makes the same mistake.

Review by the author. An agent assessing its own code finds little. A second agent with readonly: true, or a run of /agent-review, finds considerably more.

Conclusion

Multi-agent work in Cursor is not a switch you flip but a division of labour you design. The pattern that holds up in practice is always the same: rules set the shared foundation, a plan makes the task divisible, subagents absorb everything with lots of intermediate material, worktrees prevent collisions, cloud agents take the long runs, and an independent reviewer looks it over at the end.

Token usage then follows almost by itself. Distributing context deliberately, instead of letting it grow inside one long conversation, produces better results at lower cost. The order matters: settle the division of labour first, then turn the dials.

Sources

  1. Cursor: Subagents – file format, frontmatter, parallelism, cost. (Cursor Docs)
  2. Cursor: Prompting agents – context ring, compaction, @ mentions. (Cursor Docs)
  3. Cursor: Rules – rule types, frontmatter, best practices. (Cursor Docs)
  4. Cursor: Plan Mode. (Cursor Docs)
  5. Cursor: Worktrees – slash commands and worktrees.json. (Cursor Docs)
  6. Cursor: Cloud Agents and environment setup. (Cursor Docs)
  7. Cursor: Agent Skills – skill versus subagent. (Cursor Docs)
  8. Cursor: Agents Window – multi-workspace and parallel agents. (Cursor Docs)

← Back to news