pi-tutorial: The Tutorial That Teaches the Agent to Teach You

A guided onboarding extension for Pi that turns conversation history into state, uses the model as the evaluator, and ends by showing you how to build the next extension.

8 min read • View on GitHub • More from earendil-works

A terminal stage with a learner at the prompt and an agent behind a lectern marked STEPS. A corridor of doors labeled intro, chooseApp, planning, buildApp, and extension recedes into the background, then loops back to the same stage. The image explains that onboarding is both guided and recursive, with the final lesson turning the tutorial back on itself.
The tutorial is also the platform lesson. The final step points back to the mechanism that is teaching it.

Here is a little experiment: an interactive pi tutorial. Make an empty folder, then run this: pi -e git:https://t.co/gIUIPBgDMT And give feedback! Reason: pi works best if you have an onboarding buddy. But if you don't have one, maybe pi can be one for you? https://t.co/QptT78I

Armin Ronacher, mitsuhiko · @mitsuhiko on X
Key Takeaways

A tutorial that ends by explaining itself

Most tutorials tell you what to do. pi-tutorial does something stranger and more useful: it teaches the agent to watch your progress, grade the step, and then teach the next one. The final lesson is not a victory lap. It is a pointer to the extension system itself.

A WSJ-style hedcut portrait of Armin Ronacher, based on his verified GitHub avatar. It suggests the experimenter's role behind the tutorial without turning the piece into a personality profile.

The agent is the grader

The core move is a tiny one. The tutorial defines a set of named steps, each with a hint and a completion message, then gives the model a tool called mark_step_done. The LLM is not just answering questions. It is deciding when a step is complete.

const STEPS = {
  intro: {
    hint: 'The user understands what Pi is and how the onboarding flow works.',
    completionMessage: 'Intro complete, move to chooseApp.'
  },
  chooseApp: {
    hint: 'The user has picked a small app idea to build.',
    completionMessage: 'Choice made, move to planning.'
  }
};

async function mark_step_done(stepName: string) {
  // Called by the agent when the rubric says the learner is ready.
}

This diagram shows the trick: the tutorial does not store progress separately. It derives progress from events already in the session log.

A ledger page filled with conversation entries and stamped milestones. Some rows are marked complete while a hand labeled reconstructCompletedSteps traces backward through the log. The image explains that completion is inferred from history instead of written to a separate database.
The session log is the state machine. The function just reads it carefully enough to rebuild the path.

That design does two things at once. It makes onboarding feel conversational, and it avoids a separate persistence system. Instead of saving a progress blob somewhere else, pi-tutorial treats the chat history as the source of truth and reconstructs the tutorial state when needed.

History becomes state

This is the repo’s sharpest idea. The function often described as reconstructCompletedSteps scans ctx.sessionManager.getEntries(), looks for successful mark_step_done events, and rebuilds the current position from that trail. The result is stateful behavior without a dedicated database, file watcher, or checkpoint file.

function reconstructCompletedSteps(entries) {
  const done = new Set();

  for (const entry of entries) {
    if (entry.type === 'tool' && entry.name === 'mark_step_done' && entry.ok) {
      done.add(entry.args.stepName);
    }
  }

  return done;
}

That is a small amount of code with a big consequence. Reload the session and the tutorial does not forget. It replays the record. The conversation is not just a transcript. It is the event log.

Why Pi makes this possible

This repo only works because Pi is built around primitives, not a heavy opinionated app shell. Its extension model, TUI stack, and minimal core make room for workflows that feel like products without needing a separate framework for every idea.

Pi represents a philosophy: coding agents should provide primitives, not opinions. With only 4 tools and the shortest system prompt in the space, it's the anti-bloat alternative to feature-heavy competitors.

Ry Walker, Researcher · Pi Coding Agent | Ry Walker Research
ApproachProgress detectionState locationReload behaviorCan teach the tool itself?
Traditional docs tutorialManual readingNone or external notesUser restarts by handNo
File watcher or test flowFiles, tests, or scriptsDisk or CIUsually brittleRarely
Static AI promptAd hoc model judgmentPrompt onlyForgets context fastNo
pi-tutorialLLM-assisted completion eventsConversation historyReconstructed from the session logYes

That comparison is the whole point. The project is not competing with a README. It is proving that a minimal agent can host a guided experience that feels alive, remembers where you are, and teaches you how to extend it.

What this approach beats, and what it risks

The upside is obvious once you see it. The tutorial adapts to the learner, survives reloads, and avoids a pile of scaffolding. The trade-off is just as real: if the model is the grader, the rubric has to be clear, and borderline completions can feel fuzzy.

That is not a bug in the design. It is the design. The tutorial is deliberately model-mediated, so the lesson is conversational rather than mechanical. You get flexibility, but you also accept judgment.

A blueprint for agentic onboarding

The deeper lesson is larger than Pi. Any agentic tool can borrow this pattern: make the tutorial a living workflow, let the model evaluate progress, and let the session itself carry the memory. That turns onboarding into part of the product instead of an afterthought.