Why generateLearningPath() makes zero LLM calls
The obvious design for a "AI-powered learning path generator" is to call an LLM. Pass the user's role, tools, and goal to Claude or GPT-4, prompt it to generate a 4-week curriculum, and stream the response. We seriously considered this. We did not build it.
The core problem is trust. A stochastic function cannot be unit-tested, cannot be audited, cannot be reproduced. Every time a PM at a company configures a learning path for their team, they need to know what they are getting. Not "roughly this". Exactly this. If the same input produces different output on Tuesday than it did on Monday, something went wrong - even if both outputs are technically good.
So generateLearningPath() is a pure function. A djb2 hash of the input produces stable lesson IDs across runs. The week structure, lesson count, and durations are computed deterministically from the role, level, and tools. You can test it with Vitest. You can snapshot it. You can pin a version and know that every engineer who joins your team will get the same week one as the engineer who joined six months ago.
The tradeoff is expressiveness. A pure function cannot write prose as varied as GPT-4, cannot adapt to a user's previous session history, cannot interpolate from a corpus of real practitioners' notes. We accepted that tradeoff. Version 0 of LearnKit AI ships zero LLM calls and zero API keys. The AI Guide component is a UI primitive, not a live model. If you want LLM personalization on top, the hook-based API makes it easy to swap in your own inference layer.
This is the right first trade. Build the substrate deterministic and testable, then add stochasticity where the variance is a feature, not a bug.