✦ Open Format · Zero Dependencies · MIT License

LLMs don't need syntax.
They need context.

SLIM is the file format built for AI — not humans. Replace Markdown in your prompts, agent configs, and tool schemas. Strip the noise, keep the meaning. Save 43% of tokens on average.

agent-config.md Markdown · ~118 tokens sent to LLM
---
model: claude-opus-4-7
agent: CodeReviewer
task: PR-942
retry: 3
---

<!-- System prompt -->
# Role
You are a senior code reviewer for PR-942.

# Instructions
- Check for security vulnerabilities
- Flag breaking changes
- Be concise and direct

```python
def review(diff):
    return analyze(diff)
```
agent-config.slm SLIM · ~69 tokens sent to LLM
@slim: 2.0
@model: claude-opus-4-7  ← stripped
@retry: 3  ← stripped
@+agent: CodeReviewer
@+task: PR-942
~ System prompt
# Role
You are a senior code reviewer for $task.

# Instructions
Check for security vulnerabilities
Flag breaking changes
Be concise and direct

::REVIEW python
def review(diff):
    return analyze(diff)
24.5% avg savings (YAML configs)
85/85 conformance tests pass
0 runtime dependencies
8 directive keywords

Markdown was built for humans.
Not for AI pipelines.

Every token costs money and latency. Markdown makes you pay for metadata that the LLM never needs.

💸

Metadata burns tokens

Model name, retry count, timeouts — orchestrator config that the LLM never reads still gets sent to it, wasting tokens on every call.

🔓

No injection boundaries

Markdown has no concept of block boundaries. A user who pastes --- or a frontmatter key can silently override your system config.

🧩

No AI-native primitives

There's no standard way to define tool schemas, declare variables, write directives, or separate orchestrator intent from LLM instructions.

🔁

Manual string templating

Injecting dynamic values like agent name or task ID requires ad-hoc string interpolation outside the format, making prompts brittle.

Everything a prompt format should have.

Six first-class primitives that cover every AI workflow need — all in one clean, human-writable format.

🔇

Token Stripping

@key headers are consumed by the orchestrator and never forwarded to the LLM. Zero extra tokens for config metadata.

@model: claude-opus-4-7 ← stripped @retry: 3 ← stripped @+agent: Reviewer ← LLM sees this
🔗

Variable Interpolation

Define values in headers and reference them with $var anywhere in the body. Resolved before the LLM call — no template engine needed.

@+task: PR-942 You are reviewing $task today. → "You are reviewing PR-942 today."
📦

Sections

Named, typed content regions with hard injection boundaries. No close tag needed — :: is a single token, saving ~5 tokens per block.

::SCHEMA json {"name": "string"}
🛠️

Schema Definitions

First-class :tool_name syntax for AI function call schemas. Required/optional fields, defaults, and typed return values.

:search_web desc: Search the internet query!: str limit?: int = 10 -> results: json

Directive System

Structured > KEYWORD workflow primitives for AI agent pipelines. CALL, ASSERT, YIELD, EMIT, LOG, ABORT, WAIT, RETRY.

> CALL analyze(diff: $pr_diff) > ASSERT $result.passed == true > YIELD $result.report
🔒

Security Model

Built-in sanitize_user_content() escapes all SLIM sigils before user text is embedded. Header injection prevention by design.

~ @ $ > ~ :: all escaped result = sanitize_user_content( user_input )

Honest numbers. 47 real files.

47 real-world AI config and prompt files. Measured with cl100k_base on LLM-facing tokens only — orchestrator @headers are stripped before the LLM call, which is the actual API cost.

24.5%
average savings on YAML-frontmatter agent configs  ·  4.4% average on plain-prose files
Agent config (YAML + rich format)
34.0%
README (YAML + tables + links)
33.2%
Skill file (YAML + heavy format)
31.7%
Prompt template (YAML + bullets)
27.9%
Plain agent config (no YAML)
6.5%
Pure prose instructions
4.4%

Measured as: (MD tokens − LLM-facing SLIM tokens) / MD tokens × 100 · cl100k_base tokenizer
We're actively working to increase savings on plain-prose files. Contributions welcome →

Clean. Consistent. Learnable in 5 minutes.

SigilZoneDescriptionIn LLM Text?
@key: value Header Orchestrator-only metadata. Model name, retry count, timeout. Auto-coerced to int/float/bool/null/list. stripped
@+key: value Header LLM-visible header. Appears at the top of LLM text. Also available as $key variable. visible
~ text Any Comment line. Stripped before LLM call. Great for author notes, change logs, debugging hints. stripped
$var Body Variable reference. Resolved from @key or @+key headers. Dot-path access: $obj.field. substituted
::NAME type
:::NESTED type
Body Named section with optional type tag. Hard injection boundary — \:: at line start is literal. Sections can be nested one level with :::. visible
> KEYWORD args Body Directive. CALL, ASSERT, YIELD, EMIT, LOG, ABORT, WAIT, RETRY. ALL_CAPS only — prose > is not parsed. visible
:tool_name Body Schema definition block. Indented properties with ! (required), ? (optional). Return type with ->. visible
agent-config.slm
~ SLIM v2.0 complete example
@slim: 2.0
@model: claude-opus-4-7     ~ stripped from LLM
@retry: 3                   ~ stripped from LLM
@timeout: 30               ~ stripped from LLM
@+agent: SecurityBot       ~ LLM-visible
@+task: PR-942             ~ LLM-visible + interpolatable

# Role
You are $agent, a security-focused code reviewer assigned to $task.

# Instructions
- Check for OWASP Top 10 vulnerabilities
- Review SQL queries for injection risks
- Flag insecure deserialization patterns

::CONTEXT markdown
PR title: Fix authentication flow
Changed files: auth.py, session.py

> CALL analyze_pr(id: $task, depth: full)
> ASSERT $result.severity != "critical"
> YIELD $result.summary
tools.slm — Schema definitions
@slim: 2.0

~ Tool definitions for function calling

:search_web
  desc: Search the internet for recent information
  query!: str
  max_results?: int = 10
  safe_search?: bool = true
  -> results: json

:run_code
  desc: Execute code in a sandboxed environment
  language!: [python|javascript|bash]
  code!: str
  timeout?: int = 30
  -> output: str
  -> exit_code: int

:send_email
  desc: Send an email via the outbox queue
  to!: str
  subject!: str
  body!: str
  cc?: str
  priority?: [low|normal|high] = normal
  -> message_id: uuid
SLIM type system
~ Primitive types
@count: 42            → int
@ratio: 0.85          → float
@active: true         → bool
@ctx: null            → None/null
@name: Alice          → str (default)
@id: "42"             → str (quoted, prevents int)

~ List (comma-separated)
@stack: python, js, go  → ["python", "js", "go"]

~ Multi-line continuation
@desc: First line
  second line           → "First line second line"

~ Schema types
name!: str            → required string
age?: int = 18        → optional int, default 18
env!: [prod|staging|dev]  → enum
items?: list<str>    → typed list
meta?: dict<str,any> → typed dict

Try the converter now.

Paste your Markdown, JSON, or plain text — get SLIM output instantly. See how many tokens you save.