Skip to content

How to Run Parallel AI Coding Agents on One Python Project

Run each AI coding agent in its own git worktree, and give each worktree its own uv environment. A worktree is a second working directory on its own branch, backed by the same .git store. One uv sync per worktree produces an isolated virtual environment, so Claude Code, Codex, and Cursor can work in parallel, each on its own branch and in its own .venv, without sharing a working tree.

Confirm your starting point

You need an existing uv project with a pyproject.toml (the first uv sync creates the uv.lock and .venv if you don’t have them yet), uv installed, and git 2.17 or newer, which is where git worktree remove landed. Run these commands from the root of that project.

Create a worktree for each agent

Add one worktree per task, each on a fresh branch:

git worktree add ../myproject-auth -b agent-auth
git worktree add ../myproject-docs -b agent-docs

Each command creates a sibling directory (../myproject-auth) checked out to a new branch (agent-auth). Creating a worktree is cheap: it links to the existing .git store instead of copying history.

List what you have:

git worktree list
/path/to/myproject        a1e219e [main]
/path/to/myproject-auth   a1e219e [agent-auth]
/path/to/myproject-docs   a1e219e [agent-docs]

Give each worktree its own environment

Each worktree is a separate checkout, so give each its own environment rather than sharing one. A .venv records absolute paths tied to the directory it was created in, and for a workspace, sharing one sends imports to the wrong source tree (Keep uv workspaces isolated across worktrees).

cd ../myproject-auth
uv sync
Creating virtual environment at: .venv
Installed 7 packages in 3ms

The first uv sync populates uv’s global cache. Every later sync, including ../myproject-docs, hardlinks from that cache: a small project finishes in a few milliseconds, a large dependency set (torch, numpy) in seconds.

cd ../myproject-docs
uv sync

Add .venv/ to your .gitignore if it is not already there. Worktrees share one .git object store, so an agent that commits its .venv bloats that store for every worktree, and the bloat survives even after you delete the branch.

Tip

Wrap both steps in a shell function so spinning up a new agent is one command:

new-agent() { git worktree add "../$1" -b "$1" && (cd "../$1" && uv sync); }
# new-agent agent-auth

Point each agent at its worktree

Open a separate terminal per worktree, cd into it, and start the agent there. For terminal agents like Claude Code and Codex:

cd ../myproject-auth && claude   # or: codex

For Cursor, open the worktree as a folder (File > Open Folder, then select ../myproject-auth) so the editor and its agent operate on that branch.

An agent started in the worktree runs its shell commands against that branch and .venv. For a uv project, uv run and uv sync select the .venv at the worktree (project) root, so uv run pytest from ../myproject-auth tests the agent-auth branch in its own environment. To make Claude Code activate that .venv before running tools, see How to configure Claude Code to use virtual environments; the same principle applies to Codex and Cursor.

Warning

If UV_PROJECT_ENVIRONMENT is set in the agent’s environment, especially to an absolute path, uv uses that one environment for every worktree and collapses the isolation. Unset it so each worktree gets its own .venv.

Keep uv workspaces isolated across worktrees

A uv workspace keeps its .venv and uv.lock at the workspace root. In a worktree, that root is the worktree’s own directory, so uv sync there builds a self-contained environment whose members resolve from that worktree’s source. No extra configuration is needed.

Don’t share one .venv across worktrees to save disk. Workspace members install as editable, so the environment stores an absolute path to one worktree’s source. A second worktree pointed at that shared environment imports the first worktree’s code:

# Correct: each worktree's own uv sync
wt-auth resolves shared_lib -> /path/to/myproject-auth/packages/shared-lib/src
wt-docs resolves shared_lib -> /path/to/myproject-docs/packages/shared-lib/src

# Broken: myproject-docs pointed at myproject-auth's shared .venv
myproject-docs imports shared_lib -> /path/to/myproject-auth/packages/shared-lib/src

An edit in one agent’s worktree then silently changes what the other runs. A separate uv sync per worktree costs little from uv’s cache and keeps each pointed at the right source.

Review and merge each agent’s work

Each agent’s changes live on its own branch. Review one worktree’s commits, then merge the branch or open a pull request:

git -C ../myproject-auth log --oneline main..agent-auth
git switch main && git merge agent-auth

When several agents finish at once, open a pull request per branch (gh pr create from each worktree) so the reviews stay separate. Enough Git to Supervise Your AI Coding Agent covers branches and pull requests in more depth.

Clean up a worktree when the agent is done

After merging a branch, remove its worktree and delete the branch:

git worktree remove ../myproject-auth
git branch -d agent-auth

git worktree remove deletes the directory, including its .venv. If an agent left uncommitted changes, git refuses to remove the worktree; inspect them first, then pass --force if you want to discard them.

Learn More

Last updated on