Build a Documentation Generator Skill

Create a reusable AI agent skill that generates consistent technical docs.

Introduction

30 Second Summary

AI coding agents can generate code on the fly, but ask one to write API documentation twice and you will get two completely different structures. Without a shared standard, every generated document is a one-off.

In this project, you will build a reusable Agent Skill that teaches any compatible AI agent how to generate consistent, well-structured technical documentation. You will author a skill definition, create reference templates for four document types, and add a validation script to verify the output.

What You'll Build

A production-ready documentation generator Agent Skill portable across Google Antigravity, Claude Code, Cursor, and other skills-compatible agents.

By the end of this project, you'll have:

  • A complete writing-documentation skill with a SKILL.md file, YAML frontmatter, and a conditional workflow routing to four document types.
  • Four reference templates (API docs, system design, database schema, README) loaded on demand through progressive disclosure.
  • A Python validation script the agent can run to verify generated documentation meets required standards.
  • Secret Mission: Build a second Agent Skill for automated test generation, applying the same patterns independently.

Are there any prerequisites?

This project assumes you are familiar with Markdown and have basic Python experience. You should also have used at least one AI coding agent before, such as Google Antigravity, Claude Code, or Cursor.

Set Up the Skill Directory Structure

Right now, every time you ask an AI coding agent to write documentation, you start from scratch. You describe the format, the sections, the tone. The result depends entirely on how well you prompt each time.

Agent Skills solve this by giving agents a reusable set of instructions they can follow automatically. In this step, you will create the directory structure that makes your first skill discoverable by any compatible agent tool.

In this step, get ready to:
  • Create the skill directory with references/ and scripts/ subdirectories.
  • Add a skeleton SKILL.md file with empty frontmatter.
  • Verify the skill is discoverable in Google Antigravity.
Create the skill directory

The Agent Skills specification defines a standard directory layout that compatible agents scan automatically. Your skill lives inside a .agents/skills/ directory at the root of any project folder.

  • Press the Windows key (Windows) or Cmd+Space (macOS) to open your search bar.
  • Type PowerShell (Windows) or Terminal (macOS) and press Enter to open it.
  • Move to your Desktop by running this command:
cd ~/Desktop
  • Create a project folder and the full skill directory structure by running these commands:

macOS

mkdir my-project
cd my-project
mkdir -p .agents/skills/writing-documentation/references
mkdir -p .agents/skills/writing-documentation/scripts

Windows

mkdir my-project
cd my-project
mkdir .agents/skills/writing-documentation/references
mkdir .agents/skills/writing-documentation/scripts

What is this directory structure?

The .agents/skills/ path is the widely adopted cross-client convention. Skills placed here are automatically discoverable by Google Antigravity, Claude Code, Cursor, GitHub Copilot, and other compatible agents.

Inside writing-documentation/, the references/ subdirectory will hold your document templates. The scripts/ subdirectory will hold a validation script the agent can run to check its own output.

  • Confirm the directories exist by running:
ls .agents/skills/writing-documentation/

You should see references and scripts listed in the output.

Not seeing the directories?

Make sure you ran cd my-project before creating the skill directories. If you skipped that step, the .agents folder was created on your Desktop instead of inside the project folder.

On macOS, folders starting with a dot are hidden in Finder by default. They still exist and will appear in your code editor and terminal.

Help me troubleshoot my skill directory structure.

Create a skeleton SKILL.md

The SKILL.md file is the only required file in a skill. Everything else (scripts, references, assets) is optional. The agent reads this file to understand what the skill does and how to use it.

  • Press the Windows key (Windows) or Cmd+Space (macOS) to open your search bar.
  • Type the name of your code editor (e.g. VS Code) and press Enter to open it.
  • Click File in the top menu bar.
  • Click Open Folder.
  • Select the my-project folder on your Desktop, then click Open.

You should see the .agents folder in the file explorer sidebar on the left.

  • In the file explorer sidebar, expand the .agents folder.
  • Expand skills, then writing-documentation.
  • Right-click on writing-documentation and select New File.
  • Name the file SKILL.md and press Enter.
  • Add the empty YAML frontmatter delimiters by copying this into the file:
---
---

What is YAML frontmatter?

YAML frontmatter is a block of metadata at the top of a Markdown file, wrapped between two --- lines. Agent tools parse this frontmatter to learn the skill's name and description without reading the entire file.

Right now the frontmatter is empty. You will fill in the name and description fields in the next step.

  • Save SKILL.md by pressing Ctrl+S (Windows) or Cmd+S (macOS).

Your file explorer should now show SKILL.md alongside the references and scripts folders inside writing-documentation.

✔️ Awesome, I've got everything!

Great. Double check you have saved SKILL.md and you are ready to move on.

ⓧ I'd like to double check the full code

Here is the complete SKILL.md file at this point:

---
---

Don't see the .agents folder in your editor?

Some code editors hide dot-prefixed folders by default. In VS Code, the .agents folder is visible by default. If you are using a different editor, check its file-visibility or exclude settings.

Also confirm you opened the my-project folder itself, not the Desktop. The .agents folder should be at the top level of the opened folder.

Help me find my .agents folder in my code editor.

Verify the skill is discoverable

Google Antigravity scans the .agents/skills/ directory when a conversation starts. It loads the name and description from each skill's frontmatter to decide when to activate it.

  • Press the Windows key (Windows) or Cmd+Space (macOS) to open your search bar.
  • Type Google Antigravity and press Enter to open it.
  • Open the my-project folder from your Desktop inside Google Antigravity.
  • Start a new conversation.

At this point, the agent should detect the skill directory even though the frontmatter is still empty. You will fully test activation in a later step after adding the skill's name and description.

What about global skills?

Skills in .agents/skills/ are workspace-scoped. They only apply to the project that contains them.

Google Antigravity also supports global skills at ~/.gemini/config/skills/. Global skills are available across all your projects. You will have the option to copy your skill there in the Before You Go section.

Skill not appearing in Google Antigravity?

Check that your directory name matches exactly: .agents/skills/writing-documentation/. A typo in any folder name will prevent discovery.

Make sure the SKILL.md file exists inside the writing-documentation folder and that its YAML frontmatter delimiters (---) are on separate lines with no extra spaces.

Help me troubleshoot why Google Antigravity cannot find my skill.

Your skill directory is in place and your agent tool can see it. Next up, you will fill in the SKILL.md with the frontmatter, conditional workflow, and writing guidelines that turn this empty skeleton into a working documentation generator.

Author the SKILL.md

Your skill directory is set up and the agent can already see the skeleton SKILL.md file. The file is empty though, so the agent has nothing to work with yet.

In this step, you'll author the full SKILL.md content. This includes the YAML frontmatter that controls how the agent discovers the skill, and the Markdown body that guides the agent through generating documentation.

In this step, get ready to:
  • Write the YAML frontmatter with a name and description that control skill discovery.
  • Write the skill body with a conditional workflow routing to four document types.
  • Add writing guidelines that standardize the agent's documentation output.
Write the YAML frontmatter

The YAML frontmatter is the metadata block at the top of every SKILL.md. It has two fields that the agent reads at startup to decide whether to activate the skill.

  • In your code editor, open SKILL.md inside the writing-documentation/ folder.
  • Find the empty frontmatter delimiters:
---
---
  • Replace the empty frontmatter with the following:
---
name: writing-documentation
description: Generates consistent, well-structured technical documentation including API docs, system design docs, database schema docs, and README files. Use when asked to write documentation, create docs, generate API reference, document endpoints, write a README, document a database schema, or create a system design document.
---

What do these fields do?

The name field must match the parent directory name exactly. It can only use lowercase letters, numbers, and hyphens, with a maximum of 64 characters.

The description field is how the agent decides when to activate this skill. It gets injected into the system prompt, so it should be written in third person. The keywords you include (like "API docs", "write documentation", "generate reference") help the agent match your request to the right skill.

You won't see a visible change yet. The body you add next completes the skill's instructions.

YAML syntax errors later?

Make sure both --- delimiters are on their own lines with no leading spaces. The name and description fields must each have a colon and a space before the value.

help me debug my SKILL.md YAML frontmatter

Write the body with conditional workflow and guidelines

The body of SKILL.md is regular Markdown that the agent reads when the skill activates. This is where you tell the agent exactly what to do, which templates to load, and what standards to follow.

The key pattern here is a conditional workflow. Instead of dumping all four templates into the skill file, each document type points to its own reference file using a relative path. The agent only loads the specific template it needs.

What is progressive disclosure?

Progressive disclosure is a three-stage loading strategy from the Agent Skills specification. At startup, the agent reads only the metadata (about 100 tokens). On activation, it reads the full SKILL.md body (recommended under 5000 tokens). Resource files like templates are loaded only when needed.

This keeps the agent's context lean. If you ask it to write API docs, it only loads the API template. It never wastes tokens loading the README template.

  • In SKILL.md, place your cursor on the blank line below the closing --- delimiter.
  • Add the skill heading and Quick Start section, followed by the Document Types section with conditional routing, by pasting the following below the frontmatter:

# Writing Documentation

## Quick Start

When asked to generate documentation, follow these steps:

1. Identify the document type from the user's request
2. Load the appropriate template from the references directory
3. Follow the template structure and fill in content based on the codebase
4. Run the validation script to check the output

## Document Types

**API Documentation**: See [references/api-docs-template.md](references/api-docs-template.md)
Use when documenting REST APIs, GraphQL endpoints, or SDK methods.

**System Design Document**: See [references/system-design-template.md](references/system-design-template.md)
Use when documenting architecture decisions, system components, or technical proposals.

**Database Schema Document**: See [references/database-schema-template.md](references/database-schema-template.md)
Use when documenting database tables, relationships, migrations, or data models.

**README File**: See [references/readme-template.md](references/readme-template.md)
Use when creating or updating project README files.

What does this code do?

The Quick Start section gives the agent a high-level overview. It reads these steps first to understand the overall flow before diving into details.

The Document Types section is the conditional workflow. Each document type links to a reference template file using a relative path like references/api-docs-template.md. When a user asks for API docs, the agent loads only that template. When asked for a README, it loads only the README template.

The Workflow and Writing Guidelines you add next will complete the skill's instructions.

  • Add the Workflow and Writing Guidelines sections by pasting the following directly below the README File entry:

## Workflow

1. **Determine document type**: Match the user's request to one of the four types above
2. **Load template**: Read the corresponding reference file for structure and required sections
3. **Gather context**: Analyze the relevant code, configs, or schemas in the project
4. **Generate content**: Follow the template structure, filling each section with accurate, specific content from the codebase
5. **Validate**: Run `python scripts/validate-docs.py <output-file>` to check for completeness

## Writing Guidelines

- Write in present tense for current behavior, future tense for planned features
- Use consistent terminology throughout the document
- Include concrete examples with realistic values, not placeholder data
- Keep sentences concise and scannable
- Use code blocks with language identifiers for all code snippets
- Link to related documentation when referencing other systems or components

What does this code do?

The Workflow section expands the Quick Start into a detailed five-step process. Step 5 tells the agent to run a validation script you'll create in a later step. The agent treats these numbered steps as sequential instructions.

The Writing Guidelines section standardizes the agent's writing style. Without these, the agent defaults to its own habits. These rules ensure every document it generates follows the same conventions.

  • Save SKILL.md.
  • Scroll through the file in your editor. You should see five sections in order: the YAML frontmatter at the top, then # Writing Documentation, ## Quick Start, ## Document Types, ## Workflow, and ## Writing Guidelines.

Missing a section or seeing formatting issues?

Check that the closing --- of the frontmatter is followed by a blank line before the # Writing Documentation heading. Markdown headings need a blank line above them to render correctly.

Make sure each ## heading has a space between the hashes and the heading text. Missing that space turns the heading into plain text.

help me fix the formatting of my SKILL.md file

Why keep the SKILL.md body under 500 lines?

The Agent Skills specification recommends keeping the SKILL.md body under 500 lines. Detailed content like full templates belongs in separate reference files. This keeps the agent's instructions focused while the reference files provide the depth on demand.

✔️ Awesome, I've got everything!

Great. Double check you've saved SKILL.md before moving on.

ⓧ I'd like to double check the full code

Here is the complete SKILL.md file. Compare your file against this to make sure everything matches.

---
name: writing-documentation
description: Generates consistent, well-structured technical documentation including API docs, system design docs, database schema docs, and README files. Use when asked to write documentation, create docs, generate API reference, document endpoints, write a README, document a database schema, or create a system design document.
---

# Writing Documentation

## Quick Start

When asked to generate documentation, follow these steps:

1. Identify the document type from the user's request
2. Load the appropriate template from the references directory
3. Follow the template structure and fill in content based on the codebase
4. Run the validation script to check the output

## Document Types

**API Documentation**: See [references/api-docs-template.md](references/api-docs-template.md)
Use when documenting REST APIs, GraphQL endpoints, or SDK methods.

**System Design Document**: See [references/system-design-template.md](references/system-design-template.md)
Use when documenting architecture decisions, system components, or technical proposals.

**Database Schema Document**: See [references/database-schema-template.md](references/database-schema-template.md)
Use when documenting database tables, relationships, migrations, or data models.

**README File**: See [references/readme-template.md](references/readme-template.md)
Use when creating or updating project README files.

## Workflow

1. **Determine document type**: Match the user's request to one of the four types above
2. **Load template**: Read the corresponding reference file for structure and required sections
3. **Gather context**: Analyze the relevant code, configs, or schemas in the project
4. **Generate content**: Follow the template structure, filling each section with accurate, specific content from the codebase
5. **Validate**: Run `python scripts/validate-docs.py <output-file>` to check for completeness

## Writing Guidelines

- Write in present tense for current behavior, future tense for planned features
- Use consistent terminology throughout the document
- Include concrete examples with realistic values, not placeholder data
- Keep sentences concise and scannable
- Use code blocks with language identifiers for all code snippets
- Link to related documentation when referencing other systems or components

Your SKILL.md is complete, but the four reference templates it points to don't exist yet. Next up, you'll create those templates so the agent has real structures to follow when generating each document type.

Create the Reference Templates

Your SKILL.md is complete with a conditional workflow that routes to four reference template files. There is just one problem: those files do not exist yet.

Reference templates are the heart of progressive disclosure. Instead of cramming every detail into your SKILL.md, the agent loads only the specific template it needs for the request at hand.

In this step, get ready to:
  • Create an API documentation reference template.
  • Create a system design document reference template.
  • Create database schema and README reference templates.
Create the API docs template

API documentation is one of the most common doc types developers produce. A good template ensures every endpoint is documented with its method, path, parameters, request body, response shape, and status codes.

  • Create a new file called api-docs-template.md inside the references/ directory.
  • Paste the following template into the file:
# API Documentation Template

## Required Sections

### Title
# [Service Name] API Documentation

### Overview
Brief description of the API, its purpose, and intended audience.

### Base URL

Production and staging URLs in a code block.

### Authentication
Describe the authentication method (API key, OAuth 2.0, JWT, etc.).
Include example request headers showing how to pass credentials.

### Endpoints
For each endpoint, include:

#### [HTTP Method] [Path]
- **Description**: What this endpoint does
- **Parameters**:

  | Name | Type | Required | Description |
  |------|------|----------|-------------|
  | id   | string | Yes    | Resource identifier |

- **Request Body** (if applicable): JSON example in a fenced code block
- **Response**: JSON example in a fenced code block showing the success response structure
- **Status Codes**:

  | Code | Description |
  |------|-------------|
  | 200  | Success     |
  | 400  | Bad request |
  | 401  | Unauthorized |
  | 404  | Not found   |
  | 500  | Internal server error |

### Error Handling
Describe the standard error response format.
List common error codes and their meanings.

### Rate Limiting
Document rate limits, relevant response headers, and retry strategies.

## Guidelines
- Group endpoints by resource (e.g., Users, Orders, Products)
- Include curl examples for each endpoint
- Document all query parameters, including optional ones
- Show both success and error response examples
- Note deprecated endpoints clearly with migration guidance

What does this template do?

This template gives the agent a required-sections checklist for API docs. Instead of guessing what to include, the agent follows a predefined structure covering everything from authentication to rate limiting.

The repeatable #### [HTTP Method] [Path] block is especially important. It tells the agent to produce the same format for every endpoint, keeping your docs consistent across your entire API.

  • Save api-docs-template.md.
  • Confirm the file exists by running this command from the writing-documentation directory:
ls references/

You should see api-docs-template.md listed in the output.

Don't see the file?

  • Make sure you created the file inside references/, not in the root writing-documentation/ directory.
  • Check that you saved the file after pasting the content. Unsaved files won't appear in the directory listing.
  • Verify the filename is exactly api-docs-template.md with no extra spaces or typos.

Help me figure out why my template file isn't showing up in the references directory.

✔️ Awesome, I've got everything!

Great. Make sure api-docs-template.md is saved and move on to the next template.

ⓧ I'd like to double check the full code

Here is the complete api-docs-template.md for comparison.

# API Documentation Template

## Required Sections

### Title
# [Service Name] API Documentation

### Overview
Brief description of the API, its purpose, and intended audience.

### Base URL

Production and staging URLs in a code block.

### Authentication
Describe the authentication method (API key, OAuth 2.0, JWT, etc.).
Include example request headers showing how to pass credentials.

### Endpoints
For each endpoint, include:

#### [HTTP Method] [Path]
- **Description**: What this endpoint does
- **Parameters**:

  | Name | Type | Required | Description |
  |------|------|----------|-------------|
  | id   | string | Yes    | Resource identifier |

- **Request Body** (if applicable): JSON example in a fenced code block
- **Response**: JSON example in a fenced code block showing the success response structure
- **Status Codes**:

  | Code | Description |
  |------|-------------|
  | 200  | Success     |
  | 400  | Bad request |
  | 401  | Unauthorized |
  | 404  | Not found   |
  | 500  | Internal server error |

### Error Handling
Describe the standard error response format.
List common error codes and their meanings.

### Rate Limiting
Document rate limits, relevant response headers, and retry strategies.

## Guidelines
- Group endpoints by resource (e.g., Users, Orders, Products)
- Include curl examples for each endpoint
- Document all query parameters, including optional ones
- Show both success and error response examples
- Note deprecated endpoints clearly with migration guidance
Create the system design doc template

System design documents capture the big picture: architecture patterns, component responsibilities, data flow, and the trade-offs behind each decision. This template ensures the agent documents not just what a system does, but why it was built that way.

  • Create a new file called system-design-template.md inside the references/ directory.
  • Paste the following template into the file:
# System Design Document Template

## Required Sections

### Title
# [System Name] - System Design Document

### Overview
Brief description of the system, the problem it solves, and its scope.

### Goals

#### Functional Goals
- What the system must do (user-facing capabilities)

#### Non-Functional Goals
- Performance targets (latency, throughput)
- Scalability requirements
- Reliability and availability targets
- Security requirements

### Architecture
High-level architecture description. Name the architectural pattern and explain why it was chosen.

### Components
For each major component:

#### [Component Name]
- **Responsibility**: What this component does
- **Technology**: Stack and framework choices
- **Interfaces**: APIs or events it exposes and consumes
- **Dependencies**: Other components it relies on

### Data Flow
Describe how data moves through the system for key operations.

### Data Model
Key entities and their relationships at a high level.

### Trade-offs and Alternatives
Document key architectural decisions and alternatives considered.

## Guidelines
- Focus on the "why" behind decisions, not just the "what"
- Include diagrams or ASCII art for visual clarity
- Document scaling strategies and known bottlenecks
- Address failure modes and recovery strategies
- Keep the document updated as the architecture evolves

What does this template do?

The system design template splits goals into functional (what the system must do) and non-functional (how well it must do it). This distinction is one developers often skip, leading to vague design docs.

The repeatable #### [Component Name] block ensures each component gets the same treatment: responsibility, technology, interfaces, and dependencies. The Trade-offs section pushes the agent to explain alternatives considered, not just the final choice.

  • Save system-design-template.md.

You won't see a visible change yet. The next substep continues building out the references/ directory with the final two templates.

✔️ Awesome, I've got everything!

Great. Make sure system-design-template.md is saved and move on to the final two templates.

ⓧ I'd like to double check the full code

Here is the complete system-design-template.md for comparison.

# System Design Document Template

## Required Sections

### Title
# [System Name] - System Design Document

### Overview
Brief description of the system, the problem it solves, and its scope.

### Goals

#### Functional Goals
- What the system must do (user-facing capabilities)

#### Non-Functional Goals
- Performance targets (latency, throughput)
- Scalability requirements
- Reliability and availability targets
- Security requirements

### Architecture
High-level architecture description. Name the architectural pattern and explain why it was chosen.

### Components
For each major component:

#### [Component Name]
- **Responsibility**: What this component does
- **Technology**: Stack and framework choices
- **Interfaces**: APIs or events it exposes and consumes
- **Dependencies**: Other components it relies on

### Data Flow
Describe how data moves through the system for key operations.

### Data Model
Key entities and their relationships at a high level.

### Trade-offs and Alternatives
Document key architectural decisions and alternatives considered.

## Guidelines
- Focus on the "why" behind decisions, not just the "what"
- Include diagrams or ASCII art for visual clarity
- Document scaling strategies and known bottlenecks
- Address failure modes and recovery strategies
- Keep the document updated as the architecture evolves
Create the database schema doc and README templates

The final two templates follow the same pattern you have seen: required sections, repeatable structures for each item, and type-specific guidelines. You will create both files in quick succession.

  • Create a new file called database-schema-template.md inside the references/ directory.
  • Paste the following template into the file:
# Database Schema Document Template

## Required Sections

### Title
# [Database Name] Schema Documentation

### Overview
Brief description of the database, its purpose, and the application it supports.

### Tables
For each table:

#### [table_name]
**Description**: What this table stores and its role in the system.

| Column | Type | Nullable | Default | Description |
|--------|------|----------|---------|-------------|
| id | UUID | No | gen_random_uuid() | Primary key |

### Relationships
Document foreign key relationships between tables.

### Indexes
Document indexes beyond primary keys.

### Migrations
Document the migration strategy, versioning approach, and any migration tooling used.

## Guidelines
- Use consistent naming: snake_case for tables and columns
- Document all constraints, not just foreign keys
- Include example queries for complex relationships
- Note any denormalization decisions and their rationale
- Flag columns that store sensitive data (PII, credentials)

What does this template do?

The database schema template ensures the agent documents tables with a column-level detail table (type, nullable, default, description). It also reminds the agent to cover relationships, indexes, and migrations, which are often left out of database docs.

  • Save database-schema-template.md.
  • Create a new file called readme-template.md inside the references/ directory.
  • Paste the following template into the file:
# README Template

## Required Sections

### Title
# [Project Name]

One-line description of what the project does.

### Overview
2-3 paragraphs explaining what the project is, what problem it solves, and who it is for.

### Getting Started

#### Prerequisites
List required tools, runtimes, and their minimum versions.

#### Installation
Step-by-step installation commands.

#### Configuration
Environment variables and config files needed.

### Usage
Show how to run and use the project with command examples and expected output.

### Project Structure
Directory tree with brief descriptions.

### Contributing
How to contribute: branch naming conventions, PR process, code style, and testing requirements.

### License
License type and a link to the full LICENSE file.

## Guidelines
- Keep the README focused and scannable
- Use badges for build status, coverage, version, and license
- Include screenshots or GIFs for projects with a UI
- Link to detailed docs rather than duplicating content in the README
- Keep installation steps copy-pasteable

What does this template do?

The README template covers the sections developers scan for first: prerequisites, installation, usage, and project structure. The Getting Started section is broken into three sub-sections (Prerequisites, Installation, Configuration) so nothing gets buried in a wall of text.

  • Save readme-template.md.
  • Confirm all four template files exist by running this command from the writing-documentation directory:
ls references/

You should see api-docs-template.md, database-schema-template.md, readme-template.md, and system-design-template.md listed in the output.

Missing a file?

  • Check that all four files are inside references/, not in the parent writing-documentation/ directory or the scripts/ directory.
  • Verify each filename ends with .md and matches exactly: api-docs-template.md, system-design-template.md, database-schema-template.md, readme-template.md.
  • Make sure you saved each file after pasting the content.

Help me figure out why I'm not seeing all four template files in my references directory.

✔️ Awesome, I've got everything!

Great. Double check you have saved both database-schema-template.md and readme-template.md.

ⓧ I'd like to double check the full code

Here is the complete database-schema-template.md for comparison.

# Database Schema Document Template

## Required Sections

### Title
# [Database Name] Schema Documentation

### Overview
Brief description of the database, its purpose, and the application it supports.

### Tables
For each table:

#### [table_name]
**Description**: What this table stores and its role in the system.

| Column | Type | Nullable | Default | Description |
|--------|------|----------|---------|-------------|
| id | UUID | No | gen_random_uuid() | Primary key |

### Relationships
Document foreign key relationships between tables.

### Indexes
Document indexes beyond primary keys.

### Migrations
Document the migration strategy, versioning approach, and any migration tooling used.

## Guidelines
- Use consistent naming: snake_case for tables and columns
- Document all constraints, not just foreign keys
- Include example queries for complex relationships
- Note any denormalization decisions and their rationale
- Flag columns that store sensitive data (PII, credentials)

And here is the complete readme-template.md for comparison.

# README Template

## Required Sections

### Title
# [Project Name]

One-line description of what the project does.

### Overview
2-3 paragraphs explaining what the project is, what problem it solves, and who it is for.

### Getting Started

#### Prerequisites
List required tools, runtimes, and their minimum versions.

#### Installation
Step-by-step installation commands.

#### Configuration
Environment variables and config files needed.

### Usage
Show how to run and use the project with command examples and expected output.

### Project Structure
Directory tree with brief descriptions.

### Contributing
How to contribute: branch naming conventions, PR process, code style, and testing requirements.

### License
License type and a link to the full LICENSE file.

## Guidelines
- Keep the README focused and scannable
- Use badges for build status, coverage, version, and license
- Include screenshots or GIFs for projects with a UI
- Link to detailed docs rather than duplicating content in the README
- Keep installation steps copy-pasteable

Why are templates kept in separate files?

This is progressive disclosure at work. The agent's SKILL.md stays lean (under 500 lines) while each template lives in its own file. When the agent needs to write API docs, it loads only api-docs-template.md. The other three templates stay unread, keeping the agent's context window focused.

The Agent Skills specification recommends keeping reference files one level deep from SKILL.md. All four templates link directly from the main skill file, so the agent reads complete files when needed without chasing nested references.

Your skill now has four reference templates ready for the agent to load on demand. Next up, you will build a validation script that the agent can run to check whether its generated documentation actually meets your template standards.

Add the Validation Script

Your skill now has a complete SKILL.md with a conditional workflow and four reference templates that cover every document type.

Templates alone cannot guarantee consistent output. An agent might skip sections or leave headings empty. In this step, you will add a Python validation script that the agent can run after generating any document to check whether all required sections are present.

In this step, get ready to:
  • Write a validation script that checks generated documents for missing and empty sections.
  • Test the script locally against a sample markdown file.
Write the validation script

The validation script reads a markdown file, auto-detects the document type, and checks it against the required sections defined in your templates. It uses only Python standard library modules so it stays self-contained with zero external dependencies.

Why no external dependencies?

The Agent Skills specification recommends that scripts be self-contained or clearly document their dependencies. Using only sys and re from the standard library means the script runs on any machine with Python installed. No pip install needed.

  • Open scripts/validate-docs.py in your code editor (this file does not exist yet, so create it inside the scripts/ directory).
  • Add the imports and the required-sections dictionary by pasting this code:
import sys
import re

# Each key maps a document type to the headings that must appear
REQUIRED_SECTIONS = {
    "api": [
        "Overview",
        "Base URL",
        "Authentication",
        "Endpoints",
        "Error Handling",
    ],
    "system-design": [
        "Overview",
        "Goals",
        "Architecture",
        "Components",
        "Data Flow",
    ],
    "database-schema": [
        "Overview",
        "Tables",
        "Relationships",
        "Indexes",
    ],
    "readme": [
        "Overview",
        "Getting Started",
        "Usage",
    ],
}

What does this code do?

The REQUIRED_SECTIONS dictionary is the source of truth for what the script checks. Each key (api, system-design, database-schema, readme) maps to a list of heading names the generated document must contain.

These headings mirror the required sections from the four reference templates you created in the previous step.

You will not see any output yet. The next chunks add the functions that use this dictionary.

  • Below the REQUIRED_SECTIONS dictionary, add three helper functions that parse and analyze the markdown file:

def extract_headings(content):
    # Pull every markdown heading (# through ######) from the file
    headings = []
    for line in content.split("\n"):
        match = re.match(r"^(#{1,6})\s+(.+)$", line)
        if match:
            level = len(match.group(1))
            title = match.group(2).strip()
            headings.append((level, title))
    return headings


def detect_doc_type(headings, content):
    # Guess the document type by scanning for keywords in the content
    content_lower = content.lower()
    if "endpoint" in content_lower or "base url" in content_lower:
        return "api"
    if "architecture" in content_lower or "data flow" in content_lower:
        return "system-design"
    if "tables" in content_lower and ("schema" in content_lower or "database" in content_lower):
        return "database-schema"
    if "getting started" in content_lower or "installation" in content_lower:
        return "readme"
    return None


def find_empty_sections(content):
    # Find headings that have no content before the next heading
    empty = []
    lines = content.split("\n")
    for i, line in enumerate(lines):
        match = re.match(r"^#{1,6}\s+(.+)$", line)
        if match:
            section_content = []
            for j in range(i + 1, len(lines)):
                if re.match(r"^#{1,6}\s+", lines[j]):
                    break
                section_content.append(lines[j])
            if not "".join(section_content).strip():
                empty.append(match.group(1).strip())
    return empty

What do these functions do?

  • extract_headings() scans every line for markdown heading syntax (# through ######) and returns a list of (level, title) pairs.
  • detect_doc_type() checks the content for keywords like "endpoint" or "architecture" to figure out which document type was generated.
  • find_empty_sections() catches headings followed by no content before the next heading. These are sections the agent created but forgot to fill in.

You still will not see any output. The next chunk ties everything together.

  • Below the helper functions, add the main validate function and the entry point that runs when you call the script from the terminal:

def validate(filepath, doc_type=None):
    # Open the file and read its contents
    try:
        with open(filepath, "r", encoding="utf-8") as f:
            content = f.read()
    except FileNotFoundError:
        print(f"Error: File not found: {filepath}")
        return False
    if not content.strip():
        print(f"Error: File is empty: {filepath}")
        return False
    headings = extract_headings(content)
    # Auto-detect or use the provided document type
    if doc_type is None:
        doc_type = detect_doc_type(headings, content)
        if doc_type is None:
            print("Warning: Could not detect document type.")
            print("Specify type with: python validate-docs.py <file> <type>")
            print(f"Available types: {', '.join(REQUIRED_SECTIONS.keys())}")
            return False
        print(f"Detected document type: {doc_type}")
    if doc_type not in REQUIRED_SECTIONS:
        print(f"Error: Unknown document type '{doc_type}'.")
        print(f"Available types: {', '.join(REQUIRED_SECTIONS.keys())}")
        return False
    # Compare the file's headings against required sections
    required = REQUIRED_SECTIONS[doc_type]
    heading_titles = [h[1].lower() for h in headings]
    missing = []
    for section in required:
        if section.lower() not in heading_titles:
            missing.append(section)
    empty_sections = find_empty_sections(content)
    # Print the validation report
    print(f"\nValidation Report: {filepath}")
    print(f"Document Type: {doc_type}")
    print(f"Total Headings: {len(headings)}")
    print()
    passed = True
    if missing:
        print("Missing required sections:")
        for section in missing:
            print(f"  - {section}")
        passed = False
    else:
        print("All required sections present.")
    if empty_sections:
        print("\nEmpty sections (no content):")
        for section in empty_sections:
            print(f"  - {section}")
        passed = False
    print()
    if passed:
        print("Result: PASSED")
    else:
        print("Result: NEEDS ATTENTION")
    return passed


if __name__ == "__main__":
    # Show usage instructions when called without arguments
    if len(sys.argv) < 2:
        print("Usage: python validate-docs.py <filepath> [doc-type]")
        print(f"Available types: {', '.join(REQUIRED_SECTIONS.keys())}")
        sys.exit(1)
    filepath = sys.argv[1]
    doc_type = sys.argv[2] if len(sys.argv) > 2 else None
    success = validate(filepath, doc_type)
    sys.exit(0 if success else 1)

What does the validate function do?

  • It opens the file and handles errors (file not found, empty file).
  • It auto-detects the document type if one is not provided. If detection fails, it prints the available types and exits.
  • It compares the file's headings against REQUIRED_SECTIONS and reports any missing or empty sections.
  • The __main__ block at the bottom is the entry point. It reads the file path and optional document type from the command line arguments.
  • Save scripts/validate-docs.py.

File not saving?

Make sure the file is inside the scripts/ directory, not at the root of writing-documentation/. The full path should be .agents/skills/writing-documentation/scripts/validate-docs.py.

Help me figure out why my validation script file is not saving correctly.

✔️ Awesome, I've got everything!

Great. Double check you have saved validate-docs.py before moving on.

ⓧ I'd like to double check the full code

Here is the complete scripts/validate-docs.py file. Compare yours against it:

import sys
import re


REQUIRED_SECTIONS = {
    "api": [
        "Overview",
        "Base URL",
        "Authentication",
        "Endpoints",
        "Error Handling",
    ],
    "system-design": [
        "Overview",
        "Goals",
        "Architecture",
        "Components",
        "Data Flow",
    ],
    "database-schema": [
        "Overview",
        "Tables",
        "Relationships",
        "Indexes",
    ],
    "readme": [
        "Overview",
        "Getting Started",
        "Usage",
    ],
}


def extract_headings(content):
    headings = []
    for line in content.split("\n"):
        match = re.match(r"^(#{1,6})\s+(.+)$", line)
        if match:
            level = len(match.group(1))
            title = match.group(2).strip()
            headings.append((level, title))
    return headings


def detect_doc_type(headings, content):
    content_lower = content.lower()
    if "endpoint" in content_lower or "base url" in content_lower:
        return "api"
    if "architecture" in content_lower or "data flow" in content_lower:
        return "system-design"
    if "tables" in content_lower and ("schema" in content_lower or "database" in content_lower):
        return "database-schema"
    if "getting started" in content_lower or "installation" in content_lower:
        return "readme"
    return None


def find_empty_sections(content):
    empty = []
    lines = content.split("\n")
    for i, line in enumerate(lines):
        match = re.match(r"^#{1,6}\s+(.+)$", line)
        if match:
            section_content = []
            for j in range(i + 1, len(lines)):
                if re.match(r"^#{1,6}\s+", lines[j]):
                    break
                section_content.append(lines[j])
            if not "".join(section_content).strip():
                empty.append(match.group(1).strip())
    return empty


def validate(filepath, doc_type=None):
    try:
        with open(filepath, "r", encoding="utf-8") as f:
            content = f.read()
    except FileNotFoundError:
        print(f"Error: File not found: {filepath}")
        return False
    if not content.strip():
        print(f"Error: File is empty: {filepath}")
        return False
    headings = extract_headings(content)
    if doc_type is None:
        doc_type = detect_doc_type(headings, content)
        if doc_type is None:
            print("Warning: Could not detect document type.")
            print("Specify type with: python validate-docs.py <file> <type>")
            print(f"Available types: {', '.join(REQUIRED_SECTIONS.keys())}")
            return False
        print(f"Detected document type: {doc_type}")
    if doc_type not in REQUIRED_SECTIONS:
        print(f"Error: Unknown document type '{doc_type}'.")
        print(f"Available types: {', '.join(REQUIRED_SECTIONS.keys())}")
        return False
    required = REQUIRED_SECTIONS[doc_type]
    heading_titles = [h[1].lower() for h in headings]
    missing = []
    for section in required:
        if section.lower() not in heading_titles:
            missing.append(section)
    empty_sections = find_empty_sections(content)
    print(f"\nValidation Report: {filepath}")
    print(f"Document Type: {doc_type}")
    print(f"Total Headings: {len(headings)}")
    print()
    passed = True
    if missing:
        print("Missing required sections:")
        for section in missing:
            print(f"  - {section}")
        passed = False
    else:
        print("All required sections present.")
    if empty_sections:
        print("\nEmpty sections (no content):")
        for section in empty_sections:
            print(f"  - {section}")
        passed = False
    print()
    if passed:
        print("Result: PASSED")
    else:
        print("Result: NEEDS ATTENTION")
    return passed


if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: python validate-docs.py <filepath> [doc-type]")
        print(f"Available types: {', '.join(REQUIRED_SECTIONS.keys())}")
        sys.exit(1)
    filepath = sys.argv[1]
    doc_type = sys.argv[2] if len(sys.argv) > 2 else None
    success = validate(filepath, doc_type)
    sys.exit(0 if success else 1)
Test the script locally

Before the agent uses this script, you should confirm it works by running it yourself against a sample document.

First, confirm that Python 3 is available on your machine. Open a terminal and check your version by running:

python --version

✔️ I see Python 3.x

Python is ready. Move on to creating the sample file below.

ⓧ Python is not recognized

Python is not installed or not on your PATH. Install it from the official Python downloads page.

  • Download the latest Python 3 installer for Windows.
  • Run the installer. On the first screen, check the box labeled Add Python to PATH, then click Install Now.
  • Close and reopen your terminal, then run python --version again to confirm.

Still not recognized after installing?

The Add Python to PATH checkbox must be checked during installation. If you missed it, re-run the installer, select Modify, and ensure the PATH option is enabled.

Help me get Python recognized in my terminal after installing it.

  • In your terminal, navigate to the writing-documentation skill directory by running:
cd .agents/skills/writing-documentation
  • Create a small sample markdown file to test against by running:
echo "# Sample API Docs" > sample.md
echo "## Overview" >> sample.md
echo "This API provides user management." >> sample.md
echo "## Endpoints" >> sample.md
echo "GET /users" >> sample.md
echo "## Error Handling" >> sample.md

What is this sample file for?

This creates a minimal API-style markdown file with some required sections present (Overview, Endpoints, Error Handling) and some deliberately missing (Base URL, Authentication). It gives the script something realistic to validate against.

  • Run the validation script against the sample file:
python scripts/validate-docs.py sample.md

You should see a validation report that detects the document type as api, lists Base URL and Authentication as missing required sections, and shows a result of NEEDS ATTENTION.

  • Test the error handling by running the script without any arguments:
python scripts/validate-docs.py

You should see a usage message showing the expected syntax and available document types.

Seeing a syntax error or traceback?

Open scripts/validate-docs.py and look for missing colons at the end of def or if lines. Also check that every f-string uses f" at the start, not just a plain quote.

Use the double-check tab above to compare your code line by line against the complete file.

Help me debug a Python error in my validate-docs.py script.

  • Clean up the sample file by running:
del sample.md

Your validation script is tested and ready. Next up, you will put the complete skill to the test by activating it in Google Antigravity and watching the full discovery-activation-execution lifecycle in action.

Test the Skill in Action

Your validation script is tested and ready to catch missing sections in any generated document. Now it's time to put the entire skill through its paces.

Google Antigravity follows a three-phase model when working with skills: discovery, activation, and execution. In this step, you'll see all three phases play out with a real documentation request.

In this step, get ready to:
  • Verify that Google Antigravity discovers the writing-documentation skill.
  • Test the skill by asking the agent to generate real documentation.
Verify skill discovery

Google Antigravity scans the .agents/skills/ directory at the start of each conversation. It reads the name and description from every skill's frontmatter to decide when each one is relevant.

  • In Google Antigravity, start a new conversation.
  • Type something like "What skills do you have available?" and press Enter.
  • Look for writing-documentation in the agent's response.

You should see writing-documentation listed among the agent's available skills.

What is progressive disclosure?

Progressive disclosure is how agents keep their context lean. At conversation start, the agent only reads your skill's metadata (the name and description fields). That costs roughly 100 tokens.

When you make a request that matches the skill's description keywords, the agent activates the skill and reads the full SKILL.md body. It only loads the specific reference template it needs after that. This keeps each phase under 5000 tokens.

Skill not showing up?

  • Check that the directory name (writing-documentation) exactly matches the name field in your SKILL.md frontmatter.
  • Make sure your YAML frontmatter opens and closes with --- on its own line. A missing delimiter breaks the frontmatter parsing.
  • Confirm the skill folder sits inside .agents/skills/ at the root of your project folder. Google Antigravity only scans this specific path for workspace-scoped skills.
  • Try starting a fresh conversation. Google Antigravity scans for skills at conversation start, so an older conversation won't pick up new skills.

Why isn't Google Antigravity discovering my skill in .agents/skills/?

Test the skill with a real documentation request

Now that the agent knows about your skill, give it a real documentation task. This triggers the activation and execution phases of the skill lifecycle.

  • In the same conversation, send a documentation request. For example, type "Create a README for this project" or "Write API documentation for the user authentication endpoints."
  • Watch how the agent responds. It should activate the writing-documentation skill and load the matching reference template.
  • Wait for the agent to generate the full document.

The agent's output should include the section headings from the matching reference template. For a README request, you should see sections like Overview, Getting Started, and Usage.

What should I look for in the output?

Review the generated documentation against three criteria:

  • Template structure: Does the output include all the required sections from the reference template? Compare the headings side by side.
  • Writing guidelines: Is the content in present tense? Does it use concrete examples instead of placeholder data? Are code blocks tagged with language identifiers?
  • Validation script: Did the agent run validate-docs.py on the output? If not, ask it to: "Run the validation script on the document you just created."

Iterate on your instructions

If the output misses sections or does not follow the template closely, go back to SKILL.md and strengthen the instructions. Small wording changes make a big difference.

  • Change "include" to "ALWAYS include" for critical sections.
  • Make workflow steps more specific. For example, instead of "fill in content," try "fill in every section from the template, using data from the codebase."
  • Add examples of good output directly in the guidelines section.

After making changes, start a new conversation and test again. Each conversation re-reads the skill from disk.

Agent ignoring the template?

  • Make sure your request matches the keywords in the skill's description field. Words like "write documentation," "create docs," or "generate API reference" trigger activation.
  • Check that the relative paths in your Document Types section are correct. A broken link like reference/api-docs-template.md (missing the 's') means the agent cannot find the template file.
  • If the agent generates documentation in its own format without following your template, explicitly ask it: "Use the writing-documentation skill to generate this."

My agent is not following the reference template when generating documentation. How can I debug this?

✔️ Awesome, I've got everything!

Great. Double check you have saved any changes to SKILL.md if you iterated on the instructions.

ⓧ I'd like to double check the full code

Here is the complete SKILL.md for reference. Your file should match this structure.

---
name: writing-documentation
description: Generates consistent, well-structured technical documentation including API docs, system design docs, database schema docs, and README files. Use when asked to write documentation, create docs, generate API reference, document endpoints, write a README, document a database schema, or create a system design document.
---

# Writing Documentation

## Quick Start

When asked to generate documentation, follow these steps:

1. Identify the document type from the user's request
2. Load the appropriate template from the references directory
3. Follow the template structure and fill in content based on the codebase
4. Run the validation script to check the output

## Document Types

**API Documentation**: See [references/api-docs-template.md](references/api-docs-template.md)
Use when documenting REST APIs, GraphQL endpoints, or SDK methods.

**System Design Document**: See [references/system-design-template.md](references/system-design-template.md)
Use when documenting architecture decisions, system components, or technical proposals.

**Database Schema Document**: See [references/database-schema-template.md](references/database-schema-template.md)
Use when documenting database tables, relationships, migrations, or data models.

**README File**: See [references/readme-template.md](references/readme-template.md)
Use when creating or updating project README files.

## Workflow

1. **Determine document type**: Match the user's request to one of the four types above
2. **Load template**: Read the corresponding reference file for structure and required sections
3. **Gather context**: Analyze the relevant code, configs, or schemas in the project
4. **Generate content**: Follow the template structure, filling each section with accurate, specific content from the codebase
5. **Validate**: Run `python scripts/validate-docs.py <output-file>` to check for completeness

## Writing Guidelines

- Write in present tense for current behavior, future tense for planned features
- Use consistent terminology throughout the document
- Include concrete examples with realistic values, not placeholder data
- Keep sentences concise and scannable
- Use code blocks with language identifiers for all code snippets
- Link to related documentation when referencing other systems or components

The reference templates and validation script should remain unchanged from the previous steps. Verify that your references/ directory contains four template files and your scripts/ directory contains validate-docs.py.

Secret mission

Build a Test Generation Skill

You have built one Agent Skill from scratch. Can you build a second one independently? Create a test generation skill that teaches AI agents how to write unit tests, integration tests, and end-to-end tests for any codebase.

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely locally, so there are no ongoing costs. Decide whether to keep your skill files in place, pause by closing your tools, or delete everything entirely.

Resources you used:

  • The .agents/skills/writing-documentation/ directory containing SKILL.md, four reference templates, and a validation script.
  • The .agents/skills/generating-tests/ directory containing SKILL.md and a test patterns reference (if you completed the Secret Mission).

Keep everything running

No action needed. Choose this if you plan to keep using these skills in your coding sessions.

  • Your skills are local Markdown and Python files with zero ongoing cost. Leave them in .agents/skills/ and they activate automatically whenever you open this project in a compatible agent tool.

Make your skills portable

To use these skills across all your projects in Google Antigravity, copy the skill directories to ~/.gemini/config/skills/. This makes them global instead of workspace-scoped.

You can also push the skills to a Git repository so other developers can clone them into their own .agents/skills/ directory.

Pause - I'll come back to this later

Since the skills are static files, there are no running processes to stop. Your files sit idle and consume no resources until an agent activates them.

  • Close Google Antigravity if you want to free up memory.
  • Your skill files will still be in .agents/skills/ when you return.

Delete - I don't want to use this again

Remove all skill directories and start fresh. This deletes the skills permanently from this project.

  • Open a terminal in your project folder (the folder that contains the .agents/ directory).

macOS

  • Remove the documentation skill directory by running:
rm -rf .agents/skills/writing-documentation
  • If you completed the Secret Mission, remove the test generation skill directory by running:
rm -rf .agents/skills/generating-tests
  • If you created a sample.md test file in your project folder, delete it by running:
rm -f sample.md

Windows

  • Remove the documentation skill directory by running:
rmdir /s /q .agents\skills\writing-documentation
  • If you completed the Secret Mission, remove the test generation skill directory by running:
rmdir /s /q .agents\skills\generating-tests
  • If you created a sample.md test file in your project folder, delete it by running:
del sample.md

Nice Work!

Nice Work!

Nice work! You just built a production-ready documentation generator Agent Skill using the open Agent Skills specification.

You've learned how to:

  • Authored a SKILL.md with valid YAML frontmatter and a conditional workflow routing to four document types via relative file references.
  • Created four reference templates using progressive disclosure and a Python validation script the agent runs to check generated documentation.
  • Tested the full skill lifecycle in Google Antigravity, from automatic discovery to activation to execution.
  • Secret Mission: Built a generating-tests skill from scratch, proving you can create new Agent Skills independently.

Ready to quiz yourself?