Tutorial

How to Add Search to a Contract Review Agent

Enhance a contract review AI agent with web search for legal precedents, clause benchmarks, and regulatory updates. Python tutorial with Scavio API.

Add web search to a contract review agent by extracting key clauses, building targeted search queries, fetching legal precedents and regulatory context, and compiling enriched context for the LLM to reference during review. Contract review agents that rely solely on training data miss recent regulatory changes, industry-specific clause benchmarks, and relevant case law. Adding a search layer gives the agent access to current legal context without requiring a specialized legal database subscription.

Prerequisites

  • Python 3.8+ installed
  • requests library installed
  • A Scavio API key from scavio.dev
  • A contract text or extracted clause list to review

Walkthrough

Step 1: Extract key clauses

Parse the contract to identify clauses that benefit from external context: indemnification, liability caps, termination, IP assignment, and non-compete.

Python
import os, requests, re

API_KEY = os.environ['SCAVIO_API_KEY']

SEARCHABLE_CLAUSES = [
    'indemnification', 'limitation of liability', 'termination',
    'intellectual property', 'non-compete', 'confidentiality',
    'force majeure', 'data protection', 'warranty',
]

def extract_clauses(contract_text: str) -> list:
    found = []
    text_lower = contract_text.lower()
    for clause in SEARCHABLE_CLAUSES:
        if clause in text_lower:
            # Find the paragraph containing the clause
            for para in contract_text.split('\n\n'):
                if clause in para.lower():
                    found.append({'type': clause, 'text': para[:500]})
                    break
    return found

sample = 'The limitation of liability shall not exceed 12 months of fees paid.\n\nForce majeure events include...'
print(f'Found {len(extract_clauses(sample))} searchable clauses')

Step 2: Build search queries from clauses

Convert each extracted clause into a targeted search query that finds relevant precedents and benchmarks.

Python
def build_queries(clauses: list) -> list:
    queries = []
    for clause in clauses:
        clause_type = clause['type']
        # Regulatory query
        queries.append({
            'clause': clause_type,
            'query': f'{clause_type} clause standard 2026 SaaS contract',
            'purpose': 'benchmark',
        })
        # Precedent query
        queries.append({
            'clause': clause_type,
            'query': f'{clause_type} clause legal precedent enforceability',
            'purpose': 'precedent',
        })
    return queries

clauses = [{'type': 'limitation of liability', 'text': 'Cap at 12 months fees'}]
for q in build_queries(clauses):
    print(f"[{q['purpose']}] {q['query']}")

Step 3: Fetch legal precedents via search

Run each query through Scavio and collect relevant results as context for the contract review.

Python
def fetch_precedents(queries: list) -> list:
    context = []
    for q in queries:
        resp = requests.post('https://api.scavio.dev/api/v1/search',
            headers={'x-api-key': API_KEY},
            json={'platform': 'google', 'query': q['query']}, timeout=15)
        results = resp.json().get('organic_results', [])[:3]
        for r in results:
            context.append({
                'clause': q['clause'],
                'purpose': q['purpose'],
                'title': r.get('title', ''),
                'snippet': r.get('snippet', ''),
                'url': r.get('link', ''),
            })
    print(f'Collected {len(context)} precedent references')
    return context

queries = [{'clause': 'limitation of liability', 'query': 'limitation of liability SaaS contract 2026', 'purpose': 'benchmark'}]
fetch_precedents(queries)

Step 4: Compile review context

Organize the search results into a structured context block that the LLM uses during contract review.

Python
def compile_review_context(clauses: list, precedents: list) -> str:
    context_parts = []
    for clause in clauses:
        clause_type = clause['type']
        relevant = [p for p in precedents if p['clause'] == clause_type]
        context_parts.append(f'\n## {clause_type.title()}')
        context_parts.append(f'Contract text: {clause["text"][:200]}')
        benchmarks = [p for p in relevant if p['purpose'] == 'benchmark']
        if benchmarks:
            context_parts.append('Industry benchmarks:')
            for b in benchmarks:
                context_parts.append(f'  - {b["title"]}: {b["snippet"][:150]}')
        precs = [p for p in relevant if p['purpose'] == 'precedent']
        if precs:
            context_parts.append('Legal precedents:')
            for p in precs:
                context_parts.append(f'  - {p["title"]}: {p["snippet"][:150]}')
    return '\n'.join(context_parts)

clauses = [{'type': 'limitation of liability', 'text': 'Cap at 12 months'}]
precedents = [{'clause': 'limitation of liability', 'purpose': 'benchmark', 'title': 'SaaS Liability Caps 2026', 'snippet': 'Industry standard is 12-24 months of fees', 'url': ''}]
print(compile_review_context(clauses, precedents))

Python Example

Python
import requests, os
H = {'x-api-key': os.environ['SCAVIO_API_KEY']}

def search_clause_context(clause_type):
    data = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
        json={'platform': 'google', 'query': f'{clause_type} clause SaaS contract standard 2026'}).json()
    return [{'title': r['title'], 'snippet': r.get('snippet', '')} for r in data.get('organic_results', [])[:3]]

print(search_clause_context('limitation of liability'))

JavaScript Example

JavaScript
const H = {'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json'};
async function searchClause(clauseType) {
  const r = await fetch('https://api.scavio.dev/api/v1/search', {
    method: 'POST', headers: H,
    body: JSON.stringify({platform: 'google', query: `${clauseType} clause SaaS contract standard 2026`})
  });
  return ((await r.json()).organic_results || []).slice(0, 3).map(r => ({title: r.title, snippet: r.snippet}));
}
searchClause('limitation of liability').then(console.log);

Expected Output

JSON
A contract review agent enriched with current legal precedents, clause benchmarks, and regulatory context sourced from web search for each key clause.

Related Tutorials

Frequently Asked Questions

Most developers complete this tutorial in 15 to 30 minutes. You will need a Scavio API key (free tier works) and a working Python or JavaScript environment.

Python 3.8+ installed. requests library installed. A Scavio API key from scavio.dev. A contract text or extracted clause list to review. A Scavio API key gives you 250 free credits per month.

Yes. The free tier includes 250 credits per month, which is more than enough to complete this tutorial and prototype a working solution.

Scavio has a native LangChain package (langchain-scavio), an MCP server, and a plain REST API that works with any HTTP client. This tutorial uses the raw REST API, but you can adapt to your framework of choice.

Start Building

Enhance a contract review AI agent with web search for legal precedents, clause benchmarks, and regulatory updates. Python tutorial with Scavio API.