The problem: you do not know the words the document uses
The Tribunal de Contas dos Municípios de Goiás (TCM-GO) holds a large body of decisions, rulings and internal regulations. Anyone who has searched a collection like that knows the failure mode. You know what you are looking for, but the document phrases it differently, so a keyword search returns nothing, or returns hundreds of results in the wrong order.
ChatDoc is the tool I worked on to fix that. It lets the institution's staff run semantic searches across rulings and regulations in natural language. I worked on it in a team in partnership with CEIA/UFG, across frontend, backend, architecture, machine learning and data science, and it was presented publicly at AI.Brasil Experience.
Keyword search versus semantic search
Keyword search asks: which documents contain these terms? Semantic search asks: which passages mean something close to this question?
The usual way to do the second is with embeddings. A model turns each passage into a vector of numbers so that passages with similar meaning end up close together. A question is turned into a vector the same way, and the system returns the nearest passages.
import numpy as np
def cosine_similarity(a: np.ndarray, b: np.ndarray) -> float:
return float(a @ b / (np.linalg.norm(a) * np.linalg.norm(b)))
def top_passages(question_vec, passage_vecs, k=5):
scores = [cosine_similarity(question_vec, p) for p in passage_vecs]
return sorted(range(len(scores)), key=scores.__getitem__, reverse=True)[:k]This snippet is illustrative. A real system adds an index for speed, handles long documents by splitting them into passages and filters by metadata such as document type or date. The idea underneath is the same.
Making it trustworthy, not just fast
For a public institution, an answer that cannot be checked is a liability. A few principles I would apply to any search tool over official documents:
- Always show the source. Return the passage and the document it came from, so the person can read the original wording rather than trust a paraphrase.
- Split documents along their natural structure. Rulings and regulations have articles, sections and numbered items. Cutting passages along that structure keeps each result self-contained.
- Combine meaning with exact terms. Legal text is full of identifiers: process numbers, article numbers, names. People searching for those want exact matches, so the best systems keep keyword matching alongside semantic matching.
- Evaluate with real questions. Collect the questions staff actually ask, record which passage answers each one and measure whether the system finds it. That is the only honest way to compare changes.
What changes for the user
The shift is subtle but real. Instead of guessing the vocabulary of the document, a person can ask the question the way they would ask a colleague. For the tribunal, that means less time lost hunting for the right passage and a lower barrier for people who are not experts in how the documents are phrased.
I also explored ChatDoc together with GAIA, a Brazilian Portuguese language model, as noted in the case study.



