jevbooks

← All design patterns

Prefetch

Speculative heads · 预问

Ask every branch, read the one you take

Ask the questions for every branch up front, then read only the answers on the branch you actually take.

stateoptargettargettarget

The problem

Every step of your browser agent — a program that drives a web page on its own — takes two decisions: first whether this step is a click, a keystroke or a scroll, and then which element to click or which field to fill.

The natural way to write that is two calls. Ask the operation, wait 300 ms, and once the answer is in, ask the target — another 300 ms. That is 600 ms per step, so a forty-step task spends half a minute purely waiting for round trips. Nest the decisions five deep and a single step takes 1.5 seconds.

You think about caching the answers ahead of time, and you cannot: what the next question even is depends on the answer to the last one. The time is not going into thinking, it is going into waiting to find out what to ask.

The solution

The Prefetch pattern says: send the questions that each branch would need together with the branching question, without waiting.

One request carries all three at once: which operation is next, which element if it is a click, which field if it is typing. Everything comes back together, you look at the first answer, and you read only the one that matches.

The branches you did not take are thrown away unread — there is nothing to check, because nothing will be acted on. This works as long as each branch’s list of candidates can be written before you ask: the clickable elements and the fillable fields were enumerated by your code anyway, and neither depends on the first answer.

Ask · Answer · Act

  1. AskPut in the goal and the page, and ask three things at once: which operation is next, which element if it is a click, which field if it is typing.
  2. AnswerClick at 0.84; for the click, element 12 at 0.71; the typing target was answered too, and will not be used.
  3. ActIt is a click, so the code follows the click answer and drops the typing answer on the floor.

Where the name comes from

The cabling a builder buries in a wall. Nobody knows yet whether a television or a lamp will hang there, but once the wall is closed, cutting a channel is expensive — so while it is open you run several lines in and pull whichever one you end up needing. This is not caching an answer in advance; it is asking several undecided routes in one go.

Use it when

The decision is at least two levels deep, and the options at the second level can be listed before the first level is answered.

Not when

The second level’s options only exist once the first is settled — you learn which buttons are there only after clicking through. Or there are so many branches that the extra words cost more than the round trip you saved.

Projects that do this

  • jev-ultrafast — Browser agent where Jev picks each action and element; LLM only types text.
  • huncho — Decisions as code on System One models: typed questions, hysteresis, journal, calibration.
  • mobile-jev — Android agent where Jev picks every action from live device state.

All projects with this pattern →

Read this code
Show me the code
const { answers } = await jev(state, {
  operation:      choice("Which operation comes next?", ["click", "type", "scroll"]),
  "click.target": choice("Which element would be clicked?", clickable),
  "type.target":  choice("Which field would be typed into?", fields),
});
const op = answers.operation.choice;
const head = answers[`${op}.target`];   // the other branches are dropped, not validated
if (!head) return act(op);              // scrolling has no target
perform(op, head.choice);
How jevbooks recognises it

How do we know a project does this? We put one question about its README to Jev and it returns a percentage; the higher, the more it looks like it. If you copy the question, copy one thing: ask whether the text mentions this one concrete thing, never whether the project is good.

questions.json · sent for every README
{
  "speculative-heads": {
    "type": "noul",
    "instructions": {
      "what": "Does the text describe asking questions for every possible branch up front and consuming only the ones matching the chosen branch, such as an operation question sent together with one target question per operation?",
      "not_for": "Asking follow-up questions only after the first answer arrives."
    },
    "criteria": {
      "true": "The text explicitly describes this. One sentence is enough; other content does not cancel it.",
      "false": "The text does not describe this."
    }
  }
}

Build this with Jev →