← Volver al catálogo
Agentes IASistemaIntermedioGratis

Subagentes locales con LM Studio

Orquesta subagentes especializados sobre modelos LLM locales via LM Studio para delegar tareas de alto volumen (resumen, clasificacion, extraccion) sin coste de API. Incluye estrategia de enrutamiento inteligente entre modelos locales y cloud.

Descargar SKILL.md

Descarga abierta · sin registro · para LM Studio, Python, OpenAI SDK

// resultado_de_ejemplo

""" Legalify × CULTIVA IA — Subagentes locales con LM Studio

Sistema de 3 subagentes especializados para procesar ~800 contratos/mes sin coste de API. Ahorro estimado: 180 €/mes vs GPT-4.

Dependencias: pip install openai Requisito: LM Studio corriendo en http://localhost:1234 con Llama-3.1-8B-Instruct-Q4_K_M cargado. """

import asyncio import json from dataclasses import dataclass, field from datetime import datetime from openai import AsyncOpenAI

── Configuración ──────────────────────────────────────────────────────────────

LM_STUDIO_URL = "http://localhost:1234/v1" LM_STUDIO_KEY = "lm-studio" # LM Studio acepta cualquier string MODEL_ID = "loaded-model" # LM Studio usa el modelo activo, ignora este valor MAX_CONCURRENT = 2 # LM Studio procesa 1-2 peticiones en paralelo

client = AsyncOpenAI(base_url=LM_STUDIO_URL, api_key=LM_STUDIO_KEY)

── Clase base LocalSubagent ───────────────────────────────────────────────────

class LocalSubagent: """ Subagente genérico sobre LM Studio. Cada subagente especializado hereda de aquí y sobreescribe SYSTEM_PROMPT. """ SYSTEM_PROMPT: str = "Eres un asistente útil." TEMPERATURE: float = 0.2 MAX_TOKENS: int = 512

def __init__(self, semaphore: asyncio.Semaphore):
    self._sem = semaphore

async def run(self, user_input: str) -> str:
    async with self._sem:
        resp = await client.chat.completions.create(
            model=MODEL_ID,
            messages=[
                {"role": "system",  "content": self.SYSTEM_PROMPT},
                {"role": "user",    "content": user_input},
            ],
            temperature=self.TEMPERATURE,
            max_tokens=self.MAX_TOKENS,
        )
    return resp.choices[0].message.content.strip()

── Subagente 1: Clasificador de contratos ────────────────────────────────────

class ClasificadorAgente(LocalSubagent): """ Clasifica un contrato en una de las categorías predefinidas. temperature=0.0 para máxima determinismo. """ SYSTEM_PROMPT = ( "Eres un clasificador legal experto en contratos españoles. " "Analiza el texto del contrato y responde SOLO con una de estas categorías exactas, " "sin explicación ni puntuación adicional:\n" "arrendamiento | servicios | nda | laboral | otro" ) TEMPERATURE = 0.0 MAX_TOKENS = 20

── Subagente 2: Extractor de entidades ───────────────────────────────────────

class ExtractorAgente(LocalSubagent): """ Extrae partes, fecha de firma y cuantía principal del contrato. Devuelve JSON válido. """ SYSTEM_PROMPT = ( "Eres un extractor de datos legales. " "Del texto del contrato extrae exactamente estos campos y devuelve SOLO JSON, " "sin markdown ni texto adicional:\n" '{"parte_a": "", "parte_b": "", "fecha_firma": "YYYY-MM-DD o null", ' '"cuantia_eur": null_o_numero, "objeto": ""}' ) TEMPERATURE = 0.0 MAX_TOKENS = 256

── Subagente 3: Generador de resúmenes ejecutivos ────────────────────────────

class ResumenAgente(LocalSubagent): """ Genera un resumen ejecutivo de UNA frase (<20 palabras). """ SYSTEM_PROMPT = ( "Eres un analista jurídico senior. " "Resume el contrato en UNA frase de máximo 20 palabras, en español, " "indicando tipo de relación, partes y plazo/cuantía principal si consta." ) TEMPERATURE = 0.3 MAX_TOKENS = 80

