Module 8 — Intégration avec des applications existantes
Le cabinet dispose maintenant d'un moteur d'inférence local fiable, calibré et accéléré. Reste à le rendre utilisable par les collaborateurs qui ne veulent pas ouvrir un terminal. Ce module montre trois voies d'intégration — script métier autonome, chaîne LangChain (cours 26), interface web Open WebUI — et clôt le sujet en abordant l'exposition réseau et l'authentification, qui sont, sur ce type de déploiement, la première source d'incidents.
Le script métier autonome
C'est le cas le plus fréquent : une petite tâche répétitive à automatiser. Pour le cabinet, la première a été un script qui reçoit chaque matin un dossier de PDF de courriers entrants, extrait une synthèse en trois lignes et une catégorie parmi une dizaine, et envoie le tout dans un tableur partagé.
from pathlib import Path
from ollama import Client
from pypdf import PdfReader
import json
client = Client(host="http://serveur-interne:11434")
CATEGORIES = ["baux", "recouvrement", "prud'hommes", "penal", "famille",
"societes", "administratif", "notaire", "autre"]
def resumer_courrier(chemin_pdf: Path) -> dict:
texte = "\n".join(p.extract_text() or "" for p in PdfReader(chemin_pdf).pages)
reponse = client.chat(
model="cabinet-fr",
messages=[
{"role": "system",
"content": "Reponds uniquement par du JSON valide : "
"{\"synthese\": \"...\", \"categorie\": \"...\"}. "
f"La categorie appartient a : {', '.join(CATEGORIES)}."},
{"role": "user", "content": texte[:8000]},
],
options={"temperature": 0, "num_ctx": 8192, "num_predict": 300},
format="json",
keep_alive="30m",
)
return json.loads(reponse["message"]["content"])
Trois points à souligner. Le modèle utilisé est le cabinet-fr créé au module 5 : sa consigne système est déjà en place, on n'a plus à la retransmettre. Le paramètre format="json" d'Ollama (également disponible dans l'API OpenAI-compatible via response_format) contraint le modèle à produire du JSON valide — précieux pour éviter les sorties partielles ou mal fermées. Et keep_alive="30m" garde le modèle chaud pendant la durée du traitement du lot, évitant de recharger 4,7 Go à chaque courrier.
LangChain, à peu de frais
Le cours 26 sur LangChain a montré comment composer des chaînes de traitement. Ollama y devient un fournisseur parmi d'autres via l'adaptateur langchain-ollama :
from langchain_ollama import ChatOllama
from langchain_core.prompts import ChatPromptTemplate
modele = ChatOllama(
model="cabinet-fr",
base_url="http://serveur-interne:11434",
temperature=0.2,
num_ctx=4096,
keep_alive="15m",
)
gabarit = ChatPromptTemplate.from_messages([
("system", "Tu extrais les references legales citees dans un courrier."),
("user", "{courrier}"),
])
chaine = gabarit | modele
extrait = chaine.invoke({"courrier": texte_courrier})
L'intérêt est double. Premièrement, la chaîne est exactement la même que si l'on parlait à OpenAI ou à Anthropic : changer ChatOllama pour ChatOpenAI en haut du fichier suffit à basculer, sans toucher au reste. Deuxièmement, tous les mécanismes de LangChain — récupérateurs, mémoire, agents, traceur — s'appliquent tels quels au modèle local. C'est cette portabilité qui fait de LangChain un choix pertinent quand le prototype pourrait un jour migrer, ou quand on veut tester A/B deux fournisseurs sur les mêmes questions.
Open WebUI, l'interface web pour non-techniciens
Les collaborateurs qui ne codent pas veulent une interface qui ressemble à celle qu'ils connaissent des chatbots publics. Open WebUI est un projet open source qui offre exactement cela, avec en plus la gestion multi-utilisateurs, l'historique des conversations et le téléversement de documents. Il se déploie en un conteneur Docker :
docker run -d --name open-webui \
-p 3000:8080 \
-e OLLAMA_BASE_URL=http://serveur-interne:11434 \
-v open-webui-data:/app/backend/data \
--restart always \
ghcr.io/open-webui/open-webui:main
Ouvert sur http://serveur-interne:3000, il présente un chat qui parle directement à Ollama, avec le choix du modèle en haut à droite (Ollama expose sa liste de modèles à Open WebUI automatiquement). Le premier compte créé devient administrateur ; il crée ensuite les comptes des collaborateurs et peut réserver certains modèles à certains rôles. Les conversations restent dans le volume Docker, jamais dans le cloud.
Exposition réseau et authentification — le sujet à ne pas escamoter
Nous avons vu au module 1 que définir OLLAMA_HOST=0.0.0.0:11434 rend le service joignable par tout le sous-réseau. C'est nécessaire pour permettre au poste du secrétariat d'interroger le serveur commun. C'est aussi extrêmement risqué par défaut : Ollama ne gère aucune authentification. Toute personne qui atteint le port 11434 peut lister les modèles, envoyer n'importe quelle question, et — via la route /api/create — créer un modèle dérivé. Sur un réseau d'entreprise avec cloisonnement fort, cela peut passer ; sur un réseau ouvert, c'est inacceptable.
La solution standard consiste à placer un proxy inverse (Nginx, Caddy, Traefik) devant Ollama, qui écoute lui sur 127.0.0.1:11434 et n'est joignable qu'à travers le proxy. Le proxy exige une authentification (basique HTTP, en-tête Authorization, mTLS selon le niveau souhaité) et impose le TLS. Voici l'extrait Caddyfile minimal utilisé par le cabinet :
ollama.cabinet.local {
reverse_proxy 127.0.0.1:11434
basicauth {
cabinet JDJhJDE0JC5B... # bcrypt du mot de passe
}
tls internal
}
Les clients — script Python, Open WebUI, LangChain — passent ensuite l'en-tête Authorization: Basic ... et pointent sur https://ollama.cabinet.local. Ollama continue de croire qu'il ne parle qu'à localhost ; le proxy gère l'accès. C'est un pattern éprouvé, léger, et immédiatement compatible avec l'infrastructure existante.
Sans proxy, un OLLAMA_HOST=0.0.0.0 sur un serveur cloud avec un port ouvert transforme votre facture d'électricité en machine à générer du texte pour n'importe qui. Plusieurs milliers d'instances Ollama ouvertes sont recensées publiquement sur Shodan à toute heure. La règle absolue pour tout déploiement au-delà du réseau interne : proxy inverse + authentification + TLS, pas d'exception.
En résumé
- Un script métier autonome utilise
ollama-python,format="json"pour les sorties structurées etkeep_alivepour maintenir le modèle chaud pendant un lot. - LangChain via
ChatOllama(cours 26) rend le modèle local interchangeable avec un fournisseur cloud sans réécrire la chaîne — chaînes, agents et mémoire s'appliquent tels quels. - Open WebUI, en un conteneur Docker, offre une interface de chat multi-utilisateurs branchée sur Ollama, adoptée en dix minutes par les non-techniciens.
- Ollama n'a aucune authentification native ; toute exposition au-delà de
localhostdoit passer par un proxy inverse avec authentification et TLS, sans exception.
Module suivant : brancher un système de questions-réponses local sur les documents internes du cabinet, entièrement hors ligne.