Skip to main content

Your First AXON Program

Let’s build a complete AXON program that analyzes documents. You’ll learn the core concepts while creating something functional.
This guide assumes you’ve completed the installation and have at least one API key configured.

Step 1: Create Your First .axon File

Create a file called analyzer.axon:
analyzer.axon
persona Analyst {
  domain: ["analysis", "research"]
  tone: professional
  confidence_threshold: 0.8
}

flow AnalyzeText(input: Document) -> Summary {
  step Extract {
    given: input
    ask: "What are the key points in this text?"
    output: KeyPoints
  }
  
  step Summarize {
    given: Extract.output
    ask: "Create a concise summary"
    output: Summary
  }
}
1

Understand the persona block

The persona defines the cognitive identity of your AI:
persona Analyst {
  domain: ["analysis", "research"]
  tone: professional
  confidence_threshold: 0.8
}
  • domain: Areas of expertise
  • tone: Communication style
  • confidence_threshold: Minimum confidence level (0-1)
2

Understand the flow block

The flow defines a pipeline of cognitive steps:
flow AnalyzeText(input: Document) -> Summary {
  step Extract { ... }
  step Summarize { ... }
}
Flows:
  • Take typed inputs (input: Document)
  • Return typed outputs (-> Summary)
  • Execute steps sequentially
  • Pass data between steps

Step 2: Validate Your Syntax

Before running, check that your syntax is correct:
axon check analyzer.axon
✓ Lexer: 23 tokens
✓ Parser: AST built
✓ Type Checker: No errors

analyzer.axon is valid.
Always use axon check during development to catch errors early. It runs the lexer, parser, and type checker without executing anything.

Step 3: Compile to IR

Compile your AXON program to Intermediate Representation (IR):
axon compile analyzer.axon
This creates analyzer.ir.json - a JSON representation of your program that any backend can execute.
The IR is a JSON structure that captures the semantic meaning of your program:
{
  "type": "program",
  "personas": [
    {
      "name": "Analyst",
      "domain": ["analysis", "research"],
      "tone": "professional",
      "confidence_threshold": 0.8
    }
  ],
  "flows": [
    {
      "name": "AnalyzeText",
      "parameters": [{"name": "input", "type": "Document"}],
      "return_type": "Summary",
      "steps": [...]
    }
  ]
}

Step 4: Execute Your Program

Run your AXON program with a specific backend:
axon run analyzer.axon --backend anthropic
axon run analyzer.axon --backend anthropic
Requires ANTHROPIC_API_KEY environment variable.

Step 5: Add Constraints with Anchors

Now let’s add hard constraints that can never be violated:
analyzer.axon
persona Analyst {
  domain: ["analysis", "research"]
  tone: professional
  confidence_threshold: 0.8
}

anchor NoSpeculation {
  require: factual_claims
  confidence_floor: 0.75
  unknown_response: "Insufficient information to answer"
  on_violation: raise AnchorBreachError
}

flow AnalyzeText(input: Document) -> Summary {
  step Extract {
    given: input
    ask: "What are the key points in this text?"
    output: KeyPoints
  }
  
  step Summarize {
    given: Extract.output
    ask: "Create a concise summary"
    validate: NoSpeculation
    output: Summary
  }
}
Anchors are hard constraints. If violated, AXON’s self-healing runtime will retry with failure context. If max attempts are exceeded, it raises AnchorBreachError.

Step 6: Add Self-Healing with Refine

Make your program automatically retry and self-correct:
analyzer.axon
flow AnalyzeText(input: Document) -> Summary {
  step Extract {
    given: input
    ask: "What are the key points in this text?"
    output: KeyPoints
  }
  
  step Summarize {
    given: Extract.output
    ask: "Create a concise summary"
    validate: NoSpeculation
    if confidence < 0.8 -> refine(max_attempts: 2)
    output: Summary
  }
}
The refine directive:
  • Automatically retries when confidence is too low
  • Injects failure context back to the LLM
  • Respects max attempts to prevent infinite loops
  • Creates a closed feedback loop for self-healing

Step 7: Enable Execution Tracing

Get detailed insights into what happened during execution:
axon run analyzer.axon --backend anthropic --trace
This saves a trace to analyzer.trace.json. View it with:
axon trace analyzer.trace.json
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
AXON Execution Trace
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[FLOW_START] AnalyzeText
  timestamp: 2026-03-06T14:23:01.234Z
  input: {"text": "Sample document..."}

  [STEP_START] Extract
    timestamp: 2026-03-06T14:23:01.235Z
  
  [MODEL_CALL] anthropic/claude-3-5-sonnet
    timestamp: 2026-03-06T14:23:01.240Z
    duration: 1.23s
  
  [STEP_COMPLETE] Extract
    output: {"key_points": [...]}
    confidence: 0.92
  
  [STEP_START] Summarize
    timestamp: 2026-03-06T14:23:02.470Z
  
  [VALIDATION_SUCCESS] NoSpeculation
    timestamp: 2026-03-06T14:23:03.120Z
  
  [STEP_COMPLETE] Summarize
    output: {"summary": "..."}
    confidence: 0.89

[FLOW_COMPLETE] AnalyzeText
  timestamp: 2026-03-06T14:23:03.125Z
  duration: 1.89s
  status: success

Advanced Example: Contract Analyzer

Here’s a production-ready example from the AXON repository:
contract_analyzer.axon
persona LegalExpert {
  domain: ["contract law", "IP", "corporate"]
  tone: precise
  confidence_threshold: 0.85
  cite_sources: true
}

context LegalReview {
  memory: session
  language: "en"
  depth: exhaustive
  max_tokens: 4096
  temperature: 0.3
}

anchor NoHallucination {
  require: source_citation
  confidence_floor: 0.75
  unknown_response: "I don't have sufficient information."
  on_violation: raise AnchorBreachError
}

type RiskScore(0.0..1.0)

type Party {
  name: FactualClaim,
  role: FactualClaim
}

type Risk {
  score: RiskScore,
  mitigation: Opinion?
}

tool WebSearch {
  provider: brave
  max_results: 5
  timeout: 10s
}

flow AnalyzeContract(doc: Document) -> ContractAnalysis {
  step Extract {
    given: doc
    ask: "Extract all parties, obligations, dates, and penalties"
    output: EntityMap
  }
  step Assess {
    given: Extract.output
    ask: "Identify ambiguous or risky clauses"
    output: RiskAnalysis
  }
}

run AnalyzeContract(myContract)
  as LegalExpert
  within LegalReview
  constrained_by [NoHallucination]
  on_failure: retry(backoff: exponential)
  output_to: "report.json"
  effort: high
This example demonstrates:

Personas

Specialized domain expertise with citation requirements

Context

Session configuration for consistent behavior

Anchors

Hard constraints preventing hallucination

Types

Custom semantic types with ranges and optional fields

Tools

External capabilities with timeout configuration

Flows

Multi-step pipelines with data passing

Using the Python API

You can also use AXON programmatically:
from axon import Lexer, Parser, TypeChecker, IRGenerator, get_backend

# Read source
source = open("analyzer.axon").read()

# Compile
tokens = Lexer(source).tokenize()
ast = Parser(tokens).parse()
errors = TypeChecker(ast).check()

if errors:
    for error in errors:
        print(f"Error: {error}")
    exit(1)

# Generate IR and execute
ir = IRGenerator().generate(ast)
backend = get_backend("anthropic")
result = backend.compile(ir)

print(f"Result: {result}")

Common CLI Commands

Here’s a quick reference of useful commands:
# Validate syntax
axon check program.axon

# Compile to IR
axon compile program.axon -b openai

# Execute with tracing
axon run program.axon --backend anthropic --trace

# View trace
axon trace program.trace.json

# Check version
axon version

Error Hierarchy

AXON has a six-level error hierarchy:
LevelErrorWhen it occurs
1ValidationErrorOutput type mismatch
2ConfidenceErrorConfidence below floor
3AnchorBreachErrorAnchor constraint violated
4RefineExhaustedMax retry attempts exceeded
5RuntimeErrorModel call failed
6TimeoutErrorExecution time limit exceeded
Levels 1-3 trigger automatic self-healing via the RetryEngine. Level 4 means healing failed after max attempts.

Next Steps

Language Reference

Deep dive into AXON’s syntax and semantics

Type System

Learn about epistemic types and subsumption

Examples

Real-world AXON programs

CLI Reference

Complete CLI documentation

Build docs developers (and LLMs) love