── Orquestador principal ──────────────────────────────────────────────────────

@dataclass class ResultadoContrato: filename: str categoria: str = "" entidades: dict = field(default_factory=dict) resumen: str = "" error: str = "" duracion_ms: float = 0.0

async def procesar_contrato( filename: str, texto: str, clasificador: ClasificadorAgente, extractor: ExtractorAgente, resumen_ag: ResumenAgente, ) -> ResultadoContrato: """Procesa un contrato con los 3 subagentes en paralelo.""" inicio = datetime.now() resultado = ResultadoContrato(filename=filename)

try:
    # Los 3 subagentes se lanzan en paralelo (comparten el semáforo)
    categoria_raw, entidades_raw, resumen_raw = await asyncio.gather(
        clasificador.run(texto),
        extractor.run(texto),
        resumen_ag.run(texto),
    )

    resultado.categoria = categoria_raw.lower().strip()

    try:
        resultado.entidades = json.loads(entidades_raw)
    except json.JSONDecodeError:
        resultado.entidades = {"raw": entidades_raw}

    resultado.resumen = resumen_raw

except Exception as exc:
    resultado.error = str(exc)

resultado.duracion_ms = (datetime.now() - inicio).total_seconds() * 1000
return resultado

async def batch_procesar( contratos: list[dict], # [{"filename": "...", "texto": "..."}] max_concurrent: int = MAX_CONCURRENT, ) -> list[ResultadoContrato]: """Procesa un lote de contratos de forma asíncrona.""" sem = asyncio.Semaphore(max_concurrent) clasificador = ClasificadorAgente(sem) extractor = ExtractorAgente(sem) resumen_ag = ResumenAgente(sem)

tareas = [
    procesar_contrato(c["filename"], c["texto"], clasificador, extractor, resumen_ag)
    for c in contratos
]
return await asyncio.gather(*tareas)

── Datos de muestra (simulan 10 contratos reales de Legalify) ─────────────────

CONTRATOS_MUESTRA = [ { "filename": "contrato_001_arrendamiento.txt", "texto": ( "CONTRATO DE ARRENDAMIENTO DE LOCAL COMERCIAL\n" "En Madrid, a 3 de enero de 2026.\n" "REUNIDOS: De una parte, Inversiones Rueda S.L. (arrendador), con CIF B-12345678, " "representada por D. Carlos Rueda. De otra, Legalify Technologies S.L. (arrendatario), " "con CIF B-87654321, representada por Dña. Ana Martínez.\n" "OBJETO: Arrendamiento del local sito en Calle Gran Vía 42, Madrid, 120 m².\n" "PRECIO: 2.400 €/mes, pagaderos los 5 primeros días de cada mes.\n" "DURACIÓN: 3 años desde el 1 de febrero de 2026." ), }, { "filename": "contrato_002_nda.txt", "texto": ( "ACUERDO DE CONFIDENCIALIDAD (NDA)\n" "Entre Legalify Technologies S.L. y SoftVenture Partners S.A., " "firmado el 15 de febrero de 2026 en Barcelona.\n" "Las partes se comprometen a no divulgar información confidencial " "intercambiada durante las negociaciones de adquisición de tecnología. " "Vigencia: 2 años. Sin contraprestación económica." ), }, { "filename": "contrato_003_servicios.txt", "texto": ( "CONTRATO DE PRESTACIÓN DE SERVICIOS TECNOLÓGICOS\n" "Celebrado en Sevilla el 20 de marzo de 2026.\n" "PROVEEDOR: DataStream S.L., CIF B-11223344.\n" "CLIENTE: Legalify Technologies S.L., CIF B-87654321.\n" "OBJETO: Desarrollo e integración de API OCR para extracción automática de texto en PDF.\n" "IMPORTE: 18.500 € + IVA, pagaderos en 3 hitos.\n" "PLAZO DE EJECUCIÓN: 4 meses desde la firma." ), }, { "filename": "contrato_004_laboral.txt", "texto": ( "CONTRATO DE TRABAJO INDEFINIDO A TIEMPO COMPLETO\n" "En Madrid, 1 de abril de 2026.\n" "EMPRESA: Legalify Technologies S.L.\n" "TRABAJADOR: D. Pablo García Fernández, DNI 12345678-Z.\n" "PUESTO: Desarrollador Full-Stack Senior.\n" "SALARIO BRUTO ANUAL: 52.000 €, en 12 pagas.\n" "JORNADA: 40 horas semanales. Convenio colectivo: TIC 2024." ), }, { "filename": "contrato_005_servicios_marketing.txt", "texto": ( "CONTRATO DE SERVICIOS DE MARKETING DIGITAL\n" "Madrid, 5 de mayo de 2026.\n" "ENTRE: CULTIVA IA S.L.U. (proveedor) y Legalify Technologies S.L. (cliente).\n" "OBJETO: Gestión mensual de campañas Google Ads, SEO y contenidos para captación B2B.\n" "RETAINER MENSUAL: 1.500 € + IVA.\n" "DURACIÓN: 6 meses, renovable automáticamente." ), }, { "filename": "contrato_006_arrendamiento_nave.txt", "texto": ( "ARRENDAMIENTO DE NAVE INDUSTRIAL\n" "Getafe (Madrid), 10 de enero de 2026.\n" "ARRENDADOR: Patrimonios Getafe S.A., representada por Dña. Rosa Blanco.\n" "ARRENDATARIO: LogiTech Express S.L.\n" "INMUEBLE: Nave 7B, Polígono Industrial Las Dehesas, 850 m².\n" "RENTA: 3.200 €/mes. FIANZA: 2 mensualidades. PLAZO: 5 años." ), }, { "filename": "contrato_007_nda_bilateral.txt", "texto": ( "NON-DISCLOSURE AGREEMENT (BILATERAL)\n" "Signed in Valencia on February 28, 2026.\n" "Between: OpenLex AI S.L. and Legalify Technologies S.L.\n" "Purpose: Exchange of proprietary algorithms and client data models " "for a potential joint-venture in legal AI. Duration: 18 months. " "No monetary compensation." ), }, { "filename": "contrato_008_servicios_contabilidad.txt", "texto": ( "CONTRATO DE SERVICIOS DE ASESORÍA CONTABLE Y FISCAL\n" "Firmado en Madrid el 15 de enero de 2026.\n" "ASESORÍA: Gestión Pyme Asesores S.L., representada por D. Fernando López.\n" "CLIENTE: Legalify Technologies S.L.\n" "SERVICIOS: Contabilidad mensual, liquidaciones IVA, IS y nóminas (hasta 10 empleados).\n" "HONORARIOS: 350 €/mes + IVA. DURACIÓN: Indefinida con preaviso de 30 días." ), }, { "filename": "contrato_009_laboral_practicas.txt", "texto": ( "CONTRATO EN PRÁCTICAS\n" "Madrid, 1 de junio de 2026.\n" "EMPRESA: Legalify Technologies S.L.\n" "TRABAJADOR: Dña. Laura Sánchez Torres, titulada en Derecho (UCM, 2025).\n" "CATEGORÍA: Abogada Junior en Prácticas.\n" "RETRIBUCIÓN: 1.200 €/mes brutos. JORNADA: 35 h/semana.\n" "DURACIÓN: 12 meses, del 1/6/2026 al 31/5/2027." ), }, { "filename": "contrato_010_suministro.txt", "texto": ( "CONTRATO MARCO DE SUMINISTRO DE HARDWARE\n" "Valencia, 20 de marzo de 2026.\n" "PROVEEDOR: TechSupply Ibérica S.A.\n" "COMPRADOR: Legalify Technologies S.L.\n" "OBJETO: Suministro de servidores Dell PowerEdge y portátiles MacBook Pro durante 2026.\n" "IMPORTE ESTIMADO ANUAL: 45.000 € + IVA. Pedidos mínimos de 3.000 €.\n" "GARANTÍA: 3 años on-site. Entrega máxima: 5 días hábiles." ), }, ]

── Ejecución principal ────────────────────────────────────────────────────────

def imprimir_resultado(r: ResultadoContrato, idx: int) -> None: sep = "─" * 70 print(f"\n{sep}") print(f"[{idx:02d}] {r.filename}") print(f" Categoría : {r.categoria or 'ERROR'}") if r.resumen: print(f" Resumen : {r.resumen}") if r.entidades: ent_str = json.dumps(r.entidades, ensure_ascii=False) print(f" Entidades : {ent_str}") if r.error: print(f" ⚠ Error : {r.error}") print(f" Tiempo : {r.duracion_ms:.0f} ms")

def calcular_ahorro(n_contratos: int) -> None: # GPT-4o: ~1500 tokens promedio × 3 llamadas × $0.005/1K tokens de salida coste_gpt4_por_contrato = (1500 / 1000) * 0.005 * 3 # ~$0.0225 coste_total_usd = coste_gpt4_por_contrato * n_contratos coste_total_eur = coste_total_usd * 0.92 print(f"\n{'═' * 70}") print(f" ESTIMACIÓN DE AHORRO — {n_contratos} contratos/mes") print(f"{'═' * 70}") print(f" Coste con GPT-4o : ~{coste_total_eur:.0f} €/mes") print(f" Coste con LM Studio: 0 € (inferencia local)") print(f" Ahorro mensual : ~{coste_total_eur:.0f} €") print(f" Ahorro anual : ~{coste_total_eur * 12:.0f} €") print(f"{'═' * 70}\n")

async def main(): print("=" * 70) print(" LEGALIFY × CULTIVA IA — Subagentes locales con LM Studio") print(" Procesando contratos con Llama-3.1-8B en http://localhost:1234") print("=" * 70)

inicio_total = datetime.now()
resultados = await batch_procesar(CONTRATOS_MUESTRA, max_concurrent=MAX_CONCURRENT)
duracion_total = (datetime.now() - inicio_total).total_seconds()

for idx, r in enumerate(resultados, 1):
    imprimir_resultado(r, idx)

# Resumen estadístico
categorias: dict[str, int] = {}
for r in resultados:
    cat = r.categoria or "error"
    categorias[cat] = categorias.get(cat, 0) + 1

print(f"\n{'═' * 70}")
print(f"  RESUMEN BATCH — {len(resultados)} contratos procesados en {duracion_total:.1f}s")
print(f"{'═' * 70}")
for cat, count in sorted(categorias.items(), key=lambda x: -x[1]):
    bar = "█" * count
    print(f"  {cat:<20} {bar} ({count})")

calcular_ahorro(800)  # estimación mensual real de Legalify

if name == "main": asyncio.run(main())

// qué_hace

Crea subagentes Python sobre LM Studio para procesar tareas LLM de forma local y gratuita.

// cómo_lo_hace

Expone el servidor local de LM Studio como API compatible con OpenAI y enruta tareas segun complejidad entre modelos locales y cloud.

// ejemplo_de_uso

Perfecta cuando quieres evitar costes de API cloud para tareas LLM repetitivas internas. Ej.: enruta resúmenes de documentos al modelo local de LM Studio y reserva GPT-4 solo para los casos más complejos.

// plataformas

LM StudioPythonOpenAI SDK
Categoría
Agentes IA
Tipo
Sistema
Nivel
Intermedio
Licencia
Apache-2.0
Seguridad
seguro · riesgo bajo
Versión
1.0.0

// opiniones_de_la_comunidad

Opiniones

Cargando opiniones…

// pase_cultiva_ia

Llévate todo el arsenal con el Pase

Todas las skills, prompts y automatizaciones del catálogo en un único archivo, listas para usar: un pago, acceso de por vida y las novedades que añadamos. Sin suscripción.

Pago único · IVA incluido · pago seguro con Stripe.

Acceso inmediato · si no es lo que esperabas, te devolvemos los 10 €.