By embedding native chat UI components directly into your SKILL.md instructions, you transform your agent from a passive text parser into an active technical interviewer with a delightful user experience.
Here is what you will get out of this deep dive:
📝 About this series: Welcome to Elevating Antigravity Agent Skills series, a 5-part engineering guide to mastering the agent tools that reduce orchestration tax and transform AI agents into autonomous collaborators: ask_question, generate_image, define_subagent + invoke_subagent, send_message and manage_subagents.
In Antigravity, agent capabilities are packaged as skills. These are dedicated directories containing a SKILL.md
file with YAML frontmatter for discovery and Markdown instructions for execution. By default, agents interpret instructions sequentially and execute terminal commands or file edits. However, when an Antigravity agent encounters explicit instructions to invoke the ask_question tool, it suspends execution and renders a native, interactive UI modal in the chat window.
This simple tool invocation bridges the gap between agent autonomy and human-in-the-loop (HITL) alignment. Instead of guessing parameter values or parsing ambiguous prompts, the agent presents structured radio buttons, checkboxes, and write-in fields.
To eliminate repetitive questioning across sessions and subagents, I pair UI interrogation with persistent state hydration. My agent's lifecycle follows a structured sequence:
user_prefs.json
) At the start of the workflow, the agent checks the workspace root for a namespaced configuration file. If found, it extracts saved defaults to use during UI presentation.
ask_question modals
) The agent invokes ask_question
with finite option arrays and multi-select flags, prefixing hydrated defaults with "(Current Setting) " so the user sees active preferences immediately.
user_prefs.json
) The agent serializes updated selections back to user_prefs.json
in the workspace root, establishing an unshakeable source of truth for future subagent invocations. This is not a special Antigravity file, but rather one I've named and created for the use of my project. You should name and place this file in a location most suitable for your needs.Before diving into custom skill authoring, it is worth noting that Antigravity natively supports interactive alignment through the /grill-me
slash command.
When you trigger /grill-me
during a chat session, the agent temporarily s code execution to conduct a rigorous, multi-question interview. Instead of making silent architectural assumptions, the agent systematically interrogates you on design trade-offs, edge cases, and implementation boundaries until ambiguity is resolved.
While /grill-me
is an exceptional built-in tool for ad-hoc session planning and general requirements gathering, custom Interactive Skills take this concept a step further. By authoring custom markdown skills that invoke UI selection modals, engineering teams can standardize domain-specific interview workflows (like form scaffolding or cloud deployments) and persist the resulting answers directly into workspace configuration files for subagent grounding.
You can learn more about the /grill-me
command in Richard Seroter's article, Crafting an agent team that still includes me.
To see this architecture in action, examine how I've implemented the exemplar making-forms-demo skill. This skill interviews developers before generating a web form, ensuring validation rules and label layouts match team standards.
Figure 1: When we prompt "Make a web form", our making-forms-demo skill is auto-discovered by the agent and read into context. The skill instructs the agent to present the user with a series of questions using the ask_question tool.
Before rendering UI components, the skill instructs the agent to read the existing state from user_prefs.json
.
---
name: making-forms-demo
description: >
Interviews the user for critical implementation details needed to
generate a Web Form. Manages FORM namespace in `user_prefs.json`.
Use when making Web Forms.
---
Interviews the user for critical implementation details needed to
generate a Web Form.
## Workflow Steps
1. **Confirm Intent & Hydrate State:**
Check if `user_prefs.json` exists in the workspace root.
If present, read the `"FORMS"` object to identify any previously
saved preferences. Tell the user that a form has been identified
and that a few questions must be answered (or confirmed) before
building the form.
If previous preferences exist, the agent prefixes those strings with "(Current Setting) " and places them at the top of the options array. When executed, this Markdown block generates an interactive modal supporting multi-selection checkboxes (is_multi_select: true). Because the options are explicitly enumerated, the agent never guesses validation requirements.
2. **Query Validation Type:**
Invoke the `ask_question` tool to present the user with an option
selection UI. If previously saved values exist in
`user_prefs.json`, prefix those option strings with
`"(Current Setting) "` and list them first:
* **Question:** "How would you like to handle field validation?
(select all that apply)"
* **Options:** ["Client-side validation",
"Server-side validation"]
Use the selected value as `FIELD_VALIDATION_TYPE`.
For mutually exclusive architectural choices, the skill configures single-selection lists. By omitting an explicit "other" string from the options array, the agent automatically enables Antigravity's native default write-in option in the UI modal.
3. **Query Validation Location:**
Invoke the `ask_question` tool to present the user with an option
selection UI. If a previously saved value exists in
`user_prefs.json`, prefix that option string with
`"(Current Setting) "` and list it first:
* **Question:** "How would you like to handle validation
messages?"
* **Options:** ["Above the field", "Below the field",
"Summary Card", "Tooltip"]
Use the selected value as `FIELD_VALIDATION_LOCATION`.
If a developer selects the write-in option in the modal and types "Inline below label", the agent captures that custom string directly into FIELD_VALIDATION_LOCATION
without requiring custom syntax parsing.
Once the user submits the modal, the agent cleans the input strings by removing "(Current Setting) " prefixes and writes the finalized structure back to the workspace root:
4. **Persist User Preferences:**
Write the user's selected form preferences to a `user_prefs.json`
file in the workspace root directory using the `write_to_file`
tool (or overwrite existing preferences). This guarantees that
future agent invocations and subagents are grounded in the user's
exact specifications without needing
to re-interview them:
``` json
{
"FORMS": {
"FIELD_VALIDATION_TYPE": ["<SELECTED_VALUES>"],
"FIELD_VALIDATION_LOCATION": "<SELECTED_VALUE>",
"FIELD_LABEL_TYPE": "<SELECTED_VALUE>"
}
}
Mock Skill Instructions #
Since this skill is just a mock skill for illustrating how to create interviewer UI within the chat window, don't actually create a form. Instead:
- Write the selections to
user_prefs.jsonin the workspace root. - Output the form selections to the user as confirmation using the template below:
For each field: <FIELD_NAME>: <SELECTED_VALUE>
By nesting form preferences under the "FORMS" namespace, the workspace configuration file remains clean and scalable. Other skills, such as deployment or database bootstrappers, can safely manage their own state within the same JSON root without collision.
*Figure 2: The next time the skill is used it finds the user_prefs.json file previously created and uses the data to mark appropriate responses as "(Current Selection) ". The preferences file is updated should the user change their selections.*
As you transition your team's custom skills from static text prompts to interactive interviewers, adhere to these four best practices to keep your workflows sharp and maintainable:
Interactive modals are designed for fast scanability. If a selection list exceeds seven items the user can get overwhelmed with options and revert to guessing. When dealing with large datasets, such as hundreds of marketing campaigns or cloud regions, never dump the raw array directly into an `ask_question`
block. Instead, instruct the agent to query an MCP tool first to filter the choices down to a top-5 list relevant to the current workspace before rendering the modal.
A common mistake is explicitly adding "Other" or "Custom value" to the options array in `SKILL.md`
. In Antigravity, the `ask_question`
tool renders a default write-in text field automatically whenever an interactive question is presented. Explicitly including an "other" string creates redundant, confusing options and forces the agent to handle an unnecessary secondary text-prompting step.
When persisting user selections to `user_prefs.json`
, always nest key-value pairs under a high-level domain namespace (such as "FORMS", "DEPLOYMENT", or "TESTING"). If multiple skills write flat keys directly to the root of the JSON object, key collisions become inevitable as your team's skill pack grows. Namespacing guarantees strict boundary isolation across autonomous subagents.
Format option strings as the user's direct voice (e.g., "Floating labels (Labels sit inside the input field)") rather than third-person imperative commands (e.g., "Set form layout to floating"). Direct-response phrasing reduces cognitive friction and makes interactive modals read more naturally.
The era of typing massive, brittle paragraphs into chat prompts to guide autonomous coding agents is over. By combining declarative Markdown instructions, native `ask_question`
UI components, and round-trip JSON state hydration, skill authors can transform AI assistants into rigorous technical interviewers.
`ask_question`
`generate_image`
`define_subagent`
, `invoke_subagent`
`send_message`
`manage_subagents`
Thanks for reading!