dspy.ChainOfThought writes the answer. This page keeps the passages in Pixeltable: one row per document, a view that splits each document into chunks, and an embedding index on the chunk text. search() ranks those chunks with similarity() and returns them as passages.
The DSPy RAG tutorial calls any Python function as the retriever. search() is that function. It returns a dspy.Prediction whose passages list is the chunk text, the same attribute dspy.retrievers.Embeddings returns. dspy.Retrieve reads a retrieval model from dspy.settings.rm. Leave that unset and call search() from the module.
This page matches Pixeltable 0.7.23, DSPy 3.4.1, sentence-transformers 6.2.0, and mistune 3.4.0. The index uses
sentence-transformers/all-MiniLM-L6-v2. The model runs locally, so retrieval needs no API key. The answer step below calls dspy.LM('openai/gpt-4o-mini'), which reads OPENAI_API_KEY. Other providers use the same call with a different model string (connecting a language model).Install
Pixeltable needs Python 3.11 or later.sentence-transformers pulls in PyTorch. On a machine without a GPU, install the CPU wheel first, or pip fetches a CUDA build that can be several gigabytes:
all-MiniLM-L6-v2. mistune parses the Markdown files in the next section.
Build the chunk index
The script creates the directory, the document table, the chunk view, and the index. It deletes an existingdspy_rag directory first, including its rows, so you can run it again.
An application file declares the same table, view, and index. In a new folder, pxt init writes pixeltable.toml and marks the project root. pxt schema update creates dspy_rag.docs and dspy_rag.chunks. The app file declares only those two, so pxt schema prune would drop the runs table created later on this page. Running docs.insert() again duplicates the documents, since only the script clears the directory.
- Script
- Application file
separators='paragraph' yields one chunk per Markdown paragraph.
Insert the documents
topic is metadata on the document. The chunk view includes it, so a later where clause can limit retrieval to one topic. The two files are the corpus:
Retrieve passages
search() orders chunks by similarity() and returns at most k texts. topic adds a where clause on the document’s topic column.
Filter on a column
The same function withtopic set drops every chunk from the other documents. A question about how bees share the location of flowers returns the waggle-dance chunk. The same question with topic='pixeltable' returns the chunk about a where clause limiting the ranking to one collection:
where clauses: Queries and expressions.
Answer from the passages
RAG is a dspy.Module. forward() retrieves, then dspy.ChainOfThought reads context and question and writes response. The module also fills reasoning. Run export OPENAI_API_KEY=... first.
Inserts update the index
Insert another document. The view adds a chunk for the new paragraph, and the embedding index adds its vector. The next call tosearch() returns that chunk.
ChainOfThought.
Store the answer
To keep a DSPy answer, write the question and the response into a table:Embedding indexes
Declare an index and rank rows with similarity().