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
// 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 {
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]
3. Use Low Temperature for Legal Work
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