skills/consiliency/baml-integration/SKILL.md
Generic BAML patterns for type-safe LLM prompting. Covers schema design, DTO generation, client wrappers, and cross-language codegen. Framework-agnostic.
npx skillsauth add aiskillstore/marketplace baml-integrationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Universal patterns for working with BAML (Boundary ML) in any project. BAML provides type-safe LLM prompting with automatic code generation for Python and TypeScript.
This skill is framework-generic. It provides universal BAML patterns that work in any codebase:
| Variable | Default | Description | |----------|---------|-------------| | BAML_SRC | baml_src | Directory containing BAML files | | AUTO_GENERATE | true | Auto-run baml-cli generate on changes | | STRICT_TYPES | true | Enforce strict type matching |
MANDATORY - Follow the Workflow steps below in order.
If you're about to:
baml-cli generate after schema changesSTOP -> Define BAML types -> Generate client -> Then proceed
Check the BAML configuration:
# Find BAML source directory
find . -name "*.baml" -type f | head -5
# Check BAML client
ls -la baml_client/ || ls -la baml_src/baml_client/
# Check for generator config
cat baml_src/generators.baml 2>/dev/null
Before adding new types, review what exists:
// Common patterns in baml_src/types/
// Enums
enum TaskStatus {
PENDING
IN_PROGRESS
COMPLETED
FAILED
}
// Classes (DTOs)
class UserRequest {
query string
context string?
preferences map<string, string>?
}
class UserResponse {
answer string
confidence float
sources string[]
}
When adding LLM-powered features:
// 1. Define input type
class MyInput {
field1 string @description("Clear description")
field2 int @description("What this number represents")
}
// 2. Define output type
class MyOutput {
result string
metadata MyMetadata?
}
class MyMetadata {
confidence float
reasoning string
}
// 3. Define the function
function MyFunction(input: MyInput) -> MyOutput {
client GPT4
prompt #"
Given: {{ input.field1 }}
Count: {{ input.field2 }}
Provide your analysis.
{{ ctx.output_format }}
"#
}
After schema changes:
# Generate Python and TypeScript clients
baml-cli generate
# Or with specific config
baml-cli generate --config baml_src/generators.baml
# Python usage
from baml_client import b
async def process_request(input_data: dict):
result = await b.MyFunction(
input=MyInput(
field1=input_data["query"],
field2=input_data["count"]
)
)
return result.result
// TypeScript usage
import { b } from './baml_client';
async function processRequest(inputData: Record<string, unknown>) {
const result = await b.MyFunction({
field1: inputData.query as string,
field2: inputData.count as number
});
return result.result;
}
./cookbook/schema-sync.md./cookbook/dto-generation.md./cookbook/client-wrapper.md| Type | Syntax | Example |
|------|--------|---------|
| String | string | name string |
| Int | int | count int |
| Float | float | score float |
| Boolean | bool | active bool |
| Optional | type? | nickname string? |
| Array | type[] | tags string[] |
| Map | map<K, V> | metadata map<string, string> |
| Enum | enum Name | status TaskStatus |
| Class | class Name | Custom types |
| Union | type1 \| type2 | result string \| Error |
| Attribute | Purpose | Example |
|-----------|---------|---------|
| @description | Field documentation | @description("User's email") |
| @alias | JSON key mapping | @alias("user_id") |
| @skip | Exclude from output | @skip |
// Define clients in clients.baml
client GPT4 {
provider openai
options {
model "gpt-4-turbo"
temperature 0.7
}
}
client Claude {
provider anthropic
options {
model "claude-3-opus"
max_tokens 4096
}
}
// Use in functions
function MyFunc(input: Input) -> Output {
client GPT4 // or Claude
prompt #"..."#
}
// Configure retries
client GPT4WithRetry {
provider openai
retry_policy {
max_retries 3
strategy exponential_backoff
}
}
// Fallback chain
client_fallback MainClient {
primary GPT4
fallback [Claude, GPT35Turbo]
}
Always define explicit types:
// Good: Explicit types
class BookAnalysis {
title string
author string
summary string @description("2-3 sentence summary")
rating float @description("Rating from 0-5")
tags string[]
}
// Bad: Using generic types
function AnalyzeBook(text: string) -> string // Loses type safety
Add descriptions for LLM guidance:
class SearchQuery {
query string @description("The user's search query in natural language")
filters SearchFilters? @description("Optional filters to narrow results")
limit int @description("Maximum number of results to return, default 10")
}
Define error types:
class Error {
code string
message string
}
function SafeAnalysis(input: Input) -> Output | Error {
// LLM can return either success or error
}
Keep schema versions aligned:
// baml_src/version.baml
// Schema version: 1.2.0
// Last updated: 2025-12-24
// Document breaking changes in CHANGELOG
BAML types should align with database models:
// BAML type
class User {
id int
email string
name string?
}
// Should match SQLAlchemy model
class User(Base):
id: Mapped[int]
email: Mapped[str]
name: Mapped[str | None]
BAML types can generate API response types:
// BAML response type
class APIResponse {
success bool
data ResponseData
error string?
}
// Use generated types in FastAPI
@app.post("/analyze")
async def analyze(request: Request) -> APIResponse:
result = await b.Analyze(request.data)
return APIResponse(success=True, data=result)
Generated TypeScript types work with frontend:
// Generated by BAML
import type { BookAnalysis } from './baml_client/types';
// Use in React component
function BookCard({ analysis }: { analysis: BookAnalysis }) {
return (
<div>
<h2>{analysis.title}</h2>
<p>{analysis.summary}</p>
<Rating value={analysis.rating} />
</div>
);
}
# Check BAML syntax
baml-cli check
# Verbose generation
baml-cli generate --verbose
If LLM output doesn't match expected type:
@description hints# Ensure client is generated
try:
from baml_client import b
except ImportError:
# Run: baml-cli generate
raise RuntimeError("BAML client not generated. Run: baml-cli generate")
development
Apple Human Interface Guidelines for content display components. Use this skill when the user asks about charts component, collection view, image view, web view, color well, image well, activity view, lockup, data visualization, content display, displaying images, rendering web content, color pickers, or presenting collections of items in Apple apps. Also use when the user says how should I display charts, what's the best way to show images, should I use a web view, how do I build a grid of items, what component shows media, or how do I present a share sheet. Cross-references: hig-foundations for color/typography/accessibility, hig-patterns for data visualization patterns, hig-components-layout for structural containers, hig-platforms for platform-specific component behavior.
tools
Automate HelpDesk tasks via Rube MCP (Composio): list tickets, manage views, use canned responses, and configure custom fields. Always search tools first for current schemas.
testing
Expert Haskell engineer specializing in advanced type systems, pure functional design, and high-reliability software. Use PROACTIVELY for type-level programming, concurrency, and architecture guidance.
tools
GraphQL gives clients exactly the data they need - no more, no less. One endpoint, typed schema, introspection. But the flexibility that makes it powerful also makes it dangerous. Without proper controls, clients can craft queries that bring down your server. This skill covers schema design, resolvers, DataLoader for N+1 prevention, federation for microservices, and client integration with Apollo/urql. Key insight: GraphQL is a contract. The schema is the API documentation. Design it carefully.