What reusable modules look like — and why you should build them
Once you’ve shipped a few projects, patterns emerge. You write the same notification logic, the same data-pulling code, the same scraping setup. Every time from scratch. That’s wasted work. Package common patterns into reusable modules. One import, any project. The second project that uses a module is where you start getting leverage. Your stack will look different based on what you’re solving for — the examples below are the pattern, not the prescription
If AI can write code on the fly — why build anything reusable?
| Dimension | AI-Generated (per session) | Packaged Module |
|---|---|---|
| State | Gone when conversation ends | Persistent credentials, connections |
| Errors | AI decides whether to retry | Backoff, logging, alerts |
| Composition | Re-derived every session | Same interface every time |
| Autonomous | Needs active conversation | Cron jobs, background workers |
| Testable | Output varies by prompt | Deterministic, CI-friendly |
Your stack gives your agents both a vocabulary and a set of imports. There are two ways to get leverage from it
| Mode | How it works | Prompt shape |
|---|---|---|
| Name the rails | You already know your modules, so you speak in their names. The agent can stop guessing at architecture and operate on infrastructure you understand | Update Olympus Echo to do X, then use Olympus Aegis to lock that feature behind academy access |
| Add intent hooks | As you build, give the system hooks that map plain-English intent to existing infrastructure. The agent hears what you want, checks what already exists, and reaches for the right module before writing new code | When I ask to notify the cohort, route through notifications. When I ask to lock a page, check auth groups. When I ask to run it every morning, create a scheduled job |
Over time, the prompt changes. You stop asking for code in the abstract and start asking the system to use the layers you already have. Sometimes you name the layer directly. Sometimes you teach the stack enough intent that the agent can find it for you
The most important architectural decision you'll make is what not to build. Don't reinvent the wheel
pip install and npm install give you access to millions of hours of other people's work. Learning to evaluate, install, and compose open-source tools is a core engineering skillEach module is standalone — pip install and go. The pattern matters more than the naming
| Module | What it does | Why you'd build it |
|---|---|---|
| Notifications | Route messages to Slack, email, SMS | Every app needs to tell you when something happens |
| Data Feeds | Adapters for external APIs (market data, weather, CRM) | Normalize many sources into one interface |
| Scraping | Extract data from any website | Write the retry + rate-limit logic once |
| Inference | Call LLMs, TTS, image gen through one interface | Swap providers without changing app code |
| Search | Index content, keyword + semantic retrieval | Every app with data needs findability |
| Auth | Login, sessions, role-based access | Shared across all your web apps |
from your_toolkit.notifications import send_alertfrom your_toolkit.data import get_pricefrom your_toolkit.scraper import extract
Analyze AAPL, GOOGL, MSFT stocks and generate a deck. One pipeline. Data → analysis → report → deliver
| Step | Module | What happens |
|---|---|---|
| 1. Pull data | Data Feeds | Fetch from 3 APIs, normalize into one format |
| 2. Analyze | Your app logic | Transform, filter, calculate — this is where your domain expertise lives |
| 3. Generate output | Templates (Jinja2) | Render HTML report or PowerPoint deck from the data |
| 4. Deliver | Notifications | Email the deck, post to Slack, update a dashboard |
Four steps. Three modules. The analysis in Step 2 is where your thinking lives. Everything else is infrastructure that shouldn’t be rewritten every time
That pipeline used three simple modules. Some modules are complex enough to deserve their own deep dive — search is the most common. Almost every production app needs it, and the implementation choices compound across everything you build
| Pattern | How it works | When to use |
|---|---|---|
| Keyword (BM25) | Match query tokens against indexed documents | Structured data, exact term matching, Postgres full-text search |
| Semantic (Vectors) | Embed text into vectors, find nearest neighbors by cosine similarity | Natural language queries, “find similar”, RAG pipelines |
| Hybrid | Run both, merge and re-rank results | Production systems where you need both precision and recall |
from your_toolkit.search import index, query# Index your content onceindex(documents, method="hybrid") # keyword + vector# Query naturallyresults = query("how do I deploy to production", top_k=5)
This is the same pattern behind every AI chatbot, knowledge base, and recommendation engine. Wrap the embedding model, vector store, and retrieval logic into one module. Your app just calls query()
Search is one module. Combine it with data feeds, notifications, auth, and templates, and full applications start to feel assembled
| Application | Modules used | What it does |
|---|---|---|
| Market Report | Data Feeds + Templates + Notifications | Pulls market data, generates a deck, emails it to the team every morning |
| Outbound Engine | Scraping + Notifications | Scrapes contacts from the web, enriches them, runs multi-channel outreach |
| Internal Tool | Auth + Database + Templates | Configurable dashboards with login, persistent state, and role-based access |
| Knowledge Base | Search + Inference + Database | Index company docs, search semantically, answer questions with LLM + retrieved context (RAG) |
Four applications, four different module combinations. The modules are interchangeable — swap data feeds for scraping, swap templates for a dashboard, and you have a different product built on the same infrastructure
Those four are starting points. Here’s a broader set — each project exercises different layers and teaches different skills. Pick one that maps to a problem you actually have
| Build This | Layers | What You Learn |
|---|---|---|
| Daily market report emailer | Data feeds + Jinja2 + SMTP + cron | API adapters, HTML templating, scheduled jobs, email delivery |
| Internal dashboard with login | Flask + Postgres + Auth + Dokku | CRUD, session management, role-based access, deployment |
| Outbound recruiting engine | Web scraping + enrichment + email sequences | Rate limiting, data normalization, multi-step pipelines |
| Knowledge base chatbot (RAG) | Embeddings + pgvector + LLM + FastAPI | Chunking, vector search, prompt engineering, streaming |
| PDF report generator | pdfplumber + openpyxl + Jinja2 + click CLI | File parsing, data extraction, templated output, CLI design |
| Webhook-driven Slack bot | Flask + Slack SDK + background workers | Event-driven architecture, async processing, API integration |
| Automated video pipeline | TTS API + moviepy + upload APIs + cron | Media processing, API orchestration, multi-platform distribution |
| Prediction market trading bot | Market data feeds + strategy engine + risk mgmt + Postgres | Real-time data, state machines, financial logic, observability |
| People search system | Postgres + pgvector + NL parser + Flask | Schema design, hybrid search, hard/soft constraint ranking |
| CI/CD pipeline from scratch | GitHub Actions + Docker + nginx + Let's Encrypt | Containers, automated testing, zero-downtime deploys, SSL |
The specific tools matter less than the pattern. Every system is a composition of the same layers: data in, logic applied, output delivered. Level Up teaches the vocabulary. Building these teaches the muscle memory
Haven't read the foundation yet?
Level Up →