Cómo hacer que Claude analice un contrato
Extrae cláusulas clave, riesgos y obligaciones de un contrato PDF con la API de Claude en minutos.

- Cuenta en console.anthropic.com con API key activa
- Python 3.9+ instalado
- Librería anthropic (pip install anthropic)
- Un contrato en PDF o texto para analizar
- Conocimientos básicos de Python
- Enviar un PDF de contrato directamente a Claude usando la Document API
- Diseñar un prompt estructurado para extraer cláusulas, riesgos y obligaciones
- Forzar salida en JSON para integrar el análisis en tu sistema
- Manejar contratos largos y controlar el coste de tokens
- Añadir un checklist legal reutilizable con system prompts
Instalar el SDK y configurar la API key
Empieza por preparar el entorno. Instala el SDK oficial de Anthropic y guarda tu API key como variable de entorno para no exponerla en el código. En España y LATAM puedes pagar la API con tarjeta normal; el consumo es por tokens, así que analizar un contrato de 10 páginas cuesta céntimos. Crea la key en console.anthropic.com bajo 'API Keys'. Exporta la variable en tu terminal (o usa un archivo .env con python-dotenv). Nunca la subas a Git: añade .env a tu .gitignore. Verifica que la instalación funciona importando la librería sin errores. Con esto tendrás el cliente listo para hacer llamadas al modelo claude-opus-4-8, que es el que usaremos por su capacidad de razonamiento sobre documentos legales complejos.
pip install anthropic python-dotenv
# En tu terminal (Linux/Mac):
export ANTHROPIC_API_KEY='sk-ant-tu-key-aqui'Cargar el contrato PDF en base64
Claude puede leer PDFs nativamente mediante la Document API, sin que tú extraigas el texto manualmente. Esto es clave porque conserva tablas, firmas y estructura de las cláusulas, algo que un extractor de texto plano suele romper. Abre el archivo en modo binario, codifícalo en base64 y prepáralo para incluirlo en el mensaje. Este método funciona para contratos de hasta 100 páginas o 32 MB. Si tu contrato viene en Word, expórtalo a PDF primero (o usa el texto plano directamente, que también es válido). El PDF viaja dentro del bloque de contenido del mensaje, por lo que no necesitas subirlo a ningún servidor externo: todo va en la misma llamada a la API.
import base64
from anthropic import Anthropic
client = Anthropic()
with open('contrato.pdf', 'rb') as f:
pdf_base64 = base64.standard_b64encode(f.read()).decode('utf-8')Definir un system prompt de abogado revisor
El system prompt fija el rol y el rigor del análisis. Aquí le indicamos a Claude que actúe como revisor legal senior y que sea conservador: ante ambigüedad, debe señalarla como riesgo en lugar de asumir. Esto reduce falsos negativos, que en revisión de contratos son los más caros. Incluye instrucciones concretas sobre qué buscar: partes, objeto, duración, cláusulas de resolución, penalizaciones, jurisdicción y protección de datos (relevante por el RGPD en España y normativas equivalentes en LATAM). Un buen system prompt convierte a Claude en un asistente reproducible: mismo criterio en cada contrato. Guárdalo como constante para reutilizarlo en todo tu pipeline.
SYSTEM_PROMPT = """Eres un abogado revisor senior especializado en
contratos mercantiles. Analizas documentos con criterio conservador:
ante cualquier ambigüedad, la marcas como riesgo en lugar de asumir
la interpretación favorable.
Siempre identificas: partes, objeto, duración y renovación,
obligaciones de cada parte, penalizaciones, causas de resolución,
jurisdicción aplicable y cláusulas de protección de datos (RGPD).
No das consejo legal vinculante; señalas puntos que requieren
revisión humana."""Pedir el análisis con salida en JSON
Ahora combinamos todo en una llamada. Enviamos el PDF como documento y un prompt que exige la respuesta en JSON estructurado. Forzar JSON te permite integrar el resultado en una base de datos, un dashboard o un flujo de aprobación sin parsear texto libre. Usamos un truco fiable: pre-llenar el turno del asistente con '{' para que Claude arranque directamente en JSON y no añada texto introductorio. Definimos el esquema en el prompt: resumen, partes, lista de cláusulas relevantes y lista de riesgos con severidad. El parámetro max_tokens debe ser generoso porque un análisis completo puede ocupar varios miles de tokens. Con claude-opus-4-8 obtienes razonamiento profundo sobre implicaciones legales cruzadas entre cláusulas.
message = client.messages.create(
model="claude-opus-4-8",
max_tokens=4096,
system=SYSTEM_PROMPT,
messages=[
{"role": "user", "content": [
{"type": "document",
"source": {"type": "base64",
"media_type": "application/pdf",
"data": pdf_base64}},
{"type": "text", "text": """Analiza este contrato y devuelve SOLO JSON con este esquema:
{
"resumen": "string",
"partes": ["string"],
"duracion": "string",
"clausulas_clave": [{"titulo": "string", "contenido": "string"}],
"riesgos": [{"descripcion": "string", "severidad": "alta|media|baja"}]
}"""}
]},
{"role": "assistant", "content": "{"}
]
)
print("{" + message.content[0].text)Validar y guardar el resultado
Nunca confíes ciegamente en que la salida sea JSON válido. Envuelve el parseo en un try/except y valida los campos mínimos antes de guardar. Si el modelo devolvió texto extra por algún motivo, recórtalo desde el primer '{' hasta el último '}'. Una vez parseado, puedes ordenar los riesgos por severidad y generar un informe legible o volcarlo a tu sistema. Este paso convierte la respuesta del modelo en datos accionables: un flujo donde los riesgos de severidad alta disparan una alerta a tu equipo legal humano. Recuerda que Claude asiste, no sustituye: el análisis acelera la revisión, pero la decisión final es humana.
import json
raw = "{" + message.content[0].text
try:
data = json.loads(raw)
except json.JSONDecodeError:
raw = raw[raw.find('{'): raw.rfind('}') + 1]
data = json.loads(raw)
riesgos = sorted(data['riesgos'],
key=lambda r: {'alta':0,'media':1,'baja':2}[r['severidad']])
print(f"Resumen: {data['resumen']}\n")
print("RIESGOS PRIORITARIOS:")
for r in riesgos:
print(f" [{r['severidad'].upper()}] {r['descripcion']}")
with open('analisis.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)Optimizar coste con prompt caching
Si vas a analizar muchos contratos con el mismo criterio, el system prompt largo se reenvía en cada llamada y suma tokens. Activa el prompt caching para que Claude cachee la parte estática (tu system prompt de revisor) y solo procese el contrato nuevo. El ahorro puede llegar al 90% en los tokens del prompt cacheado. Añade el bloque cache_control al final del contenido que se repite. La caché dura unos minutos, así que es ideal para procesar lotes de contratos en la misma sesión. Combínalo con un bucle sobre una carpeta de PDFs para montar un pipeline de revisión masiva a coste muy bajo, algo habitual en despachos y departamentos de compras.
message = client.messages.create(
model="claude-opus-4-8",
max_tokens=4096,
system=[{
"type": "text",
"text": SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"}
}],
messages=[...] # igual que el paso 4
)Has montado un pipeline completo que envía un contrato PDF a Claude, extrae partes, cláusulas clave y riesgos priorizados por severidad, y devuelve todo en JSON estructurado listo para integrar en tu sistema. Con el system prompt de revisor y el prompt caching, puedes procesar lotes de contratos con criterio consistente y coste mínimo. Este flujo es exactamente el tipo de proyecto con el que aprenderás a construir sobre la API de Claude, pasando de scripts sueltos a aplicaciones reales de análisis documental.