Systems Library / Industry Applications / How to Build a Contract Template Automation System
Industry Applications legal

How to Build a Contract Template Automation System

Generate contracts from templates with automated data population.

Jay Banlasan

Jay Banlasan

The AI Systems Guy

Contract template automation for legal documents turns a 45-minute manual process into a 2-minute form fill. I built this for a firm that drafts the same types of agreements repeatedly with minor variations. The attorney fills in the variables, the system populates the template, AI reviews for consistency, and a clean draft comes out ready for review.

What You Need Before Starting

Step 1: Create the Template System

import re
import os

TEMPLATE_DIR = "contract_templates/"

def load_template(template_name):
    path = os.path.join(TEMPLATE_DIR, f"{template_name}.txt")
    with open(path) as f:
        return f.read()

def get_template_variables(template_text):
    return list(set(re.findall(r"\{\{(\w+)\}\}", template_text)))

def populate_template(template_text, variables):
    result = template_text
    for key, value in variables.items():
        result = result.replace(f"{{{{{key}}}}}", str(value))
    
    missing = re.findall(r"\{\{(\w+)\}\}", result)
    return result, missing

Step 2: Define Common Templates

Create contract_templates/service_agreement.txt:

SERVICE AGREEMENT

This Service Agreement ("Agreement") is entered into as of {{effective_date}}
by and between:

{{provider_name}}, a {{provider_entity_type}} organized under the laws of
{{provider_state}} ("Provider")

and

{{client_name}}, a {{client_entity_type}} organized under the laws of
{{client_state}} ("Client")

1. SERVICES
Provider shall perform the following services: {{scope_of_services}}

2. TERM
This Agreement begins on {{start_date}} and continues for {{term_length}},
unless terminated earlier per Section 6.

3. COMPENSATION
Client shall pay Provider {{payment_amount}} {{payment_frequency}}.
Payment is due within {{payment_terms}} days of invoice.

4. CONFIDENTIALITY
Both parties agree to maintain the confidentiality of proprietary information
disclosed during the term of this Agreement for a period of {{confidentiality_years}} years.

5. LIABILITY
Provider's total liability under this Agreement shall not exceed {{liability_cap}}.

6. TERMINATION
Either party may terminate with {{notice_period}} days written notice.

7. GOVERNING LAW
This Agreement shall be governed by the laws of {{governing_state}}.

Step 3: Build the Generation Engine

import anthropic
from dotenv import load_dotenv
load_dotenv()

def generate_contract(template_name, variables):
    template = load_template(template_name)
    document, missing = populate_template(template, variables)
    
    if missing:
        return {"error": f"Missing variables: {', '.join(missing)}", "document": None}
    
    reviewed = review_populated_contract(document, variables)
    
    return {
        "document": document,
        "review": reviewed,
        "template": template_name,
        "variables_used": list(variables.keys())
    }

def review_populated_contract(document, variables):
    client = anthropic.Anthropic()
    
    response = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=1024,
        system="""Review this populated contract for:
1. Internal consistency (dates, names, terms match throughout)
2. Missing information or placeholder text that was not replaced
3. Potentially problematic terms based on the deal structure
4. Formatting issues
Return a brief checklist of issues found, or confirm the document looks clean.""",
        messages=[{
            "role": "user",
            "content": f"Review this contract:\n\n{document}"
        }]
    )
    
    return response.content[0].text

Step 4: Build the CLI Interface

import json

def interactive_contract_generation(template_name):
    template = load_template(template_name)
    variables = get_template_variables(template)
    
    print(f"Generating {template_name}")
    print(f"Fill in {len(variables)} fields:\n")
    
    values = {}
    for var in sorted(variables):
        label = var.replace("_", " ").title()
        value = input(f"  {label}: ")
        values[var] = value
    
    result = generate_contract(template_name, values)
    
    if result.get("error"):
        print(f"\nError: {result['error']}")
        return
    
    output_file = f"drafts/{template_name}_{values.get('client_name', 'draft').replace(' ', '_')}.txt"
    os.makedirs("drafts", exist_ok=True)
    
    with open(output_file, "w") as f:
        f.write(result["document"])
    
    print(f"\nContract saved to {output_file}")
    print(f"\nAI Review:\n{result['review']}")

Step 5: Add Clause Library Support

CLAUSE_LIBRARY = {
    "non_compete": """NON-COMPETE
During the term and for {{non_compete_period}} following termination,
Provider shall not provide similar services to direct competitors of Client
within {{non_compete_geography}}.""",

    "force_majeure": """FORCE MAJEURE
Neither party shall be liable for delays caused by circumstances beyond
reasonable control, including natural disasters, government actions, or
pandemic-related restrictions.""",

    "ip_assignment": """INTELLECTUAL PROPERTY
All work product created under this Agreement shall be the exclusive
property of {{ip_owner}}. Provider assigns all rights, title, and interest
in such work product to {{ip_owner}}."""
}

def add_clause(document, clause_name, variables=None):
    clause = CLAUSE_LIBRARY.get(clause_name)
    if not clause:
        return document
    
    if variables:
        clause, _ = populate_template(clause, variables)
    
    return document + "\n\n" + clause

if __name__ == "__main__":
    interactive_contract_generation("service_agreement")

What to Build Next

Add version tracking. When a contract goes through revisions, store each version with a diff showing what changed. That creates an audit trail of negotiation history.

Related Reading

Want this system built for your business?

Get a free assessment. We will map every system your business needs and show you the ROI.

Get Your Free Assessment

Related Systems