Skip to content

Marcrulo/DomstolAI_public

Repository files navigation

DomstolAI_public 🏛️

Blog posts:

  1. Local model
  2. Cloud deployment

Disclaimer ⚠️

This repository is a public, sanitized version intended for demonstration. The underlying data from Domstolsdatabasen is confidential and must be handled according to their terms.

Model Pipeline Overview 🧭

Workflow Cloud

This repo implements a three-stage pipeline: data extraction, vector index creation, and retrieval inference.

1) Extract data (API -> text + metadata)

  • Authenticates against Domstolsdatabasen and fetches paginated case data.
  • Saves raw HTML and plain-text files to local folders.
  • Builds a metadata table and uploads artifacts to the Azure ML datastore.

Implementation: 1_extract_process_data.py

Key outputs:

  • texts/ and texts_html/ (document contents)
  • meta.parquet (case metadata)

2) Build vector index (text -> embeddings -> FAISS)

  • Downloads meta.parquet + text artifacts from the Azure ML datastore.
  • Parses HTML blocks and splits into paragraph-level chunks.
  • Embeds each chunk with KennethTM/MiniLM-L6-danish-encoder and adds to FAISS.
  • Saves the index and chunk table, then uploads them back to the datastore.

Implementations:

Key outputs:

  • trials_chunked.faiss (FAISS index)
  • trials_chunked.parquet (chunk text + document ids)

3) Inference (query -> embedding -> top-k matches)

  • Azure ML scoring script downloads meta.parquet, trials_chunked.parquet, and trials_chunked.faiss at init.
  • The query is embedded and searched against FAISS.
  • Results are joined with metadata and returned as JSON.

Implementation: src/score.py

Deployment Overview 🚀

The project is deployed as an Azure ML online endpoint:

The deployment points to the scoring script and expects key-based auth. The scoring script uses DefaultAzureCredential to access the workspace datastore and download the model artifacts during initialization.

Results / Example ✅

Code:

import requests
import json

endpoint = "<ENDPOINT-URL>" 
api_key  = "<API-KEY>"  

headers = {
	"Content-Type": "application/json",
	"Authorization": f"Bearer {api_key}"
}

data = {
	"prompt": "Tiltalt for at besidde våben og stoffer"
}

response = requests.post(endpoint, headers=headers, json=data)
print(response.json())

Output:

'HEADLINE'     : 'Tiltale for overtrædelse af bl.a. straffelovens § 191, stk. 1, 2. pkt., jf. til dels stk. 2, jf. lov om euforiserende stoffer § 3, stk.1, jf. § 2, stk. 4, jf. bekendtgørelse om euforiserende stoffer § 30 (dagældende § 27), jf. § 3, jf. bilag 1, liste B, nr. 70 samt straffelovens § 192a, stk. 1, nr. 1, jfr. stk. 3, jfr. våbenlovens § 10, stk. 1, jfr. § 1, stk. 1, nr. 1, 2 og 3. Påstand om konfiskation'

'CASE_SUBJECTS': 'Narkotika. Våben, eksplosiver og fyrværkeri. Formueforbrydelser. Forbrydelser mod offentlig myndighed'

'CHUNK_TEXT'   : 'Lange fængselsstraffe for salg af kokain og besiddelse af skydevåben'

'DISTANCE'     : '0.79919827'

About

End-to-end RAG pipeline for Danish court data

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors