Overview
Looking up Thai law means knowing which code to open and roughly where the answer lives. Asking a general chatbot instead gets you an answer that sounds right and cites sections that may not exist. This system sits between the two: questions can be asked in everyday language, and every section it quotes is pulled from an indexed copy of the real text rather than written from the model’s memory.
My part
A solo project — I built all of it:
- Collected the four codes and the judgments from open datasets, merged the later amendments into the base text, and indexed one section per chunk. Cutting text into fixed-length pieces instead would have dropped whole sections out of the index.
- The search itself: two kinds of vector searched together, their rankings merged, then re-ordered by a cross-encoder down to the eight sections that go to the model.
- The case evaluation pipeline: break the story into issues, find the sections that apply, go through the elements of each offence one at a time, then decide. The verdict is computed from those answers in code, so it follows from the elements rather than from what the model felt like concluding.
- Tuned the search by measuring it. A hand-written question set for the three codes that public benchmarks do not cover was written specifically so the numbers would not come from the civil code alone.
What it does
- Answers questions in everyday Thai, with the sections it used shown beside the answer in full.
- Marks each citation with the result of its check, and says plainly that the check confirms the section exists and was quoted correctly — not that the interpretation is right.
- Takes an incident described in text or uploaded as a PDF or DOCX, and returns a verdict with the elements that led to it.
- Lets any section be opened on its own, showing the sections it refers to and the judgments that cite it.
- Sends only text extracted on the user’s own machine by default, never the uploaded file, and asks for consent before each run.
Tools
FastAPI for the backend and Next.js for the web app, Qdrant as the vector database, BGE-M3 for embeddings with a cross-encoder for re-ranking, the Gemini API for the language model, SQLite for the section registry, and Docker to run the pieces together.


