Have you been using Background Agent without being quite sure you're using it effectively? You start a task, wait for it to finish, get results that are close but not quite right, and repeat. At some point you start wondering if it's actually worth the effort.
I felt the same way in my first couple of weeks. The turning point came when I stopped treating Background Agent as "async chat" and understood what it actually is at an architectural level. Once I redesigned my task specifications, set up a proper AGENTS.md, and integrated git worktrees, the difference was significant enough to reshape how I structure my development days.
Why Background Agent Is Architecturally Different From "Just Async"
The most important thing to understand about Background Agent is that it runs in a fully isolated Linux virtual machine — not as an async process in your existing environment.
Inside the Sandbox VM
When you launch a Background Agent, Antigravity takes a snapshot of your repository and spins up an isolated VM. This VM:
- Has no direct access to your local environment
- Can reach the internet but cannot connect to your localhost (localhost:3000, local databases, etc.)
- Writes all file changes within its own filesystem, delivering them back as a pull request or commit when complete
- Has no access to your browser's devtools, running processes, or visual rendering
This isolation is both the strength and the constraint. Tasks that require visual feedback, local service connections, or interactive dialogue are a poor fit. Tasks that involve analyzing code, writing tests, generating documentation, or systematic refactoring are where Background Agent consistently delivers.
Choosing Between Background Agent and Inline Agent
Here's the decision framework I use:
Background Agent is the right choice when:
- The task will take more than 5 minutes to complete
- You can fully articulate the success criteria before starting
- The task doesn't depend on your running local environment
- You can productively use the time the agent is working
Inline agent is the right choice when:
- The task requires back-and-forth dialogue
- You need to see visual output as the work progresses
- The task will complete in under 10 minutes
- Design decisions will need to be made mid-task
The "can you articulate success criteria?" question is the most important filter. Vague instructions produce vague results. Clear, testable completion conditions are the single biggest factor in Background Agent output quality.
Designing Task Specifications That Actually Work
Background Agent instructions work nothing like interactive chat. Without the ability to ask clarifying questions mid-task, the quality of your initial specification directly determines the quality of the output.
The Task Specification Template
Here's the template I use for every Background Agent task. My success rate went from roughly 70% to above 90% after adopting this structure:
## Goal
Increase test coverage for the UserProfile component to 80% or above.
Current coverage: approximately 35% (verified with `npx vitest coverage`)
## Target Files
- src/components/UserProfile.tsx (primary target)
- src/components/UserProfile.test.tsx (create or extend)
- src/types/user.ts (reference only, do not modify)
## Testing Framework
- vitest + @testing-library/react
- Use vi.mock() for mocks
- Use @testing-library/user-event for user interactions
## Completion Criteria (all must be satisfied)
1. Coverage reaches 80%+ with `npx vitest coverage`
2. All existing tests pass without modification
3. Zero TypeScript build errors with `npx tsc --noEmit`
4. Each test case has a descriptive describe and it label
## Constraints
- Do not modify existing props interfaces in UserProfile.tsx
- Do not use real endpoint URLs in API mocks
- Do not create snapshot tests (maintenance cost too high)
## Reference
- Auth.test.tsx (src/components/Auth.test.tsx) is a good style reference
- Run tests with: `npx vitest run --reporter=verbose`The Constraints section is what most people skip, and it's what causes the most unpleasant surprises. Background Agent will try to be helpful in ways you didn't ask for. Explicitly stating what not to change prevents the majority of "it fixed this but broke that" situations.
Getting Task Granularity Right
Tasks that are too large are where Background Agent struggles most:
# ❌ Too large — high failure risk
"Refactor the entire project to improve type safety"
# ✅ Right size — completes within a focused session
"Add zod schema validation to all API client functions in src/api/,
validating both inputs and return values"In my experience, Background Agent performs most reliably on tasks equivalent to 1–3 hours of human effort. Tasks that would take half a day or longer are better broken into subtasks and run sequentially. The total time is often shorter because each subtask succeeds cleanly rather than getting tangled.
Pre-loading Context Before Launch
Before starting a Background Agent task, add relevant files as Knowledge Items. The most impactful ones to include:
- Architecture documentation
- Coding conventions and style guides (CONTRIBUTING.md)
- Relevant type definition files (types/ directory)
- Notes on error-prone areas
This is especially valuable for projects with non-obvious constraints. Telling the agent what the project is before it starts reading code reduces both the token usage and the likelihood of wrong assumptions early on.
Designing AGENTS.md to Auto-Inject Project Context
Having to explain your project's constraints in every single task specification is inefficient. A well-designed AGENTS.md is injected automatically into every agent session, eliminating the need for repetitive context-setting.
A Production-Ready AGENTS.md
# Project: MyApp — Agent Working Guidelines
## About This Project
A personal task management SaaS built with Next.js 16 App Router + TypeScript
+ Cloudflare Workers. Bilingual support (English/Japanese) via next-intl v4.
## Critical Technical Constraints
- No Node.js built-ins (Cloudflare Workers environment)
- No `fs` module — all file I/O goes through the ASSETS binding
- `npm run build` requires `node scripts/generate-content.mjs` first
(already configured in prebuild hook — do not remove)
- Test runner: vitest (not Jest — different configuration)
## Coding Conventions
- Type definitions centralized in src/types/
- Mark components as Server/Client explicitly ('use client' directive)
- API routes in src/app/api/, named route.ts
- Prefer descriptive variable names over abbreviations
## Common Mistakes to Avoid
### ❌ Typical errors
- Calling `headers()` synchronously → requires async/await
- Using `cookies().set()` in client components → server components only
- Importing from 'fs' → use ASSETS binding instead
### ✅ Correct patterns
- Environment variables: process.env.NEXT_PUBLIC_* (client) / process.env.* (server)
- Database access: getCloudflareContext().env.DB
## Test Commands
\`\`\`bash
npx vitest run # Run all tests
npx vitest coverage # Coverage report
npx tsc --noEmit # Type check only
\`\`\`
## Files That Must Not Be Modified
- src/config/pricing.ts (contains Stripe price IDs)
- public/robots.txt (SEO configuration)
- wrangler.toml (Cloudflare deployment config)The difference this makes is hard to overstate. Agents no longer need to discover your constraints by running into them — they know upfront.
Directory-Level AGENTS.md
You can place AGENTS.md files in subdirectories as well as at the project root. My typical structure:
project/
├── AGENTS.md ← Project-wide rules
├── src/
│ ├── components/
│ │ └── AGENTS.md ← UI component design rules
│ └── api/
│ └── AGENTS.md ← API route conventions
└── scripts/
└── AGENTS.md ← Notes on script modifications
Running Multiple Background Agents in Parallel
A single Background Agent is already powerful. Multiple agents running simultaneously can meaningfully compress development timelines — but only if you manage file ownership carefully.
Identifying Safe Parallel Tasks
Parallel execution is safe when the tasks have non-overlapping file scope:
# ✅ Safe to run in parallel
Agent A: Add tests in src/components/
Agent B: Add validation in src/api/
Agent C: Update documentation in docs/
# ❌ Dangerous — likely to conflict
Agent A: Improve types in src/types/user.ts
Agent B: Refactor UserProfile component
(both will likely modify user.ts)
Before launching parallel agents, map out which files each task will touch. Any overlap is a signal to serialize those tasks or further refine their scope.
Git Worktree Integration
Git worktrees let each agent work on a completely independent copy of the repository, eliminating merge conflicts during execution. Each agent gets its own branch and filesystem, merging back to main only when both are done.
#\!/bin/bash
# setup-parallel-agents.sh
PROJECT_DIR="$HOME/myapp"
WORKTREES_DIR="$HOME/myapp-worktrees"
mkdir -p "$WORKTREES_DIR"
# Create isolated worktrees for each parallel task
declare -A TASKS=(
["test-coverage"]="Add test coverage to src/components/"
["api-validation"]="Add zod validation to src/api/"
["docs-update"]="Update API documentation in docs/"
)
for task in "${\!TASKS[@]}"; do
branch="agent/${task}-$(date +%Y%m%d-%H%M)"
worktree_path="$WORKTREES_DIR/$task"
# Remove any leftover worktree from previous run
git -C "$PROJECT_DIR" worktree remove "$worktree_path" --force 2>/dev/null || true
# Create fresh worktree from main
git -C "$PROJECT_DIR" worktree add \
-b "$branch" \
"$worktree_path" \
main
echo "✅ Worktree ready: $worktree_path"
echo " Branch: $branch"
echo " Task: ${TASKS[$task]}"
done
git -C "$PROJECT_DIR" worktree listAfter all agents complete:
#\!/bin/bash
# merge-agent-results.sh
PROJECT_DIR="$HOME/myapp"
WORKTREES_DIR="$HOME/myapp-worktrees"
for task in "test-coverage" "api-validation" "docs-update"; do
worktree_path="$WORKTREES_DIR/$task"
if [ \! -d "$worktree_path" ]; then
echo "⚠️ Worktree not found: $task — skipping"
continue
fi
branch=$(git -C "$worktree_path" rev-parse --abbrev-ref HEAD)
echo "Merging $branch..."
# Run tests before merging
cd "$worktree_path"
if \! npm test -- --passWithNoTests 2>/dev/null; then
echo "❌ Tests failed in $task — skipping merge"
continue
fi
# Merge into main
git -C "$PROJECT_DIR" merge --no-ff "$branch" \
-m "feat: agent/$task auto-generated changes"
# Clean up
git -C "$PROJECT_DIR" worktree remove "$worktree_path"
git -C "$PROJECT_DIR" branch -d "$branch"
echo "✅ Merged and cleaned up: $task"
doneFor more on git worktree workflows, see Antigravity × git worktree Parallel Development Guide.
Monitoring, Error Handling, and Recovery
Background Agents are designed to run unattended, but "set it and forget it" isn't the full story — especially for long-running tasks. Knowing when and how to check in is what separates reliable results from occasional disappointments.
Effective Checkpoint Usage
Antigravity saves periodic checkpoints during execution. When a task fails mid-way, you can resume from the most recent checkpoint rather than starting over.
My recommended check-in schedule:
- 5–10 minutes after launch: Confirm the agent understood the task correctly
- Midpoint: Verify the approach aligns with your intent
- At completion: Confirm all stated completion criteria are satisfied
If the early check-in shows the agent heading in the wrong direction, it's almost always faster to cancel and relaunch with a clearer specification than to let it continue.
Common Failure Patterns and Fixes
Pattern 1: Context starvation — agent goes in circles
Symptom: No meaningful progress after a long runtime. Agent appears to be retrying the same approach repeatedly.
Root cause: Insufficient project context. The agent is discovering constraints by trial and error.
Fix: Improve AGENTS.md with specific notes about the area being worked on. Break the task into a smaller scope. Add a Knowledge Item with relevant architectural notes.
Pattern 2: Existing tests break
Symptom: The target code improved, but existing tests now fail.
Root cause: "Existing tests must pass" was not explicitly stated as a completion criterion.
Fix: Always include "all existing tests pass without modification" as a completion criterion. Instruct the agent to run the full test suite before starting work.
Pattern 3: TypeScript errors left in place
Symptom: Implementation works at runtime, but type errors remain.
Root cause: Type checking was not included in the completion criteria.
Fix: Always include npx tsc --noEmit shows zero errors as a required completion criterion.
Pattern 4: Unintended file modifications
Symptom: Files you didn't ask about were modified.
Root cause: Agent made "helpful" improvements beyond the task scope.
Fix: Explicitly list files and directories that must not be touched in the Constraints section.
Integrating Background Agent Into CI/CD
This is where Background Agent stops being a productivity tool and becomes infrastructure. Connecting it to GitHub Actions means certain classes of work happen automatically, without you thinking about them.
Automated Test Generation on PR Creation
When new components or API routes land in a pull request, a Background Agent automatically brings test coverage up to a minimum threshold:
# .github/workflows/auto-test-generation.yml
name: Auto Test Generation
on:
pull_request:
types: [opened, synchronize]
paths:
- 'src/components/**'
- 'src/api/**'
jobs:
check-and-generate-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run coverage check
id: coverage
run: |
set +e # Don't exit on test failure
npx vitest coverage --reporter=json 2>/dev/null
EXIT_CODE=$?
set -e
# Find files below 70% coverage threshold
LOW_COVERAGE=$(node -e "
try {
const report = require('./coverage/coverage-summary.json');
const low = Object.entries(report)
.filter(([f, d]) => f \!== 'total' && d.lines.pct < 70)
.map(([f]) => f)
.slice(0, 5)
.join(',');
console.log(low);
} catch(e) {
console.log('');
}
") || LOW_COVERAGE=""
echo "low_coverage_files=$LOW_COVERAGE" >> $GITHUB_OUTPUT
echo "Coverage check complete. Low coverage files: $LOW_COVERAGE"
- name: Launch Background Agent for test generation
if: steps.coverage.outputs.low_coverage_files \!= ''
env:
ANTIGRAVITY_API_KEY: ${{ secrets.ANTIGRAVITY_API_KEY }}
run: |
FILES="${{ steps.coverage.outputs.low_coverage_files }}"
PR_BRANCH="${{ github.head_ref }}"
echo "Launching Background Agent for: $FILES"
# Trigger Background Agent via API
# The agent will push its changes to the same PR branch
RESPONSE=$(curl -s -w "\n%{http_code}" \
-X POST "https://api.antigravity.google/v1/agents/background" \
-H "Authorization: Bearer $ANTIGRAVITY_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"task\": \"Increase test coverage to 80%+ for these files: $FILES. Use vitest. Keep all existing tests passing. Zero TypeScript errors.\",
\"branch\": \"$PR_BRANCH\",
\"auto_commit\": true
}")
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
if [ "$HTTP_CODE" \!= "200" ] && [ "$HTTP_CODE" \!= "201" ]; then
echo "⚠️ Background Agent launch returned HTTP $HTTP_CODE — continuing without auto-tests"
exit 0 # Non-blocking: don't fail the PR
fi
echo "✅ Background Agent launched successfully"Automated Documentation Updates on Merge
When API routes change, documentation should change too. This workflow triggers a Background Agent to update the relevant docs automatically:
# .github/workflows/auto-docs-update.yml
name: Auto Documentation Update
on:
push:
branches: [main]
paths:
- 'src/app/api/**'
- 'src/types/**'
jobs:
update-api-docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
token: ${{ secrets.GH_PAT }}
- name: Identify changed API files
id: changes
run: |
CHANGED=$(git diff HEAD~1 HEAD --name-only \
-- 'src/app/api/**' 'src/types/**' \
| head -10 | tr '\n' ',')
echo "files=$CHANGED" >> $GITHUB_OUTPUT
echo "Changed files: $CHANGED"
- name: Trigger documentation update
if: steps.changes.outputs.files \!= ''
env:
ANTIGRAVITY_API_KEY: ${{ secrets.ANTIGRAVITY_API_KEY }}
run: |
CHANGED="${{ steps.changes.outputs.files }}"
COMMIT_SHA="${{ github.sha }}"
curl -X POST "https://api.antigravity.google/v1/agents/background" \
-H "Authorization: Bearer $ANTIGRAVITY_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"task\": \"The following files changed in commit $COMMIT_SHA: $CHANGED. Update the corresponding documentation in docs/api/ to reflect the changes. Add JSDoc comments to any new exported functions. Do not modify source files.\",
\"branch\": \"docs/auto-update-${COMMIT_SHA:0:8}\",
\"create_pr\": true,
\"pr_title\": \"docs: auto-update API documentation\",
\"pr_base\": \"main\"
}"For context engineering strategies that complement this CI/CD setup, see Antigravity Context Engineering Advanced Masterclass.
Cost Management and Optimization
Background Agent is powerful, but misused it can consume credits faster than expected. Here's what I've learned about keeping costs in check without sacrificing output quality.
Understanding Credit Consumption
Credit usage is driven primarily by:
- Context window size per step: Large AGENTS.md files and many Knowledge Items increase per-step consumption
- Number of retry attempts: When specifications are ambiguous, agents retry more, consuming more credits
- Output volume: Tasks that generate large amounts of code naturally cost more
In practice, the difference between a well-specified task and a vague one can be 2–3x in credit consumption due to retry reduction alone. Good specifications pay for themselves.
Practical Cost Optimization Techniques
Technique 1: Start small, calibrate first
Before delegating a large, expensive task, run a small version of it first. Get a feel for how the agent interprets your specifications and how many credits a task of that type consumes.
Technique 2: Invest in AGENTS.md to reduce retries
Better project documentation reduces agent retries. An hour spent improving your AGENTS.md will save credits on every subsequent task. This is the highest-ROI investment you can make.
Technique 3: Match agent type to task size
Background Agent has overhead — it's most efficient for tasks equivalent to 1–3 hours of human effort. For quick 5-minute tasks, the inline agent is often more credit-efficient. Use each tool for the tasks it's optimized for.
Technique 4: Monitor consumption by task type
After a few weeks of use, you'll have a feel for which task types are credit-efficient. Test generation tends to be efficient. Open-ended refactoring tasks tend to be less so. Optimize toward the patterns that give you the best output-per-credit ratio.
Real Production Use Cases
The most convincing evidence for any technique is seeing it work in practice. Here are the Background Agent workflows that have become a regular part of my development routine.
Use Case 1: Overnight Technical Debt Reduction
Launch a Background Agent before sleep, wake up to completed work:
## Task: Improve type safety in src/utils/
### Goal
For all files in src/utils/, achieve the following:
- Zero `any` type usage
- Explicit type annotations on all functions
- JSDoc comments on all exported functions and types
### Completion Criteria
1. `npx tsc --noEmit` shows zero errors
2. `grep -r ": any" src/utils/` returns no results
3. All existing tests pass
4. Every exported function has @param and @returns JSDoc
### Out of Scope
- src/utils/legacy/ (scheduled for separate migration)
- Test mock filesUse Case 2: Rapid Prototyping New Features
Use Background Agent to generate an implementation scaffold, then review and refine:
## Task: Initial implementation of notification settings page
### Goal
Create a working implementation of /settings/notifications.
Reference: Mockup.png (attached as Knowledge Item)
### Implementation Scope
- NotificationSettings component
- State management with Zustand store
- Toggle UI for 4 notification types: email, push, in-app, digest
### Deliberately Out of Scope (implement later)
- Actual notification delivery logic (backend not ready)
- Animations
- Mobile-specific layout
### Completion Criteria
1. Page renders without errors
2. Zero TypeScript errors
3. Toggle state persists to Zustand store
4. Basic accessibility attributes present (aria-label, role)Getting a working scaffold from Background Agent and then refining it yourself is consistently faster than building from scratch — you're editing rather than authoring.
Moving Forward
Using Background Agent effectively is fundamentally about clear communication. The agents that "just work" are the ones where the specification left no room for ambiguity about what success looks like.
The most useful next step is to find one task in your current development backlog that meets the criteria: completable in under 3 hours, testable completion conditions, no dependency on your running local environment. Write a specification using the template from this article, and run it.
The feedback loop from that first well-specified task will tell you more than anything else here could.
Advanced AGENTS.md Patterns for Large Codebases
Once your project grows beyond a certain size, a single root-level AGENTS.md starts to feel insufficient. Here are the patterns I've developed for keeping agent context accurate at scale.
The Layered Context Architecture
The most effective setup I've found for medium-to-large projects uses three layers of context files:
Layer 1 — Project root AGENTS.md: Global constraints that apply to every agent session. Technical stack, forbidden patterns, security-sensitive files, and CI/CD conventions go here. This file should rarely change.
Layer 2 — Domain AGENTS.md: Placed in major subsystem directories (src/api/, src/components/, src/workers/). Contains domain-specific rules that the root file shouldn't need to know about. For example, the API domain file might specify authentication patterns and rate limit handling conventions without cluttering the global file.
Layer 3 — AGENTS.md in task specification: Inline context that's specific to a single task and won't apply broadly. Include this in the task description itself rather than polluting permanent context files.
The key principle is keeping each layer focused. An AGENTS.md that tries to document everything becomes a document nobody reads.
Keeping AGENTS.md Accurate Over Time
Context files that become stale are worse than no context at all — they actively mislead agents. I've started treating AGENTS.md updates as part of the definition of done for any significant refactoring.
A lightweight convention that works well: whenever you make a change that would have saved you time if it had been in AGENTS.md, add it to AGENTS.md in the same commit. This keeps the file accurate without requiring dedicated "documentation sprints."
What Makes a Good Knowledge Item
When Background Agent supports Knowledge Items — additional files you attach to provide context — the selection matters. I've found these consistently valuable:
- ERD or data model diagram: Agents make significantly better database-adjacent decisions when they can see the schema relationships
- Architecture decision records (ADRs): Especially decisions that seem counterintuitive. "We don't use X even though it would seem natural because Y" is exactly the kind of context agents can't infer from code alone
- The last failing test: When you're asking an agent to fix a bug, attaching the test that demonstrates the failure gives it a concrete success condition from the start
- A working example from elsewhere in the codebase: "Make this look like that" with a concrete reference is more reliable than describing the pattern abstractly
Multi-Agent Orchestration Patterns
As you get comfortable running individual Background Agents, you'll naturally start thinking about how to coordinate multiple agents working toward a shared goal. This section covers the orchestration patterns that have proven most reliable.
The Fan-Out / Fan-In Pattern
This is the most common multi-agent pattern and the easiest to reason about:
#\!/bin/bash
# fan-out-agents.sh — launch multiple specialized agents, collect results
PROJECT_DIR="$HOME/myapp"
WORKTREES_DIR="$HOME/myapp-worktrees"
RESULTS_DIR="$HOME/myapp-agent-results"
mkdir -p "$RESULTS_DIR"
# Define parallel workstreams
declare -A WORKSTREAMS=(
["tests"]="Add comprehensive tests to src/components/checkout/"
["types"]="Strengthen TypeScript types in src/types/checkout.ts"
["docs"]="Write JSDoc for all exported functions in src/api/checkout/"
)
# Fan out — launch all agents simultaneously
for stream in "${\!WORKSTREAMS[@]}"; do
branch="agent/${stream}-checkout-$(date +%Y%m%d)"
worktree="$WORKTREES_DIR/$stream"
# Create isolated worktree
git -C "$PROJECT_DIR" worktree add -b "$branch" "$worktree" main
# Record task start
echo "$(date -Iseconds): Started $stream" >> "$RESULTS_DIR/timeline.log"
# Launch agent (non-blocking — each runs independently)
echo "🚀 Launched agent: $stream"
echo " Task: ${WORKSTREAMS[$stream]}"
echo " Branch: $branch"
done
echo ""
echo "All agents launched. Monitor progress in Antigravity UI."
echo "When all complete, run: ./merge-results.sh"The fan-out pattern works well because each agent has a clearly scoped task with no cross-dependencies. The merge step happens only after all agents finish, making it easy to review results holistically before integrating anything.
The Sequential Dependency Pattern
When tasks have dependencies, you need sequential orchestration rather than parallel:
#\!/bin/bash
# sequential-agents.sh — run agents in dependency order
run_agent_and_wait() {
local task="$1"
local branch="$2"
local timeout_minutes="${3:-60}"
echo "▶️ Starting: $task"
# Launch agent (implementation depends on Antigravity CLI availability)
antigravity agent run \
--task "$task" \
--branch "$branch" \
--wait \
--timeout "${timeout_minutes}m" \
2>&1 | tee -a "$RESULTS_DIR/agent.log"
local exit_code=$?
if [ $exit_code -ne 0 ]; then
echo "❌ Agent failed for task: $task"
echo " Check $RESULTS_DIR/agent.log for details"
exit 1
fi
echo "✅ Completed: $task"
}
# Step 1: Generate types first (other steps depend on these)
run_agent_and_wait \
"Create TypeScript interfaces for the new payment flow in src/types/payment.ts" \
"agent/payment-types" \
30
# Step 2: Generate API client based on the new types
run_agent_and_wait \
"Implement API client functions in src/api/payment.ts using the interfaces defined in src/types/payment.ts" \
"agent/payment-api" \
45
# Step 3: Generate UI components using the API client
run_agent_and_wait \
"Create PaymentForm component in src/components/PaymentForm.tsx using the payment API client from src/api/payment.ts" \
"agent/payment-ui" \
60
echo "🎉 All sequential agents completed successfully"The critical discipline here is making each agent's task self-contained within its scope, even when the output depends on the previous step. Include the upstream output as explicit context in each downstream task specification.
Handling Partial Failures
Real orchestration needs to handle the case where some agents succeed and others don't:
# merge-with-failure-handling.sh
FAILED_STREAMS=()
SUCCEEDED_STREAMS=()
for stream in "${\!WORKSTREAMS[@]}"; do
worktree="$WORKTREES_DIR/$stream"
branch=$(git -C "$worktree" rev-parse --abbrev-ref HEAD 2>/dev/null)
if [ -z "$branch" ]; then
echo "⚠️ No branch found for $stream — skipping"
FAILED_STREAMS+=("$stream")
continue
fi
# Run validation before merging
cd "$worktree"
if \! npx tsc --noEmit 2>/dev/null; then
echo "❌ TypeScript errors in $stream — not merging"
FAILED_STREAMS+=("$stream")
continue
fi
if \! npx vitest run 2>/dev/null; then
echo "❌ Tests failing in $stream — not merging"
FAILED_STREAMS+=("$stream")
continue
fi
# Safe to merge
git -C "$PROJECT_DIR" merge --no-ff "$branch" \
-m "feat(agent): $stream changes"
SUCCEEDED_STREAMS+=("$stream")
done
echo ""
echo "=== Results ==="
echo "✅ Merged: ${SUCCEEDED_STREAMS[*]}"
echo "❌ Skipped: ${FAILED_STREAMS[*]}"
if [ ${#FAILED_STREAMS[@]} -gt 0 ]; then
echo ""
echo "Failed streams require manual review."
echo "Worktrees preserved at: $WORKTREES_DIR"
fiFor broader multi-agent orchestration strategies, the Antigravity Multi-Agent Orchestration Guide covers additional coordination patterns.
Building a Background Agent Habit Loop
The technical patterns in this guide only deliver value if you actually use them. Here's the habit structure I've found makes Background Agent a natural part of the development day rather than something you remember exists every few weeks.
The Daily Delegation Checklist
At the start of each day, I scan my task list for Background Agent candidates using these questions:
- Is there a task here that I'm context-switching into and out of? (tests, documentation, type improvements)
- Is there something I know needs to be done but am avoiding because it's tedious? (great for delegation)
- Is there a "while I sleep" opportunity — something that could run overnight without my involvement?
One or two tasks per day delegated to Background Agent adds up quickly. Over a month, that's potentially 20–40 hours of parallel work that didn't compete for your focus.
The Specification Investment Mindset
The 10–15 minutes spent writing a good task specification is not overhead — it's the work itself. The clarity you develop when writing the specification often reveals ambiguities in your own thinking about the task. Agents fail for the same reasons human team members fail: unclear requirements, unstated constraints, vague success criteria.
Treat Background Agent task specifications the way you'd treat a ticket written for a strong engineer who can't ask follow-up questions. That mental model produces specifications that work.
If you've read this far, the most useful thing you can do now is open your current project, find one task that fits the criteria, and write a specification using the template from the Task Design section. The difference between Background Agent as "occasionally useful" and Background Agent as "changes how I develop" comes down to whether you build the habit of reaching for it. Start with one well-specified task. See how it goes. Adjust and iterate.