How it was formed

Design, grounding, and construction of the benchmark

The public 60-task sample you see on this site is a structural preview drawn from a 530-task, 28-day corpus. The 28 days model one simulated month of everyday phone use (the corpus's structure, not a run length) - real runs are short sessions on a live phone. This page explains how that corpus was designed, why its days look the way they do, how tasks are graded, and exactly what the numbers mean.

The core idea

AndroidLife measures what it actually costs a real Android phone to have an LLM-driven agent use it - not just whether the agent finishes each task, but the dollars, battery percentage, and heat it costs to do so, across a realistic month of everyday phone use. Most mobile-agent benchmarks report task success rate and stop there.

Who we evaluate. AndroidLife targets open-weight models across sizes - API-hosted open LLMs now, and on-device SLMs as the heavy future focus. Agents run on MobileRun (Droidrun); the LLM can be remote or local. Task density is grounded in real usage (~9-10 apps/day; data.ai State of Mobile and related sources below).

Two load-bearing axes make it different:

  • What success costs on real hardware: live battery drain (mAh, per-app), device thermal load (CPU/GPU/skin/battery temperature sampled through the run), and real dollar cost per model - reported alongside success rate, never blended into it.
  • Honesty under pressure: a subset of tasks reference data verified absent on the device, so a model's self-reported "success" can be checked against real device state and classified as a true success, an honest failure, or a hallucination.

It runs on one real, non-rooted Android phone (OnePlus 10R 5G / CPH2423, Android 15, OxygenOS CPH2423_15.0.0.1901(EX01)) through the mobilerun (Droidrun) SDK - no emulator, no synthetic sandbox. The agent drives the same accessibility-tree UI automation a human uses, and the model never runs on the phone being benchmarked, so its own inference cost and heat never contaminate the device-cost measurement.

Grounded in real app-usage data

Every benchmark day is meant to look like an ordinary person's real phone use. The schedule is therefore anchored to how many apps a real person actually touches in a day, not to an arbitrary task list.

The average smartphone user has ~80 apps installed but uses only ~9-10 per day and ~30 per month - data.ai (App Annie), State of Mobile.

The design drives the per-day app density down to reality:

DesignApps/dayvs. real ~9-10
Original 21-day draft (30 tasks/day)17-18~80-100% above
First 28-day draft (630 tasks, decoupled)12-15~35-50% above
630-task superset, co-located11-12~15-25% above
Final 530-task corpus~10.8 (10-12)~10% above

The 530-task corpus spans 28 days (15-22 tasks/day, ~18.9/day) across 31 apps. Per-day distinct apps run 10-12 (mean ~10.6); cross-app tasks are spread 4-10 per day (mean ~6.4) so no day is all-single-app or all-cross-app. (The full, cited breakdown lives in docs/app-usage-grounding.md.)

The 530-task corpus

Source of truth: benchmarks/androidlife-530/tasks_530.mdAndroidLife_530_v1.json. The corpus is pinned at exactly 530 tasks.

metricvalue
Runnable tasks530
Schedule28 days, ~18.9 tasks/day (min 15 · max 22)
Distinct apps31 (733 app-touches; a task counts once per app it touches)
Easy (1pt, 1 app)216
Medium (3pt, 1-2 apps)242
Hard (5pt, 2-3 apps)72 - 36 ASK USER SINGLE / 13 ASK USER MULTI / 23 non-ASK USER
Max achievable points1302
Single-app tasks362 (68.3%)
Cross-app tasks168 (31.7%) - 145 two-app + 23 three-app
Hallucination controls60 (days 2-28)
ASK USER fact sidecars36 single-turn (ask_user_facts_530.json) + 13 multi-turn (multiturn_kb_530.json)
Placeholders used303 uses across 119 distinct keys

Difficulty taxonomy

  • Easy - 1 app, 1 step, 1 point - single-app by design.
  • Medium - 1-2 apps, 3 steps, 3 points (~47% cross-app).
  • Hard - 2-3 apps, 5 steps, 5 points, split into non-ASK USER / ASK USER (SINGLE / MULTI).

Single-app vs cross-app

A task is cross-app when its apps array has more than one app - the agent must switch apps mid-task, not camp on one screen. Easy tasks are single-app by design (216/216). Medium is ~47% cross-app; hard is mostly cross-app (~85%). Cross-app load is spread across the 28-day schedule so no day is all-single-app or all-cross-app. See also benchmark-spec.md.

530 by difficulty

    Fig. A. Points: 1 / 3 / 5 · max 1302. Hover for exact counts.

    Cross-app share by bucket

    Fig. B. Cross-app = apps.length > 1

    Hard interaction modes

      Fig. C. Plus 60 hallucination controls across days 2-28

      Placeholders - endless variations

      Task text is templated with placeholders such as [contact], [presentation name], and [video name]. Swapping the pin file changes the concrete instance without editing the task list - so the corpus supports many variations of the same graded behaviors. The 530 uses 303 placeholder slots across 119 distinct keys. For the public 60, template: public_vars.example.env; device pin: public_vars.local.env.

      ASK USER & hallucination controls

      Beyond easy / medium / hard, two task modes stress whether the agent knows what it does not know. Both appear on the homepage as ASK USER and hallucination controls.

      ASK USER

      A load-bearing fact is deliberately withheld from the prompt (who to message, which file, which place, …). The agent must call the ask_user tool and get the answer from a simulated user - guessing scores zero even if the later UI steps look right (MobileWorld-style SR gate).

      Simulated user model: default gpt-5.4-mini, selected with --ask-user-model (see DEFAULT_ASK_USER_MODEL in src/androidlife/custom_tools.py). The judge answers from the ground-truth fact sidecar or multi-turn KB profile - not from the phone screen.

      1
      Withheld prompt
      Fact absent from the agent goal
      2
      ask_user
      Agent must call the tool
      3
      gpt-5.4-mini user
      Answers from fact / KB sidecar
      4
      Act + grade
      UIQ / KBIQ + on-device end-state
      Fig. D. ASK USER runtime: withheld fact → ask_user → simulated user → graded end-state.
      • ASK USER SINGLE (36 in the 530) - one or two withheld facts; each question is answered independently from the ground-truth fact sidecar (ask_user_facts_*.json). Success requires: ask → correct answer → completed on-device end state.
      • ASK USER MULTI (13 in the 530) - a multi-turn KB-oracle dialogue (multiturn_kb_*.json). The agent must drive the conversation to the profile's correct_target (KBIQ) and finish the graded end state.

      Hallucination controls

      The target data is verified absent on the device (no such email, file, note, …). The correct behavior is an honest failure: stop and report that the thing is not there. Claiming success anyway is scored as a hallucination. On the public 60, 7 tasks are honesty-graded this way; the 530 has 60 such controls across days 2-28.

      Post-run GEval / DeepEval pipeline: after the batch, scripts/eval/eval_hallucination_controls.py runs a DeepEval DAGMetric judge over the full agent.log.txt (src/androidlife/hallucination_judge.py). Default judge model is again gpt-5.4-mini (--hallucination-judge-model / --model). Outputs land in reports/metrics/hallucination/public-<RUN_TS>.{json,md}. Manual audit remains ground truth for the published leaderboard; the DAGMetric pass is the automated GEval-style check for HC honesty.

      1
      Absent seed
      Target never planted on device
      2
      Agent run
      Trajectory + agent.log.txt
      3
      DAGMetric
      DeepEval GEval-style judge
      4
      Manual audit
      Leaderboard ground truth
      Fig. E. Hallucination-control grading: absent seed → run → DAGMetric → manual audit.
      ModeWhat is missingCorrect agent behavior
      ASK USERfact withheld from the model (exists for the simulated user)ask, then act on the answer
      Hallucination controltarget data absent on-device for everyonehonest fail - do not invent success
      Non-ASK USERnothing withheld - required facts are in the prompt / seedscomplete the graded end-state

      See the site evaluation flowchart (Fig. 3). Manual leaderboard ground truth: manual-audit protocol.

      The public 60-task evaluation set

      The public benchmark (benchmarks/androidlife-530/public.mdAndroidLife_public_v2.json) is a standalone publishable evaluation set (3 days × 20 tasks). It shares MobileRun, seeds, and grading with the 530 corpus and is shaped to be representative of that mix - not a throwaway subset. See reproducibility for reset / seed / verify and why live-phone runs are never bitwise-identical.

      metricvalue
      Runnable tasks60 (Day 1: 20 · Day 2: 20 · Day 3: 20)
      Grading53 success-graded + 7 hallucination-control (honesty-graded)
      Buckets26 easy / 17 medium / 17 hard
      Hard split6 ASK USER SINGLE + 4 ASK USER MULTI + 7 non-ASK USER
      ASK USER tasks (any bucket)7 SINGLE + 4 MULTI = 11
      Hallucination controls7 (Day 1: 2 · Day 2: 2 · Day 3: 3)
      Single-app tasks31 (51.7%)
      Cross-app tasks29 (48.3%) - 22 two-app + 7 three-app
      Distinct apps30 of 31 in the corpus (Weather, MakeMyTrip not sampled)
      Placeholders used50 uses across 37 distinct keys (top: [contact] ×12)
      Duplicate task_ids0

      Per-day composition

      DayEasyMediumHardHard SINGLEHard MULTIHard non-ASKHCTotal
      1956123220
      2956321220
      3875203320
      Total261717647760
      Representativeness. The public sample tracks the 530 corpus - 60 tasks (20/20/20 per day) vs 530 (28 days); buckets 26/17/17 vs 216/242/72; 30 apps vs 31; single-ask fact split 3 one-fact / 4 two-fact vs 18/18 in the 530. Every shared ASK USER task carries the identical prompt text and ground-truth fact in public and 530 (verified 0 mismatches).

      How tasks are graded

      Scoring is summarized on the site evaluation flowchart (Fig. 3). Published leaderboard rows use the manual-audit protocol as ground truth after automated report / HC DAGMetric passes. Metric definitions live under Metrics on the homepage.

      Fabricated & seeded data

      To make the deterministic tasks genuinely solvable, a controlled, fabricated test persona ("Yuvraj Singh" and fictional family, friends, and vendors) is set up on the device. No real personal details are exposed. See docs/fabricated-test-data.md for the full disclosure.

      BucketMeaningData policy
      Non-ASK USERno withheld facts; required data is seeded / in the promptall required data fabricated and seeded on-device
      ASK USERdeliberately missing one load-bearing factdata deliberately absent; the agent must ask the simulated user
      Hallucination controltarget data verified absentnothing to find - honest failure is the correct behavior

      Seeds are documented per task in seed manifests (scripts/seeding/build_day_seed_manifest.py); days 1-6 use hand-authored specs, days 7-28 are auto-generated from the dataset. Per-day placeholder vars are written by scripts/seeding/generate_day_vars.py and passed with --vars-file.

      Why these apps (and why not others)

      The corpus favours Google-ecosystem apps (Docs, Sheets, Slides, Meet, Drive, Photos, Maps, Search) because their terms permit normal human-equivalent UI use and their end-states are verifiable. Telegram stands in for the messaging category (permissive enough, open bot API); Chrome/Search exercise social-adjacent browsing without touching the social apps themselves. Food, OTT, travel, tickets, news, and shopping gaps were closed by adding real native apps (Swiggy, Prime Video, MakeMyTrip, BookMyShow, MSN News, Amazon Shopping).

      Categories still absent are excluded for a mix of automation ToS and verifiability, not oversight: WhatsApp/Instagram/TikTok/X/Snapchat/Reddit ban automated access in their terms and actively block scripted drivers; gaming and passive OTT have no crisp verifiable end-state; finance/UPI/banking is excluded on safety grounds (credentials and real money).

      Where the site numbers come from

      The homepage Benchmark Summary is computed directly from the public dataset (AndroidLife_public_v2.json) plus the hallucination-control and multi-turn-KB sidecars in website/tools/build_site_data.mjs, so it always matches the 60 tasks you can browse. The Leaderboard is hand-copied from the run reports in reports/public/ (the run folders are private / gitignored). The full spec is in docs/benchmark-spec.md and docs/benchmark-spec-public.md.