All notes

How We Benchmark On-Device Models for a Phone Agent

Our phone-local model test design, with all 96 bilingual cases and expected routes, structured metrics, fixed decoding, iPhone resource runs, evidence, and limits.

on-device AIbenchmark methodologyagent evaluationmobile inferenceLLM
How We Benchmark On-Device Models for a Phone Agent

This benchmark did not begin as an attempt to build another model leaderboard.

We had a much narrower problem. A local Agent on a phone needs one default routing model. That model cannot merely hold a conversation. Within a short response window, it has to understand the request, select the right capability, extract execution parameters, and stop to ask a question when essential information is missing. It also has to fit on the device without turning an 8K context into an unacceptable memory or thermal cost.

The question we set out to answer was:

In our bilingual, structured, on-device Agent workflow, which model can make routing and execution decisions most reliably at a practical resource cost?

That qualification matters. We are not measuring general intelligence, writing quality, mathematics, or open-domain knowledge. We are answering a product engineering question.

Start with the Agent's actual job

Before an Agent can act on a request such as “Wake me at seven tomorrow,” it has at least two decisions to make.

First, it selects the right Skill from the capabilities currently available: alarms, calendars, mail, memory, and so on. It then selects an Action inside that Skill, extracts known parameters, identifies missing ones, and decides whether to act, plan, or ask the user for clarification.

Flow diagram Preparing diagram
View diagram source
flowchart LR
    A[User request] --> B[Retrieve candidate Skills]
    B --> C[Stage 1: select Skill]
    C --> D[Stage 2: Action and parameters]
    D --> E{Enough information?}
    E -->|Yes| F[Act or plan]
    E -->|No| G[Structured clarification]
    F --> H[Swift Runtime validation]
    G --> H

We do not ask the model for a plausible paragraph and grade it by feel. The evaluator requires an explicit structure: Skill, Action, Mode, known Slots, missing Slots, and objectives. The Swift Runtime then checks that the answer belongs to the retrieved candidate set and conforms to the current schema.

That distinction matters for an Agent with access to system capabilities. “Roughly understood the request” is not a useful execution guarantee. Choosing the wrong Action and omitting one required parameter are different failures, and both need to be visible.

What is in the 96-case suite

The model comparison uses the v3-96-staged-skill-action dataset:

DimensionComposition
Language48 Chinese, 48 English
Skills12
Difficulty48 core, 48 challenge
ProtocolTwo-stage Skill → Action/Slots/Mode
ContextFull run at both 4K and 8K

Core cases cover common phrasing around alarms, calendars, mail drafts, and other routine requests. Challenge cases add nearby Skill distractors, missing required information, cross-capability planning, and more ambiguous wording.

We deliberately keep short requests in the set. Real phone commands are often only a few words long. A model that works only when every request is written like a test question is not particularly useful in a product.

Each case stores the expected Skill, Action, Mode, and relevant structural constraints. Published accuracy uses all 96 cases as the denominator. Parse failures are not quietly removed.

The 96 cases and their expected routes

The expected result below is the routing contract, not the final prose answer. A case passes each scored field only when the model selects the listed Skill, Action, and Mode. Extra assertion shows whether that case also checks missing-slot emptiness or requires a plan.

Three concrete scoring examples

  • Complete commandSet an alarm for 7 AM tomorrow.

builtin.alarm.manage → create_alarm, Mode act, missing_slots must be empty.

  • Incomplete commandCreate an email draft for me.

builtin.mail.draft → create_draft, Mode clarify, missing_slots must be non-empty. The mail schema requires recipient, subject, and body.

  • Multi-step commandFirst inspect tomorrow's calendar, then create reminders for unresolved items.

builtin.task.plan_recover → orchestrate, Mode act, and requires_plan = true.

One current limitation is visible here: the v3 suite scores missing slots as empty versus non-empty. It does not yet award separate points for naming every missing field correctly. Exact slot names and values belong in the next contract-test version.

