Tools
LLMs Need a Contract Layer — Introducing FACET v2.0
2025-12-13
0 views
admin
❌ The Problem: LLMs Are Not Deterministic Tools ## ✅ FACET v2.0: The First Contract-Layer Language for LLMs ## 1. A real Type System ## 2. Interfaces (@interface) ## 3. Reactive DAG Execution (R‑DAG) ## 4. Token Box Model (Context Algebra) ## 5. Execution Phases ## 6. Pure Mode ## 🚀 Why FACET Changes the Game for Agent Frameworks (After Seeing It in Code) ## ⚙️ How FACET Actually Guarantees Deterministic Output (The "Skeptic-Proof" Explanation) ## 4. Deterministic Compute Boundaries (Gas Model) ## 5. Hermetic Build Requirements ## 6. Profiles (Core vs Hypervisor) ## Structured Output → Deterministic JSON ## Example: Deterministic @output Contract ## Tool-Calling → Guaranteed Schemas ## Agents → Reproducible Reasoning ## 🏗 FACET as an Engineering Standard ## ✅ Example: A Minimal Deterministic Agent in FACET v2.0 ## 🔬 Deterministic R‑DAG in Action ## 📦 Token Box Model — Production Example ## ⚠️ Critical Overflow Handling (F901) ## Runtime ## 🔧 Tool Calling: FACET → Canonical Schema ## 🔒 Canonical Ordering Guarantee ## Rendered canonical schema ## 🧪 Testing: Production‑Safe FACET ## 📊 Real‑World Metric Gains ## 🌍 The Bigger Vision ## AI as a deterministic, verifiable, contract-driven system. ## 📦 Get Started ## 💬 Closing Thoughts ## 🔗 Links For the past few years, we’ve been trying to build reliable systems on top of LLMs using prompts, templates, retries, validation layers, guardrails, and a pile of patches. But the truth is simple and uncomfortable: LLMs were never designed to be reliable components. They hallucinate, drift, reorder fields, forget constraints, break schemas, and produce different outputs for identical inputs. And yet — every agent framework, every AI product, every automation system depends on an LLM behaving as if it were deterministic. This is the contradiction at the heart of modern AI engineering. FACET v2.0 was built to resolve that contradiction. Today’s structured output and tool‑calling systems fail for the same reasons: When you scale from hobby scripts to production systems, this becomes fatal: No amount of prompt hacks or retries can fix the fundamental issue: We need a contract layer. Not suggestions. Contracts. FACET v2.0 is not a prompt template language. It is a Neural Architecture Description Language (NADL) — a compiler that turns declarative specifications into deterministic, validated, bounded LLM behaviors. FACET introduces concepts that simply do not exist in prompt engineering today: Typed tool definitions that compile into provider‑specific schemas. No more hope. No more praying the LLM obeys. Variables become nodes in a dependency graph.
FACET computes them deterministically. The first formal model for deterministic context packing.
Every execution fits into a token budget provably. FACET defines a strict 5‑phase pipeline: Each phase is isolated, validated, reproducible, and predictable. Deterministic execution with: Pure Mode guarantees that the same FACET file always produces the same canonical output. This is the foundation agents have been missing. To address the biggest question engineers ask — “How can a probabilistic LLM behave deterministically?” — FACET enforces determinism at compile-time and render-time, not by trusting the model. FACET achieves this through three mechanisms: This is the mathematical foundation behind claims like: Now — to the practical engineering impact. FACET enforces a strict compute gas model (spec-defined error F902) to ensure every execution is bounded, reproducible, and safe: FACET compilers operate in a fully hermetic environment during Phases 1–3: This ensures bit‑for‑bit reproducible builds across machines, environments, and CI systems. FACET defines two execution profiles: This allows teams to scale from simple agents → full enterprise AI architectures without changing the language. Every modern agent framework — LangChain, LlamaIndex, OpenAI, Anthropic, Gemini, DeepSeek — relies on ill-defined assumptions. FACET replaces those assumptions with contracts. FACET’s @output contracts ensure: Combined with @vars and interfaces, this guarantees that whatever the model does internally, the final rendered JSON must satisfy this contract — or the build fails fast, before it ever reaches production. FACET interfaces prevent: Reactive variables + Token Box Model allow: This elevates AI development from: prompt guessing → compiler-defined correctness Below is a production‑grade expansion with real FACET v2.0–compliant examples, R‑DAG behavior, Token Box examples, and deterministic tool‑calling contracts. This FACET file cannot produce malformed JSON — ever. FACET enforces: FACET computes all variables through a strict Reactive Directed Acyclic Graph. Graph for the above example: If critical sections (shrink = 0) exceed the budget, FACET raises F901 (Critical Overflow) before rendering — guaranteeing deterministic resource enforcement.
Below is a real deterministic context allocation scenario. Token budget: 1200 tokens If examples exceed 890 tokens: This is guaranteed deterministic across runs, providers, and platforms. FACET enforces a fixed canonical JSON ordering: This ensures stable diffs, cacheability, and cross‑provider consistency. This eliminates malformed tool calls across: FACET test runs through all five phases, guaranteeing: From internal and external benchmarking: FACET is not a quality‑of-life improvement.
It is an architectural correctness layer. FACET is designed like a real language and runtime: FACET behaves like Rust or TypeScript — not a text macro engine. It’s the first language that treats LLMs as components that must obey contracts. FACET is more than a tool.
It is the beginning of a new paradigm: Not prompt hacking.
Not hoping.
Not retry loops. We stop whispering to models.
We start engineering them. You can try the FACET compiler right now using the reference Rust implementation: Then run a simple FACET agent: JavaScript/TypeScript (npm) and Python (PyPI) distributions are planned next, but today the Rust CLI is the canonical way to work with FACET. FACET is the missing layer you’ve been trying to invent with glue scripts, prompt chains, and validation wrappers. Now it exists — as a language, a spec, a compiler, and a vision. And this is just the beginning. If you want the next article — a deep dive into the Token Box Model — tell me. Or I can expand this into a full dev.to series. Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse CODE_BLOCK:
@output schema: type: "object" required: ["keywords", "title"] properties: keywords: { type: "list<string>" } title: { type: "string" } Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
@output schema: type: "object" required: ["keywords", "title"] properties: keywords: { type: "list<string>" } title: { type: "string" } CODE_BLOCK:
@output schema: type: "object" required: ["keywords", "title"] properties: keywords: { type: "list<string>" } title: { type: "string" } COMMAND_BLOCK:
@system description: "Weather reasoning agent" tools: [$WeatherAPI] @vars city: @input(type="string") weather: $WeatherAPI.get_current(city) summary: $weather |> to_json() |> trim() @interface WeatherAPI fn get_current(city: string) -> struct { temp: float condition: string } @context priority: 100 min: 150 grow: 1 Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
@system description: "Weather reasoning agent" tools: [$WeatherAPI] @vars city: @input(type="string") weather: $WeatherAPI.get_current(city) summary: $weather |> to_json() |> trim() @interface WeatherAPI fn get_current(city: string) -> struct { temp: float condition: string } @context priority: 100 min: 150 grow: 1 COMMAND_BLOCK:
@system description: "Weather reasoning agent" tools: [$WeatherAPI] @vars city: @input(type="string") weather: $WeatherAPI.get_current(city) summary: $weather |> to_json() |> trim() @interface WeatherAPI fn get_current(city: string) -> struct { temp: float condition: string } @context priority: 100 min: 150 grow: 1 COMMAND_BLOCK:
city ----> weather ----> summary Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
city ----> weather ----> summary COMMAND_BLOCK:
city ----> weather ----> summary CODE_BLOCK:
{ "city": "Berlin", "weather": { "temp": 12.4, "condition": "Cloudy" }, "summary": "{\"temp\":12.4,\"condition\":\"Cloudy\"}"
} Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
{ "city": "Berlin", "weather": { "temp": 12.4, "condition": "Cloudy" }, "summary": "{\"temp\":12.4,\"condition\":\"Cloudy\"}"
} CODE_BLOCK:
{ "city": "Berlin", "weather": { "temp": 12.4, "condition": "Cloudy" }, "summary": "{\"temp\":12.4,\"condition\":\"Cloudy\"}"
} COMMAND_BLOCK:
@context system priority: 0 min: 300 shrink: 0 # Critical @context examples priority: 200 min: 0 shrink: 1 grow: 1 Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
@context system priority: 0 min: 300 shrink: 0 # Critical @context examples priority: 200 min: 0 shrink: 1 grow: 1 COMMAND_BLOCK:
@context system priority: 0 min: 300 shrink: 0 # Critical @context examples priority: 200 min: 0 shrink: 1 grow: 1 CODE_BLOCK:
Critical sections: system (size=310)
Free space: 1200 - 310 = 890 examples gets entire flexible region via grow=1 Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
Critical sections: system (size=310)
Free space: 1200 - 310 = 890 examples gets entire flexible region via grow=1 CODE_BLOCK:
Critical sections: system (size=310)
Free space: 1200 - 310 = 890 examples gets entire flexible region via grow=1 COMMAND_BLOCK:
@interface MathAPI fn add(a: int, b: int) -> int Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
@interface MathAPI fn add(a: int, b: int) -> int COMMAND_BLOCK:
@interface MathAPI fn add(a: int, b: int) -> int CODE_BLOCK:
{ "name": "MathAPI", "tools": [ { "type": "function", "function": { "name": "add", "parameters": { "type": "object", "properties": { "a": {"type": "integer"}, "b": {"type": "integer"} }, "required": ["a", "b"] } } } ]
} Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
{ "name": "MathAPI", "tools": [ { "type": "function", "function": { "name": "add", "parameters": { "type": "object", "properties": { "a": {"type": "integer"}, "b": {"type": "integer"} }, "required": ["a", "b"] } } } ]
} CODE_BLOCK:
{ "name": "MathAPI", "tools": [ { "type": "function", "function": { "name": "add", "parameters": { "type": "object", "properties": { "a": {"type": "integer"}, "b": {"type": "integer"} }, "required": ["a", "b"] } } } ]
} CODE_BLOCK:
@test "basic flow" vars: city: "Tokyo" mock: WeatherAPI.get_current: { temp: 18, condition: "Rain" } assert: - output contains "Rain" - cost < 0.005 Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
@test "basic flow" vars: city: "Tokyo" mock: WeatherAPI.get_current: { temp: 18, condition: "Rain" } assert: - output contains "Rain" - cost < 0.005 CODE_BLOCK:
@test "basic flow" vars: city: "Tokyo" mock: WeatherAPI.get_current: { temp: 18, condition: "Rain" } assert: - output contains "Rain" - cost < 0.005 COMMAND_BLOCK:
git clone https://github.com/rokoss21/facet-compiler.git
cd facet-compiler
cargo build --release # optionally add the compiled CLI to your PATH
export PATH="$PWD/target/release:$PATH" Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
git clone https://github.com/rokoss21/facet-compiler.git
cd facet-compiler
cargo build --release # optionally add the compiled CLI to your PATH
export PATH="$PWD/target/release:$PATH" COMMAND_BLOCK:
git clone https://github.com/rokoss21/facet-compiler.git
cd facet-compiler
cargo build --release # optionally add the compiled CLI to your PATH
export PATH="$PWD/target/release:$PATH" CODE_BLOCK:
fct build examples/basic/agent.facet
fct run examples/basic/agent.facet --budget 4096 --format pretty Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
fct build examples/basic/agent.facet
fct run examples/basic/agent.facet --budget 4096 --format pretty CODE_BLOCK:
fct build examples/basic/agent.facet
fct run examples/basic/agent.facet --budget 4096 --format pretty - Schema is just text in a prompt
- JSON is treated as advice, not a contract
- LLMs reorder fields, skip required values, or respond in natural language
- Tool calls fail across providers because each model interprets constraints differently
- Multi-step agents collapse under their own uncertainty - 1–2% success rate for JSON parsing in some cases
- 20–40% tool‑calling failure rates in multi-tool chains
- Memory extraction drifting between runs
- Reruns of the same request returning different results - ints, floats
- multimodal types (image, audio, embeddings)
- structs, lists, unions - Type Checking
- Reactive Compute - no randomness
- no external nondeterministic lenses
- caching of bounded operations - Provider‑specific constrained decoding - FACET compiles @output schemas and @interface signatures into the provider’s native constrained‑decoding format (JSON Schemas, GBNF, OpenAI function-calling grammars, Anthropic tool schemas, Gemini structured formats).
- This forces the LLM to emit tokens that cannot violate the contract. - Canonical validation before context execution - FACET validates every intermediate step before the output touches the agent flow.
- If the model generates anything invalid → FACET aborts with an error instead of passing corrupted data downstream. - Pure Mode eliminates nondeterminism - No randomness
- No nondeterministic lenses
- Deterministic topology of the R‑DAG
- Cached bounded operations - 99–100% valid JSON
- Guaranteed tool schemas
- Zero malformed tool calls - each lens consumes deterministic gas
- exceeding gas triggers a compile‑time or run‑time deterministic abort
- guarantees no infinite loops, runaway pipelines, or unbounded R‑DAG expansion - no network access
- no uncontrolled filesystem access
- no environment variable leakage
- only allowlisted imports permitted - Core Profile — text‑only, lightweight, no R‑DAG, no multimodal, no interfaces
- Hypervisor Profile — full enterprise stack: Token Box Model, multimodal, interfaces, testing, security sandboxing - 99–100% success rates
- zero retries
- canonical JSON mapping - casing failures
- missing parameters
- malformed tool calls - predictable memory
- deterministic chain steps
- stable multi-turn workflows - deterministic evaluation order
- strict typing
- guaranteed tool schema
- canonical JSON in Pure Mode - no cycles (F505)
- no forward refs (F404)
- each node executes once
- deterministic lens evaluation - compression → shrink=1
- if still too large → truncated
- if still too large → removed - Local inference engines - deterministic builds
- stable layouts
- reproducible JSON - strict error codes
- hermetic build (no IO during compile phases)
- testing system (@test)
- profiles (Core vs Hypervisor)
- CLI (fct) for build/run/test/codegen - Agents are reproducible
- Reasoning is traceable
- Tools are typed
- Context is mathematically managed
- LLMs are treated like compilers, not magic boxes - autonomous workflows
- multimodal reasoning systems
- production LLM pipelines - Official Website: https://rokoss21.tech
- FACET Language/Ecosystem: https://github.com/rokoss21/FACET
- FACET Compiler (reference implementation): https://github.com/rokoss21/facet-compiler
- Quickstart & Docs: https://github.com/rokoss21/facet-compiler#readme
how-totutorialguidedev.toaiopenaillmnetworknodepythonjavascriptgitgithub