Files
Agente-Marketing/casa-hunter/app/ai_analyzer.py
T

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)