Guides

How to Build an AI Chatbot for a Website

A chatbot that's actually useful for a specific website needs to be grounded in that site's content, not just the model's general knowledge — this covers the retrieval pipeline that makes that possible, plus the interface around it.

Prerequisites

  • arrow_rightAn OpenAI (or similar) API key
  • arrow_rightA set of content to ground the bot in (docs, FAQs, product pages)
  • arrow_rightA vector database or Postgres with pgvector

Step 1: Chunk and Embed Your Content

Split source content into reasonably sized chunks (a few hundred words each is a common starting point), generate an embedding vector for each using an embeddings API, and store both the text and its vector.

Step 2: Retrieve Relevant Chunks at Query Time

const queryEmbedding = await embed(userQuestion);
const relevantChunks = await vectorDb.similaritySearch(queryEmbedding, { limit: 5 });

Step 3: Build the Prompt and Generate a Response

const prompt = `Answer using only the context below. If the answer isn't in the context, say you don't know.\n\nContext:\n${relevantChunks.join('\n\n')}\n\nQuestion: ${userQuestion}`;
const response = await openai.chat.completions.create({
  model: 'gpt-4o-mini',
  messages: [{ role: 'user', content: prompt }],
});

Explicitly instructing the model to say it doesn't know when the context doesn't cover the question is one of the simplest, highest-leverage ways to reduce fabricated answers.

Common Errors

  • arrow_rightBot confidently answers questions outside its actual content — the prompt isn't instructing it clearly enough to stick to the provided context
  • arrow_rightIrrelevant chunks getting retrieved — chunk size may be too large or too small for the content type; this usually needs iteration against real test questions
  • arrow_rightSlow response times — streaming the response token by token makes the same total latency feel much faster to the user

Security Considerations

  • arrow_rightRate limit the chat endpoint to prevent abuse and runaway API costs
  • arrow_rightNever let the retrieval step pull content the current user shouldn't have access to — respect the same permissions as the source system
  • arrow_rightSanitize and log conversations for quality monitoring without storing more personal data than necessary

Frequently Asked Questions

How much content do I need before building this?add

Enough that a keyword search would genuinely struggle to find the right answer — a handful of pages may not need a chatbot at all; a large documentation set or product catalog is where retrieval-based search starts to add real value.

Can I use this approach without a vector database?add

For a very small content set, a simpler keyword or full-text search might suffice instead of embeddings — vector search earns its complexity once content is large or the phrasing of questions varies a lot from the source text.

How do I stop the bot from making things up?add

Ground it strictly in retrieved context, instruct it explicitly to say when it doesn't know, and consider a confidence threshold below which it defers to a human rather than answering.

BUILDING SOMETHING SIMILAR?

If you'd rather have this built and shipped than build it yourself, I'm available for freelance and contract work.