⚠️ Projektin tila: Tämä projekti on kehitysvaiheessa eikä vielä ole tuotantovalmis. Koodi on toiminnallisuusdemoja ja kokeiluja varten. Älä käytä tuotannossa ilman huolellista testausta ja arviointia.
Tämä repositorio sisältää kokonaisvaltaisen järjestelmän suomalaisten lakitekstien (erityisesti Rikoslain) semanttiseen hakuun käyttäen DataStax Astra DB -vektoritietokantaa. Projekti tarjoaa työkalut Finlex-aineiston erotteluun, tekstien vektorisointiin OpenAI-embeddingsien avulla, sekä dokumenttien tallentamiseen ja semanttiseen hakuun Astra DB:ssä.
Repositorio koostuu useista komponenteista:
-
Astra Vector DB -paketti (
workspace/astra_vector_db/) - Tuotantokoodi vektoritietokanta-operaatioille- Vektorikokoelmien luonti ja hallinta
- Dokumenttien tallennus vektoreina
- Semanttinen haku OpenAI-embeddingsien avulla
-
Astra Playground (
workspace/astra-playground/) - Kehitys- ja testausympäristö- Testausskriptit ingest- ja query-operaatioille
- JSONL-tiedostojen käsittely
- Finlex-extract pipeline Rikoslain erotteluun ja indeksointiin
-
Finlex Extract Pipeline (
workspace/astra-playground/finlex_extract/)- Akoma Ntoso XML -aineiston parsinta
- Rikoslain erottelu Finlex-konsolidoidusta aineistosta
- Hierarkkinen chunkkaus (SOTA-pipeline) parent-context retrievallle
- JSONL-muotoinen output valmiina ingestointiin
-
Data ja skriptit (
DATA/)- Rikoslaki-aineisto (Akoma Ntoso XML)
- PowerShell-skriptit pipeline-ajoon
- Audit-raportit ja laatuportit
-
Dokumentaatio (
INSTRUCTIONS/)- Projektin kehityshistoria ja ohjeet
- Pipeline-versioiden dokumentaatio
├── workspace/
│ ├── astra_vector_db/ # Tuotantokoodi (pip-paketti)
│ │ ├── config.py # Konfiguraatio ja ympäristömuuttujat
│ │ ├── database.py # Astra DB -operaatiot
│ │ ├── embedding.py # OpenAI-embeddings
│ │ └── main.py # Esimerkkikäyttö
│ └── astra-playground/ # Kehitysympäristö
│ ├── finlex_extract/ # Finlex-parsinta ja chunkkaus
│ └── *.py # Testaus- ja ingest-skriptit
├── DATA/ # Aineistot ja skriptit
│ └── Rikoslaki-20260109/ # Rikoslaki-aineisto
├── INSTRUCTIONS/ # Projektidokumentaatio
└── assistant-pack/ # Apupaketti (ei projektin osa)
Projektin pääasiallinen käyttötapaus on:
- Erottelu: Finlex-aineistosta erotellaan Rikoslaki Akoma Ntoso XML -muodossa
- Parsinta: XML-aineisto parsitaan strukturoiduiksi yksiköiksi (luku, pykälä, momentti)
- Chunkkaus: Tekstit jaetaan hierarkkisesti chunkkeihin parent-context -informaatiolla
- Vektorisointi: Chunkit vektorisoidaan OpenAI:n
text-embedding-3-small-mallilla - Tallennus: Vektorit tallennetaan Astra DB:hen vektorikokoelmaan
- Haku: Semanttinen haku vektorisimilaarisuudella, parent-context -informaation kanssa
cd workspace/astra_vector_db
pip install -e .Kopioi env.example tiedostoksi .env ja täytä arvot:
cp env.example .envTarvitset:
- Astra DB: API Endpoint ja Application Token (Astra UI:sta)
- OpenAI: API Key (https://platform.openai.com/api-keys)
cd workspace/astra_vector_db
python -m astra_vector_db.main- Astra Vector DB -paketti: Katso
workspace/astra_vector_db/README.md - Astra Playground ja testaus: Katso
workspace/astra-playground/README.md - Finlex Extract Pipeline: Katso
workspace/astra-playground/finlex_extract/README_SOTA.md(SOTA-pipeline)
- Kokoelma:
docs_v1 - Vektoriulottuvuus: 1536 (OpenAI text-embedding-3-small)
- Metriikka:
dot_product - Embedding-malli:
text-embedding-3-small
Asenna dev-riippuvuudet:
pip install -e ".[dev]"Aja tyyppitarkistus:
mypy astra_vector_db/Aja linting:
ruff check astra_vector_db/Mitä on tehty:
- ✅ Pipeline toimii end-to-end: extract → chunk → ingest → query
- ✅ Parent-chunkkien koko rajoitettu token-pohjaisesti (max 1500 tokenia ≈ 5000 tavua)
- ✅ Suuret parent-chunkit jaetaan automaattisesti pienempiin
- ✅ Pipeline käyttää automaattisesti
rl_units.jsonl:ää jos filtteri tuottaa tyhjän tuloksen - ✅ Kaikki chunkit menivät onnistuneesti Astra DB:hen (ei virheitä)
- ✅ Semanttinen haku toimii ja löytää relevantteja tuloksia
Mitä toimii:
15_extract_rl_units_from_akn_xml.py- Erottaa 775 yksikköä AKN XML:stä20_chunk_from_units_parent_child.py- Luo 122 parent + 729 child chunkkia41_ingest_rl_parent_child.py- Ingestoi chunkit Astra DB:hen (idempotentti)61_query_sota_parent_context.py- Semanttinen haku parent-context assemblyllä
Tunnetut ongelmat:
- Filtteri (
16_filter_rl_units_rlonly.py) ei toimi, koskasource_fileei sisällä act_id:tä - Pipeline käyttää automaattisesti
rl_units.jsonl:ää fallbackina - Validation varoittaa act_id-puutteesta, mutta se ei estä toimintaa
1. Extract (15_extract_rl_units_from_akn_xml.py)
- Parsii AKN 3.0 XML:stä rakenteelliset yksiköt (chapter/section/subsection/point)
- Tuottaa
rl_units.jsonl(775 yksikköä) - Käyttää
FINLEX_ROOTympäristömuuttujaa (asetettuDATA/Rikoslaki-20260109)
2. Filter (16_filter_rl_units_rlonly.py) - Vapaaehtoinen
- Yrittää suodattaa vain Rikoslain (1889/39-001)
- Ei toimi nykyisellä aineistolla (source_file ei sisällä act_id:tä)
- Pipeline jatkaa automaattisesti
rl_units.jsonl:llä jos filtteri tuottaa tyhjän
3. Chunk (20_chunk_from_units_parent_child.py)
- Luo parent-chunkit: pykälät (section), max 1500 tokenia
- Luo child-chunkit: momentit (subsection/point), max 800 tokenia
- Token-pohjainen split: käyttää
cl100k_basetokenisaattoria (sama kuin embedding-malli) - Tuottaa
rl_parent.jsonl(122 chunkkia) jarl_child.jsonl(729 chunkkia) - Deterministiset ID:t: SHA256 hash
4. Ingest (41_ingest_rl_parent_child.py)
- Lukee parent ja child JSONL-tiedostot
- Luo embeddings OpenAI:n
text-embedding-3-small-mallilla (1536 ulottuvuutta) - Insertoi Astra DB:hen kokoelmaan
rl_fi_v1 - Idempotentti: voi ajaa uudelleen (upsert-logiikka)
5. Query (61_query_sota_parent_context.py)
- SOTA-retrieval: hae top-30 child chunks
- Group by
parent_idja rank parent groups - Hae top-3 parent chunks
- Assemble context: child excerpts + full parent sections
1. Tarkista ympäristö:
cd workspace/astra-playground
.\.venv\Scripts\Activate.ps1
python -c "import os; from dotenv import load_dotenv; load_dotenv(); print('OK' if os.getenv('ASTRA_DB_API_ENDPOINT') else 'MISSING .env')"2. Aja koko pipeline:
cd workspace/astra-playground
.\RUN_PIPELINE.ps13. Testaa query:
cd workspace/astra-playground
.\.venv\Scripts\Activate.ps1
$env:QUERY_TEXT='Mikä on rangaistus varkaudesta?'
python .\61_query_sota_parent_context.py4. Tarkista kokoelma:
cd workspace/astra-playground
.\.venv\Scripts\Activate.ps1
python .\LIST_COLLECTIONS.pyPrioriteetti 1 - Korjaukset:
- Korjaa filtteri (
16_filter_rl_units_rlonly.py) tunnistamaan Rikoslaki oikein - Lisää act_id metadata chunkkeihin extract-vaiheessa
- Korjaa validation-varoitukset
Prioriteetti 2 - Parannukset:
- Testaa useita eri kyselyitä ja arvioi tulosten laatu
- Optimoi parent-chunkkien koko (tällä hetkellä 1200-1500 tokenia)
- Lisää metadata-filterointi queryssä (esim. vain Rikoslaki)
Prioriteetti 3 - Uudet ominaisuudet:
- Hybrid search (vector + BM25/keyword)
- Reranking (lexical overlap + lähde-ankkuri)
- Eval-setti (50-200 kysymystä, Recall@k, Precision@k)
- Pipeline-skripti:
workspace/astra-playground/RUN_PIPELINE.ps1 - Chunking-skripti:
workspace/astra-playground/finlex_extract/20_chunk_from_units_parent_child.py - Ingest-skripti:
workspace/astra-playground/41_ingest_rl_parent_child.py - Query-skripti:
workspace/astra-playground/61_query_sota_parent_context.py - Aineisto:
DATA/Rikoslaki-20260109/unzipped_fin@20250943/main.xml - Kokoelma:
rl_fi_v1(Astra DB) - Konfiguraatio:
workspace/astra-playground/.env
Aseta workspace/astra-playground/.env:
ASTRA_DB_API_ENDPOINT="https://..."
ASTRA_DB_APPLICATION_TOKEN="AstraCS:..."
OPENAI_API_KEY="sk-..."
ASTRA_COLLECTION_NAME="rl_fi_v1"
FINLEX_ROOT="F:\-DEV-\35.Astra-datastax_eka_database\DATA\Rikoslaki-20260109"- Token-pohjainen chunkkaus: Käyttää
cl100k_basetokenisaattoria (sama kuin embedding-malli) - Parent-chunkkien koko: Max 1500 tokenia (≈5000 tavua, alle Astra DB:n 8000 tavun rajan)
- Child-chunkkien koko: Max 800 tokenia
- Idempotentti ingest: Voit ajaa uudelleen ilman duplikaatteja (deterministiset ID:t)
- SOTA-retrieval: Parent-context assembly parantaa hakutuloksia