A skeleton pipeline that already runs end to end
Replace retrieve with a version that returns the last chunk instead of the first and see the sources change.
Before writing code, decide what the tool must do and how its parts fit. You will plan docqa, a tool that answers questions about a folder of text documents, with requirements, an architecture, typed data classes and interfaces, and a project layout.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 6 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Write a frozen dataclass Source with doc (str) and index (int), and show that two equal sources compare equal and can be put in a set.
Write a Protocol called Scorer with a method score(self, question: str, text: str) -> float, and a class that satisfies it by counting shared words.
Write a function load_texts(folder) that returns a dict from file name to text for every .txt file in a folder, sorted by name. Test it by creating a folder with two files.
Explain it without notes
What is retrieval-augmented generation, and why not just give the model the whole folder?
Why define Protocols and frozen dataclasses before writing the implementations?
Why build a stub pipeline first?
How would you decide what is in scope for the first version of a tool like docqa?
Expected output
stub answer using 1 source(s) | sources: ['a.txt']
stages in order: load -> chunk -> retrieve -> model