105 lines
3.7 KiB
Python
105 lines
3.7 KiB
Python
import requests
|
|
import json
|
|
|
|
# Supports Ollama (local) or Anthropic API
|
|
# Set OLLAMA_URL to use local AI, or ANTHROPIC_KEY for Claude API
|
|
|
|
OLLAMA_URL = "http://localhost:11434"
|
|
OLLAMA_MODEL = "qwen2.5:14b"
|
|
|
|
USER_PROFILE = """
|
|
Perfil del comprador:
|
|
- Residente permanente en EE.UU., menos de 2 años en el país
|
|
- Soltero
|
|
- Trabajo independiente: electricista naval/marino ($120/hora)
|
|
- Dinero disponible para down payment: $50,000 dólares
|
|
- Presupuesto máximo: $200,000
|
|
- Busca: costas de Florida (Stuart hacia el norte hasta Jacksonville)
|
|
- Objetivo: casa para vivir, oportunidad de remate o precio bajo de mercado
|
|
- Situación crediticia: construyendo historial en USA, no califica para préstamo convencional aún
|
|
- Tipo de préstamo ideal: Non-QM, Bank Statement, o ITIN loan
|
|
"""
|
|
|
|
ANALYSIS_PROMPT = """Eres un asesor experto en bienes raíces y finanzas para compradores en Florida.
|
|
|
|
{profile}
|
|
|
|
Analiza esta propiedad y responde en español en máximo 4 oraciones:
|
|
1. ¿Es una buena oportunidad para este comprador?
|
|
2. ¿Qué tipo de préstamo le conviene para esta propiedad específica?
|
|
3. ¿Hay algo que deba investigar o que sea una señal de alerta?
|
|
|
|
Propiedad:
|
|
- Dirección: {address}
|
|
- Ciudad/Condado: {city}
|
|
- Precio: ${price:,}
|
|
- Tipo: {prop_type}
|
|
- Estado: {status}
|
|
- Habitaciones: {beds} | Baños: {baths}
|
|
- Metros cuadrados: {sqft}
|
|
- Fuente: {source}
|
|
|
|
Responde de forma directa y práctica, como si le hablaras a un amigo."""
|
|
|
|
|
|
def analyze_with_ollama(prop: dict) -> str:
|
|
prompt = ANALYSIS_PROMPT.format(
|
|
profile=USER_PROFILE,
|
|
address=prop.get("address", "N/A"),
|
|
city=f"{prop.get('city', '')} {prop.get('county', '')}".strip(),
|
|
price=prop.get("price", 0),
|
|
prop_type=prop.get("property_type", "Residencial"),
|
|
status=prop.get("status", "Foreclosure"),
|
|
beds=prop.get("beds", "N/A"),
|
|
baths=prop.get("baths", "N/A"),
|
|
sqft=prop.get("sqft", "N/A"),
|
|
source=prop.get("source", "N/A")
|
|
)
|
|
try:
|
|
r = requests.post(
|
|
f"{OLLAMA_URL}/api/generate",
|
|
json={"model": OLLAMA_MODEL, "prompt": prompt, "stream": False},
|
|
timeout=60
|
|
)
|
|
if r.status_code == 200:
|
|
return r.json().get("response", "").strip()
|
|
except Exception as e:
|
|
return f"IA local no disponible: {e}"
|
|
return "Análisis no disponible."
|
|
|
|
|
|
def analyze_with_anthropic(prop: dict, api_key: str) -> str:
|
|
prompt = ANALYSIS_PROMPT.format(
|
|
profile=USER_PROFILE,
|
|
address=prop.get("address", "N/A"),
|
|
city=f"{prop.get('city', '')} {prop.get('county', '')}".strip(),
|
|
price=prop.get("price", 0),
|
|
prop_type=prop.get("property_type", "Residencial"),
|
|
status=prop.get("status", "Foreclosure"),
|
|
beds=prop.get("beds", "N/A"),
|
|
baths=prop.get("baths", "N/A"),
|
|
sqft=prop.get("sqft", "N/A"),
|
|
source=prop.get("source", "N/A")
|
|
)
|
|
try:
|
|
r = requests.post(
|
|
"https://api.anthropic.com/v1/messages",
|
|
headers={"x-api-key": api_key, "anthropic-version": "2023-06-01", "content-type": "application/json"},
|
|
json={"model": "claude-haiku-4-5-20251001", "max_tokens": 300, "messages": [{"role": "user", "content": prompt}]},
|
|
timeout=30
|
|
)
|
|
if r.status_code == 200:
|
|
return r.json()["content"][0]["text"].strip()
|
|
except Exception as e:
|
|
return f"Error API: {e}"
|
|
return "Análisis no disponible."
|
|
|
|
|
|
def analyze_property(prop: dict, ollama_model: str = None, anthropic_key: str = None) -> str:
|
|
global OLLAMA_MODEL
|
|
if ollama_model:
|
|
OLLAMA_MODEL = ollama_model
|
|
if anthropic_key:
|
|
return analyze_with_anthropic(prop, anthropic_key)
|
|
return analyze_with_ollama(prop)
|