The Browser Manages the Model
The central promise of built-in AI is an abstraction boundary:
application
↓
browser AI API
↓
browser-managed runtime
↓
current model and execution strategy
The application asks for a capability. The browser chooses how to provide it.
That separation is powerful, but it does not make the lower layers irrelevant. Changes beneath the API can alter availability, accepted options, performance and behavior.
We encountered that fact before completing our first prompt experiment.
1. The first session worked
Our first real Chrome trace recorded this sequence:
LanguageModel exposed
↓
availability = available
↓
session creation started
↓
progress 0 → 1
↓
session ready in ~8.2 ms
The session exposed a quota of 9,216 units and supported clone() and destroy().
Later, after the extension and browser environment had changed, a new session creation failed:
The sampling options are incompatible with speculative decoding (MTP). Prompt API sessions must specify compatible sampling options, i.e.
samplingMode:'most-predictable'ortopK:1ortemperature:0.
This is the book’s thesis in miniature.
The application used the same capability name. The active runtime imposed a contract we had not previously satisfied.
2. Separate observation from explanation
The error directly supports several claims:
- the session configuration was rejected;
- the rejection concerned sampling compatibility;
- the runtime associated the constraint with speculative decoding or MTP;
- three compatible alternatives were named.
It does not directly establish:
- the complete speculative-decoding architecture;
- whether a separate draft model was involved;
- how many tokens were proposed or verified;
- whether every MTP implementation requires greedy decoding;
- the exact model identity serving the request.
Those may be plausible explanations, but they are not observations contained in the error.
This distinction matters throughout an experimental book. Browser messages, public documentation, source code, operator configuration and our own hypotheses are different evidence classes.
3. Capability detection is necessary but insufficient
An application commonly checks:
const availability = await LanguageModel.availability(options);
That check can answer whether the browser currently considers the requested capability available. It does not prove that every later lifecycle step will succeed.
Robust code must still handle creation failure:
async function openSession(options) {
const availability = await LanguageModel.availability(options);
if (availability === "unavailable") {
return { outcome: "unavailable" };
}
try {
const session = await LanguageModel.create(options);
return { outcome: "ready", session };
} catch (error) {
return {
outcome: "creation-failed",
error: { name: error.name, message: error.message }
};
}
}
Availability is one state transition, not a certificate for the whole feature.
4. Prefer a named compatibility mode
The reported runtime accepted three alternatives:
{ samplingMode: "most-predictable" }
{ topK: 1 }
{ temperature: 0 }
Browser AI Observatory uses:
const session = await LanguageModel.create({
samplingMode: "most-predictable",
expectedInputs: [{ type: "text", languages: ["en"] }],
expectedOutputs: [{ type: "text", languages: ["en"] }]
});
The named mode expresses intent more clearly than an isolated numeric parameter: choose the runtime’s most predictable supported sampling behavior.
This is a compatibility decision for the experiment harness. It is not evidence that deterministic sampling is optimal for every writing or creative feature. A product that requires diversity may need another supported execution path or may decide that the current local capability does not satisfy its contract.
5. The browser owns asset lifecycle
Browser-managed AI can depend on eligibility and local resources outside application control:
- browser version and experimental configuration;
- operating system and hardware capability;
- language support;
- available storage;
- model acquisition and update state;
- browser policies;
- current runtime implementation.
An application should not attempt to impersonate a package manager for these assets. It should observe exposed states and design user-visible recovery.
flowchart TD
A[Capability request] --> E{Eligible now?}
E -->|No| F[Explain or fall back]
E -->|Yes| R{Assets ready?}
R -->|No| P[Show acquisition progress]
R -->|Yes| C[Create session]
P --> C
C -->|Rejected| D[Record compatibility failure]
C -->|Ready| U[Run feature]
The application owns every branch even when the browser owns the model.
6. Progress is browser-managed evidence, not a byte counter
Our first trace received progress values from zero to one while availability was already available and creation completed in milliseconds.
The API’s event is named downloadprogress, but the observed sequence did not prove a new model download. The browser may emit current acquisition state to a newly attached monitor.
The debugger should preserve the raw event name while the UI uses careful wording such as:
Preparing required model assets: 100%
It should avoid:
Downloaded Gemma 4
The second message invents both a transfer and a model identity.
7. Model identity is not attested by the API
The experimental flag gives the operator a reason to label a run “Gemma 4 flag enabled.” The session object does not return an attested identity proving that a particular model produced the output.
The export therefore stores:
{
"model": {
"operatorLabel": "Gemma 4 flag enabled",
"source": "operator-supplied",
"browserAttested": false
}
}
This still supports a useful experiment. We can compare outputs under two recorded configurations while describing exactly what was controlled.
It prevents a stronger claim than the evidence supports.
8. Version evidence has layers too
The first run’s reduced user-agent string reported:
Chrome/152.0.0.0
The operator recorded the complete build:
152.0.7977.65
Both belong in the run envelope. The user agent is captured automatically but intentionally reduces version detail. The operator note preserves the precise build used for reproduction.
Automatically captured data is not automatically sufficient data.
9. Stable code can encounter a changed contract
When a browser update changes behavior behind a capability, several responses are possible:
- Adapt: choose a newly required compatible option.
- Degrade: disable the feature with a specific explanation.
- Fall back: use another local or remote path after disclosing data movement.
- Gate: block release until canonical fixtures pass.
- Pin: use a controlled browser environment for experiments, not for general web deployment.
Silent retry with arbitrary parameters is dangerous. It can change output behavior and make traces incomparable.
Compatibility policy should be versioned:
const PROMPT_PROFILE = {
id: "prompt-most-predictable/1",
options: {
samplingMode: "most-predictable",
expectedInputs: [{ type: "text", languages: ["en"] }],
expectedOutputs: [{ type: "text", languages: ["en"] }]
}
};
Now a run identifies the application-level profile as well as the browser configuration.
10. Updates require behavioral regression tests
Even if session creation succeeds after adaptation, output behavior may change.
A browser or model update can affect:
- instruction following;
- latency and throughput;
- context consumption;
- structured-output reliability;
- safety behavior;
- language coverage;
- fixture pass rate.
The correct response is not to freeze one prompt forever. It is to maintain a small corpus representing the feature contract and rerun it when the environment changes.
Operational traces answer whether the system ran. Behavioral fixtures answer whether the feature still did its job.
Part IV will turn that combination into a release gate.
11. Purging and storage pressure are user-visible states
A model that was available yesterday may need acquisition again after browser cleanup, storage pressure or an update. The web application cannot assume permanent installation merely because one prior session succeeded.
The interface needs durable language for temporary states:
- “AI capability is not available on this device.”
- “Preparing the local capability.”
- “The session configuration is no longer accepted.”
- “The local capability changed; rerunning compatibility checks.”
These messages describe the feature boundary without promising an implementation the application does not control.
12. The abstraction boundary still works
Our compatibility failure does not disprove the built-in AI architecture. It clarifies it.
The browser successfully hid model acquisition, storage and execution from the extension. The application did not download weights or initialize an inference engine.
But an abstraction boundary is a contract, not a wall against change. Applications must still negotiate supported options, handle lifecycle states, measure behavior and recover from failure.
The model can be an implementation detail while the model’s effects remain an application concern.
Conclusion
When the browser manages the model, it owns selection, acquisition, updates and execution strategy. The application owns compatibility, feature behavior, failure recovery and truthful communication.
Our first two observations demonstrated both sides. A session became ready without application-managed model code. A later session failed because the active runtime required a compatible sampling mode.
That failure is not an interruption to the book. It is the most direct evidence yet for the book’s thesis.
We now have the architecture of the browser runtime, its task APIs, session lifecycle, context budget, performance measurements and model-management boundary. Part IV asks the harder product question: when the operation resolves successfully, how do we know the result is correct enough to use?
Sources and further reading
- Chrome for Developers, The Prompt API.
- Chrome for Developers, Understand built-in model management in Chrome.
- Chrome for Developers, Get started with built-in AI.
- Google DeepMind, Gemma.