Comment mettre en place un système de recherche de documents de conformité pour les entreprises de fintech
Résumé
- Mettez en place un système RAG entièrement localisé pour les recherches de conformité, afin que les documents réglementaires ne quittent jamais votre infrastructure.
- Importez des documents de conformité accompagnés de métadonnées la juridiction, le type de document, la date d'entrée en vigueur et l'organisme de réglementation.
- Mettre en place une recherche tenant compte de la juridiction, afin que les utilisateurs ne puissent consulter que les documents autorisés dans le cadre de leur champ d'application réglementaire.
- Utilisez un LLM local pour générer des réponses référencées à partir des documents récupérés, sans recourir à des appels d'API externes.
- Enregistrer requête chaque requête à des fins d'audit et mettre à jour les documents de manière incrémentielle lorsque la réglementation évolue.
Les entreprises de la fintech exerçant des activités en Europe ne peuvent pas, par défaut, s’appuyer sur des systèmes RAG (Retrieval-Augmented Generation) hébergés dans le cloud pour effectuer des recherches dans les documents de conformité. L’article 44 du RGPD restreint le transfert de données réglementaires en dehors de l’Espace économique européen (EEE) en l’absence de garanties adéquates. Lorsqu’une nouvelle directive relative aux marchés des crypto-actifs (MiCA) ou une mise à jour du Bureau de protection financière des consommateurs (CFPB), l’équipe chargée de la conformité doit examiner des dizaines de milliers de pages de textes réglementaires, de politiques internes et de rapports d’audit afin de déterminer si les procédures existantes en matière de lutte contre le blanchiment d’argent restent conformes. La recherche par mot-clé est trop littérale pour cette tâche. Le RAG dans le cloud résoudrait techniquement le problème de recherche, mais les lois sur la souveraineté des données imposent une contrainte juridique quant au lieu où ce système peut être exploité.
Dans cet article, vous allez mettre en place un système RAG entièrement localisé destiné à la recherche en matière de conformité. Vous l'exploiterez intégralement au sein d'une infrastructure privée, traiterez des documents réglementaires, répondrez à des requêtes en langage naturel en fournissant des références, et enregistrerez chaque requête audit.
Pourquoi le cloud a ses limites
Les contraintes réglementaires empêchent les données de sortir du périmètre de l'organisation. Les API hébergées dans le cloud ne sont pas adaptées aux déploiements concrets dans le domaine de la fintech. Vous êtes confronté à trois obstacles juridiques majeurs qui font de l'infrastructure locale une exigence architecturale incontournable.
1. Souveraineté des données et transferts transfrontaliers
Article 44 du RGPD interdit le transfert de données à caractère personnel en dehors de l'EEE sans garanties spécifiques. Si des documents de conformité contiennent des données clients ou des dossiers de salariés, leur envoi vers un index de vecteurs cloud basé aux États-Unis entraîne un risque juridique immédiat. La directive PSD2 (directive révisée sur les services de paiement) et la directive MiCA imposent des exigences strictes en matière de traitement pour les dossiers relatifs aux paiements et aux crypto-actifs. Une sur site garantit que vos données ne franchissent jamais ces frontières géographiques et juridiques strictes.
2. Exigences en matière de traçabilité et de contrôle
Autorité de conduite financière (FCA) et le Financial Crimes Enforcement Network (FinCEN) exigent que les décisions prises à partir des données relatives à la lutte contre le blanchiment d’argent restent sous le contrôle direct de l’entité réglementée. Un index tiers ne satisfait pas à l’exigence de « contrôle direct ». Si une autorité de régulation demande à examiner la logique sous-jacente à une décision de conformité, vous devez prouver l’intégrité de la source de données. Vous ne pouvez pas garantir cette intégrité lorsque vos vecteurs d’encodage résident dans l’environnement cloud d’un fournisseur, où vous n’avez aucune visibilité sur l’infrastructure sous-jacente ni sur les politiques de conservation des données.
3. L'intégration en tant qu'étape de traitement réglementée
L'intégration d'un document dans le cadre du RAG constitue une étape de traitement qui nécessite une base juridique en vertu de réglementations telles que le RGPD et le CCPA. Les documents de conformité contiennent souvent des données à caractère personnel sensibles. Lorsque vous Embarquer dans un service tiers, vous effectuez un transfert de données et devez évaluer le prestataire en tant que sous-traitant au regard des réglementations applicables.
L'exécution locale du pipeline d'intégration réduit l'exposition aux transferts transfrontaliers et simplifie les évaluations des risques liés aux sous-traitants. Les données restent au sein de l'infrastructure contrôlée.

