Build a Small RAG Pipeline in a Notebook with Vectorized NumPy and pandas

Read the full interview experience this question came from →

Quick Overview

Build a small retrieval-augmented generation pipeline in a notebook: chunk documents with pandas, embed them, retrieve the most similar chunks with vectorized numpy cosine similarity, and assemble an answer with checkable citations. The question tests numpy and pandas fluency, retrieval edge cases and a simple retrieval evaluation.

Build a Small RAG Pipeline in a Notebook with Vectorized NumPy and pandas

Company: Harvey

Role: Software Engineer

Category: Machine Learning

Difficulty: hard

Interview Round: Onsite

Build a small retrieval-augmented generation (RAG) pipeline in a notebook. Given a set of documents and a user's question, the pipeline finds the passages most relevant to the question and uses them to produce an answer that cites its sources. The report names this round only as RAG coding in a notebook and notes that fluency with numpy and pandas mattered, so write the data handling and the similarity search with pandas and vectorized numpy rather than Python loops over rows. The setup below is an assumption to make the parts concrete; confirm it with the interviewer. ```text Assumed setup docs pandas DataFrame with columns doc_id (str) and text (str) embed embed(texts: list[str]) -> numpy array of shape (len(texts), d); provided generate generate(prompt: str) -> str; a provided language-model call ``` ### Clarifying Questions - Does `embed` return normalized vectors, and is the same model used for documents and for questions? - How long are the documents, and should chunk boundaries respect sentences or paragraphs? - How many passages may go into the prompt, and what context length must the prompt fit in? - What should the pipeline return when nothing relevant is found? - Are there questions with known relevant documents that can be used to check retrieval? ### Part 1 — Chunk the documents Split each document into fixed-size, overlapping chunks and return a DataFrame with one row per chunk: a chunk id, the document id, the chunk's start and end offsets in the document, and the chunk text. ```hint Keep the offsets Record where each chunk starts and ends in its document. Offsets make the overlap easy to test and let a citation point back to the exact text. ``` #### What This Part Should Cover - Correct boundaries: the last chunk, documents shorter than one chunk, empty or missing text, and the overlap - A tidy chunk table with stable ids, built without appending rows to a DataFrame one at a time - How chunk size and overlap affect retrieval quality and cost ### Part 2 — Embed and retrieve Embed every chunk once. Then, for a question, return the `k` chunks most similar to it by cosine similarity, with their scores, as a DataFrame sorted from most to least similar. ```hint Precompute what does not depend on the question Look at the cosine similarity formula and decide which part can be computed once for all chunks ahead of time, and which numpy operation then scores every chunk at once. ``` #### What This Part Should Cover - A vectorized cosine similarity that handles zero vectors and keeps the embedding matrix aligned with the chunk table - Top-k selection with a deterministic order for ties, and its cost for `N` chunks of dimension `d` - Batched embedding calls and reuse of the chunk embeddings across questions ### Part 3 — Answer with citations Put the retrieved chunks into a prompt that tells the model to answer only from them and to cite chunk ids, call the model, and return the answer together with the chunks it cites. Handle the case where no chunk is relevant enough. ```hint Make citations checkable Decide what the prompt must contain so that every citation in the model's answer can be checked against the retrieved chunks afterwards. ``` #### What This Part Should Cover - A prompt that separates instructions, sources and the question, labels each source with its id, and respects a length budget - A relevance threshold or fallback when retrieval finds nothing useful - Validating the cited ids against the retrieved chunks ### What a Strong Answer Covers - Confirms the data, the embedding function and the expected output before coding - Idiomatic pandas and vectorized numpy, with no Python loop over chunks to compute similarity - Correct handling of empty inputs, short documents, zero vectors and ties - A small retrieval check, such as how often a known relevant document appears in the top k - Notebook code organized into small functions that can be tested one at a time ### Follow-up Questions - A user searches for an exact product code that appears in one document, and retrieval misses it. How do you fix that? - The corpus grows to tens of millions of chunks. What replaces the exact similarity search, and what do you give up? - How would you measure whether answers are faithful to the retrieved passages? - Several near-identical chunks from one document fill the top k. What do you change?

Overview: Build a small retrieval-augmented generation pipeline in a notebook: chunk documents with pandas, embed them, retrieve the most similar chunks with vectorized numpy cosine similarity, and assemble an answer with checkable citations. The question tests numpy and pandas fluency, retrieval edge cases and a simple retrieval evaluation.

Read the full Harvey Software Engineer interview experience this question came from

Harvey logo
Harvey
Oct 12, 2026
hardSoftware EngineerOnsiteMachine Learning
0
0

Build a small retrieval-augmented generation (RAG) pipeline in a notebook. Given a set of documents and a user's question, the pipeline finds the passages most relevant to the question and uses them to produce an answer that cites its sources.

The report names this round only as RAG coding in a notebook and notes that fluency with numpy and pandas mattered, so write the data handling and the similarity search with pandas and vectorized numpy rather than Python loops over rows. The setup below is an assumption to make the parts concrete; confirm it with the interviewer.

Assumed setup
  docs       pandas DataFrame with columns doc_id (str) and text (str)
  embed      embed(texts: list[str]) -> numpy array of shape (len(texts), d); provided
  generate   generate(prompt: str) -> str; a provided language-model call

Clarifying Questions Guidance

  • Does embed return normalized vectors, and is the same model used for documents and for questions?
  • How long are the documents, and should chunk boundaries respect sentences or paragraphs?
  • How many passages may go into the prompt, and what context length must the prompt fit in?
  • What should the pipeline return when nothing relevant is found?
  • Are there questions with known relevant documents that can be used to check retrieval?

Part 1 — Chunk the documents

Split each document into fixed-size, overlapping chunks and return a DataFrame with one row per chunk: a chunk id, the document id, the chunk's start and end offsets in the document, and the chunk text.

What This Part Should Cover Guidance

  • Correct boundaries: the last chunk, documents shorter than one chunk, empty or missing text, and the overlap
  • A tidy chunk table with stable ids, built without appending rows to a DataFrame one at a time
  • How chunk size and overlap affect retrieval quality and cost

Part 2 — Embed and retrieve

Embed every chunk once. Then, for a question, return the k chunks most similar to it by cosine similarity, with their scores, as a DataFrame sorted from most to least similar.

What This Part Should Cover Guidance

  • A vectorized cosine similarity that handles zero vectors and keeps the embedding matrix aligned with the chunk table
  • Top-k selection with a deterministic order for ties, and its cost for N chunks of dimension d
  • Batched embedding calls and reuse of the chunk embeddings across questions

Part 3 — Answer with citations

Put the retrieved chunks into a prompt that tells the model to answer only from them and to cite chunk ids, call the model, and return the answer together with the chunks it cites. Handle the case where no chunk is relevant enough.

What This Part Should Cover Guidance

  • A prompt that separates instructions, sources and the question, labels each source with its id, and respects a length budget
  • A relevance threshold or fallback when retrieval finds nothing useful
  • Validating the cited ids against the retrieved chunks

What a Strong Answer Covers Guidance

  • Confirms the data, the embedding function and the expected output before coding
  • Idiomatic pandas and vectorized numpy, with no Python loop over chunks to compute similarity
  • Correct handling of empty inputs, short documents, zero vectors and ties
  • A small retrieval check, such as how often a known relevant document appears in the top k
  • Notebook code organized into small functions that can be tested one at a time

Follow-up Questions Guidance

  • A user searches for an exact product code that appears in one document, and retrieval misses it. How do you fix that?
  • The corpus grows to tens of millions of chunks. What replaces the exact similarity search, and what do you give up?
  • How would you measure whether answers are faithful to the retrieved passages?
  • Several near-identical chunks from one document fill the top k. What do you change?