Thuta Learning
ExercisesAIbeginner

Practice: RAG, Embeddings, and AI Agents

Relax. We'll talk through this in plain words — no textbook voice.

What you'll walk away with

  • Get hands-on practice with RAG, Embeddings, and AI Agents
  • Reinforce the skills you've already learned through practice
  • Build the habit of finding bugs, fixing them, and checking your own work

Take a moment to think about this

This lesson is a practice set that combines the RAG, embeddings, vector database, and AI agent concepts from the Advanced chapter for deeper hands-on practice. The tasks are no longer single-concept quizzes — they operate at the level of an entire end-to-end flow, from chunking a document, to comparing embeddings, to building a RAG pipeline, all the way to writing tool-decision logic for an agent. It's a step up in difficulty from Lesson 1, and it's designed to have you write the core logic yourself rather than leaning on a built-in library (e.g. LangChain), so you truly understand how it works.

Exercises

Task 1: Write a function that splits a 3-paragraph document into fixed-size chunks (around 200 characters) with 20% overlap. Task 2: Implement a cosine similarity function yourself (no built-in libraries allowed), then write code that takes 3 vectors and finds which one is closest to a given query vector. Task 3: Write a minimal RAG pipeline (in pseudo-function form) that, given a user query, retrieves the top-3 relevant chunks from a vector database, inserts those chunks into the system prompt as context, and then calls the LLM. Task 4: Design a simple agent router with decision logic that uses the get_weather tool for weather questions, the calculator tool for calculation questions, and replies with plain text when no extra tool is needed.

Code Example

python
# Task 2 — implement cosine similarity yourself (no numpy/sklearn shortcuts allowed)
import math

def cosine_similarity(vec_a, vec_b):
    dot_product = sum(a * b for a, b in zip(vec_a, vec_b))
    magnitude_a = math.sqrt(sum(a * a for a in vec_a))
    magnitude_b = math.sqrt(sum(b * b for b in vec_b))
    if magnitude_a == 0 or magnitude_b == 0:
        return 0.0
    return dot_product / (magnitude_a * magnitude_b)


def find_most_similar(query_vector, candidate_vectors):
    # candidate_vectors: list of (id, vector) tuples
    best_id, best_score = None, -1.0
    for cand_id, cand_vector in candidate_vectors:
        score = cosine_similarity(query_vector, cand_vector)
        if score > best_score:
            best_id, best_score = cand_id, score
    return best_id, best_score


# Task 3 — minimal RAG pipeline skeleton (fill in the TODOs)
def rag_answer(user_query, vector_store, llm_client):
    # TODO 1: embed the user_query
    # TODO 2: retrieve top-3 chunks from vector_store using find_most_similar
    # TODO 3: build a prompt that injects the retrieved chunks as context
    # TODO 4: call llm_client with that prompt and return the answer
    pass


# Task 4 — simple agent router
def route_to_tool(user_query):
    if "weather" in user_query.lower():
        return "get_weather"
    if any(op in user_query for op in ["+", "-", "*", "/", "calculate"]):
        return "calculator"
    return "plain_text_response"
You should see
Given a query vector, the function should correctly return the nearest chunk ID; and running the RAG pipeline on a document set should produce a context-grounded answer that includes the retrieved context.

Try it in 5 minutes

Within 5 minutes, split 2 paragraphs into chunks, run your cosine_similarity function against a sample query vector, and check for yourself which chunk comes out closest.

A quick heads-up

Calling the cosine similarity function with two vectors of different embedding dimensions can throw an error — in production, always check for dimension mismatches first.

Easy traps

  • Skipping chunk overlap entirely, so context breaks apart at chunk boundaries (a sentence gets cut right between two chunks)
  • Forgetting to add a fallback case in the agent router (for when no tool matches), causing errors on unmatched queries

Now try it yourself

Within 5 minutes, split 2 paragraphs into chunks, run your cosine_similarity function against a sample query vector, and check for yourself which chunk comes out closest.

You'll know it worked when: Given a query vector, the function should correctly return the nearest chunk ID; and running the RAG pipeline on a document set should produce a context-grounded answer that includes the retrieved context.

Practice: RAG, Embeddings, and AI Agents | Thuta Learning