Flux de données sur site : cloud ou sur site ?
Implications architecturales
Grâce à cette conception conforme, tout reste au niveau local :
- Les documents restent au sein de votre réseau.
- Les intégrations s'exécutent localement.
- L'index vectoriel reste local.
- Les requêtes s'exécutent localement.
- Le LLM génère des réponses en local.
- Le journal d'audit enregistre localement chaque action.
Toute architecture qui transmet des données vers l'extérieur enfreint au moins une contrainte réglementaire.
Ce que vous construisez
Vous développez un système de recherche de conformité à trois niveaux qui fonctionne entièrement au sein de votre infrastructure et fournit des réponses vérifiables et référencées.
Couche 1 : Le pipeline d'ingestion
Extraire du texte à partir de documents réglementaires au format PDF et de politiques internes, découper le contenu en segments de 512 tokens, puis générer des représentations vectorielles à l'aide de all-MiniLM-L6-v2. Leschéma métadonnées est l'élément le plus crucial de cette couche. Vous importez :
- Documents réglementaires (RGPD, MiCA, CFPB, MAS, etc.).
- Politiques internes.
- Procédures de lutte contre le blanchiment d'argent et de vérification de l'identité des clients (KYC).
- Rapports d'audit.
Le pipeline :
- Extraire du texte à partir de fichiers PDF.
- Diviser les documents en segments (512 tokens, 50 de chevauchement).
- Générer des représentations.
- Enregistrer dans la base de données Actian VectorAI avec métadonnées.
métadonnées devrait se présenter comme suit :
- doc_type: réglementation | politique | audit
- compétence: UE | États-Unis | Royaume-Uni | APAC
- date_d'entrée_en_vigueur: date ISO
- organisme_de_réglementation: par exemple, le RGPD, la FCA, la MAS
Couche 2 : requête filtrée par juridiction
Le système effectue une recherche hybride. Lorsqu’un responsable de la conformité pose une question, le backend applique un métadonnées en fonction de la région de ce dernier. Cela empêche les recommandations du MAS d’apparaître dans les résultats d’une requête liée au RGPD. Le LLM local génère une réponse qui doit inclure des références (nom du document, section et date).
Un responsable de la conformité pose la question suivante :
« Quelles sont les exigences en matière de transfert de données prévues à l'article 44 du RGPD ? »
Le système :
- Intègre la requête .
- Lance une recherche hybride ( métadonnées vectoriel + métadonnées ).
- Filtrage par juridiction et par type de document.
- Récupère les segments pertinents.
- Envoie les segments à un LLM local.
- Renvoie une réponse citée (nom du document, section, date).
Vous appliquez un filtrage car la pertinence dépend de la juridiction.
Niveau 3 : Le niveau d'audit obligatoire
Chaque requête un enregistrement d'audit local enregistrement utilisateur , les segments récupérés et un hachage de la réponse générée. Cet enregistrement aux auditeurs de vérifier facilement que les réponses s'appuient bien sur les données citées et que l'accès à l'information reste contrôlé.

