Legal Prompt Engineering: Compliance and Legal Analysis with Claude
By Learnia AI Research Team
Legal Prompt Engineering: Compliance and Legal Analysis with Claude
Legal prompt engineering is in a league of its own. Unlike marketing or customer support, every word carries legal weight: a misextracted clause can invalidate a contract, a missed obligation can expose a company to litigation, and a fabricated regulatory reference can compromise a compliance audit. This guide shows you how to build reliable prompts for the legal domain, with the safeguards that liability stakes demand.
Why Legal Prompting Requires Special Care
The legal domain imposes unique constraints that fundamentally differentiate legal prompt engineering from other application domains.
The 5 Domain-Specific Legal Risks
- →Citation hallucination — The model invents a statute, case law, or regulatory reference
- →Clause misinterpretation — A contractual ambiguity is resolved incorrectly
- →Obligation omission — A critical contractual obligation is missed in the analysis
- →Jurisdictional confusion — Applying rules from one jurisdiction to another (e.g., GDPR applied outside the EU)
- →False certainty — The model presents an interpretation as established fact
For a deep dive into hallucination and bias detection in AI systems, see our AI hallucinations and bias detection guide.
Anatomy of a Legal Prompt
A robust legal prompt contains specific sections that encode the role, jurisdiction, constraints, and expected output format.
Base Structure
<role>
You are a specialized legal analysis assistant.
You help legal professionals analyze and structure
legal documents.
You are NOT a lawyer and do NOT provide legal advice.
All analysis must be validated by a qualified legal professional.
</role>
<jurisdiction>
Applicable jurisdiction: {jurisdiction}
Governing law: {applicable_law}
Document language: {document_language}
</jurisdiction>
<task>
{specific_analysis_task}
</task>
<constraints>
- NEVER fabricate a legal reference (statute, case law, regulation)
- If information is not in the document, indicate [NOT FOUND]
- If interpretation is ambiguous, mark [AMBIGUOUS - review required]
- Distinguish facts from interpretations
- Always cite the source clause or section number
</constraints>
<output_format>
{expected_format_specification}
</output_format>
Python Implementation
import anthropic
client = anthropic.Anthropic()
def analyze_contract_clause(clause_text: str, jurisdiction: str = "United States") -> str:
"""Analyze a contract clause with legal safeguards."""
system = f"""<role>
You are a specialized legal analysis assistant for contract law.
You identify obligations, rights, conditions, and risks
in contractual clauses.
You are NOT a lawyer. All analysis requires validation
by a qualified legal professional.
</role>
<jurisdiction>
Jurisdiction: {jurisdiction}
</jurisdiction>
<constraints>
- Always cite the source clause or section
- If an obligation is implicit, mark [IMPLIED - to be confirmed]
- NEVER fabricate a legal reference
- Flag any ambiguity with [AMBIGUOUS]
- Distinguish firm obligations from conditional ones
</constraints>
<output_format>
For each clause analyzed, provide:
1. SUMMARY: one-sentence summary
2. TYPE: obligation | right | condition | limitation | definition
3. PARTIES: who is bound by this clause
4. OBLIGATIONS: list of identified obligations
5. DEADLINES: deadlines or milestones mentioned
6. RISKS: potential risks identified
7. FLAGS: [OK] | [AMBIGUOUS] | [HIGH RISK]
</output_format>"""
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=2048,
temperature=0,
system=system,
messages=[{"role": "user", "content": clause_text}]
)
return message.content[0].text
For reliable JSON structuring with Claude, see our structured outputs in strict mode guide.
Contract Analysis: Extraction and Risk Identification
Contract analysis is the most common use case in legal AI. It covers clause extraction, obligation identification, and risk detection.
Key Clause Extraction Prompt
def extract_contract_clauses(contract_text: str) -> str:
"""Extract key clauses from a contract."""
system = """<role>
You are a contract analysis assistant.
Extract and classify the key clauses from the provided contract.
</role>
<extraction_targets>
Extract the following clauses if present:
1. Purpose / Scope of agreement
2. Term and renewal
3. Pricing and payment terms
4. Obligations of each party
5. Confidentiality / NDA clauses
6. Limitation of liability
7. Indemnification
8. Termination (conditions, notice period, consequences)
9. Force majeure
10. Governing law and jurisdiction
11. Non-compete / Non-solicitation
12. Intellectual property
</extraction_targets>
<output_format>
Strict JSON format:
{
"contract_type": "identified type",
"parties": [{"name": "...", "role": "..."}],
"effective_date": "...",
"clauses": [
{
"category": "...",
"clause_reference": "Section/Article No.",
"summary": "one-sentence summary",
"verbatim_excerpt": "exact text excerpt",
"obligations": ["..."],
"deadlines": ["..."],
"risk_level": "low|medium|high",
"risk_notes": "explanation if medium or high",
"flags": ["AMBIGUOUS", "MISSING", "RISK"]
}
],
"missing_clauses": ["expected clauses that are absent"],
"overall_risk_assessment": "low|medium|high"
}
</output_format>
<constraints>
- VERBATIM extract: cite the exact text, not a paraphrase
- If a standard clause is absent, flag it in missing_clauses
- NEVER fabricate contractual text
- risk_level high if: unlimited liability, unilateral indemnification,
termination without notice
</constraints>"""
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=4096,
temperature=0,
system=system,
messages=[{"role": "user", "content": contract_text}]
)
return message.content[0].text
Contractual Risk Identification
def identify_contract_risks(clauses_json: str) -> str:
"""Identify risks in extracted contract clauses."""
system = """<role>
You are a specialized contractual risk management assistant.
Analyze the extracted clauses and identify risks for each party.
</role>
<risk_categories>
Evaluate each risk across these categories:
- FINANCIAL: financial exposure, penalties, indemnification
- OPERATIONAL: difficult-to-meet obligations, unrealistic deadlines
- LEGAL: potentially unenforceable clauses, non-compliance
- REPUTATIONAL: image risks, missing non-disparagement clauses
- IP: intellectual property risks
</risk_categories>
<output_format>
{
"risks": [
{
"clause_reference": "...",
"category": "FINANCIAL|OPERATIONAL|LEGAL|REPUTATIONAL|IP",
"severity": "low|medium|high|critical",
"description": "risk description",
"recommendation": "recommended action",
"negotiation_leverage": "suggested negotiation point"
}
],
"summary": {
"total_risks": 0,
"critical": 0,
"high": 0,
"medium": 0,
"low": 0,
"top_priority_actions": ["..."]
}
}
</output_format>"""
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=4096,
temperature=0,
system=system,
messages=[{"role": "user", "content": clauses_json}]
)
return message.content[0].text
M&A Due Diligence Contract Analysis Pipeline
A concrete, end-to-end use case: analyzing contracts during M&A due diligence, where document volume is massive and financial risk is high.
Regulatory Compliance: GDPR, SOX, and Industry-Specific Regulations
The second major application domain is regulatory compliance checking, where AI can dramatically accelerate analysis.
GDPR Compliance Check Prompt
def check_gdpr_compliance(document_text: str, document_type: str) -> str:
"""Check GDPR compliance of a document."""
system = f"""<role>
You are a specialized GDPR compliance assistant.
Analyze the provided document and identify compliance
and non-compliance points against the General Data
Protection Regulation (EU 2016/679).
</role>
<document_type>{document_type}</document_type>
<checklist>
Check each applicable GDPR requirement:
1. Legal basis for processing (Art. 6) — identified and valid?
2. Data subject information (Art. 13-14) — complete?
3. Data subject rights (Art. 15-22) — mentioned and actionable?
4. Retention period — defined and proportionate?
5. Transfers outside EU (Art. 44-49) — safeguarded if applicable?
6. Processors (Art. 28) — mandatory clauses present?
7. Security measures (Art. 32) — described?
8. DPO (Art. 37-39) — mentioned if applicable?
9. Records of processing (Art. 30) — compatible?
10. Data Protection Impact Assessment (Art. 35) — needed?
</checklist>
<output_format>
{{
"compliance_score": "percentage of compliant items",
"items": [
{{
"article": "Art. N GDPR",
"requirement": "requirement description",
"status": "compliant|non_compliant|partial|not_applicable",
"finding": "detailed finding",
"excerpt": "document excerpt if relevant",
"recommendation": "corrective action if non-compliant"
}}
],
"critical_gaps": ["major non-compliance issues"],
"recommendations_priority": ["actions in priority order"]
}}
</output_format>
<constraints>
- Reference ONLY articles from the GDPR (EU 2016/679)
- Do NOT invent articles or recitals
- If a point cannot be assessed from the document, indicate
[INSUFFICIENT INFORMATION - further review required]
- Distinguish confirmed non-compliance from potential risk
</constraints>"""
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=4096,
temperature=0,
system=system,
messages=[{"role": "user", "content": document_text}]
)
return message.content[0].text
SOX Compliance (Sarbanes-Oxley)
def check_sox_compliance(process_description: str, control_type: str) -> str:
"""Check SOX compliance of an internal control process."""
system = f"""<role>
You are a specialized SOX compliance assistant
(Sarbanes-Oxley Act, Sections 302 and 404).
Analyze the described internal control process.
</role>
<control_type>{control_type}</control_type>
<evaluation_criteria>
Evaluate the process on these dimensions:
1. Segregation of Duties
2. Authorization and approval controls
3. Audit trail — complete traceability
4. Reconciliation controls
5. System access controls
6. Documentation and formalization of procedures
7. Periodic testing and monitoring
</evaluation_criteria>
<output_format>
{{
"control_effectiveness": "effective|partially_effective|ineffective",
"findings": [...],
"material_weaknesses": ["identified material weaknesses"],
"remediation_actions": ["recommended corrective actions"]
}}
</output_format>"""
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=2048,
temperature=0,
system=system,
messages=[{"role": "user", "content": process_description}]
)
return message.content[0].text
Legal Document Generation
AI can accelerate the drafting of legal memos, summaries, and analysis notes, provided strict safeguards are applied.
Structured Legal Memo
def generate_legal_memo(question: str, facts: str, jurisdiction: str) -> str:
"""Generate a structured legal memo."""
system = f"""<role>
You are a legal writing assistant.
You generate structured analysis memos from
the provided facts and legal question.
This memo is a DRAFT that must be reviewed and completed
by a qualified legal professional.
</role>
<jurisdiction>{jurisdiction}</jurisdiction>
<memo_format>
Mandatory IRAC structure:
1. ISSUE (Legal question) — precise restatement of the question
2. RULE (Applicable rule) — relevant legal principles
WARNING: cite only rules you are certain about.
If uncertain, indicate [RULE TO VERIFY - further research required]
3. APPLICATION (Application to facts) — analysis of facts
against identified rules
4. CONCLUSION — answer to the question with certainty level
(certain | probable | uncertain | insufficient information)
</memo_format>
<constraints>
- NEVER fabricate a reference (statute, case law, regulation)
- If you cite a text, mark [REFERENCE TO VERIFY]
- Clearly distinguish facts from interpretations
- Flag areas of uncertainty with [UNCERTAIN]
- Indicate necessary further research
</constraints>"""
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=4096,
temperature=0,
system=system,
messages=[{
"role": "user",
"content": f"QUESTION: {question}\n\nFACTS:\n{facts}"
}]
)
return message.content[0].text
Citation Verification and Hallucination Prevention
This is the most critical point in legal AI. Legal citation hallucinations are unacceptable in a professional context.
3-Layer Anti-Hallucination Strategy
def legal_analysis_with_citation_check(
document: str,
question: str,
known_references: list[str] = None
) -> dict:
"""Legal analysis with 3-layer citation verification."""
# Layer 1: Prompt that forbids fabrication
system = """<role>
Legal analysis assistant with strict anti-hallucination protocol.
</role>
<citation_protocol>
ABSOLUTE RULES on citations:
1. NEVER cite a statute without marking [TO VERIFY]
2. NEVER cite case law without marking [CASE LAW TO VERIFY]
3. If you're uncertain about a reference, use a general formulation:
"Under generally recognized legal principles..."
4. List all cited references at the end in a
[REFERENCES TO VERIFY] section
</citation_protocol>"""
# Call 1: main analysis
analysis = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=4096,
temperature=0,
system=system,
messages=[{
"role": "user",
"content": f"Document:\n{document}\n\nQuestion:\n{question}"
}]
).content[0].text
# Layer 2: citation extraction and verification
citation_check_system = """Extract ALL legal references
mentioned in the text below.
For each reference, indicate:
- reference: the exact reference text
- type: statute | case_law | regulation | directive
- verifiable: true if the reference is specific enough to
verify, false otherwise
Strict JSON format."""
citations = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
temperature=0,
system=citation_check_system,
messages=[{"role": "user", "content": analysis}]
).content[0].text
# Layer 3: verification against known list (if provided)
verified = []
if known_references:
import json
try:
citation_list = json.loads(citations)
for cite in citation_list:
cite["in_known_references"] = any(
ref in cite["reference"] for ref in known_references
)
verified.append(cite)
except json.JSONDecodeError:
verified = [{"error": "parsing failed", "raw": citations}]
return {
"analysis": analysis,
"citations": citations,
"verified_citations": verified
}
For a systematic approach to evaluating AI outputs, see our Promptfoo evaluation guide for Claude.
Confidentiality Safeguards
Attorney-client privilege and professional secrecy impose additional precautions when using AI APIs.
Legal Document Anonymization
import re
def anonymize_legal_document(text: str) -> str:
"""Anonymize a legal document before sending to the API.
Removes information identifying parties and sensitive amounts."""
patterns = {
"company_name": r'\b(?:Inc|LLC|Corp|Ltd|LLP|PLC|GmbH|AG|SA|SAS)\b[^.]*',
"person_name": r'\b(?:Mr|Mrs|Ms|Dr|Prof)\.?\s+[A-Z][a-z]+(?:\s+[A-Z][a-z]+)+\b',
"address": r'\d+\s+(?:Street|Avenue|Boulevard|Drive|Road|Lane|Way)[^,\n]*',
"ssn": r'\b\d{3}-\d{2}-\d{4}\b',
"ein": r'\b\d{2}-\d{7}\b',
"iban": r'\b[A-Z]{2}\d{2}\s?(?:\d{4}\s?){4,7}\d{1,4}\b',
"email": r'\b[\w.-]+@[\w.-]+\.\w+\b',
"phone": r'\b(?:\+1|1)?[-.\s]?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b',
"amount_usd": r'\$\s?\d{1,3}(?:[,]\d{3})*(?:\.\d{2})?\b',
}
anonymized = text
for info_type, pattern in patterns.items():
anonymized = re.sub(
pattern,
f'[{info_type.upper()}_REDACTED]',
anonymized,
flags=re.IGNORECASE
)
return anonymized
# Always anonymize BEFORE the API call
safe_document = anonymize_legal_document(raw_contract)
response = client.messages.create(
model="claude-sonnet-4-20250514",
messages=[{"role": "user", "content": safe_document}]
)
Confidentiality Vigilance Points
| Requirement | Implementation |
|---|---|
| Anonymization | Systematic pre-processing before any API call |
| Professional secrecy | Never send un-anonymized attorney-client correspondence |
| Legal privilege | Verify that AI usage doesn't waive attorney-client privilege |
| Data retention | Log retention policy compliant with regulations |
| Client consent | Inform clients about AI tool usage |
| Audit trail | Log every analysis without confidential data |
Evaluating Legal Accuracy
Evaluating a legal AI pipeline requires domain-specific metrics.
Evaluation Script
def evaluate_legal_output(output: str, reference: dict) -> dict:
"""Evaluate the quality of a legal analysis output."""
scores = {}
# 1. Extraction completeness
expected_clauses = reference.get("expected_clauses", [])
found = [c for c in expected_clauses if c.lower() in output.lower()]
scores["clause_extraction_completeness"] = (
len(found) / len(expected_clauses) if expected_clauses else 1.0
)
# 2. Uncertainty markers (should be > 0 for ambiguous cases)
uncertainty_markers = (
output.count("[AMBIGUOUS]")
+ output.count("[TO VERIFY]")
+ output.count("[UNCERTAIN]")
+ output.count("[NOT FOUND]")
)
scores["uncertainty_flagging"] = uncertainty_markers
# 3. Disclaimer presence
scores["has_disclaimer"] = any(
term in output.lower()
for term in [
"legal professional",
"legal advice",
"validation",
"disclaimer"
]
)
# 4. Detection of potentially hallucinated citations
import re
article_refs = re.findall(r'[Ss]ection\s*\d+|[Aa]rt(?:icle)?\.?\s*\d+', output)
scores["legal_references_found"] = len(article_refs)
scores["references_flagged_for_review"] = output.count("[TO VERIFY]")
# 5. Flagged-to-total citation ratio
if article_refs:
scores["citation_safety_ratio"] = (
scores["references_flagged_for_review"] / len(article_refs)
)
else:
scores["citation_safety_ratio"] = 1.0
return scores
Deployment Checklist
Before putting a legal AI pipeline into production, validate every item:
- → Anonymization — No confidential data is sent un-anonymized
- → Disclaimers — Present on every output: "does not constitute legal advice"
- → Uncertainty protocol — The model flags what it can't find and what it doesn't know
- → Citation verification — Every legal reference is flagged for review
- → Lawyer review — Human validation workflow in place
- → Regression tests — Test suite covering document types and jurisdictions
- → Confidentiality — Attorney-client privilege and professional secrecy verified
- → Monitoring — Tracking hallucination rate, completeness, and accuracy
- → Documentation — Versioned prompts, changelog, baseline metrics
- → Training — Lawyers understand how to interpret and correct AI outputs
For a structured approach to the prompt engineering process (versioning, testing, iteration), see our prompt engineering process guide.
FAQ
Why does legal prompt engineering require special care?
The legal domain imposes strict terminological precision (every term has a specific legal meaning), legal liability (an error can have major financial consequences), and jurisdictional variations (the same concept can have very different implications across countries). A hallucination in a legal context — such as a fake case law citation — can compromise an entire legal opinion.
How can Claude help with contract analysis?
Claude can extract key clauses, identify obligations and deadlines, detect potential risks, compare clauses to market standards, and flag missing elements. The optimal pipeline separates extraction (structured, JSON) from analysis (interpretation, risks), with legal validation at each step. All output remains a draft subject to lawyer review.
Can AI replace a lawyer for regulatory compliance?
No. AI is an assistance tool that accelerates analysis by automating point-by-point verification of regulatory requirements. It does not constitute legal advice and cannot replace the expertise, judgment, and accountability of a legal professional. Its role is to accelerate preparatory work, not to render opinions.
How do you evaluate the reliability of a legal AI pipeline?
Combine automated metrics (extraction completeness, format compliance, defined term detection) with systematic lawyer review. Key metrics are: hallucination rate on citations (should approach 0%), clause extraction completeness (≥ 95%), and false positive rate in risk detection (< 5%). Purely automated evaluation is insufficient.
Weekly AI Insights
Tools, techniques & news — curated for AI practitioners. Free, no spam.
Free, no spam. Unsubscribe anytime.
→Related Articles
FAQ
Why does legal prompt engineering require special care?+
The legal domain imposes strict terminological precision, legal liability, and jurisdictional variations. A misinterpreted clause or hallucinated legal citation can lead to major financial and legal consequences for the parties involved.
How can Claude help with contract analysis?+
Claude can extract key clauses, identify obligations and deadlines, detect potential risks, and compare clauses to market standards. However, all output must be validated by a qualified legal professional before use in any professional context.
Can AI replace a lawyer for regulatory compliance?+
No. AI is an assistance tool that accelerates analysis and document structuring. It does not constitute legal advice. All conclusions must be reviewed and validated by a qualified legal professional in the relevant jurisdiction.
How do you evaluate the reliability of a legal AI pipeline?+
Combine automated metrics (clause extraction, defined term detection, format compliance) with lawyer review. Measure hallucination rates on legal citations, extraction completeness, and regulatory reference accuracy.