all work

han-dong.link — spatial portfolio cockpit, grounded Q&A, and Role Fit agent

  • TypeScript
  • Astro
  • React
  • Three.js
  • Spatial UI
  • Provider-agnostic LLM
  • LLM Tool-Calling
  • Generative UI
  • Guardrails
  • Progressive Enhancement

Role Fit turns pasted or uploaded JDs into source-backed fit briefs for recruiters; the same han-dong.link system also pairs a live Q&A assistant for source-backed answers with a Three.js cockpit for profile, work, research, and CV.

Open live site

Project overview

Role Sole builder — interactive cockpit UI, Three.js navigation, Q&A and Role Fit agent loops, source-backed answer cards, file/JD guardrails, deployment

Scenario

A public portfolio has to serve recruiters, technical peers, and research collaborators without making them guess which evidence supports each claim. Static pages can list work, but they rarely answer role-specific questions or show how the site itself organizes evidence.

Product strategy

I built a spatial cockpit plus canonical read-mode pages, then connected both to the same Astro content collections that power Q&A and Role Fit. The portfolio can be browsed visually, read linearly, or queried through evidence-backed cards.

Outcome and current stage

Live on han-dong.link · homepage cockpit entry with live portfolio counts · answer cards cite source pages · visible answer trace · Role Fit turns JD text or files into strengths, transferable experience, gaps, and questions

My contribution

  • Spatial portfolio cockpit: a Three.js experience around the assistant, with four planets for profile, work, research, and CV, plus read-mode pages for reduced-motion, mobile, and no-WebGL contexts
  • Five typed tools (getProjects / getPublications / getStack / getTimeline / getContact) the LLM chooses between per question, with a prose fallback
  • Role Fit agent: a dedicated `/role-fit` page accepts pasted JD text or PDF/PNG/JPEG/WebP uploads, then returns an advocacy brief with strong matches, transferable experience, gaps to confirm, and recruiter questions while leaving hiring judgment with the reader
  • Source-linked generative UI: every tool result renders a React card (project cards, publication list, stack chips, timeline, contact) that links back to its canonical page
  • Visible answer trace: the assistant surfaces the source-backed path from retrieved content to answer cards, so a visitor can see why a response was produced
  • Content collections are the single source of truth — a new project flows into the agent with no retraining and no embeddings
  • Evidence-led persuasion: leads with supported strengths, marks gaps briefly, and keeps facts, titles, and numbers tied to public site records

Technical evidence

  • Progressively enhanced Three.js shell: WebGL/reduced-motion/mobile checks, boot sequence, keyboard and wheel navigation, and a cockpit dashboard that shows live content counts from the same Astro content collections
  • Agent loop: validate input → build a grounded system prompt from collections → LLM tool decision → dedup tool calls → resolve typed tools → render cards + prose
  • Observable agent traces keep retrieved collection records, selected tool cards, and final prose visibly connected for inspection
  • Guardrails: input validation (length cap, prompt-injection regex, refuse off-topic and prompt-reveal attempts) plus per-IP rate limiting
  • Role Fit safeguards: JD-specific validation, pasted text or local file input, PDF/image extraction, evidence allowlisting, numeric/credential claim guards, and site-evidence brief generation when full analysis is delayed
  • Provider-agnostic LLM integration with a deterministic mock fallback, so dev / no-key runs work fully offline
  • Server-rendered on Astro + Vercel; trilingual (EN / 繁中 / 简中); answers render through markdown

The agent loop

Each question runs: validate input → assemble a grounded system prompt from the content collections → ask the LLM which tools to call → dedup the tool calls → resolve the typed tools → render cards plus prose. The LLM directs tool selection and response framing; the code handles typed resolution and rendering.

The latest agent pass makes that path visible as an answer trace: retrieved source records, chosen cards, and final prose stay connected, giving each response an inspectable route back to the site content.

Role Fit — evidence-backed JD matching

Role Fit is a dedicated task workflow. A recruiter can paste a job description or upload a PDF/screenshot image; the site extracts the JD text, checks it against public content collections, and returns a brief organized into strong matches, transferable experience, gaps, and questions to confirm.

JD text, results, and trace records stay within the browser session. Analysis uses pasted or uploaded content plus public site evidence, and returns evidence categories and follow-up questions while leaving scoring and hiring decisions to the recruiter.

Grounded in site content

The agent reads directly from the Astro content collections, so a new project becomes available immediately without embeddings or retraining. Answers stay tied to the information provided; when a detail is absent, the assistant points visitors to the contact options.

Guardrails and evidence-led answers

Input validation covers length, prompt-injection patterns, topic scope, and per-IP rate limits. Role Fit adds JD-specific validation, uploaded-file extraction limits, evidence allowlisting, and numeric/credential claim guards. Responses lead with supported strengths, mark gaps plainly, and stay within public site evidence.

Cockpit shell — spatial portfolio

The cockpit is the site's interactive front end, built as a full-window Three.js cockpit with four navigable planets: profile, work, research, and CV. Scroll wheel, keyboard, or click moves between the four planets; each planet opens cards drawn from the same Astro content collections that feed the assistant, so the 3D scene, dossier views, and answer cards stay aligned.

The dashboard surfaces live counts from those same collections. Reduced-motion, mobile, and no-WebGL contexts keep the canonical read-mode pages, so the spatial layer adds interaction while the underlying portfolio remains accessible and source-linked.

Screenshots

The spatial cockpit is the default portfolio entry.
The quick-read mode keeps traditional pages available beside the cockpit.
The work page provides a linear fallback with inline project drawers.

Enlarge screenshot