Périmètre du réseau de l'organisation
Configuration matérielle de référence
Vous pouvez utiliser ce système sur :
- Au moins 8 Go de RAM (16 Go ou plus recommandés).
- 10 Go d'espace disque (100 Go ou plus recommandés).
Conditions préalables
Pour suivre ce tutoriel, installez les outils suivants :
- Docker et Docker Compose.
- Python .10 ou version ultérieure.
- PIP ou UV: Ce guide utilise UV pour des raisons de rapidité et de fiabilité.
Mise en place du projet
Avant de mettre en place votre système de recherche de conformité, configurez votre environnement local de manière à ce que l'ensemble du traitement reste à l'intérieur des limites de votre réseau. Cette configuration utilise uv, un installateur rapide Python , afin de garantir la reproductibilité et l'isolation de l'environnement.
Téléchargez le package client Actian VectorAI. Cela crée un fichier fichier actian_vectorai-0.1.0b2-py3-none-any.whl .
- Initialisez votre espace de travail
Créez un répertoire dédié à votre projet de conformité fintech.
mkdir compliance-rag && cd compliance-rag
uv init .
- Activer l'environnement virtuel
Dans un nouveau terminal, créez et activez un environnement virtuel :
uv venv
- Installer les dépendances
Ajoutez les bibliothèques nécessaires aux opérations vectorielles, à l'extraction de texte et aux représentations locales.
# Install the Actian VectorAI Python client (ensure the .whl file is in your directory)
uv pip install actian_vectorai-0.1.0b2-py3-none-any.whl
# Add sentence-transformers, PDF processing tools
uv add sentence-transformers
Mise en place d'un système de recherche de documents relatifs à la conformité
Dans cette section, vous allez mettre en place un système sur site entièrement sur site capable de traiter des documents réglementaires, d’assurer une recherche tenant compte de la juridiction applicable, de répondre aux requêtes de conformité en fournissant des références, et d’enregistrer chaque interaction à des fins d’audit.
Étape 1 : Déployer une base de données vectorielle
Déployer une instance locale de Actian VectorAI DB avec un stockage persistant pour les données vectorielles et les journaux d'audit.
Créez un fichier fichier docker-compose.yaml :
services:
vectorai:
image: actian/vectorai:latest
platform: linux/amd64
container_name: vectorai_db
ports:
- "50051:50051"
volumes:
# vector data persists across restarts
- ./data:/app/data
# audit log lives on host -- not inside the container
- ./audit_logs:/app/audit_logs
environment:
- VECTORAI_LOG_LEVEL=info
restart: unless-stopped
Lancez le service :
docker-compose up -d
Résultat attendu :

Sortie lors du démarrage du conteneur
La base de données démarre et expose le port 50051 pour l'accès local. Les données vectorielles sont stockées dans ./data. Les journaux d'audit sont enregistrés directement dans ./audit_logs sur l'hôte, ce qui permet de conserver tous les enregistrements d'accès à l'intérieur des limites de votre réseau.
Remarque :
- VectorAI DB est actuellement en cours de développement. Veuillez vérifier les paramètres dans la documentation officielle avant toute utilisation en production.
- Conservez les journaux d'audit en dehors du conteneur afin de préserver les preuves de conformité.
Vérifier le déploiement:
docker-compose logs

Sortie du terminal indiquant que le conteneur a démarré correctement et son état de fonctionnement
Étape 2 : Mettre en place le pipeline d'ingestion
Lancez le pipeline d'ingestion pour convertir les documents réglementaires et les politiques internes en représentations vectorielles, puis stockez-les dans votre base de données vectorielle locale.
Créer ingest.py et saisissez le contenu suivant :
import hashlib
import json
from sentence_transformers import SentenceTransformer
from actian_vectorai import VectorAIClient, VectorParams, Distance, PointStruct, FilterBuilder, Field
# ── Config ────────────────────────────────────────────────────────────────────
BASE_ADDRESS = "localhost:50051"
COLLECTION = "compliance_docs"
EMBED_MODEL = "sentence-transformers/all-MiniLM-L6-v2"
VECTOR_DIM = 384
CHUNK_TOKENS = 512
OVERLAP_TOKENS = 50
# ── Sample Regulatory Corpus ───────────────────────────────────────────────────
REG_DOCS = [
{
"document_id": "MAS_637_2025",
"jurisdiction": "SG",
"doc_type": "regulation",
"section": "Section 2.1: Capital Adequacy Ratios",
"date": "2025-01-15",
"text": "MAS Notice 637 on Risk Based Capital Adequacy Requirements for Banks..."
},
{
"document_id": "GDPR_ART_44",
"jurisdiction": "EU",
"doc_type": "regulation",
"section": "Chapter 5: Transfers of Personal Data",
"date": "2018-05-25",
"text": "Any transfer of personal data to a third country shall take place only if..."
}
]
# ── Processing Logic ───────────────────────────────────────────────────────────
def chunk_text(text, size=CHUNK_TOKENS, overlap=OVERLAP_TOKENS):
tokens = text.split()
chunks, start = [], 0
while start < len(tokens):
end = min(start + size, len(tokens))
chunks.append(" ".join(tokens[start:end]))
if end == len(tokens):
break
start += size - overlap
return chunks
model = SentenceTransformer(EMBED_MODEL)
def ingest(docs):
with VectorAIClient(BASE_ADDRESS) as client:
# Create collection if it doesn't exist
try:
client.collections.create(
COLLECTION,
vectors_config=VectorParams(size=VECTOR_DIM, distance=Distance.Cosine),
)
except Exception as e:
if "already exists" not in str(e).lower():
raise
points = []
for doc in docs:
chunks = chunk_text(doc["text"])
vectors = model.encode(chunks).tolist()
for i, chunk in enumerate(chunks):
point_id = int(
hashlib.sha256(f"{doc['document_id']}:{i}".encode()).hexdigest()[:15],
16,
)
points.append(PointStruct(
id=point_id,
vector=vectors[i],
payload={
"document_id": doc["document_id"],
"jurisdiction": doc["jurisdiction"],
"doc_type": doc["doc_type"],
"section": doc.get("section", ""),
"date": doc.get("date", ""),
"text": chunk,
}
))
client.points.upsert(COLLECTION, points)
print(f"✓ Ingested {len(points)} chunks from {len(docs)} documents")
if __name__ == "__main__":
ingest(REG_DOCS)
Ce script effectue les actions suivantes :
- Segmentation des textes : Le système divise les documents réglementaires en segments de 512 tokens avec un chevauchement de 50 tokens afin de préserver le contexte juridique d'un segment à l'autre.
- Intègre les segments : Le modèle convertit les segments en vecteurs numériques à l'aide d'un modèle local, garantissant ainsi que vos données ne quittent jamais votre infrastructure.
- Stocke les métadonnées: Chaque vecteur est stocké avec sa juridiction et type de document. Ces champs sont obligatoires pour garantir le respect de votre périmètre réglementaire lors des recherches.
Exécution de l'ingestion :
uv run ingest.py
Résultat attendu :

