Skip to content
Forward Deployed

Forward Deployed
Lessons and contents
Python & Data Toolkit RefresherLesson 1 of 5
5 lessons
Learn

Python & Data Toolkit Refresher: overview

Source
From the RAG & Agents Engineering course
By
Sourav Banerjee
Last updated
8 Nov 2026

Report an issue

Every RAG and agent notebook in this course moves data through the same few Python tools. Chunks arrive as rows in a table, become rows of a float matrix, get scored with one matrix product, and the results land back in a table you can query. The model calls in between are slow network waits, so they run concurrently. The T2.1 notebooks build on four ideas: NumPy arrays, pandas DataFrames, SQL from Python, and asyncio for concurrent calls.

The running example is the Larkspur Cloud handbook that T5.1 to T5.3 index: twelve chunks on pricing, refunds, exports, outages and server sizing. Here the chunks sit in a DataFrame and a NumPy matrix, T5.1's baseline numbers sit in a SQLite table, and the lab sends eight handbook questions to a model at once.

In short

  • An embedding index is a 2-D NumPy array, one row per chunk. Normalise the rows with keepdims=True and one matrix product gives every cosine score. Without keepdims, a square toy matrix divides columns instead of rows and the ranking flips.
  • float32 halves the memory of float64: a million 1,536-dimension vectors take 6.1 GB instead of 12.3 GB.
  • The baseline row every later module compares against is a groupby: T5.1's mean recall is 0.33, 0.50, 0.50 and 0.50 at k = 1, 2, 5 and 12. mean() skips NaN, so a question that errored silently raises the average.
  • Pass values to SQL as parameters (? in sqlite3, %s in PyMySQL and psycopg2), never through an f-string. A plan name of starter' OR '1'='1 returns every plan when the query is built from a string.
  • In the lab, eight model calls take 11.0 s one at a time, 5.6 s with a semaphore of 2, 3.1 s with 4, and 2.6 s from a limit of 7, the time of the slowest call. A sync client inside async def keeps it at 11.0 s at any limit.

Mental model

The T2.1 toolkit in one small RAG run Tables in: pandas reads twelve handbook chunks from a CSV file into a DataFrame and cleans it, then asyncio sends the twelve embedding calls together. Vectors out: the vectors become one NumPy array of shape 12 by 384, one matrix product scores every chunk against a question and the top two are kept, and the run’s results go into a SQLite table. Tables in: pandas and asyncio Vectors out: NumPy and SQL pd.read_csv DataFrame asyncio.gather chunks.csv id, text: 12 rows 12 calls in flight vectors NumPy array scores = E @ q SQLite shape (12, 384) top k = 2 ids runs table
  1. pd.read_csv reads twelve handbook chunks, one row each.
  2. The DataFrame drops empty rows and keeps the id and text columns.
  3. asyncio.gather sends the twelve embedding calls together instead of one after another.
  4. The twelve vectors become one NumPy array of shape (12, 384).
  5. One matrix product scores every chunk against the question, and argsort keeps the top two.
  6. The run’s results go into a SQLite table, where GROUP BY gives the baseline row.

Each tool holds the data in the shape the next step needs. pandas keeps labelled rows and columns, NumPy keeps one dtype in a fixed shape so arithmetic runs on whole arrays, SQL keeps results you can filter and group later, and asyncio keeps the slow calls from waiting on each other. Most bugs in the later modules are a shape, a dtype or a blocked event loop at one of these handoffs.

Interactive lab

Concurrent calls with asyncio: open the file in a browser. Slide the semaphore from 1 to 8 and watch the wall time fall from 11.0 s to 2.6 s, then stop falling at 7. Then switch the client to llm.invoke and move the slider again; nothing changes, because a sync call never hands the event loop back.

How it connects

  • Before: nothing. T2.1 is the first module; skim the lessons you know.
  • Next: T2.2 makes the model calls this module runs concurrently. NumPy scoring returns in T5.1 (TF-IDF nearest neighbours) and T5.4 (embeddings). SQL becomes a retriever in T8.3 (text-to-SQL) and a memory store in T10.2. asyncio drives LangGraph's async nodes in T4.4 and the parallel agents of T11.2.

Key Takeaways

  • Keep vectors in one 2-D array of a fixed dtype; check .shape and .dtype before you trust a score.
  • Make the baseline a groupby over a long results table, and compare count() with size() before you read the mean.
  • Every value that reaches SQL from outside goes in as a parameter, and every credential comes from the environment.
  • Use asyncio for many slow network calls, cap them with a semaphore, and make sure every call inside async def is awaited.

Rate your confidence and keep notes on the module page.