Pick an output format
Pick one and stay in it. The formats differ only in how you declare tools and read the output. The rest of this page applies to both.
Single-shot JSON through
structured_outputs works on every model, Holo4 included: element localization uses it.
Answer tool
Holo ends a task by calling a tool namedanswer, with its report in the content argument. Register it with your action tools, in both formats, and stop the loop when it is called. A step with no tool call is not a stop: append the message and keep looping.
Reasoning
Each call returns a thinking trace inmessage.reasoning and the action in content (or tool_calls). Holo is trained to plan before each step, so keep thinking on in agent loops:
On Holo4,
reasoning_effort: "none" turns thinking off. The Agents API spelling disabled returns 400 here. All parameters: Chat completions.
The Qwen 3.5 chat template Holo inherits drops past reasoning between turns, so anything the model must remember goes through content. When you append the assistant message, push only the parsed output, never the reasoning.
Coordinates in [0, 1000]
Send a screenshot at any size. Holo returns integer coordinates in [0, 1000], normalized to that image, origin top-left. Scale back with its dimensions:
Observations
An observation is what the agent sees after it acts. Agents without a screen (code, MCP) need nothing extra: the task is the firstuser message and each tool result goes back as a tool result. The rest of this section is for screen agents.
Each step, send the current screenshot as a user message wrapped in <observation> tags:
Image budget
Keep at most the last 3 screenshots in context: more degrades accuracy. Replace older ones with a text placeholder and keep their<observation> wrapper. Call this helper after appending each observation. The loop guides and cookbooks use it.
Sampling
Common pitfalls
Format-specific pitfalls are on each loop guide.