Skip to content

// Define typed LLM functions in BAML's DSL, generate clients, and get robust structured output via Schema-Aligned Parsing.

BAML Structured Output

skill --stat
  • last update

    Jun 24, 2026

  • license

    MITv1.0.0

  • format

    SKILL.md

quickstart.sh
3 steps
  1. Install

    // Downloads SKILL.md into ~/.claude/skills/baml-structured-output/

    $ curl -fsSL --create-dirs -o ~/.claude/skills/baml-structured-output/SKILL.md https://claudeskil.com/skills/baml-structured-output/SKILL.md
  2. Invoke

    // Inside Claude Code, type the skill name as a slash command

    > /baml-structured-output fine-tune on this CSV
  3. Or just ask

    // Claude loads the skill by itself when a request matches its description

    > fine-tune on this CSV
baml-structured-output/
references
SKILL.md
readonly
name:
BAML Structured Output
slug:
baml-structured-output
version:
v1.0.0
license:
MIT
author:
@chiragthummar16
categories:
tags:
#baml#structured-output#schema-aligned-parsing#type-safe-llm#boundaryml
description:

Define typed LLM functions in BAML's DSL, generate clients, and get robust structured output via Schema-Aligned Parsing.

README.md

baml-structured-output/README.md
7 sections

BAML Structured Output

BAML (BoundaryML) is a domain-specific language for defining LLM functions with real types, then generating idiomatic client code for your app. This skill helps you author .baml files, run the generator, and rely on Schema-Aligned Parsing (SAP) so model outputs deserialize into your types even when the raw response is imperfect JSON. It's for engineers who are tired of brittle json.loads + retry loops and try/except wrappers around extraction, classification, and agent-tool prompts.

When to use it

  • You need an LLM call to return a structured object (extraction, classification, entity tagging, routing) and want a typed result instead of a dict.
  • You're hitting parse failures on models that emit markdown fences, trailing commas, unquoted keys, or partial JSON during streaming.
  • You want one prompt definition consumed across Python, TypeScript, Go, and Ruby services.
  • You want to iterate on prompts with live token/output preview before wiring them into code.

How it works

You write functions in the BAML DSL — class for objects, enum for closed sets, and union types (int | string, Cat | Dog) for variants. A function block declares input args, a return type, the client (model), and a prompt using the {{ ctx.output_format }} and {{ _.role("user") }} helpers. Run baml-cli generate (or let the VSCode extension regenerate on save) to emit a baml_client package with fully typed wrappers. At call time, BAML's Schema-Aligned Parsing coerces the model's text toward your declared schema rather than demanding strict JSON, so it recovers fenced blocks, fixes minor syntax, and fills partials during streaming. Annotate fields with @description to steer the model and @alias to map prompt-facing names to your code names.

Usage example

bash
curl -fsSL --create-dirs -o ~/.claude/skills/baml-structured-output/SKILL.md https://claudeskil.com/skills/baml-structured-output/SKILL.md
rust
// baml_src/resume.baml
class Resume {
  name string
  skills string[] @description("technical skills only")
  years_experience int @alias("yoe")
}

function ExtractResume(text: string) -> Resume {
  client "openai/gpt-4o"
  prompt #"
    Extract the resume.
    {{ ctx.output_format }}
    {{ _.role("user") }} {{ text }}
  "#
}
python
# after: baml-cli generate
from baml_client import b
resume = b.ExtractResume(raw_text)   # typed Resume, parsed via SAP
print(resume.skills, resume.years_experience)

Tips & gotchas

  • Don't hand-edit baml_client/ — it's regenerated; change the .baml source instead.
  • Use b.stream.ExtractResume(...) for partial typed objects as tokens arrive; SAP keeps each partial valid.
  • Prefer enum over free string for categories — the model is constrained and parsing is more reliable.
  • Add test blocks in .baml and run them from the VSCode playground to catch prompt regressions early.

FAQ

Does this force JSON mode or function-calling? No. SAP parses ordinary text output, so it works on models without native structured-output APIs.

Can I use my own model/proxy? Yes — define a client<llm> with the provider and base_url, including Anthropic, OpenAI, Ollama, or any OpenAI-compatible endpoint.

What happens if the output truly can't match? BAML raises a typed parsing error rather than returning a malformed object, so failures are explicit.

$ cat reviews/

Reviews

// No reviews yet. Be the first.
Loading review form…

$ ls related/

explore all →