Core: 48 routine cases

# / Case IDLangTest inputExpected Skill → ActionModeExtra assertion
1 · zh-alarm-createZH明天早上七点设置一个起床闹钟builtin.alarm.managecreate_alarmactmissing: empty
2 · zh-alarm-listZH查看我在 Vesta 里创建的所有闹钟builtin.alarm.managelist_alarmsretrieve
3 · en-alarm-createENSet an alarm for 7 AM tomorrow.builtin.alarm.managecreate_alarmactmissing: empty
4 · en-alarm-listENList all alarms currently managed by Vesta.builtin.alarm.managelist_alarmsretrieve
5 · zh-schedule-eventZH明天下午三点在 A 会议室安排项目评审,持续一小时builtin.schedule.managecreate_calendar_eventactmissing: empty
6 · zh-schedule-reminderZH提醒我周五下午六点提交周报builtin.schedule.managecreate_reminderactmissing: empty
7 · en-schedule-eventENCreate a calendar event for project review tomorrow at 3 PM for one hour.builtin.schedule.managecreate_calendar_eventactmissing: empty
8 · en-schedule-reminderENRemind me Friday at 6 PM to submit the weekly report.builtin.schedule.managecreate_reminderactmissing: empty
9 · zh-brief-todayZH汇总我今天的日程和未完成提醒builtin.daily.briefingsummarize_scheduleretrieve
10 · zh-brief-conflictZH看看本周安排里有没有冲突和逾期事项builtin.daily.briefingsummarize_scheduleretrieve
11 · en-brief-todayENSummarize today's calendar and unfinished reminders.builtin.daily.briefingsummarize_scheduleretrieve
12 · en-brief-overdueENShow my schedule conflicts and overdue reminders this week.builtin.daily.briefingsummarize_scheduleretrieve
13 · zh-general-explainZH解释一下什么是最终一致性builtin.general.answeransweranswer
14 · zh-general-howtoZH如何安全地删除一个文件?只需要解释步骤builtin.general.answeransweranswer
15 · en-general-explainENExplain eventual consistency in simple terms.builtin.general.answeransweranswer
16 · en-general-howtoENHow do I delete a file safely? Explain only.builtin.general.answeransweranswer
17 · zh-knowledge-citeZH根据我的本地项目文档,发布日期是什么?请引用来源builtin.knowledge.answeranswer_from_knowledgeretrieve
18 · zh-knowledge-summaryZH总结我导入的合同里关于违约责任的内容builtin.knowledge.answeranswer_from_knowledgeretrieve
19 · en-knowledge-citeENSearch my local documents for the launch date and cite the source.builtin.knowledge.answeranswer_from_knowledgeretrieve
20 · en-knowledge-compareENCompare the pricing terms in my two imported contracts.builtin.knowledge.answeranswer_from_knowledgeretrieve
21 · zh-connected-contactZH查一下通讯录里 Alex 的电话号码builtin.connected.contextanswer_from_sourceretrieve
22 · zh-connected-webZH总结这个网页的内容:https://example.com/reportbuiltin.connected.contextanswer_from_sourceretrieve
23 · en-connected-mailENLook in my Gmail for the latest message from Alex.builtin.connected.contextanswer_from_sourceretrieve
24 · en-connected-locationENWhat city am I currently in?builtin.connected.contextanswer_from_sourceretrieve
25 · zh-document-importZH选择并导入这份 PDF 到本地知识库builtin.document.ingestimport_documentact
26 · zh-document-ocrZH识别我选择的图片文字并录入知识库builtin.document.ingestscan_documentact
27 · en-document-importENImport the selected PDF into my local knowledge base.builtin.document.ingestimport_documentact
28 · en-document-ocrENRun OCR on the selected image and add it to the knowledge base.builtin.document.ingestscan_documentact
29 · zh-memory-rememberZH记住我不喜欢订阅制软件builtin.memory.governancerememberactmissing: empty
30 · zh-memory-forgetZH忘记我之前保存的语言偏好builtin.memory.governanceforgetact
31 · en-memory-listENShow the long-term preferences you remember about me.builtin.memory.governancelist_memoriesretrieve
32 · en-memory-rememberENRemember that I prefer one-time purchases.builtin.memory.governancerememberactmissing: empty
33 · zh-mail-completeZH给 Alex 起草邮件,主题是周会,正文写明改到周五下午三点builtin.mail.draftcreate_draftactmissing: empty
34 · zh-mail-missingZH帮我起草一封邮件builtin.mail.draftcreate_draftclarifymissing: non-empty
35 · en-mail-completeENDraft an email to Alex with subject Weekly Sync and say it moved to Friday at 3 PM.builtin.mail.draftcreate_draftactmissing: empty
36 · en-mail-missingENCreate an email draft for me.builtin.mail.draftcreate_draftclarifymissing: non-empty
37 · zh-runtime-contractZH检查 Vesta 当前的 Runtime 和安全执行契约builtin.runtime.inspectinspect_runtimeretrieve
38 · zh-runtime-mcpZH列出本机 MCP Runtime 当前暴露的能力builtin.runtime.inspectinspect_runtimeretrieve
39 · en-runtime-contractENInspect Vesta's current runtime and safety contract.builtin.runtime.inspectinspect_runtimeretrieve
40 · en-runtime-mcpENShow the capabilities exposed by the local MCP runtime.builtin.runtime.inspectinspect_runtimeretrieve
41 · zh-plan-sequenceZH先查看明天日程,然后为没有空闲时间的事项创建提醒builtin.task.plan_recoverorchestrateactrequires plan
42 · zh-plan-breakdownZH把准备发布会这件事拆成可验证的步骤并跟踪进度builtin.task.plan_recoverorchestrateactrequires plan
43 · en-plan-sequenceENFirst inspect tomorrow's calendar, then create reminders for unresolved items.builtin.task.plan_recoverorchestrateactrequires plan
44 · en-plan-breakdownENBreak down the product launch preparation into verifiable steps and track progress.builtin.task.plan_recoverorchestrateactrequires plan
45 · zh-data-exportZH导出并加密备份我的全部 Vesta 本地数据builtin.data.portabilityexport_packageact
46 · zh-data-restoreZH从这个 vestaexport 数据包选择性恢复记忆和任务builtin.data.portabilityrestore_packageact
47 · en-data-exportENExport an encrypted backup of all my local Vesta data.builtin.data.portabilityexport_packageact
48 · en-data-inspectENInspect this Vesta backup package without restoring it.builtin.data.portabilityinspect_packageretrieve

Challenge: 48 boundary cases

# / Case IDLangTest inputExpected Skill → ActionModeExtra assertion
49 · challenge-zh-alarm-recurringZH每个工作日早上八点半叫我起床builtin.alarm.managecreate_alarmactmissing: empty
50 · challenge-zh-alarm-queryZH我明早有设叫醒铃吗?builtin.alarm.managelist_alarmsretrieve
51 · challenge-en-alarm-recurringENWake me at 6:45 every weekday.builtin.alarm.managecreate_alarmactmissing: empty
52 · challenge-en-alarm-queryENDo I have a wake-up alarm tomorrow morning?builtin.alarm.managelist_alarmsretrieve
53 · challenge-zh-schedule-createZH下周一上午十点留半小时和产品经理同步builtin.schedule.managecreate_calendar_eventactmissing: empty
54 · challenge-zh-schedule-deleteZH删除明天下午由 Vesta 创建的牙医提醒builtin.schedule.managedelete_reminderact
55 · challenge-en-schedule-createENPut lunch with Sam on my calendar at noon Tuesday.builtin.schedule.managecreate_calendar_eventactmissing: empty
56 · challenge-en-schedule-deleteENCancel the Vesta reminder to pay rent.builtin.schedule.managedelete_reminderact
57 · challenge-zh-brief-tomorrowZH我明天有哪些会和待办,按时间排一下builtin.daily.briefingsummarize_scheduleretrieve
58 · challenge-zh-brief-loadZH这周哪几天的安排最满?builtin.daily.briefingsummarize_scheduleretrieve
59 · challenge-en-brief-morningENGive me a morning briefing from my calendar and reminders.builtin.daily.briefingsummarize_scheduleretrieve
60 · challenge-en-brief-loadENWhich days this week are overloaded?builtin.daily.briefingsummarize_scheduleretrieve
61 · challenge-zh-general-rewriteZH把这句话改得更礼貌:你写错了builtin.general.answeransweranswer
62 · challenge-zh-general-calculateZH计算 240 的 18% 是多少builtin.general.answeransweranswer
63 · challenge-en-general-rewriteENRewrite this more politely: You are wrong.builtin.general.answeransweranswer
64 · challenge-en-general-howtoENHow can I set an alarm on iPhone? Explain the steps only.builtin.general.answeransweranswer
65 · challenge-zh-knowledge-policyZH从已经收录的报销制度里找出打车标准builtin.knowledge.answeranswer_from_knowledgeretrieve
66 · challenge-zh-knowledge-compareZH对比知识库中两份方案的风险章节builtin.knowledge.answeranswer_from_knowledgeretrieve
67 · challenge-en-knowledge-policyENAccording to documents already in my library, what is the reimbursement limit?builtin.knowledge.answeranswer_from_knowledgeretrieve
68 · challenge-en-knowledge-summaryENSummarize the termination clause from the contract I previously imported.builtin.knowledge.answeranswer_from_knowledgeretrieve
69 · challenge-zh-connected-webZH打开并概括这个链接:https://example.com/briefbuiltin.connected.contextanswer_from_sourceretrieve
70 · challenge-zh-connected-outlookZH在 Outlook 里找 Alex 最新发来的邮件builtin.connected.contextanswer_from_sourceretrieve
71 · challenge-en-connected-contactENFind Jordan's phone number in my contacts.builtin.connected.contextanswer_from_sourceretrieve
72 · challenge-en-connected-webENRead and summarize https://example.com/brief.builtin.connected.contextanswer_from_sourceretrieve
73 · challenge-zh-document-scanZH把我刚选的扫描件 OCR 后加入资料库builtin.document.ingestscan_documentact
74 · challenge-zh-document-wordZH导入这个 Word 文件并建立本地索引builtin.document.ingestimport_documentact
75 · challenge-en-document-photoENExtract text from this selected photo and save it to my local library.builtin.document.ingestscan_documentact
76 · challenge-en-document-sheetENAdd the selected spreadsheet to my local documents.builtin.document.ingestimport_documentact
77 · challenge-zh-memory-rememberZH以后回答尽量简短,请记住这个偏好builtin.memory.governancerememberactmissing: empty
78 · challenge-zh-memory-listZH列出你长期保存的关于我的偏好builtin.memory.governancelist_memoriesretrieve
79 · challenge-en-memory-forgetENForget that I prefer dark mode.builtin.memory.governanceforgetact
80 · challenge-en-memory-updateENChange my saved language preference to Chinese.builtin.memory.governancerememberact
81 · challenge-zh-mail-completeZH给财务起草邮件,说明发票将在周五补交builtin.mail.draftcreate_draftactmissing: empty
82 · challenge-zh-mail-missingZH写封邮件通知项目延期builtin.mail.draftcreate_draftclarifymissing: non-empty
83 · challenge-en-mail-completeENDraft an email to finance saying the invoice will arrive Friday.builtin.mail.draftcreate_draftactmissing: empty
84 · challenge-en-mail-missingENWrite an email announcing the delay.builtin.mail.draftcreate_draftclarifymissing: non-empty
85 · challenge-zh-runtime-sourcesZH检查 Vesta 当前授权了哪些数据源builtin.runtime.inspectinspect_runtimeretrieve
86 · challenge-zh-runtime-toolsZH查看本地执行器现在注册了哪些工具builtin.runtime.inspectinspect_runtimeretrieve
87 · challenge-en-runtime-toolsENWhich tools are currently registered in the local runtime?builtin.runtime.inspectinspect_runtimeretrieve
88 · challenge-en-runtime-writeENCheck whether this runtime is allowed to execute write operations.builtin.runtime.inspectinspect_runtimeretrieve
89 · challenge-zh-task-sequenceZH先找出今天逾期的事项,再逐项建立新的提醒builtin.task.plan_recoverorchestrateactrequires plan
90 · challenge-zh-task-resumeZH继续上次中断的发布准备任务并从失败步骤恢复builtin.task.plan_recoverrecoveractrequires plan
91 · challenge-en-task-sequenceENReview today's overdue items first, then create a reminder for each one.builtin.task.plan_recoverorchestrateactrequires plan
92 · challenge-en-task-resumeENResume the interrupted launch task from its failed step.builtin.task.plan_recoverrecoveractrequires plan
93 · challenge-zh-data-inspectZH只检查这个备份包里有什么,不要恢复builtin.data.portabilityinspect_packageretrieve
94 · challenge-zh-data-exportZH把知识库和长期偏好导出成加密数据包builtin.data.portabilityexport_packageact
95 · challenge-en-data-restoreENRestore only memories from this Vesta export package.builtin.data.portabilityrestore_packageact
96 · challenge-en-data-inspectENVerify this backup archive without importing anything.builtin.data.portabilityinspect_packageretrieve

