Portfolio Agent
A durable, bilingual AI agent embedded in this portfolio to answer questions about my career, projects, and technical decisions.
- Eve
- OpenAI
- json-render
- Transformers.js
- Next.js
Challenge
Make a portfolio agent useful enough for recruiters and engineers without letting it invent career facts or turn into an unrestricted general-purpose assistant.
Approach
Generate always-on canonical context from the same typed portfolio data used by the site and instruct the model to verify every claim against it. Generative UI components take only portfolio identifiers, so cards and timelines render from the site's own data instead of model-written facts, and every spec is validated before it reaches the browser. The default harness tools are disabled, and a suite of evals covers grounding, prompt injection, language and UI choices. Speech-to-text runs entirely in a Web Worker.
Outcome
A bilingual conversation surface grounded in the public portfolio, transparent when information is unavailable, and backed by local speech transcription.
Architecture
Decisions and trade-offs
Generative UI components take portfolio identifiers, never free text
The model picks which project, company or skill to show, and the card renders that item's facts from the site's own data, so the model never writes what a card says.
A component can only show what the data already records; a new kind of fact needs a code change, not a prompt.
The role-fit comparison passes a second, independent model check
It is the one component with model-written text, and a visitor once got the agent to render an insult in it. The checker sees only the block, not the conversation, and fails closed.
One more model call per role-fit answer, and a legitimate comparison can be rejected.
Follow-up questions are generated outside the agent loop
A tool the agent called at the end of each answer was skipped about a third of the time, so the chat now asks for them in one short structured call after the turn completes.
A separate endpoint that needs its own rate limit and body cap.
