PLM URA Finder

Case study
Next.js React Tailwind CSS Google Gemini
PLM URA Finder — screenshot 1PLM URA Finder — screenshot 2PLM URA Finder — screenshot 3
9
research agendas
10
titles per batch
top-3
alternatives shown

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.