Skip to main content

Overview

This example demonstrates a production-ready contract analysis agent that extracts entities, identifies risks, and generates comprehensive reports. It showcases personas, contexts, anchors, custom types, tools, and multi-step flows.

Use Case

Analyze legal contracts to:
  • Extract parties, obligations, dates, and penalties
  • Identify ambiguous or risky clauses
  • Assess risk levels with quantified scores
  • Generate structured reports with citations
  • Prevent hallucination through hard constraints

Complete Code

contract_analyzer.axon
// AXON Example — Contract Analyzer
// A complete agent that extracts, reasons, and reports on contracts.

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

Key Components

Persona: LegalExpert

persona LegalExpert {
  domain: ["contract law", "IP", "corporate"]
  tone: precise
  confidence_threshold: 0.85
  cite_sources: true
}
Defines a specialized legal expert with:
  • Domain expertise: Contract law, intellectual property, corporate law
  • Tone: Precise and formal
  • Confidence threshold: High (0.85) for legal accuracy
  • Citation requirement: All claims must cite sources

Context: LegalReview

context LegalReview {
  memory: session
  language: "en"
  depth: exhaustive
  max_tokens: 4096
  temperature: 0.3
}
Configures the execution environment:
  • Memory: Session-scoped (persists during execution)
  • Language: English
  • Depth: Exhaustive analysis
  • Max tokens: 4096 for detailed responses
  • Temperature: Low (0.3) for consistent, factual output

Anchor: NoHallucination

anchor NoHallucination {
  require: source_citation
  confidence_floor: 0.75
  unknown_response: "I don't have sufficient information."
  on_violation: raise AnchorBreachError
}
Enforces hard constraints:
  • Requires: Source citation for all claims
  • Confidence floor: Minimum 0.75 confidence
  • Unknown response: Explicit admission when uncertain
  • On violation: Raises error to trigger self-healing
Anchors are non-negotiable constraints. If violated, AXON’s self-healing runtime will retry with failure context. After max attempts, it raises AnchorBreachError.

Custom Types

type RiskScore(0.0..1.0)

type Party {
  name: FactualClaim,
  role: FactualClaim
}

type Risk {
  score: RiskScore,
  mitigation: Opinion?
}
RiskScore: Range-constrained float (0.0-1.0)
  • Compile-time validation ensures scores are always valid
  • Cannot be confused with arbitrary floats
Party: Structured type with epistemic fields
  • name and role must be FactualClaim (not opinions or speculation)
  • Prevents hallucinated party information
Risk: Combines quantitative and qualitative
  • score: Quantified risk level
  • mitigation: Optional opinion on how to address it
Use epistemic types (FactualClaim, Opinion) to separate facts from interpretations. This prevents the LLM from mixing subjective opinions into factual fields.

Tool: WebSearch

tool WebSearch {
  provider: brave
  max_results: 5
  timeout: 10s
}
Defines external web search capability:
  • Provider: Brave Search API
  • Max results: Top 5 results
  • Timeout: 10 seconds to prevent hanging
This tool can be invoked with use WebSearch("legal precedents") to find relevant case law or regulations.

Flow: AnalyzeContract

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
  }
}
Two-step cognitive pipeline: Step 1: Extract
  • Input: The contract document
  • Task: Extract structured entities
  • Output: EntityMap with parties, obligations, dates, penalties
Step 2: Assess
  • Input: Extracted entities from Step 1
  • Task: Identify risks and ambiguities
  • Output: RiskAnalysis with risk scores and descriptions
Steps execute sequentially, with outputs flowing from one to the next.

Run Statement

run AnalyzeContract(myContract)
  as LegalExpert
  within LegalReview
  constrained_by [NoHallucination]
  on_failure: retry(backoff: exponential)
  output_to: "report.json"
  effort: high
Executes the flow with:
  • as LegalExpert: Use the LegalExpert persona
  • within LegalReview: Use the LegalReview context
  • constrained_by: Apply NoHallucination anchor
  • on_failure: Retry with exponential backoff on errors
  • output_to: Save results to report.json
  • effort: High effort level for thorough analysis

Usage

Validate Syntax

axon check contract_analyzer.axon
Expected output:
✓ Lexer: 156 tokens
✓ Parser: AST built
✓ Type Checker: No errors

contract_analyzer.axon is valid.

Compile to IR

axon compile contract_analyzer.axon
Generates contract_analyzer.ir.json — the intermediate representation that any backend can execute.

Execute with Tracing

axon run contract_analyzer.axon --backend anthropic --trace
Runs the analyzer with Claude and saves execution trace to contract_analyzer.trace.json.

View Trace

axon trace contract_analyzer.trace.json
Displays detailed execution flow, model calls, and validation checkpoints.

Example Output

When analyzing a contract, the output might look like:
{
  "type": "ContractAnalysis",
  "entities": {
    "parties": [
      {
        "name": "Acme Corporation",
        "role": "Service Provider"
      },
      {
        "name": "Widget Industries LLC",
        "role": "Client"
      }
    ],
    "obligations": [
      "Deliver services within 30 days of contract signing",
      "Maintain confidentiality of client data",
      "Provide monthly progress reports"
    ],
    "dates": {
      "effective_date": "2026-01-15",
      "termination_date": "2027-01-14",
      "renewal_deadline": "2026-12-15"
    },
    "penalties": [
      "Late delivery: $500 per day after deadline",
      "Breach of confidentiality: up to $50,000"
    ]
  },
  "risk_analysis": {
    "overall_risk_score": 0.42,
    "risks": [
      {
        "score": 0.65,
        "description": "Ambiguous termination clause lacks specific notice requirements",
        "mitigation": "Recommend adding 30-day written notice requirement"
      },
      {
        "score": 0.48,
        "description": "Force majeure clause may not cover pandemic-related delays",
        "mitigation": "Consider explicitly including infectious disease outbreaks"
      }
    ]
  },
  "confidence": 0.87,
  "sources": [
    "Contract document, Section 4.2",
    "Contract document, Section 7.1",
    "Contract document, Appendix B"
  ]
}

Advanced Enhancements

Add Precedent Research

Enhance the flow to search for legal precedents:
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
  }
  
  step ResearchPrecedents {
    use WebSearch("legal precedents for " + Assess.output.risks)
    output: Precedents
  }
  
  weave [Extract.output, Assess.output, Precedents] into ContractAnalysis {
    format: StructuredReport
    priority: [risks, obligations, precedents]
  }
}

Add Validation

Ensure high-confidence results:
flow AnalyzeContract(doc: Document) -> ContractAnalysis {
  step Extract {
    given: doc
    ask: "Extract all parties, obligations, dates, and penalties"
    output: EntityMap
  }
  
  validate Extract.output against EntitySchema {
    if confidence < 0.85 -> refine(max_attempts: 2)
    if structural_mismatch -> raise ValidationError
  }
  
  step Assess {
    given: Extract.output
    ask: "Identify ambiguous or risky clauses"
    output: RiskAnalysis
  }
  
  validate Assess.output against RiskSchema {
    if confidence < 0.80 -> refine(max_attempts: 3)
  }
}

Add Deep Reasoning

Use explicit chain-of-thought reasoning:
flow AnalyzeContract(doc: Document) -> ContractAnalysis {
  step Extract {
    given: doc
    probe doc for [parties, obligations, dates, penalties]
    output: EntityMap
  }
  
  reason RiskAssessment {
    given: Extract.output
    about: "contractual risks and ambiguities"
    ask: "What are the potential legal risks?"
    depth: 4
    show_work: true
    chain_of_thought: true
    output: RiskAnalysis
  }
}

Best Practices

1. Use Epistemic Types for Facts

// ✅ Good: Separates facts from opinions
type Analysis {
  facts: List<FactualClaim>,
  recommendations: List<Opinion>
}

// ❌ Bad: Mixes facts and opinions
type Analysis {
  content: List<String>
}

2. Apply Anchors to Critical Steps

// Apply to steps that must never hallucinate
run AnalyzeContract(myContract)
  constrained_by [NoHallucination]
context LegalReview {
  temperature: 0.3  // Low for consistency
}

4. Require Source Citations

persona LegalExpert {
  cite_sources: true
}

anchor NoHallucination {
  require: source_citation
}

5. Handle Failures Gracefully

run AnalyzeContract(myContract)
  on_failure: retry(backoff: exponential)

Sentiment Analysis

Analyze text sentiment with epistemic confidence

Data Extraction

Extract structured data from unstructured text

Multi-Step Reasoning

Complex reasoning with chain-of-thought
  • Persona — Define agent identities
  • Context — Configure execution environments
  • Anchor — Enforce hard constraints
  • Types — Epistemic type system
  • Tools — External capabilities
  • Flow — Cognitive pipelines

Build docs developers (and LLMs) love