Advanced

Giving the bot knowledge

The model only knows what it was trained on. Learn to hand it your own documents each turn so it answers questions about your product, FAQ, or data.

What you will see

Retrieved doc 1: The warranty covers two years. Retrieved doc 2: Company refund policy is 30 days. Retrieved doc 3: Parking is free on Mondays.

About 2 min of reading

Try It

A base model only knows what it trained on, so it guesses about your data. Retrieval-Augmented Generation solves this by matching the question to stored documents, fetching the few relevant ones, and answering from just those instead of inventing.

1

I store documents in a searchable list and show the incoming question, establishing what knowledge the model can access without retraining.

facts = [ "Company refund policy is 30 days.", "Office hours are 9 to 5.", "Parking is free on Mondays.", ] query = "how do I get my money back" print("Giving the bot knowledge") print("Documents available: %d" % len(facts)) print("Question: %s" % query)

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Giving the bot knowledge Documents available: 3 Question: how do I get my money back
A base model cannot know facts from after its training date. Retrieval is what keeps the answer current without ever retraining the model.
2

I score each document against the question by shared words, keep the top three, and print the matches so only the relevant documents reach the model.

facts = [ "Company refund policy is 30 days.", "Office hours are 9 to 5.", "Parking is free on Mondays.", "The warranty covers two years.", ] def similarity(query, doc): q = set(query.lower().split()) d = set(doc.lower().split()) return len(q & d) query = "how do I get my money back and what is the warranty" sc = [(doc, similarity(query, doc)) for doc in facts] sc = [s for s in sc if s[1] > 0] sc.sort(key=lambda x: x[1], reverse=True) top = sc[:3] for i, doc in enumerate(top, 1): print("Retrieved doc %d: %s" % (i, doc))

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Retrieved doc 1: The warranty covers two years. Retrieved doc 2: Company refund policy is 30 days. Retrieved doc 3: Parking is free on Mondays.
The words do not need to match exactly; shared meaning is enough. Retrieving the closest documents before answering is what keeps answers grounded in your data instead of guesses.

Data Flow

The user question is matched against stored documents, the relevant ones are fetched, and the model answers using only that context.
1 User asks a question
↓
2 The app searches the document store
↓
3 The most relevant documents are retrieved
↓
4 Those documents are added to the prompt
↓
5 The model answers from the provided context
↓
6 Only grounded answers are returned
Line by line

Read the first example one line at a time. A line that prints shows what appears on screen; the rest set things up quietly.

facts = [ sets nothing on screen
"Company refund policy is 30 days.", sets nothing on screen
"Office hours are 9 to 5.", sets nothing on screen
"Parking is free on Mondays.", sets nothing on screen
] sets nothing on screen
query = "how do I get my money back" sets nothing on screen
print("Giving the bot knowledge") Giving the bot knowledge
print("Documents available: %d" % len(facts)) Documents available: 3
print("Question: %s" % query) Question: how do I get my money back
Why this works
Why RAG matters

A base model cannot know things that happened after its training, like your product details or company policies.

Retrieval-Augmented Generation solves this:

  • You keep your documents somewhere searchable.
  • On each question, you find the most relevant ones.
  • You send just those to the model to answer from.

This keeps your bot current and specific without ever retraining the model. It is how production chatbots stay grounded in real information.

Examples

Passing documents in the prompt

The simplest way to teach a bot your content is to include it in the request:

const answer = await fetch(API_URL, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    model: 'gpt-4o-mini',
    messages: [
      { role: 'system', content: 'Answer using only the context below.' },
      { role: 'user', content: 'Context: ' + facts + '\n\nQuestion: ' + question }
    ]
  })
});

By telling the model to use only the provided context, you keep answers grounded in your data instead of letting it guess or make things up.

Searching before answering

For larger libraries, don't paste everything. Find the relevant part first:

async function relevantFacts(query) {
  return facts
    .map((doc) => ({ doc, score: similarity(query, doc) }))
    .sort((a, b) => b.score - a.score)
    .slice(0, 3)
    .map((x) => x.doc);
}

Then send only those three documents to the model. This is the pattern behind **RAG*: retrieve, then generate. It keeps answers accurate while saving tokens and time.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Input and output safety
Previous Lesson
Input and output safety
Next Lesson
Evaluating your chatbot
Evaluating your chatbot →