Journaux d'ingestion indiquant le nombre de blocs indexés
Étape 3 : Exécutez vos requêtes
Exécutez des requêtes sur votre système RAG local et vérifiez le fonctionnement de la récupération des données, du filtrage en fonction de la juridiction et de la journalisation d'audit.
Créer un fichier requête.py contenant le contenu suivant:
import json
import datetime
import hashlib
import requests # type: ignore
from pathlib import Path
from sentence_transformers import SentenceTransformer # type: ignore
from actian_vectorai import VectorAIClient, Field, FilterBuilder
# ── Config ────────────────────────────────────────────────────────────────────
BASE_ADDRESS = "localhost:50051"
COLLECTION = "compliance_docs"
AUDIT_LOG = Path("./audit_logs/compliance_queries.jsonl")
# ── Jurisdiction Permissions ──────────────────────────────────────────────────
OFFICER_PERMISSIONS = {
"sg_compliance_officer": ["SG"],
"eu_data_privacy_lead": ["EU"],
"global_auditor": ["SG", "EU", "UK", "US"]
}
model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
def write_audit(record):
AUDIT_LOG.parent.mkdir(parents=True, exist_ok=True)
with open(AUDIT_LOG, "a") as f:
f.write(json.dumps(record) + "\n")
def run_compliance_query(user_id, role, query_text):
timestamp = datetime.datetime.now().isoformat()
allowed_jurisdictions = OFFICER_PERMISSIONS.get(role, [])
if not allowed_jurisdictions:
write_audit({
"timestamp": timestamp,
"user_id": user_id,
"role": role,
"query": query_text,
"docs": [],
"access": "DENIED"
})
return "Access Denied."
# Embed query
q_vec = model.encode([query_text])[0].tolist()
# Build filter for jurisdiction access control (database-level enforcement)
# Using Filter DSL: for single jurisdiction use must(), for multiple use should() with OR semantics
if len(allowed_jurisdictions) == 1:
# Single jurisdiction: use must() for strict enforcement
jurisdiction_filter = FilterBuilder().must(
Field("jurisdiction").eq(allowed_jurisdictions[0])
).build()
else:
# Multiple jurisdictions: OR them together using should()
filter_builder = FilterBuilder()
for jurisdiction in allowed_jurisdictions:
filter_builder = filter_builder.should(Field("jurisdiction").eq(jurisdiction))
jurisdiction_filter = filter_builder.build()
with VectorAIClient(BASE_ADDRESS) as client:
# Search with database-level jurisdiction filter
# The filter is applied at the database level, not after retrieval
search_results = client.points.search(
COLLECTION,
vector=q_vec,
limit=3, # Get top 3 results
filter=jurisdiction_filter # Database enforces access control here
)
# Convert results to our expected format
results = [
{
"id": result.id,
"score": result.score,
"metadata": result.payload
}
for result in search_results
]
doc_refs = [
{
"doc_id": r["metadata"].get("document_id"),
"jurisdiction": r["metadata"].get("jurisdiction")
}
for r in results
]
# Audit ONLY filtered (authorized) results
write_audit({
"timestamp": timestamp,
"user_id": user_id,
"role": role,
"query": query_text,
"jurisdictions_accessed": allowed_jurisdictions,
"docs": doc_refs,
"access": "ALLOWED"
})
return results
if __name__ == "__main__":
print("\n--- Query 1: Authorized SG Officer ---")
res = run_compliance_query(
"officer_tan",
"sg_compliance_officer",
"What are capital adequacy rules?"
)
for r in res:
print(f"Found: {r['metadata']['document_id']} ({r['metadata']['jurisdiction']})")
print("\n--- Query 2: EU trying SG data ---")
res2 = run_compliance_query(
"officer_schmidt",
"eu_data_privacy_lead",
"MAS Notice 637"
)
print(f"Results returned: {len(res2)}")
Le script effectue trois opérations principales:
- Assure le contrôle de la juridiction : Le système vérifie votre rôle avant toute récupération. Le contrôle de la juridiction est appliqué au niveau de la base de données en injectant un filtre dans la requête de recherche vectorielle. La base de données ne renvoie que les documents relevant du champ d'application réglementaire autorisé.
- Récupère les données filtrées : La recherche de similarité vectorielle est limitée à votre périmètre réglementaire spécifique.
- Enregistre le journal d'audit obligatoire : Chaque requête est enregistré localement afin de répondre à vos exigences de conformité.
Exécuter :
uv run query.py
Résultat attendu:

requête affichant les segments récupérés avec leurs scores et métadonnées
Étape 4 : Générer des réponses à l'aide d'un LLM local
Les réponses sont générées en utilisant uniquement les documents récupérés.
Lancer Ollama :
ollama run mistral:7b
Ajoutez la logique de génération à votre fichier requête.py:
import requests
OLLAMA_URL = "http://127.0.0.1:11434/api/generate"
OLLAMA_MODEL = "mistral:7b"
def build_context(results):
"""Build context string from retrieved documents for LLM prompt."""
blocks = []
for idx, result in enumerate(results, start=1):
md = result["metadata"]
doc_id = md.get("document_id", "unknown")
section = md.get("section") or "(section not specified)"
date = md.get("date") or "(date not specified)"
text = md.get("text", "")
blocks.append(
f"Document {idx}: {doc_id}\n"
f"Section: {section}\n"
f"Date: {date}\n"
f"Text: {text}"
)
return "\n---\n".join(blocks)
def generate_answer(results, query_text):
"""
Generate an answer using Ollama's mistral:7b model.
Note: First generation may take 2-3 minutes as the model loads into memory.
Subsequent calls are faster once the model is warm.
"""
if not results:
return "No documents retrieved to generate answer from."
context = build_context(results)
prompt = f"""
Answer using only the context below.
Include document name, section, and date.
Context:
{context}
Question:
{query_text}
"""
try:
# Increase timeout to 600s (10 minutes) for mistral:7b generation
# First run may take 2-3 minutes as the model loads
response = requests.post(
OLLAMA_URL,
json={
"model": OLLAMA_MODEL,
"prompt": prompt,
"stream": False, # Ensure non-streaming response
},
timeout=600, # 10 minutes to account for model warmup
)
response.raise_for_status()
payload = response.json()
# Ollama /api/generate endpoint returns 'response' field
answer = payload.get("response", "")
if not answer:
return f"⚠️ Ollama returned empty response. Payload: {payload}\n\nContext for manual review:\n{context}"
return answer
except requests.exceptions.Timeout as e:
return f"⚠️ Ollama generation timed out after 10 minutes.\n\nMistral:7b can take 2-3 minutes on first run. Try again--it will be faster next time.\n\nContext for manual review:\n{context}"
except requests.exceptions.ConnectionError as e:
return f"⚠️ Ollama server not running on {OLLAMA_URL}\n\nTo start Ollama:\n docker compose up -d ollama\n docker exec ollama_inference ollama pull mistral:7b\n\nContext for manual review:\n{context}"
except Exception as e:
return f"Error calling Ollama: {e}\n\nContext sent:\n{context}"
if res:
print("\n--- Generated answer for SG officer ---")
print(generate_answer(res, "What are capital adequacy rules?"))
Cette étape permet de garantir :
- Aucun appel d'API externe.
- Des réponses fondées sur vos documents.
- Références incluses à des fins de vérifiabilité.
Relancer :
<>uv run query.py
Résultat attendu:

