baml-codegen
Scanned@killerapp
npx machina-cli add skill @killerapp/baml-codegen --openclawBAML Code Generation
Generate type-safe LLM extraction code. Use when creating structured outputs, classification, RAG, or agent workflows.
Golden Rules
- NEVER edit
baml_client/- 100% generated, overwritten on everybaml-cli generate; checkbaml_src/generators.bamlforoutput_type(python, typescript, ruby, go) - ALWAYS edit
baml_src/- Source of truth for all BAML code - Run
baml-cli generateafter changes - Regenerates typed client code for target language
Philosophy (TL;DR)
- Schema Is The Prompt - Define data models first, compiler injects types
- Types Over Strings - Use enums/classes/unions, not string parsing
- Fuzzy Parsing Is BAML's Job - BAML extracts valid JSON from messy LLM output
- Transpiler Not Library - Write
.baml→ generate native code (Python/TypeScript/Ruby/Go), no runtime dependency - Test-Driven Prompting - Use VS Code playground or
baml-cli testto iterate
Workflow
Analyze → Pattern Match (MCP) → Validate → Generate → Test → Deliver
↓ [IF ERRORS] Error Recovery (MCP) → Retry
BAML Syntax
| Element | Example |
|---|---|
| Class | class Invoice { total float @description("Amount") @assert(this > 0) @alias("amt") } |
| Enum | enum Category { Tech @alias("technology") @description("Tech sector"), Finance, Other } |
| Function | function Extract(text: string, img: image?) -> Invoice { client GPT5 prompt #"{{ text }} {{ img }} {{ ctx.output_format }}"# } |
| Client | client<llm> GPT5 { provider openai options { model gpt-5 } retry_policy Exponential } |
| Fallback | client<llm> Resilient { provider fallback options { strategy [FastModel, SlowModel] } } |
Types
- Primitives:
string,int,float,bool| Multimodal:image,audio - Containers:
Type[](array),Type?(optional),map<string, Type>(key-value) - Composite:
Type1 | Type2(union), nested classes - Annotations:
@description("..."),@assert(condition),@alias("json_name"),@check(name, condition)
Providers
openai, anthropic, gemini, vertex, bedrock, ollama + any OpenAI-compatible via openai-generic
Pattern Categories
| Pattern | Use Case | Model | Framework Markers |
|---|---|---|---|
| Extraction | Unstructured → structured | GPT-5 | fastapi, next.js |
| Classification | Categorization | GPT-5-mini | any |
| RAG | Answers with citations | GPT-5 | langgraph |
| Agents | Multi-step reasoning | GPT-5 | langgraph |
| Vision | Image/audio data extraction | GPT-5-Vision | multimodal |
Resilience
- retry_policy:
retry_policy Exp { max_retries 3 strategy { type exponential_backoff } } - fallback client: Chain models
[FastCheap, SlowReliable]for cost/reliability tradeoff
MCP Indicators
- Found patterns from baml-examples | Validated against BoundaryML/baml | Fixed errors using docs | MCP unavailable, using fallback
Output Artifacts
- BAML Code - Complete
.bamlfiles (types, functions, clients, retry_policy) - Tests - pytest/Jest with 100% function coverage
- Integration - Framework-specific client code (LangGraph nodes, FastAPI endpoints, Next.js API routes)
- Metadata - Pattern used, token count, cost estimate
References
- providers.md - OpenAI, Anthropic, Google, Ollama, Azure, Bedrock, openai-generic
- types-and-schemas.md - Full type system, classes, enums, unions, map, image, audio
- validation.md - @assert, @check, @alias, block-level @@assert
- patterns.md - Pattern library with code examples
- philosophy.md - BAML principles, golden rules
- mcp-interface.md - Query workflow, caching
- languages-python.md - Python/Pydantic, async
- languages-typescript.md - TypeScript, React/Next.js
- frameworks-langgraph.md - LangGraph integration
Overview
BAML Code Gen turns natural language requirements into complete BAML artifacts, including types, functions, clients, tests, and framework integrations. It supports Python, TypeScript, Ruby, and Go across 10+ frameworks, queries MCP for real-time patterns, and handles multimodal inputs like images and audio with 50-70% token optimization and 95%+ compilation success.
How This Skill Works
Follow the end-to-end workflow: Analyze → Pattern Match (MCP) → Validate → Generate → Test → Deliver, with MCP-based error recovery if needed. The system enforces that baml_client remains 100% generated, while baml_src is the source of truth; run baml-cli generate to regenerate typed code for the target language. It uses a schema-first approach where prompts define data models and the compiler injects types, producing BAML code that transpiles to Python/TypeScript/Ruby/Go without a runtime dependency.
When to Use It
- You need type-safe LLM extraction, classification, or RAG pipelines generated from natural language requirements.
- You are building multi-step agent workflows with framework-specific clients and tests.
- You handle multimodal inputs (images, audio) across Python/TypeScript/Ruby/Go using 10+ frameworks.
- You want ready-to-run, compilable code with high compilation success across target languages.
- MCP is available to fetch real-time patterns; if MCP is unavailable, you rely on offline cached patterns (80% functionality).
Quick Start
- Step 1: Describe the required types, functions, clients, and integrations in natural language.
- Step 2: Run baml-cli generate to create baml_src and the generated clients for your language.
- Step 3: Run baml-cli test and iterate until 100% function coverage and successful compilation.
Best Practices
- Never edit baml_client/ – it is 100% generated and overwritten on every baml-cli generate.
- Always edit baml_src/ – the source of truth for all BAML code.
- Run baml-cli generate after changes to regenerate typed client code.
- Follow Schema Is The Prompt: define data models first; the compiler injects types.
- Use test-driven prompting with a VS Code playground or baml-cli test to iterate.
Example Use Cases
- Python: generate a type-safe extraction service with a typed client and pytest tests.
- TypeScript: create a LangGraph-enabled RAG workflow with citations and Next.js API routes.
- Go: build an agent workflow with multi-step orchestration and integrated tests.
- Multimodal pipeline: process image and audio inputs with end-to-end BAML code and tests.
- Offline/fallback: generate code using cached MCP patterns when MCP is unavailable.