Completed

Supreme Court of Korea - E-litigation Search and Analysis

Back to Projects
Java
Spring
Oracle
Jenkins
GitLab
Python
PyTorch
BERT
Docker
Linux
C++
5+ min → 8 s
Search latency
37×
Speed improvement
375+
Misanalysed cases resolved
+4%
NER extraction quality

Figures

The query pipeline I designed. Entities are tagged into typed fields offline, so at query time SFX and NER can route each term to the field that holds it rather than matching against the whole corpus. Vector search handles expansion and typo correction; search-log analytics feed expansion terms back in.
The query pipeline I designed. Entities are tagged into typed fields offline, so at query time SFX and NER can route each term to the field that holds it rather than matching against the whole corpus. Vector search handles expansion and typo correction; search-log analytics feed expansion terms back in.
The part of this work I would point at first. Expanding a query term does not mean fetching synonyms — in law it means walking a hierarchy. Here 손해 (damages) expands into hyponyms (lost profit, medical expenses, direct, consequential, foreseeable, irrecoverable) and separately into related concepts (intent to cause damage, damage security, mitigation duty). A user searching the general term still reaches judgments that only ever use the specific one, which is exactly the omission problem a court system cannot tolerate.Open full size
The part of this work I would point at first. Expanding a query term does not mean fetching synonyms — in law it means walking a hierarchy. Here 손해 (damages) expands into hyponyms (lost profit, medical expenses, direct, consequential, foreseeable, irrecoverable) and separately into related concepts (intent to cause damage, damage security, mitigation duty). A user searching the general term still reaches judgments that only ever use the specific one, which is exactly the omission problem a court system cannot tolerate.
The same concept mapped across all five corpora at once. 손해 (damages) surfaces as 손해액 and 위자료 in case law, 손해배상 and 이해관계인 in statutes, 불가항력 and 국제사법재판소 in treaties, 배상기 and 상당인과관계 in literature, and 확정일자 and 유가증권 in registry precedents. The same legal idea is expressed with different vocabulary depending on which corpus you are in, which is why a single flat synonym list does not work here.Open full size
The same concept mapped across all five corpora at once. 손해 (damages) surfaces as 손해액 and 위자료 in case law, 손해배상 and 이해관계인 in statutes, 불가항력 and 국제사법재판소 in treaties, 배상기 and 상당인과관계 in literature, and 확정일자 and 유가증권 in registry precedents. The same legal idea is expressed with different vocabulary depending on which corpus you are in, which is why a single flat synonym list does not work here.
Case law results. The system I worked on runs mostly on a closed network, but this public portal exposes the same class of features I built: morphological search rather than substring matching, related terms beside the query, relevance-versus-popularity ranking, result counts per field (full text 14,377 / summary 4,874 / holding 4,154), and facet counts by court level, precedent grade and case type.Open full size
Case law results. The system I worked on runs mostly on a closed network, but this public portal exposes the same class of features I built: morphological search rather than substring matching, related terms beside the query, relevance-versus-popularity ranking, result counts per field (full text 14,377 / summary 4,874 / holding 4,154), and facet counts by court level, precedent grade and case type.
Auto-completion over the literature corpus. The suggestions are whole article titles containing the typed term, not prefix matches on a static dictionary — on the systems I delivered these candidates came from search-log analysis, so they tracked what users were actually looking for.Open full size
Auto-completion over the literature corpus. The suggestions are whole article titles containing the typed term, not prefix matches on a static dictionary — on the systems I delivered these candidates came from search-log analysis, so they tracked what users were actually looking for.
Statutes, with a schema of their own: promulgation number and date, enforcement date, amendment status, and a choice between current-only and historical versions. Each corpus needs its own typed fields; a single generic index cannot answer "which version was in force on this date".Open full size
Statutes, with a schema of their own: promulgation number and date, enforcement date, amendment status, and a choice between current-only and historical versions. Each corpus needs its own typed fields; a single generic index cannot answer "which version was in force on this date".
Treaties, again with a different schema — bilateral versus multilateral, counterpart country, subject area, continent, effective date versus gazette date. Five corpora, five field sets, one query-understanding layer in front of them.Open full size
Treaties, again with a different schema — bilateral versus multilateral, counterpart country, subject area, continent, effective date versus gazette date. Five corpora, five field sets, one query-understanding layer in front of them.
Rules, established practice and registry precedents. Note the field-scoped tabs — title (7) / body (157) / appendix (0) / forms (3) / rule number (19) — which is the same idea as scoping a query to the field the entity actually lives in, surfaced to the user as a choice.Open full size
Rules, established practice and registry precedents. Note the field-scoped tabs — title (7) / body (157) / appendix (0) / forms (3) / rule number (19) — which is the same idea as scoping a query to the field the entity actually lives in, surfaced to the user as a choice.

Overview

The Supreme Court of Korea was replacing its electronic litigation search system. The users are judges, clerks and litigants searching case law, judgments and treaties — a domain where a missed result is not an inconvenience but a consequence for someone's case. I owned the NLP and search layer end to end, from requirements analysis and infrastructure design through deployment and post-launch stabilisation. The role had been scoped for an engineer at assistant-manager grade, which at that company required three years and a track record. I was assigned to it on the day I completed my first year.

Why not a rule-based layer

The common approach in comparable systems was a rule-based chatbot sitting in front of search. That works until a user phrases something the rules did not anticipate, and in a legal corpus that is most of the time. I argued for learned query understanding instead, and built it in two parts: SFX (speech act analysis) with SRL to work out what the user was actually constraining — recency, which court, case context — and a BERT-based NER to pull out the entities that matter in law: case numbers, statute names, party names. Where documents resisted clean categorisation, SRL-derived labels were used as the training signal rather than forcing a category that did not fit.

Routing instead of matching

Once entities are tagged into typed fields at index time, a query does not have to be matched against everything. SFX segments it, each term is routed to the field that actually holds that entity type, and the result comes back without scanning the rest. On top of that, vector search handles query expansion and typo correction, so a slightly wrong case number or an unfamiliar phrasing still lands.

Results

Search latency dropped from over five minutes to eight seconds, a 37× improvement, from rebuilding the Java backend algorithms and the indexing pipeline. Fine-tuning the NER and re-indexing improved extraction quality by 4%+. 375+ previously misanalysed cases were resolved. I also set up the Jenkins CI/CD pipelines on GitLab for unit and integration testing through to production deployment.

The feedback loop

Search logs were mined for related and recommended keywords, which fed back into query expansion and the results UI. Supervised tagging (LKWD) degraded results because of errors in the tagging step, so unsupervised LDA with careful preprocessing was used instead — it performed better in a single pass. I also attempted TF-IDF summarisation and was not satisfied with the quality; it stayed unfinished. Administrators got search analytics dashboards — line, bubble and dendrogram charts — so search quality could be monitored rather than assumed.

What I took from it

Because omissions in a court system affect real trials, "good enough on average" was not an acceptable bar. I kept testing and iterating until omissions were eliminated rather than reduced. That is the same instinct I later formalised in my dissertation, where an aggregate metric turned out to be hiding a failure mode, and it is why evaluation work interests me now.