How Phases Are Ordered and Prerequisite Lesson Dependencies Work in AI Engineering from Scratch
In the rohitg00/ai-engineering-from-scratch curriculum, phases are ordered numerically from 00 to 19 in the phases/ directory, while lesson prerequisites are declared in each lesson's docs/en.md frontmatter using a structured format like "Phase 2 · 14 (Naive Bayes)" that the CI validates as a directed acyclic graph.
The repository structures a self-contained AI engineering learning path through rigid file naming conventions and explicit dependency declarations. Understanding how phases are ordered and how prerequisite lesson dependencies are encoded is essential for navigating the curriculum or contributing new content. The system enforces these relationships automatically through validation scripts that prevent logical gaps or circular dependencies.
Phase Ordering via Directory Structure
The curriculum lives under the top-level phases/ directory. Each subfolder uses a two-digit numeric prefix that defines the chronological learning path, starting at 00-setup-and-tooling and ending at 19-capstone-projects.
Because the directory names begin with zero-padded numbers, a simple lexical sort yields the correct sequence. The intermediate phases follow this pattern:
00-setup-and-tooling– Environment preparation01-math-foundations– Linear algebra and calculus02-ml-fundamentals– Linear regression and decision trees- ...
19-capstone-projects– End-to-end integration projects
The canonical ordering is documented in ROADMAP.md, which serves as the master reference table. As implemented in the phase_order() function within the repository's tooling, the sequence is generated by matching directory names against the pattern \d\d- and sorting them alphabetically.
Declaring Lesson Prerequisites in Frontmatter
Every lesson resides in a leaf directory containing a docs/en.md file. This markdown file begins with frontmatter that includes a Prerequisites field using the syntax:
**Prerequisites:** Phase X · Y (Lesson Title)
For example, the text processing lesson in phases/05-nlp-foundations-to-advanced/01-text-processing/docs/en.md declares:
**Prerequisites:** Phase 2 · 14 (Naive Bayes)
The format supports several dependency types:
- Cross-phase requirements –
Phase 3 · 02 (Backpropagation)references phase 3, lesson 2 - Multiple prerequisites – Comma-separated lists like
Phase 1 · 08, Phase 2 · 05 - Intra-phase dependencies – Lessons within the same phase referencing each other
The middle dot (·) serves as a standard delimiter between the phase number and lesson number, making the string parseable by the validation tooling.
Automated Dependency Graph Validation
The repository treats curriculum dependencies as a directed acyclic graph (DAG) that must be validated continuously. The scripts/audit_lessons.py script runs in CI to parse prerequisite declarations from every docs/en.md file.
The validation process extracts phase and lesson numbers using regex patterns, then verifies that:
- Referenced prerequisites exist as actual files
- No circular dependencies exist (e.g., lesson A depending on lesson B which depends on lesson A)
- Prerequisites do not reference future phases or lessons that occur later in the sequence
This automated enforcement prevents contributors from introducing lessons that depend on future content or creating logical gaps in the learning path. If the DAG validation fails, the CI build prevents the pull request from merging.
Parsing Prerequisites Programmatically
You can extract the dependency graph using Python to analyze the curriculum structure. The following script demonstrates how the repository tooling reads the roadmap and extracts prerequisite relationships:
import pathlib
import re
ROOT = pathlib.Path(__file__).parent.parent
def phase_order():
"""Return a list of phase folder names in canonical order."""
# The folder names already encode the order.
return sorted(p.name for p in (ROOT / "phases").iterdir()
if p.is_dir() and re.match(r'\d\d-', p.name))
def parse_prereq(frontmatter: str) -> list[tuple[str, int]]:
"""Parse the '**Prerequisites:**' line into (phase, lesson) tuples."""
m = re.search(r'\*\*Prerequisites:\*\*\s*(.*)', frontmatter)
if not m:
return []
raw = m.group(1)
deps = []
for part in raw.split(','):
match = re.search(r'Phase\s*(\d+)\s*·\s*(\d+)', part)
if match:
deps.append((f'{int(match.group(1)):02d}', int(match.group(2))))
return deps
def collect_lessons():
"""Yield (phase, lesson, prereqs) for every lesson."""
for phase_dir in (ROOT / "phases").iterdir():
if not re.match(r'\d\d-', phase_dir.name):
continue
phase_id = phase_dir.name.split('-')[0]
for lesson_dir in phase_dir.rglob('docs/en.md'):
with open(lesson_dir) as f:
text = f.read()
prereqs = parse_prereq(text)
lesson_id = int(lesson_dir.parent.name.split('-')[0])
yield (phase_id, lesson_id, prereqs)
if __name__ == "__main__":
print("Phase order:", phase_order())
for phase, lesson, deps in collect_lessons():
print(f"Phase {phase} – Lesson {lesson:02d} → {deps}")
The parse_prereq function uses regex to capture the Phase and Lesson numbers, handling the middle dot delimiter and multiple prerequisite declarations. Running this script outputs the complete DAG of dependencies, which mirrors the validation performed by scripts/audit_lessons.py.
Summary
- Phases are ordered numerically from
00to19in thephases/directory using zero-padded prefixes - Prerequisites are declared in
docs/en.mdfrontmatter using the format "Phase X · Y (Title)" - The
scripts/audit_lessons.pyCI tool validates the dependency DAG and prevents circular references - Lexical sorting of directory names produces the correct learning sequence without additional configuration files
Frequently Asked Questions
What is the correct order of phases in ai-engineering-from-scratch?
The phases follow a zero-padded numeric sequence from 00 (setup-and-tooling) through 19 (capstone-projects), with intermediate phases covering math foundations, ML fundamentals, deep learning, NLP, and other topics. This order is enforced by the two-digit prefix in each phase directory name, and a simple ls phases/ command lists them in the correct learning sequence.
How do I specify that my lesson requires knowledge from a previous phase?
Add a Prerequisites line to your lesson's docs/en.md frontmatter using the format Phase X · Y (Lesson Name). For multiple prerequisites, separate them with commas. The CI will validate that these lessons exist and that you are not creating circular dependencies or referencing future content.
What happens if I create a prerequisite that points to a non-existent lesson?
The CI will fail because scripts/audit_lessons.py validates that every prerequisite string references an actual file in the repository. If the validation script cannot find the corresponding docs/en.md file for the phase and lesson number you specified, the build will fail and prevent the merge of your pull request.
Can a lesson in phase 10 depend on a lesson from phase 5?
Yes, cross-phase dependencies are fully supported and expected. The prerequisite syntax Phase 5 · 12 (Lesson Name) explicitly allows lessons to reference content from any previous phase, enabling the curriculum to build upon foundational concepts introduced earlier in the learning path while maintaining strict forward-only dependencies.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →