Projects
/ project/Agent UX

This portfolio agent

This site: a sparse portfolio wrapped around an AI agent that can answer questions about the work.

Status
Selected project
Type
Agent UX
Link
Live site

The idea

This site keeps a normal portfolio structure, but it also gives visitors a direct way to ask questions about the work.

How it works

The chat route builds a small deterministic context pack from profile facts, project Markdown, and writing metadata. It then streams a response through the OpenAI Responses API. The public route also has origin checks, payload limits, rate limiting, degraded fallbacks, and lightweight diagnostics.

Implementation detail

The project has three separate layers:

src/content/profile.ts        -> durable facts, case studies, links
src/content/projects/*.md     -> project pages and agent summaries
src/lib/prompt/contextPacking -> deterministic context selection
src/app/api/chat/route.ts     -> validation, rate limits, OpenAI streaming

The context packer classifies the latest visitor question before building the system prompt:

export type ContextPackName =
  | "overview"
  | "projects"
  | "project_detail"
  | "writing"
  | "hiring"
  | "current"

Each response includes debugging headers such as X-Agent-Context-Pack, X-Agent-Context-Items, and rate-limit backend headers. Those headers are boring in the best way: they make production behavior easier to diagnose without exposing private prompt internals.

Why keep the normal pages?

The agent is an interface, not a replacement for legible information architecture. Projects and essays should still be browsable without starting a conversation.

What I learned

A portfolio chatbot is only as good as the content model underneath it. The prompt can add voice, but the factual layer needs stable project pages, summaries, links, and retrieval cues. Otherwise the agent becomes a stylish way to hallucinate.