ANTIGRAVITY LABJP
Articles/Tips & Best Practices
Tips & Best Practices/2026-07-10Advanced

You Can Measure a Request Before You Send It — Sizing Agent Tasks by Working Backward from Rework Rate

When an Antigravity agent returns code that misses the mark, the cause is rarely the wording of the prompt. It is the size of the task. Here is a Python scorer that grades a request before you send it, plus what happened when I scored 80 past requests against their actual rework outcomes.

antigravity427agents123workflow49automation79metrics4

Premium Article

On a Thursday evening I rewrote the same request three times. Working as an indie developer, the time lost in a stall comes straight out of my own pocket. I asked Antigravity to rework an article listing page, looked at the diff, and rolled back to a checkpoint. I polished the wording and rolled back again. By the time the third attempt landed, I had spent longer than writing it myself would have taken.

The next morning I dumped my recent request log to CSV and read through it. Every request I had rolled back shared something — and it had nothing to do with how carefully the prompt was written. Every rolled-back request was heavy in either the number of files it touched or the number of decisions it contained.

Those are not matters of taste. They are quantities you can count before you press send. And if you can count them before you send, you can judge them before you send. This is the record of building that judge and running it against 80 of my own requests.

One metric: rework rate

"Output quality" is slippery. If a human grades it on a five-point scale, the score drifts with how tired that human is. So I narrowed it to a single binary.

Rework rate = the share of requests that were not accepted on the first pass, requiring a rollback, a substantial rewrite, or a course correction through follow-up instructions.

Recording it is trivial: label each request accepted or reworked. If you use Antigravity's checkpoints, the presence of a rollback is the label. I pulled mine from editor session logs, but a handwritten note works. What matters is that the label is binary. Binary labels correlate; five-point impressions do not.

Three weeks of requests came to 80. Overall rework rate: 41%. I had been redoing nearly half of everything I asked for. Seeing that number for the first time sat heavily in my chest.

Scoring a request before it is sent

The scorer reads the request text. Its only job is to stop oversized requests from leaving the keyboard, so it does no real parsing. It counts six factors.

FactorHow it is countedWeightWhy
Estimated files touchedFilenames, component names, enumerated "and also" clauses×2.0Past six files, later edits stop agreeing with earlier ones
Open decisions"whatever makes sense", "the best approach", "you decide"×3.0The single strongest predictor of rework
Implementation plus tests"and write tests", "with tests"×2.5Different modes of thought; one of them always gets sloppy
Bundled asks"while you're at it", "also", "at the same time"×2.0Bundling hides added decisions
Standing rules inline"never use any", "comments in Japanese"×1.0Pulls attention away from the actual ask
Non-self-contained work"wire it up later", "for now", "just a stub"×1.5Intermediate artifacts create reconciliation work downstream

The weights are not invented. I started every factor at 1.0, ran a logistic regression over the 80 labeled requests, kept only the ordering of the coefficients, and rounded to numbers I could hold in my head. Eighty samples do not justify precise coefficients. Preserving the order is enough.

# preflight_score.py — grade a request before it reaches the agent
import re
from dataclasses import dataclass
 
DECISION_MARKERS = [
    "whatever makes sense", "the best approach", "you decide",
    "as appropriate", "figure out", "up to you", "however you like",
]
TEST_MARKERS = ["and write tests", "with tests", "plus tests", "include tests"]
BUNDLE_MARKERS = ["while you're at it", "also", "at the same time", "and then"]
POLICY_MARKERS = ["never use any", "comments in Japanese", "naming convention", "formatter"]
DEFERRAL_MARKERS = ["wire it up later", "for now", "just a stub", "temporarily"]
 
FILE_PAT = re.compile(r"[\w./-]+\.(tsx?|jsx?|py|go|rs|mdx?|css)\b")
COMPONENT_PAT = re.compile(r"\b[A-Z][a-zA-Z0-9]{2,}\b")
 
WEIGHTS = {
    "files": 2.0, "decisions": 3.0, "tests": 2.5,
    "bundles": 2.0, "policies": 1.0, "deferrals": 1.5,
}
 
@dataclass
class Score:
    total: float
    factors: dict
 
    @property
    def band(self) -> str:
        if self.total < 6:
            return "GREEN"
        if self.total < 12:
            return "AMBER"
        return "RED"
 
def _count(text: str, markers: list[str]) -> int:
    lowered = text.lower()
    return sum(lowered.count(m.lower()) for m in markers)
 
def score_request(text: str) -> Score:
    files = len(set(FILE_PAT.findall(text))) + len(set(COMPONENT_PAT.findall(text)))
    factors = {
        # Up to three files is harmless. Penalize only the excess.
        "files": max(0, files - 3),
        "decisions": _count(text, DECISION_MARKERS),
        "tests": _count(text, TEST_MARKERS),
        "bundles": _count(text, BUNDLE_MARKERS),
        "policies": _count(text, POLICY_MARKERS),
        "deferrals": _count(text, DEFERRAL_MARKERS),
    }
    total = sum(WEIGHTS[k] * v for k, v in factors.items())
    return Score(total=total, factors=factors)
 
if __name__ == "__main__":
    import sys
    s = score_request(sys.stdin.read())
    print(f"score={s.total:.1f} band={s.band}")
    for k, v in s.factors.items():
        if v:
            print(f"  {k}: {v} (+{WEIGHTS[k] * v:.1f})")
    sys.exit(0 if s.band != "RED" else 1)

Penalizing only files beyond the third is a small implementation choice that turned out to matter. Scoring in direct proportion to file count put weight on tiny single-file requests and blurred the threshold. Flattening the harmless region to zero lets the threshold sit exactly where the danger starts.

The decision factor carries the heaviest weight because the data said so. "Add authentication" folds three judgments into four words: how sessions are managed, where the token lives, what happens on failure. The agent will not ask. It will quietly pick the most common option for each. When that choice collides with how the existing codebase does things, the diff breaks silently.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
A preflight scorer that grades a request before it reaches the agent, built on lightweight heuristics rather than parsing
Retrospective scoring of 80 real requests, with first-pass acceptance measured per score band
Three axes for splitting a task that actually lower the score, and which instructions belong in AGENTS.md instead
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

Agents & Manager2026-06-18
Three Boundaries I Draw Before Handing Work to an Antigravity 2.0 Agent
What to hand a background agent, and what to keep in your own hands. The three boundaries I actually drew while running solo-dev automation in parallel, and how to encode them so the lines hold.
Tips2026-06-20
Keeping Scheduled Runs Reproducible: Pinning the Antigravity CLI Version to Tame Behavior Drift
The Go-based Antigravity CLI is now available to everyone, and updates are landing at a quick pace. When a CLI baked into your automation upgrades underneath you, a single morning's job can behave differently. Here is how I keep things reproducible — pinning the binary, recording its identity in each run's log, and rolling upgrades forward one job at a time — drawn from running four sites on an overnight schedule.
Tips2026-06-16
Measuring the Go-Based Antigravity CLI's Responsiveness to Rethink My Nightly Batch
The Antigravity CLI was reimplemented in Go, and startup and first-response feel different now. I measure startup, time-to-first-token, and throughput as three separate intervals, then use those numbers to move my nightly batch from serial to parallel.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →