Tutorial Writing Guide
Write technical tutorials that are beginner-friendly, consistent in structure, and fully runnable from start to finish.
Core Principles
- Every tutorial should be runnable end-to-end. A reader should be able to start from zero and have a working result by the end. No hand-waving, no "left as an exercise."
- Label every code snippet. Bold description above the block explaining what it does and why. Never drop a code block without context.
- Explain concepts when they first appear. Brief, plain-language definitions — 2-3 sentences max. Use concrete examples tied to the tutorial's dataset.
- Show strengths AND weaknesses. When introducing a technique, explain what it's good at and where it falls short. This builds trust and motivates the next step.
- Connect every step to the one before it. Each section should end with a bridge sentence that tells the reader why the next step matters.
- Use real data. Avoid generic placeholder data ("foo", "test123", "Document 1"). Use a real, interesting dataset with proper attribution and licensing.
- Be explicit about tooling choices. State what you're using (e.g., "We'll be using uv as a package manager for this") and link to alternatives so readers aren't locked in.
File Structure
Every tutorial lives in its own folder and should contain:
Tutorial-Name/
├── README.md # The full step-by-step walkthrough
├── setup.sql # One-command setup (if DB-related): schema, data, indexes
├── requirements.txt # Python dependencies (if applicable)
└── script.py # Supporting script(s) with clear docstrings
├── .env.example # Template with placeholder values for any required API keys
└── .env # Actual keys (gitignored, never committed)
At the repo root:
.gitignore — must exclude .env and include !.env.example
README.md — root README linking to the tutorial with a file index table
LICENSE — appropriate open-source license
README Structure
Follow this exact section order:
1. Title and Overview
# Tutorial Name
One-sentence description of what this tutorial demonstrates.
## Overview
2-3 short paragraphs or bullet points explaining:
- What techniques/tools this covers
- Why you'd use them together
- What the reader will have by the end
2. Getting Started — Prerequisites
## Getting Started
### What You'll Need
Bulleted list of every dependency:
- The primary tool/database and where to get it
- Extensions or plugins needed
- Programming language + version
- API keys and where to obtain them
- Package manager — state your choice, link alternatives
Rules for prerequisites:
- List them in order of "most likely to already have" → "most likely to need to install"
- Every item gets a bold name, a dash, and a plain-English explanation
- Link directly to download/signup pages — don't make the reader search
3. Getting Started — Setup Options
Offer multiple paths ordered by ease:
### Option 1: Managed service (recommended for beginners)
### Option 2: Docker (recommended for local development)
### Option 3: Manual install
Rules for setup options:
- Each option must be self-contained — don't assume they read the other options
- Docker options should include the exact
docker run command, connection instructions, and any relevant notes (e.g., Apple Silicon compatibility)
- Manual install should have numbered steps with sub-steps (2a, 2b, 2c) for complex operations
- Include platform-specific commands in a table or with labeled blocks (Linux, macOS, Windows)
- Every step that can fail should have a verification command and troubleshooting for common errors
- End each option with a clear "you're all set" signal
4. The Tutorial Steps
Number them sequentially: Step 1, Step 2, Step 3, etc.
Each step follows this pattern:
## Step N: Action-Oriented Title
1-2 sentences explaining what this step does and why it matters.
Connect it to the previous step if applicable.
**Sub-step label** — brief description of what this specific block does:
\```language
code here
\```
Expected output or what to look for after running it.
Rules for tutorial steps:
- Titles should be action-oriented: "Create a Table", "Try Keyword Search", "Generate Embeddings" — not "Tables" or "Keyword Search"
- When introducing a new concept (embeddings, RRF, BM25), add a brief explainer paragraph before the first code block. Keep it to 2-4 sentences with a concrete example from the tutorial's dataset.
- Every code snippet gets a bold label above it explaining what it does
- After each code snippet, tell the reader what they should see (expected output, success message, or what to verify)
- When a step has multiple examples, label them: "Basic search", "Search with a filter", etc.
- At the end of steps that demonstrate a technique, include a "What X is good at:" and "Where it falls short:" summary. Use these to motivate the next step.
- End each step with a transition sentence bridging to the next one
5. Going Further
## Going Further
The tutorial above covers the core pattern. This section collects
tips and techniques for when you're ready to go deeper.
Rules:
- Each subsection is a self-contained recipe with a descriptive heading
- Every code snippet has a 1-2 sentence explanation above it saying what it does and when you'd use it
- Order from most common needs to most specialized
6. Limitations
## Current Limitations
Things to be aware of in [tool] [version]:
- **Limitation name**: Brief explanation. Workaround if one exists.
Keep this factual and concise. Link to workarounds shown in "Going Further" when applicable.
7. What's Next
## What's Next
You've built [what they built]. Here are some directions to explore:
- **Direction** — 1-2 sentences on what to do and a link if relevant
Rules:
- 4-6 concrete next steps, ordered from easiest to most ambitious
- Each should be a distinct direction, not a variation of the same thing
- Include links to repos, tools, or docs where applicable
- At least one should point to expanding the tutorial's dataset
- At least one should point to integrating with a real application
8. Resources
## Resources
- [Name](url) — one-line description
Link to: source repos, the dataset used, managed service options, relevant blog posts, and related demos.
Supporting Scripts
Python scripts (embed.py, load.py, etc.)
- Start with a docstring explaining what the script does, usage instructions, and configurable env vars
- Use
python-dotenv to load from a .env file in the same directory as the script
- Use
os.getenv() with sensible defaults for all config (host, port, user, password, database)
- Print progress messages: what it's about to do, how many items, and a "Done!" summary
- Make scripts idempotent where possible (e.g., skip rows that already have data)
- Include a clear error message if a required env var is missing, with instructions on how to fix it
SQL setup files (setup.sql)
- Comment header with: what it does, dataset attribution, and usage command
- Numbered sections: 1. Extensions, 2. Table, 3. Sample data, 4. Indexes
- Use
IF NOT EXISTS / IF NOT EXISTS for idempotency
- Include 8-15 rows of sample data — enough to show variety, not so many it's overwhelming
Writing Style
- Voice: direct, second person ("you"), conversational but not chatty
- Explain the "why" before the "how" — tell the reader why a step matters before showing the code
- Use the dataset to make concepts concrete. Don't explain BM25 in the abstract — show how it finds the "Imposter Syndrome" episode when you search for "imposter syndrome" but misses it when you search for "feeling like a fraud."
- Label alternatives clearly: "We'll be using [X] for this tutorial, but feel free to use [Y] or [Z]"
- Callouts and tips: Use
> blockquotes for tips, notes, and "where do I find X?" answers
- Don't over-explain what's obvious. If the reader just ran
CREATE TABLE, you don't need to explain what a table is.
- Transition between sections. End steps with a sentence that previews what's next and why it matters.
- Keep definitions brief. 2-3 sentences with a concrete example, not a textbook paragraph.
Checklist Before Shipping
1---2name: write-tutorial3description: Write a consistent, step-by-step technical tutorial. Use when creating a new cookbook, guide, or walkthrough — especially for database, search, or data engineering topics. Produces a README, supporting scripts, and a setup file following a proven structure.4---56# Tutorial Writing Guide78Write technical tutorials that are beginner-friendly, consistent in structure, and fully runnable from start to finish.910## Core Principles1112- **Every tutorial should be runnable end-to-end.** A reader should be able to start from zero and have a working result by the end. No hand-waving, no "left as an exercise."13- **Label every code snippet.** Bold description above the block explaining what it does and why. Never drop a code block without context.14- **Explain concepts when they first appear.** Brief, plain-language definitions — 2-3 sentences max. Use concrete examples tied to the tutorial's dataset.15- **Show strengths AND weaknesses.** When introducing a technique, explain what it's good at and where it falls short. This builds trust and motivates the next step.16- **Connect every step to the one before it.** Each section should end with a bridge sentence that tells the reader why the next step matters.17- **Use real data.** Avoid generic placeholder data ("foo", "test123", "Document 1"). Use a real, interesting dataset with proper attribution and licensing.18- **Be explicit about tooling choices.** State what you're using (e.g., "We'll be using uv as a package manager for this") and link to alternatives so readers aren't locked in.1920## File Structure2122Every tutorial lives in its own folder and should contain:2324```25Tutorial-Name/26├── README.md # The full step-by-step walkthrough27├── setup.sql # One-command setup (if DB-related): schema, data, indexes28├── requirements.txt # Python dependencies (if applicable)29└── script.py # Supporting script(s) with clear docstrings30├── .env.example # Template with placeholder values for any required API keys31└── .env # Actual keys (gitignored, never committed)32```3334At the repo root:35- `.gitignore` — must exclude `.env` and include `!.env.example`36- `README.md` — root README linking to the tutorial with a file index table37- `LICENSE` — appropriate open-source license3839## README Structure4041Follow this exact section order:4243### 1. Title and Overview4445```markdown46# Tutorial Name4748One-sentence description of what this tutorial demonstrates.4950## Overview51522-3 short paragraphs or bullet points explaining:53- What techniques/tools this covers54- Why you'd use them together55- What the reader will have by the end56```5758### 2. Getting Started — Prerequisites5960```markdown61## Getting Started6263### What You'll Need6465Bulleted list of every dependency:66- The primary tool/database and where to get it67- Extensions or plugins needed68- Programming language + version69- API keys and where to obtain them70- Package manager — state your choice, link alternatives71```7273**Rules for prerequisites:**74- List them in order of "most likely to already have" → "most likely to need to install"75- Every item gets a bold name, a dash, and a plain-English explanation76- Link directly to download/signup pages — don't make the reader search7778### 3. Getting Started — Setup Options7980Offer multiple paths ordered by ease:8182```markdown83### Option 1: Managed service (recommended for beginners)84### Option 2: Docker (recommended for local development)85### Option 3: Manual install86```8788**Rules for setup options:**89- Each option must be self-contained — don't assume they read the other options90- Docker options should include the exact `docker run` command, connection instructions, and any relevant notes (e.g., Apple Silicon compatibility)91- Manual install should have numbered steps with sub-steps (2a, 2b, 2c) for complex operations92- Include platform-specific commands in a table or with labeled blocks (Linux, macOS, Windows)93- Every step that can fail should have a verification command and troubleshooting for common errors94- End each option with a clear "you're all set" signal9596### 4. The Tutorial Steps9798Number them sequentially: Step 1, Step 2, Step 3, etc.99100Each step follows this pattern:101102```markdown103## Step N: Action-Oriented Title1041051-2 sentences explaining what this step does and why it matters.106Connect it to the previous step if applicable.107108**Sub-step label** — brief description of what this specific block does:109110\```language111code here112\```113114Expected output or what to look for after running it.115```116117**Rules for tutorial steps:**118- Titles should be action-oriented: "Create a Table", "Try Keyword Search", "Generate Embeddings" — not "Tables" or "Keyword Search"119- When introducing a new concept (embeddings, RRF, BM25), add a brief explainer paragraph before the first code block. Keep it to 2-4 sentences with a concrete example from the tutorial's dataset.120- Every code snippet gets a **bold label** above it explaining what it does121- After each code snippet, tell the reader what they should see (expected output, success message, or what to verify)122- When a step has multiple examples, label them: "Basic search", "Search with a filter", etc.123- At the end of steps that demonstrate a technique, include a **"What X is good at:"** and **"Where it falls short:"** summary. Use these to motivate the next step.124- End each step with a transition sentence bridging to the next one125126### 5. Going Further127128```markdown129## Going Further130131The tutorial above covers the core pattern. This section collects132tips and techniques for when you're ready to go deeper.133```134135**Rules:**136- Each subsection is a self-contained recipe with a descriptive heading137- Every code snippet has a 1-2 sentence explanation above it saying what it does and when you'd use it138- Order from most common needs to most specialized139140### 6. Limitations141142```markdown143## Current Limitations144145Things to be aware of in [tool] [version]:146147- **Limitation name**: Brief explanation. Workaround if one exists.148```149150Keep this factual and concise. Link to workarounds shown in "Going Further" when applicable.151152### 7. What's Next153154```markdown155## What's Next156157You've built [what they built]. Here are some directions to explore:158159- **Direction** — 1-2 sentences on what to do and a link if relevant160```161162**Rules:**163- 4-6 concrete next steps, ordered from easiest to most ambitious164- Each should be a distinct direction, not a variation of the same thing165- Include links to repos, tools, or docs where applicable166- At least one should point to expanding the tutorial's dataset167- At least one should point to integrating with a real application168169### 8. Resources170171```markdown172## Resources173174- [Name](url) — one-line description175```176177Link to: source repos, the dataset used, managed service options, relevant blog posts, and related demos.178179## Supporting Scripts180181### Python scripts (`embed.py`, `load.py`, etc.)182183- Start with a docstring explaining what the script does, usage instructions, and configurable env vars184- Use `python-dotenv` to load from a `.env` file in the same directory as the script185- Use `os.getenv()` with sensible defaults for all config (host, port, user, password, database)186- Print progress messages: what it's about to do, how many items, and a "Done!" summary187- Make scripts idempotent where possible (e.g., skip rows that already have data)188- Include a clear error message if a required env var is missing, with instructions on how to fix it189190### SQL setup files (`setup.sql`)191192- Comment header with: what it does, dataset attribution, and usage command193- Numbered sections: 1. Extensions, 2. Table, 3. Sample data, 4. Indexes194- Use `IF NOT EXISTS` / `IF NOT EXISTS` for idempotency195- Include 8-15 rows of sample data — enough to show variety, not so many it's overwhelming196197## Writing Style198199- **Voice:** direct, second person ("you"), conversational but not chatty200- **Explain the "why" before the "how"** — tell the reader why a step matters before showing the code201- **Use the dataset to make concepts concrete.** Don't explain BM25 in the abstract — show how it finds the "Imposter Syndrome" episode when you search for "imposter syndrome" but misses it when you search for "feeling like a fraud."202- **Label alternatives clearly:** "We'll be using [X] for this tutorial, but feel free to use [Y] or [Z]"203- **Callouts and tips:** Use `>` blockquotes for tips, notes, and "where do I find X?" answers204- **Don't over-explain what's obvious.** If the reader just ran `CREATE TABLE`, you don't need to explain what a table is.205- **Transition between sections.** End steps with a sentence that previews what's next and why it matters.206- **Keep definitions brief.** 2-3 sentences with a concrete example, not a textbook paragraph.207208## Checklist Before Shipping209210- [ ] Every code snippet has a bold label and description211- [ ] Every concept is explained when first introduced212- [ ] Every step has a verification command or expected output213- [ ] All file paths, table names, and column names are consistent across README, setup.sql, and scripts214- [ ] `.env.example` exists in the tutorial folder with placeholder values215- [ ] `.gitignore` excludes `.env` but includes `.env.example`216- [ ] Dataset has proper attribution and license noted217- [ ] Root README has a file index table and getting started instructions218- [ ] Scripts load from `.env` and print helpful errors if config is missing219- [ ] setup.sql is runnable with a single `psql -f` command220- [ ] The tutorial is runnable end-to-end by someone starting from zero