← All projects

Ask the EU Digital Services Act

A portfolio project by Malav Naik: semantic search over the EU Digital Services Act (Regulation (EU) 2022/2065), with keyword, semantic and hybrid search compared on 25 hand-written test questions.

  • Python
  • BeautifulSoup
  • sentence-transformers
  • BM25
  • transformers.js
  • Kaggle
  • Hugging Face
  • GitHub Actions

See it live → · Code on GitHub →

Not legal advice. This demo only quotes the law and links to it; it never writes answers of its own.

The problem

The EU’s Digital Services Act (DSA) sets the rules for how online platforms handle illegal content, appeals, ads and transparency. It is 93 articles and 156 recitals long. People who work in trust & safety need to find the right article fast, but they ask in everyday words (“can a platform take down my post without telling me why?”), while the law uses its own terms (“statement of reasons”).

What I built

A search tool that takes a plain-English question and returns the three articles most likely to answer it, each with the matching paragraph quoted and a link to the official text.

I deliberately made it quote the law only: no AI-written answer. A generated answer can sound confident and still be wrong about the law, while a quoted paragraph can always be checked. This also means it runs free in the visitor’s browser.

How it works

Flow: the official DSA text from EUR-Lex is split into 638 paragraph chunks and published as a Hugging Face dataset; each chunk is turned into a vector by a small embedding model; in the browser the question is turned into a vector with the same model and the closest articles are shown with quotes and links; three search methods are compared on 25 test questions in a Kaggle notebook Official DSA text(EUR-Lex) 638 paragraph chunks(Hugging Face dataset) Vectors from a smallembedding model Kaggle: 3 searchmethods, 25 questions Browser demo: top 3articles, quoted
  1. Get the official text. The English DSA from EUR-Lex, the EU’s official law website.
  2. Split it into chunks, one per paragraph of each article (long lists, like the definitions in Article 3, are split into their points), plus the recitals. Each chunk keeps its article number, title, chapter and link: 638 chunks in total, published as an open dataset.
  3. Write a test set first: 25 questions in everyday language, each with the article(s) that answer it, checked against the text.
  4. Compare three ways of searching: classic keyword search (BM25), semantic search with the small open model all-MiniLM-L6-v2 (it matches meaning, not exact words), and a hybrid of the two.
  5. Ship the winner in a demo that runs entirely in your browser, using a compressed copy of the same model (about 23 MB).

Demo

Ask a question and see the top 3 articles. Nothing you type is sent anywhere.

· open it on Hugging Face

Results

How often the right article was found, on the 25 test questions (searching the 482 article chunks). Keyword = BM25:

  Keyword Semantic Hybrid
Ranked first 48% 52% 56%
In top 3 68% 84% 80%
In top 5 72% 92% 84%
MRR* 0.599 0.675 0.701

*Mean reciprocal rank: 1 means the right article always came first.

  • Why semantic search in the demo: the demo shows three articles, and semantic search put the right one in the top 3 most often (84%). The hybrid was slightly better at ranking it first.
  • The browser version is weaker: the compressed model in the demo finds the right article in the top 3 for 72% of the questions (56% first, 92% in the top 5). That’s the honest price of a free, private demo, and the reason it always shows three results with links.
  • Where it fails: everyday words that the law expresses differently. “Does a platform have to explain why it removed my post?” should find Article 17, which the law calls a statement of reasons and which never uses the word “explain”. The hybrid search ranked three other articles above it.

Source of the law: EUR-Lex, © European Union. Only the Official Journal text is authentic.