Ce projet fait partie d'un Travail de Bachelor réalisé à l'HEIG-VD, dans la filière Informatique et systèmes de communication (ISC) par Lazar Pavicevic et supervisé par le Professeur Marcel Graf.
Le Travail de Bachelor est également composé d'une API accessible sur ce repository :
Structurizer est une application web de structuration de données issues du langage naturel.
L'application se repose sur l'API LLM-Structurizer
qui, à son tour, utilise des LLMs pour structurer les données.
Structurizer propose les fonctionnalités suivantes:
- Upload de documents pour extraction et structuration des données.
- Structuration des données guidée sous forme de pipelines ou automatique.
- Vérification humaine des données structurées avec assistance possible d'un LLM.
- Consultation des données structurées et affichage de statistiques et agrégations sous forme de graphiques.
- Question Answering en langage naturel sur les données structurées.
L'application web est au stade de Proof of Concept, elle propose la structuration de documents pdf uniquement. Elle se limite également à la catégorisation et l'extraction de données structurées de factures, de tickets de reçu et de relevés de carte de crédit.
demo.mp4
L'application stocke ses documents pdf en utilisant le package @aws-sdk/client-s3
. N'import quel Object Storage compatible S3 devrait fonctionner.
Les Object Storages suivants ont été testés et sont fonctionnels avec l'application:
- NodeJS >= version 16
- NPM >= version 8
- PostgreSQL version 15
- Docker
- Clé d'API OpenAI
- Clé d'API de LLM-Structurizer
- Credentials d'un Object Storage compatible S3
git clone git@github.com:Lazzzer/structurizer.git
cd structurizer
npm install
Créer un fichier .env
à partir du fichier .env.example et mettez-y vos valeurs.
Exemple:
# Format: postgresql://[POSTGRES_USER]:[POSTGRES_PASSWORD]@[DB_HOST]:[DB_PORT]/[DB_NAME]?schema=[DB_SCHEMA]&connect_timeout=300
DATABASE_URL=postgresql://postgres:root@localhost:5432/structurizer?schema=public&connect_timeout=300
# Vous pouvez générer un secret ici: https://generate-secret.vercel.app/32
NEXTAUTH_SECRET=
NEXTAUTH_URL=http://localhost:3001
# S3 Credentials et le nom du bucket
S3_ACCESS_KEY_ID=...
S3_SECRET_ACCESS_KEY=...
S3_BUCKET=...
S3_REGION=...
S3_ENDPOINT=...
# L'URL de votre instance LLM-Structurizer
LLM_STRUCTURIZER_URL=http://localhost:3000
# Les clés d'API
X_API_KEY=...
OPENAI_API_KEY=sk-...
npx prisma db push
Note
La base de données doit être initialisée et accessible par le serveur.
npm run dev
L'application est accessible sur ce lien.
La branche main
est protégée et les pull requests doivent passer l'action ci
pour être mergées.

La CI est gérée avec une Github Action qui sépare le processus en trois étapes.
D'abord, elle effectue une installation des dépendances et une mise en cache pour les prochains runs. Ensuite, elle lance le linting, puis finalement elle vérifie, le build. Les erreurs de négligence détectées lors du linting empêcheront le lancement du build, ce dernier étant relativement long.
Ce workflow s'inspire fortement de l'excellent article de Maxime Heckel sur le sujet.
Note
Docker est nécessaire pour cette étape.
L'environnement de production se lance à l'aide de docker compose, dont un template est disponible dans le fichier docker-compose.example.yml. Il ne dépend pas de l'installation précédente.
Comme pour le fichier .env
, il faut créer un fichier docker-compose.yml
à partir du template et y mettre les bonnes variables.
Le docker-compose fourni part du principe que vous lancez l'instance de LLM-Structurizer
avec son propre docker-compose et connecte structurizer-app
au network llm-structurizer_network
pour faire les appels à l'API. La variable LLM_STRUCTURIZER_URL
peut être ajustée pour répondre aux besoins de votre configuration.
cd structurizer
docker compose build
L'image de l'application se trouve dans le fichier Dockerfile, basée sur Debian 10.
docker compose up
Il est préférable que la base de données soit initialisée avant de lancer le container du serveur. Dans ce cas, vous pouvez lancer les commandes suivantes:
# Lancement de la base de données [en background s'il le faut]
docker compose up db [-d]
# Lancement de l'application
docker compose up app [-d]
Le serveur de l'application web est initialisé, si ce dernier ne tourne pas en fond, ouvrez une nouvelle instance de votre terminal et lancez la commande suivante:
docker exec -it structurizer-app npx prisma migrate deploy
La base de données reste accessible localement avec les valeurs présentes dans DATABASE_URL
sauf celle du port qui forwardée sur 5433
pour éviter tout conflit avec la base de données de LLM-Structurizer
.
L'application est maintenant disponible sur le même lien que précédemment.
docker compose down
Le Dockerfile avec ses variables d'environnement suffit pour avoir une API fonctionnelle. L'image n'est actuellement pas dans un container registry.
Lors du premier déploiement, il faut s'assurer que la base de données associée ait bien reçu les migrations avec npx prisma migrate deploy
. La commande peut se lancer depuis un container actif du serveur de l'application. Il est également possible de lancer la commande localement depuis la racine du projet, après avoir modifié la variable d'environnement DATABASE_URL
avec la connection string de la base de données de production.
Le déploiement du projet a été testé sur App Platform de Digital Ocean.
Ce projet s'inspire fortement de l'ingéniosité des travaux suivants :
- nextjs-postgres-auth-starter : Ce repository a permis une mise en place rapide de Next.js 13 avec un template pour NextAuth.js et Prisma.
- shadcn/taxonomy : Cet excellent projet met en avant les nouvelles fonctionnalités de Next.js 13 version App Router et de la librairie de composants React shadcn/ui.
- Build UI recipes : Il s'agit d'une collection de code snippets par Sam Selikoff pour des interfaces utilisateurs modernes et intuitives. Structurizer contient notamment du code inspiré du Multistep Wizard et de l'Artificial Delay.
- Animated Gradient Border CSS : Un code snippet par Shantanu Jana modifié pour le glowing effect présent un peu partout dans l'application.