Introduction
This sixth AI agent is designed for a critical business function: Legal Document Review & Contracting. This agent reads legal documents such as contracts, identifies key clauses (e.g., confidentiality, payment terms, termination rights), checks for compliance with internal policies, and proposes edits or approvals. It ensures that the contract language adheres to guidelines set by the legal team, avoiding vague terms or conflicting clauses. The agent never claims success unless actions are executed, and it always tracks changes, offering receipts for any alterations made.
The Use Case
Legal teams often handle contracts with numerous clauses, terms, and stipulations. A contract review process typically includes scanning for standard terms, checking for specific prohibitions, ensuring that the language matches company policy, and flagging terms that require manual review. The AI agent must perform these tasks and, if all conditions are met, propose edits or even auto-generate parts of the contract while preserving its integrity.
Prompt Contract (agent interface)
# file: contracts/legal_review_v1.yaml
role: "LegalContractAgent"
scope: >
Review legal documents for compliance, standard clauses, and conflicts.
Ask once for missing fields (contract_text, contract_type, jurisdiction, clauses).
Propose tool calls; never assert success unless a receipt is present.
output:
type: object
required: [summary, decision, contract_clauses, citations, next_steps, tool_proposals]
properties:
summary: {type: string, maxWords: 100}
decision: {type: string, enum: ["approve","edit","need_approval","reject","need_more_info"]}
contract_clauses:
type: array
items:
type: object
required: [clause_name, clause_text, compliance_status]
properties:
clause_name: {type: string}
clause_text: {type: string}
compliance_status: {type: string, enum: ["compliant", "non-compliant", "needs_review"]}
citations: {type: array, items: {type: string}}
next_steps: {type: array, items: {type: string}, maxItems: 6}
tool_proposals:
type: array
items:
type: object
required: [name, args, preconditions, idempotency_key]
properties:
name: {type: string, enum: [AnalyzeContract, CheckCompliance, SuggestEdits, ApproveContract]}
args: {type: object}
preconditions: {type: string}
idempotency_key: {type: string}
policy_id: "contract_policy.v3"
citation_rule: "1–2 minimal-span claim_ids per factual sentence"
decoding:
narrative: {top_p: 0.92, temperature: 0.72, stop: ["\n\n## "]}
bullets: {top_p: 0.82, temperature: 0.45}
Example claims (context given to the model)
[
{"claim_id":"policy:confidentiality:standard","text":"Confidentiality clause must last at least 2 years after termination.",
"effective_date":"2025-01-01","source_id":"doc:contract_policy_v3","span":"2 years after termination"},
{"claim_id":"policy:payment_terms:max_delay","text":"Payment terms must not exceed 60 days from invoice.",
"effective_date":"2025-01-01","source_id":"doc:contract_policy_v3","span":"60 days from invoice"},
{"claim_id":"policy:termination:early_notice","text":"Termination requires at least 90 days' notice for both parties.",
"effective_date":"2025-01-01","source_id":"doc:contract_policy_v3","span":"90 days' notice"}
]
Tool Interfaces (typed, with receipts)
# tools.py
from pydantic import BaseModel
from typing import Optional, List, Dict
from datetime import date
class AnalyzeContractArgs(BaseModel):
contract_text: str
contract_type: str # "NDAs", "SaaS", "Employment"
jurisdiction: str
clauses: Optional[List[str]] = []
class CheckComplianceArgs(BaseModel):
clause_name: str
clause_text: str
policy_id: str
class SuggestEditsArgs(BaseModel):
clause_name: str
clause_text: str
recommended_changes: str
class ApproveContractArgs(BaseModel):
contract_id: str
approver_id: str
class ToolReceipt(BaseModel):
tool: str
ok: bool
ref: str
message: str = ""
data: Optional[Dict] = None
# adapters.py (demo logic)
from tools import *
from datetime import datetime, timedelta
CONTRACTS = {"contract_1234": {"status": "draft", "type": "SaaS", "jurisdiction": "US"}}
CLAUSE_RULES = {
"confidentiality": {"text": "Confidentiality must last at least 2 years", "compliant": False},
"payment_terms": {"text": "Payment must be within 60 days", "compliant": True},
"termination": {"text": "Termination requires 90 days' notice", "compliant": False}
}
def analyze_contract(a: AnalyzeContractArgs) -> ToolReceipt:
contract = CONTRACTS.get(a.contract_type)
if not contract:
return ToolReceipt(tool="AnalyzeContract", ok=False, ref="contract-missing", message="Contract not found")
clauses = []
for clause_name in CLAUSE_RULES:
clauses.append({"clause_name": clause_name, "clause_text": CLAUSE_RULES[clause_name]["text"],
"compliance_status": "non-compliant" if not CLAUSE_RULES[clause_name]["compliant"] else "compliant"})
return ToolReceipt(tool="AnalyzeContract", ok=True, ref=f"contract-{a.contract_type}",
message="Contract analyzed", data={"clauses": clauses})
def check_compliance(a: CheckComplianceArgs) -> ToolReceipt:
rule = CLAUSE_RULES.get(a.clause_name)
if not rule:
return ToolReceipt(tool="CheckCompliance", ok=False, ref="clause-not-found", message="Clause not found")
if a.clause_text != rule["text"]:
return ToolReceipt(tool="CheckCompliance", ok=False, ref="clause-mismatch", message="Clause text mismatch")
return ToolReceipt(tool="CheckCompliance", ok=True, ref=f"clause-{a.clause_name}", message="Clause is compliant")
def suggest_edits(a: SuggestEditsArgs) -> ToolReceipt:
changes = f"Replace with: 'Confidentiality will last for 2 years post-termination'"
return ToolReceipt(tool="SuggestEdits", ok=True, ref=f"edit-{a.clause_name}", message="Suggested edit",
data={"recommended_changes": changes})
def approve_contract(a: ApproveContractArgs) -> ToolReceipt:
return ToolReceipt(tool="ApproveContract", ok=True, ref=f"approve-{a.contract_id}", message="Contract approved")

Join the conversation! Your thoughts help the community grow.