Overview
PLM URA Finder classifies research titles against the Pamantasan ng Lungsod ng Maynila’s 9 University Research Agendas using Google Gemini — returning the best-matching agenda, a confidence score, and a justification. I built the full app: a Next.js frontend and a server-side classification pipeline engineered to make an LLM’s output trustworthy.
Context
Sorting research by University Research Agenda by hand is slow and inconsistent — the same title can land in different buckets depending on who reads it. URA Finder makes the call fast, consistent, and explainable: paste one title or a batch and get the best-matching agenda with a confidence score and a justification you can act on.
My Role
I designed and built the app end to end — the Next.js UI and the server-side Gemini pipeline, including the reliability guardrails that stop the model from inventing categories.
Architecture & Key Decisions
Next.js 16 (App Router) + React 19 + Tailwind 4, with a server-side API route owning the model call. The real work is making a generative model reliable enough to classify:
- Structured, deterministic output. Gemini runs at temperature 0 against a forced JSON
responseSchema, so every result is typed and parseable — not free text to scrape. - Hallucination guard. Each agenda the model returns is validated against the canonical 9-agenda list with a hand-written Sørensen–Dice coefficient; weak matches abstain rather than guess, so the tool can’t surface an agenda that doesn’t exist.
- No library bloat. The Gemini call is a direct server-side API request and the fuzzy matcher is hand-implemented — no third-party AI or string-matching dependencies.
- Batch + context. Up to 10 titles per request, each with an optional abstract and keywords to sharpen accuracy.
- Explainable by default. Every result shows agenda, area, confidence, a justification, and the top-3 alternative agendas, so a human can audit the call.
- Built for real use. Light/dark theming, a responsive table-to-accordion results view, CSV and clipboard export, and keyboard shortcuts.
Hardest Challenge
Making a generative model reliable enough to trust for classification. LLMs happily return plausible-but-wrong categories in free-form prose. The fix was layered: temperature 0 plus a forced schema to kill drift, then validating every output against the canonical agenda list with a Sørensen–Dice match and an abstain path — so a low-confidence answer says “not sure” instead of inventing an agenda. The balance to strike was rejecting bad outputs without over-rejecting good ones.
Outcome & Impact
- Classifies against all 9 University Research Agendas with per-title reasoning and top-3 alternatives.
- Live and deployed — handles single titles or batches of 10, with CSV and clipboard export.
- Turns an LLM from a plausible-sounding guesser into an auditable classifier that abstains when unsure.


