El modelo LLM que hemos creado lo debemos poner en producción y empezar así a sacarle provecho. Este tipo de modelos, para poder ser usados, requieren de una API que pueda conectar las peticiones de un usuario con la red neuronal.
La API es el mecanismo por el cual NOFRAUD conecta el comportamiento expresado por un colaborador, con el análisis de la red neuronal.
Vamos a ver cómo exponemos una API y la preparamos para que The Fraud Explorer, el sistema que recolecta los comportamientos, pueda preguntarle a FraudGPT por su análisis y así obtener una decisión binaria sobre si un acto puede ser considerado anti ético o no.
Ollama como motor
Ollama es una plataforma de código abierto diseñada para ejecutar modelos de lenguaje grande (LLM) directamente en hardware local, sin necesidad de conexión a la nube ni interacciones con APIs de terceros.
Su principal objetivo es democratizar el acceso a la inteligencia artificial avanzada, permitiendo a desarrolladores, investigadores y entusiastas trabajar con sus propios modelos de forma segura, privada y eficiente.
En NOFRAUD usamos Ollama para alojar nuestra IA de forma segura y privada, permitiéndole a todos nuestros clientes poder conectarse con FraudGPT y realizar el análisis automático del comportamiento del usuario en ambiente laboral.
Instalación de Ollama
Configurar Ollama es una tarea sencilla que se realiza con un simple comando:
# curl https://ollama.ai/install.sh | sh
Una vez tengamos instalado el motor, realizamos una configuración base editando su archivo de parámetros:
# systemct edit ollama
Establecemos el número de hilos para procesamiento en paralelo y la gestión de memoria:
[Service]
Environment="OLLAMA_KEEP_ALIVE=-1"
Environment="OLLAMA_FLASH_ATTENTION=1"
Environment="OLLAMA_NUM_PARALLEL=12"
Environment="OLLAMA_NEW_ESTIMATES=1"
Adaptación del modelo
Creamos el archivo Modelfile donde especificamos los parámetros y plantilla harmony de FraudGPT:
FROM ./fraudgpt7-mxfp4.gguf
SYSTEM """
Reasoning: high
Eres un experto en la detección de comportamientos anti éticos y usas como base teórica el modelo
de Donald Cressey (presión, oportunidad y justificación). Tu tarea es analizar mensajes que
escriben los empleados en herramientas colaborativas y en caso de que encuentres en ellos la
presencia de actos éticamente cuestionables, deshonestos o malintencionados, responderás con un
SI, en caso contrario responderás con un NO.
"""
TEMPLATE """
<|start|>system<|message|>{{ .System }}<|end|>
{{- $lastUserIdx := -1 }}
{{- $prefillingContent := false }}
{{- $prefillingThinkingOnly := false }}
{{- range $i, $msg := .Messages }}
{{- $last := eq (len (slice $.Messages $i)) 1 -}}
{{- if eq $msg.Role "user" }}
{{- $lastUserIdx = $i }}
{{- end -}}
{{- if and $last (eq $msg.Role "assistant") (gt (len $msg.Content) 0) }}
{{- $prefillingContent = true }}
{{- else if and $last (eq $msg.Role "assistant") (gt (len $msg.Thinking) 0) }}
{{- $prefillingThinkingOnly = true }}
{{- end }}
{{- end -}}
{{- /* Now render messages */ -}}
{{- range $i, $msg := .Messages }}
{{- $last := eq (len (slice $.Messages $i)) 1 -}}
{{- if (ne $msg.Role "system") -}}
{{- if eq $msg.Role "assistant" -}}
{{- if and $msg.Thinking (gt $i $lastUserIdx) -}}
<|start|>assistant<|channel|>analysis<|message|>{{ $msg.Thinking }}
{{- if not $prefillingThinkingOnly -}}<|end|>{{- end -}}
{{- end -}}
{{- if gt (len $msg.Content) 0 -}}
<|start|>assistant<|channel|>final<|message|>{{ $msg.Content }}
{{- if not $prefillingContent -}}<|end|>{{- end -}}
{{- end -}}
{{- else if eq $msg.Role "user" -}}
<|start|>{{ $msg.Role }}<|message|>{{ $msg.Content }}<|end|>
{{- end }}
{{- else }}
{{- end }}
{{- end -}}
{{- if not (or $prefillingContent $prefillingThinkingOnly) -}}
<|start|>assistant
{{- end -}}
"""
PARAMETER temperature 0
PARAMETER top_p 1
PARAMETER seed 3407
PARAMETER num_ctx 4096
Luego se crea el modelo fraudgpt7 con el siguiente comando:
# ollama create -f Modelfile fraudgpt7
Con esto tendríamos creado en Ollama un modelo llamado fraudgpt7, con las instrucciones precisas para poder responder de manera determinista como fue entrenado. Ahora realizaremos una consulta de prueba para verificar cómo responde el modelo.
Prueba de inferencia
Ahora que tenemos Ollama con el modelo disponible para consulta, vamos a crear un script en PHP que nos sirva como prueba para solicitarle a FraudGPT que nos ayude a detectar si un comportamiento es anti ético o no de acuerdo a su entrenamiento:
function llm_inference($alertContent)
{
$username = "myuser";
$password = "mypass";
$model = "fraudgpt7";
$num_threads = "14";
$urlLLM = "https://internal/api/generate";
$es_prompt = "Analiza si el siguiente mensaje escrito por un empleado es relevante para\
identificar actos éticamente cuestionables, deshonestos o malintencionados: ### %s ###\
Este empleado trabaja para una empresa llamada 'XYZ', ubicada en Colombia, cuyo sector\
económico es 'Financiero'. Tu respuesta debe ser exactamente SI o NO.";
$prompt = sprintf($es_prompt, $alertContent);
$params = '{ "model": "'.$model.'",
"stream" : false,
"think": "medium",
"keep_alive" : -1,
"options" : {
"use_mmap": false,
"num_thread": '.$num_threads.'
},
"prompt" : "'.$prompt.'"
}';
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $urlLLM);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$resultLLM = curl_exec($ch);
$curl_errno = curl_errno($ch);
$curl_error = curl_error($ch);
curl_close($ch);
if ($curl_errno > 0 || str_contains($resultLLM, "Bad Gateway"))
{
if ($curl_errno == 28)
{
$arrJSON['answer'] = "SI";
$arrJSON['analysis'] = "SI (hubo un timeout de 2 minutos)";
return $arrJSON;
}
else
{
$arrJSON['answer'] = "SI";
$arrJSON['analysis'] = "SI (la conexión con la API no estaba disponible)";
return $arrJSON;
}
}
$response = json_decode($resultLLM, true);
if (isset($response['error']))
{
$arrJSON['answer'] = "SI";
$arrJSON['analysis'] = "SI (el mensaje no fue procesado correctamente)";
return $arrJSON;
}
else
{
$answer = strtoupper(trim($response['response']));
if (str_contains($answer, "Í")) $answer = str_replace("Í", "I", $answer);
if (str_starts_with($answer, "SI"))
{
$arrJSON['answer'] = "SI";
$arrJSON['analysis'] = "SI (porque el modelo respondió con un SI)";
return $arrJSON;
}
else if (str_starts_with($answer, "NO"))
{
$arrJSON['answer'] = "NO";
$arrJSON['analysis'] = "NO (porque el modelo respondió con un NO)";
return $arrJSON;
}
else
{
$arrJSON['answer'] = "SI";
$arrJSON['analysis'] = "SI (porque el modelo no respondió con un SI o un NO)";
return $arrJSON;
}
}
}
$llmResult = llm_inference("De una, me acompaña al hueco o que?, hágale nos pillamos\
ahorita, caiga pues que lo estoy esperando para que hagamos esa vuelta");
var_dump($llmResult);
Ejecutamos la inferencia desde la línea de comandos:
# php llm.php
Y obtenemos el siguiente resultado:
string(10061)
{
"model": "fraudgpt7",
"created_at": "2025-09-23T16:14:37.497163361Z",
"thinking": "Necesitamos analizar el mensaje: [De una, me acompaña al hueco o que?, hágale nos
pillamos ahorita, caiga pues que lo estoy esperando para que hagamos esa vuelta]. Necesitamos
ver si muestra alguna de las conductas poco éticas que nos pidieron buscar. El mensaje parece
una charla informal, posiblemente sobre ir a algún sitio, una broma. No menciona ninguna
irregularidad, ni ocultación de información, ni fraude, ni nada. Es solo un mensaje informal.
Así que responderé NO.",
"response": "NO",
"done": true,
"done_reason":"stop"
}
Sucede en tiempo real
Mientras el agente de The Fraud Explorer está recolectando comportamientos en tiempo real, al mismo tiempo los está enviando a FraudGPT a través de la API para su análisis instantáneo, de esta forma, NOFRAUD puede entregar alertas lo más cercano al tiempo real posible para que nuestros clientes tengan la oportunidad de detener un acto anti ético antes de que se materialice.
Muchas gracias
Hemos llegado al final de la serie de 4 artículos, donde mostramos cómo NOFRAUD ha logrado crear un LLM a partir de un modelo fundacional, permitiendo mejorar hasta en un 36% más las métricas F1, Recall y Precision de los modelos comercialmente disponibles al público.
Para devolverse a la tercera parte de clic aquí: Finetuning de un LLM con Python.
Acerca de NOFRAUD
NOFRAUD es la compañía que desarrolla el software antifraude The Fraud Explorer y apoya a personas y empresas a enfrentar y solucionar sus retos en materia de fraude interno, corrupción y abuso corporativo. NOFRAUD ha creado la base de datos conductual de actos deshonestos más grande del mundo en Español e Inglés, que sirve para que la inteligencia artificial encuentre patrones sospechosos de corrupción al interior de las organizaciones.

Mejoramos la capacidad de las organizaciones incrementando sus beneficios, arrebatándole a los perpetradores la posibilidad de afectar negativamente los ingresos a través del fraude, la corrupción, el abuso corporativo y la generación de ambientes tóxicos.
Contacte conmigo en » jrios@nofraud.la y Visítenos en » www.nofraud.la.