MARGINALIA.PRG

2023-06-19 → 2023-08-03 · 39 commits · solo · PUBLIC

WHAT IT IS.

Marginalia is a retrieval-augmented Q&A service over a private microeconomics course corpus I used for study. The repository was originally named brian_gpt and is now public as marginalia. A Tornado server routes chat, question-answering, database and search requests to separate handlers, with a React client for conversation and source navigation. Postgres with pgvector holds the embedded document chunks; LangChain coordinates retrieval and answer generation. The history includes transcript processing, embeddings, chat revisions, Docker packaging and a search interface. A sibling q_and_a directory contains a containerized variant of the service; the archive establishes its structure, while current deployment status is outside this devlog's scope. Course material and persona prompts remain private. This 2023 project is distinct from the later industrial-organization paper-study workflow.

THE ARC.

The opening day is one of the most compressed in the journal: Parsed first time builds the transcript-processing path, followed by Output.json retouch, Computed embeddings, and Basic Q&A with pgvector — four substantive commits from source material to a working retrieval loop. The repo then sits quiet for three weeks.

Return: Working, Review continued, then two Rearrange commits 30 seconds apart moving files before the refactor. Hardening week: refactoring, Refactoring chat, UI is usable, QA handler OK. Docker push follows: Q&A working fine, Docker build, Improved logging (qa_handler rewritten). Final stretch: updated question prompts (chunking and prompts getting their first real audit), added lint, custom query (custom_query.jsx 219 lines in), Fixed in docker images, and the closing commit Search (search_handler.py +76 in, notebooks/explore.ipynb -354 lines of dead exploration retired). The q_and_a fork reuses the server-side handler skeleton with a built dist/ bundle — same lineage, containerised.

The architecture: server.py is the Tornado router; qa_handler.py is where the LangChain chain lives (MapReduce retriever over pgvector; the lecture-PhD persona prompt is intentionally not shown); db_handler.py owns the pgvector connection via psycopg/psycopg_pool. On the client, chat.jsx is the conversation, question.jsx the suggested questions, custom_query.jsx the user-typed retrieval, navigator.jsx the file-source list. notebooks/explore.ipynb is where chunking and prompt-template choices were actually made — the production scripts are the trimmed residue.

Stack chips: Tornado · LangChain (community + core) · pgvector · psycopg/psycopg_pool · OpenAI · tiktoken · unstructured · pydub · PyPDF2 · ebooklib · BeautifulSoup4 · spacy · Redis · React · SCSS · ESLint · concurrently · Docker.

WHAT I LEARNED.

  • Chunking policy and the teaching voice were the main levers. The first day proved that a modest retrieval pipeline could become useful quickly; the later revisions show how much work remained in context selection and answer behavior.

  • The notebook was the workshop: notebooks/explore.ipynb is where chunking, prompt-template and reducer choices were tested; the production scripts are the trimmed residue.

  • The search handler made retrieval inspectable in the UI. That turned prompt changes from blind tuning into something I could diagnose against the retrieved material.

[ DEODORO ] > CODE / marginalia EJECT → SHELF