All articlesAlfara
AI / LLM2 min read

Building Ask Alfara: A Grounded, Provider-Agnostic LLM Chat

If you have used the chat in the header of this site, you have used the thing this post is about. Ask Alfara answers questions about me and my work. It is small on purpose, but it is a real production LLM app, and it is built on the same principle as my research: the model is never allowed to make things up.

AI / LLM

The one rule

There is a single canonical profile file that is the source of truth. The model grounds every answer in that file. If a fact is not in the profile or my resume, the correct answer is "I don't have that detail" plus a pointer to contact me — not a confident guess. A portfolio chatbot that invents a client or a skill is worse than no chatbot at all.

Provider-agnostic on purpose

The app talks to models through an OpenAI-compatible layer over OpenRouter, using the Vercel AI SDK. That means the underlying model is a config value, not a rewrite. If a better or cheaper model shows up next month, I change a string. I have been burned before by pipelines welded to one vendor's SDK, so now I default to provider-agnostic from day one.

  • A Next.js App Router route handler owns the server side — no separate backend to deploy.
  • The Vercel AI SDK handles streaming so answers appear token by token instead of after an awkward pause.
  • OpenRouter abstracts the provider, so switching models is a config change.
  • Upstash gives me rate limiting at the edge, because a public LLM endpoint without a rate limit is just a way to donate money to a token bill.

Streaming is a UX decision, not a technical one

Server-sent events stream the response as it generates. This is not about speed — the total time is similar. It is about the feeling of the thing. A blank box for four seconds reads as broken. The same four seconds with text flowing reads as thinking. For a chat that represents me, that difference matters.

Rate limiting and grounding are not features you add later. On a public endpoint that speaks for you, they are the first two things you build.

Why this pattern travels

Swap the profile file for a product's docs and you have a support assistant. Swap it for internal runbooks and you have an ops helper. The bones — grounded context, provider-agnostic model, streaming, rate limiting — are the same bones every serious LLM feature needs. This chat is a deliberately small proof of a pattern I ship at real scale.

Written by

Alfara Nafi Dinara

Full-stack, blockchain, and LLM engineer. Building something and want a hand? Tell me what you're building and where you're stuck — I usually reply within minutes.

Start a project
Read nextAutomating 10,000+ Products Across 30 Stores: Architecture Notes