Struckdown

Markdown-based syntax for structured conversations with language models.

Struckdown makes it easy to extract structured, typed data from text using LLMs. Instead of parsing free-form responses, you define exactly what you want with a simple template syntax.

Quick Example

Turn unstructured text into structured data:

sd batch *.txt "Purpose, <5 words: [[purpose]]"

Output:

[
  {"filename": "butter_robot.txt", "purpose": "Pass butter, question existence."},
  {"filename": "portal_gun.txt", "purpose": "Interdimensional travel device."}
]

Or with type constraints:

sd batch *.txt "Price: [[number:price]] Currency: [[pick:currency|USD,GBP,EUR]]"

Key Features

  • Slot syntax[[variable]] for completions, [[type:variable]] for typed extraction
  • Type safety – Extract booleans, numbers, dates, or pick from options
  • Batch processing – Process hundreds of files with progress bars
  • Token management – Use <checkpoint> to save tokens between steps
  • Caching – Automatic disk caching saves money and time
  • Custom actions – Extend with Python functions (RAG, APIs, databases)
  • Web integration – Fetch URLs and search the web directly in prompts
  • Multiple outputs – JSON, CSV, Excel, or stdout

Installation

# Requires UV (https://docs.astral.sh/uv/)
uv tool install git+https://github.com/benwhalley/struckdown

Configure your LLM:

export LLM_API_KEY="sk-..."
export LLM_API_BASE="https://api.openai.com/v1"
export DEFAULT_LLM="gpt-4o-mini"

Basic Usage

Single Prompts

# Simple extraction
sd chat "Is Python compiled? [[bool:answer]]"

# Pick from options
sd chat "Sentiment of 'I love it': [[pick:sentiment|positive,negative,neutral]]"

# Number with constraints
sd chat "Rate 1-10: 'Great!' [[int:rating|min=1,max=10]]"

Batch Processing

# Process files to JSON
sd batch *.txt "Summarise: [[summary]]" -o results.json

# Extract to CSV
sd batch documents/*.txt "Name: [[extract:name]] Email: [[extract:email]]" -o contacts.csv

# Chain operations
sd batch *.txt "Company: [[extract:company]]" | \
  sd batch "Find  stock ticker: [[ticker]]" -k

Multi-Step Reasoning

sd chat "
Document: 
Extract key points: [[extract+:points]]

<checkpoint>

Based on: 
Recommendation: [[recommendation]]
" -s document.txt

Python API

from struckdown import chatter

result = chatter("""
Analyse this review: 

Sentiment: [[pick:sentiment|positive,negative,neutral]]
Rating: [[int:rating|min=1,max=5]]
""", context={"review": "Great product but slow shipping"})

print(result["sentiment"])  # "positive"
print(result["rating"])     # 4
print(result.total_cost)    # 0.0001 (USD)

Documentation

Section Description
Getting Started Installation and first steps
Template Syntax Complete syntax reference
CLI Reference All CLI commands
Custom Actions Extend with Python plugins
Caching How caching works
API Reference Python API documentation

Environment Variables

Variable Description Default
LLM_API_KEY API key for LLM provider Required
LLM_API_BASE API base URL (OpenAI-compatible) OpenAI default
DEFAULT_LLM Default model name gpt-4o-mini
STRUCKDOWN_CACHE Cache directory (0 to disable) ~/.struckdown/cache
STRUCKDOWN_CACHE_SIZE Cache size limit in MB 10240 (10 GB)
SD_MAX_CONCURRENCY Max concurrent API calls 20

This site uses Just the Docs, a documentation theme for Jekyll.