Journaux des réponses générés par Ollama
Remarque : l'exécution locale de mistral:7b sans accélération par GPU prend 2 à 3 minutes pour la première inférence, mais les requêtes suivantes avantage la mise en cache du modèle.
Étape 5 : Configurer le journal d'audit
Enregistrez chaque requête en utilisant le mappage de volume défini lors déploiement.
La configuration Docker monte ./audit_logs depuis votre hôte dans le conteneur. Chaque interaction avec le système crée une entrée dans le fichier compliance_queries.jsonl.
Exemple d'entrée de journal :
{"timestamp": "2026-04-16T20:08:11.929639", "user_id": "officer_tan", "role": "sg_compliance_officer", "query": "What are capital adequacy rules?", "jurisdictions_accessed": ["SG"], "docs": [{"doc_id": "MAS_637_2025", "jurisdiction": "SG"}], "access": "ALLOWED"}
{"timestamp": "2026-04-16T20:08:13.397832", "user_id": "officer_schmidt", "role": "eu_data_privacy_lead", "query": "MAS Notice 637", "jurisdictions_accessed": ["EU"], "docs": [{"doc_id": "GDPR_ART_44", "jurisdiction": "EU"}], "access": "ALLOWED"}
Chaque entrée contient :
- Qui a formulé la demande ?
- Ce qu'ils ont demandé.
- Quels documents ont été consultés ?
Ce fichier relève entièrement de votre infrastructure et répond aux exigences d'audit.
Gestion des mises à jour réglementaires
Mettez à jour les documents réglementaires de manière incrémentielle sans avoir à reconstruire l'index. Lorsqu'une autorité de régulation publie une nouvelle version, vous ne remplacez que les vecteurs de documents concernés. Cela permet de préserver l'intégrité de l'audit et de maintenir votre système à jour.
Lorsqu'un document d'orientation est modifié, supprimez tous les vecteurs liés au document_id, puis insérez les segments mis à jour avec la nouvelle date d'entrée en vigueur.
Mettez à jour votre pipeline d'ingestion
Ajoutez cette fonction à ingest.py:
def update_regulatory_document(document_id, updated_doc):
"""
Update a regulatory document by deleting old vectors and inserting new ones.
This maintains 'Effective Date' integrity by replacing the entire document's chunks.
"""
with VectorAIClient(BASE_ADDRESS) as client:
# Delete existing vectors for the old document
delete_filter = FilterBuilder().must(Field("document_id").eq(document_id)).build()
client.points.delete(COLLECTION, filter=delete_filter)
print(f"✓ Deleted old vectors for document {document_id}")
# Ingest the updated document
chunks = chunk_text(updated_doc["text"])
vectors = model.encode(chunks).tolist()
points = []
for i, chunk in enumerate(chunks):
point_id = int(
hashlib.sha256(f"{updated_doc['document_id']}:{i}".encode()).hexdigest()[:15],
16,
)
points.append(PointStruct(
id=point_id,
vector=vectors[i],
payload={
"document_id": updated_doc["document_id"],
"jurisdiction": updated_doc["jurisdiction"],
"doc_type": updated_doc["doc_type"],
"section": updated_doc.get("section", ""),
"date": updated_doc.get("date", ""),
"text": chunk,
}
))
client.points.upsert(COLLECTION, points)
print(f"✓ Updated document {document_id} with {len(points)} chunks (new effective date: {updated_doc.get('date', 'N/A')})")
Exemple d'utilisation
# Update MAS_637_2025 with new content and date
updated_mas_doc = {
"document_id": "MAS_637_2025",
"jurisdiction": "SG",
"doc_type": "regulation",
"section": "Section 2.1: Capital Adequacy Ratios (Updated)",
"date": "2026-04-16", # New effective date
"text": "Updated MAS Notice 637 text here..."
}
update_regulatory_document("MAS_637_2025", updated_mas_doc)
Lancer la mise à jour
uv run ingest.py
Résultat attendu :
Journaux d'ingestion et de mise à jour
Ceci :
- Importer les documents initiaux
- Mise à jour MAS_637_2025 avec un nouveau contenu et une nouvelle date (16/04/2026)
Vérifier la mise à jour
uv run query.py
Résultat attendu :

requête avec le document mis à jour
Le système :
- Renvoie le document mis à jour (16/04/2026) pour les requêtes SG.
- Affiche la nouvelle section dans les résultats obtenus.
- Génère des réponses fondées sur le contenu mis à jour.
Pour conclure
Les contraintes réglementaires interdisent l'envoi de données de conformité vers des systèmes RAG hébergés dans le cloud. Vous avez résolu ce problème en mettant en place un pipeline entièrement local, dans lequel l'ingestion, la récupération, la génération et la journalisation d'audit restent au sein de votre infrastructure.
Vous disposez désormais :
- Un corpus de conformité consultable.
- Filtrage tenant compte de la juridiction.
- Le LLM local répond en fournissant des références.
- Une piste d'audit complète pour chaque requête.
Appliquez cette architecture à d'autres charges de travail réglementées, telles que l'analyse de la fraude ou les systèmes de gestion des risques internes. Consultez la documentation de VectorAI DB et dépôt GitHub pour obtenir les mises à jour et les détails de mise en œuvre.
Rejoignez la communauté et découvrez-en davantage sur Actian.