What we score

We do not collapse the result into one weighted score that lets strengths hide failures.

MetricQuestion it answers
ParseDid both stages produce a complete contract?
SkillWas the correct capability selected?
ActionWas the correct operation selected?
ModeShould the Agent act, plan, or clarify?
Missing SlotsDid it stop when required information was absent?
Scope ValidityDid the answer remain inside the candidate set and schema?
TTFT / E2EHow quickly did generation begin and routing finish?

A high Parse rate does not imply semantic correctness. A model can emit perfectly valid JSON while consistently selecting the wrong Skill. The opposite failure is also possible: the model appears to understand the request, but its output drifts far enough that the Runtime cannot use it.

For a model that may drive execution, Skill, Action, Mode, and missing-slot behavior matter most. A model with strong Skill selection but weak Action accuracy may still be interesting as a first-stage shortlist model, but it should not receive direct authority to produce execution parameters.

Fair does not mean one literal prompt wrapper

All 10 models use GGUF Q4_K_M, the same evaluator, dataset, 4K/8K settings, and fixed decoding:

temperature = 0
top_p = 1
top_k = 1
seed = 42
candidate_limit = 3

We do not force the same ChatML string onto every model. Llama 3 uses its header tokens, SmolLM3 explicitly disables extended thinking, and LFM2.5 receives its required start-of-text token. The task, information, and output contract stay the same; the outer template follows the model's native format.

That is our definition of a fair comparison: keep the work and rules constant without knowingly giving a model the wrong input format.

For every weight, we also record the publisher, repository, commit, filename, byte count, SHA-256, license, and Prompt Profile. A model name alone is not enough to reproduce a result. Two conversions or quantizations carrying the same name may behave differently.

Why capability and phone measurements are separate

This is the easiest part of the study to misread.

The 96 capability cases run with the same model files in a desktop Metal evaluator. That environment makes it practical to execute the suite in bulk, retain every raw answer, and repeat comparisons under stable conditions.

Resource measurements come from an iPhone 15 Pro Max with A17 Pro, 8 GB of physical memory, SwiftLlama, and llama.cpp b8668. Every model is tested at 4K and 8K, with three independent launches for each combination, for 60 launches in total.

The phone run records:

  • model load time;
  • TTFT for a short prompt;
  • process memory;
  • Metal memory;
  • thermal state;
  • whether basic generation completed.
Flow diagram Preparing diagram
View diagram source
flowchart TB
    A[Pin model file and SHA-256] --> B1[Desktop Metal capability run]
    A --> B2[iPhone resource run]
    B1 --> C1[96 bilingual requests]
    C1 --> D1[Parse Skill Action Mode]
    B2 --> C2[Three independent 4K and 8K launches]
    C2 --> D2[Load TTFT Memory Thermal]
    D1 --> E[Selection decision]
    D2 --> E

We keep these evidence tracks separate. Desktop capability accuracy is not presented as iPhone end-to-end task success. Successful loading on the phone does not prove that the model understood the 96 requests.

What 4K and 8K mean in this round

The phone prompt and generation are intentionally short. The 4K/8K measurements answer three questions:

  1. Can the model load with that context configuration on the target device?
  2. How much extra memory does the larger context reserve?
  3. Are startup, first-token latency, and thermal state acceptable for a short request?

They do not prove that speed remains unchanged after filling 8K tokens, and they do not measure long-prompt prefill throughput. That requires real workloads around 3.5K and 7.5K tokens, plus prefill speed, generation throughput, energy use, and sustained thermal curves.

In this round, 8K is a capacity and resource test, not an “8K long-context certification.”

How one result becomes evidence

Each capability run retains the raw model output and its SHA-256, not just the final percentage. The summary JSON records:

  • dataset version and digest;
  • model file SHA-256;
  • Prompt configuration SHA-256;
  • Prompt Profile;
  • context size and candidate limit;
  • expected and actual values for each case;
  • TTFT, end-to-end latency, and token counts;
  • whether format repair was needed.

On the phone side, we retain the raw text from every independent launch, CSV summaries, and per-model checksum files. The full evidence directory has a separate SHA256SUMS.txt.

This does not eliminate every possible human error. It does let us answer three basic questions later: which exact file was tested, which configuration was used, and which raw samples produced the percentage in the table.

What this benchmark does not prove

The current evidence supports choosing a router for this particular on-device Agent. It does not directly support claims that:

  • one model has greater general intelligence;
  • one model is better across every language and Tool domain;
  • long 8K prefill performance has been validated;
  • real alarm, calendar, or mail tasks achieve a stated end-to-end success rate;
  • this is an academic or industry-wide ranking.

Of the 96 current cases, the 48 core cases have participated in development feedback and are not a fully independent final holdout. Important slices such as clarification and planning are still small. Each phone configuration has only three launches, without randomized model order, controlled cool-down, battery measurement, or a sustained 20-turn session.

Those limitations are not a polite paragraph added at the end. They are part of the result.

What we are adding next

The next version has a stricter target:

  1. Build an independent holdout with at least 300 cases, isolated from tuning.
  2. Have two non-authors review every case against a versioned rubric.
  3. Run at least three trials per case and report stable passes, unstable cases, and the 95% Wilson lower bound.
  4. Add real 3.5K/7.5K prefill, sustained sessions, energy use, thermal curves, and Jetsam recovery.
  5. Validate parameters, Tool order, approvals, clarification, and final environment state in isolated Tool fixtures.
  6. Finish with a small set of high-risk end-to-end checks against real system capabilities on the phone.

A 300-case tuning/holdout draft and the evaluation harness already exist, but the cases have not completed independent two-person review. We therefore do not present them as formal results.

Back to the original question

This method does not try to identify “the world's smartest small model.” It does something narrower and more useful: under a defined device, Runtime, and Agent contract, it identifies the best default for the current workflow and makes the reasons, failures, and evidence boundaries inspectable.

For the full 10-model results, including 4K/8K iPhone resources and model-by-model findings, read 10 Small Language Models on an iPhone.

From MonoWare

Build trust before the App Store tap.

Explore the product portfolio or subscribe for future privacy and product engineering notes.

Newsletter

Privacy and product engineering notes, sent occasionally.