portfolio

Shipped
in public_

Nine projects, one screen each: agents with evals and approval gates, MLOps pipelines, streaming, and the products around them, one of them on the App Store. Then every public repository, with its link. The colour of the page is the project you are on.

22 public repositories 9 told in full 5 live, one on the app store python · typescript · swift · r · sql

scroll

01agent · retrieval · evals

An assistant that cites its sources and admits what it does not know

novamart-assistant-agent · Python, TypeScript · Google ADK, Gemini, FastAPI, React, Terraform

An internal support assistant for store employees. It answers policy questions grounded in company documents with a citation on every fact, looks up live order status through an internal API, and refuses when the documentation does not cover the question, logging every refusal as a documentation gap for the policy team.

One entry point serves the CLI, the HTTP API and the evaluation harness, so what gets evaluated is exactly what users get. Deployed with Terraform on Cloud Run, scale-to-zero.

  • google adk
  • gemini
  • hybrid retrieval (bm25 + embeddings)
  • fastapi
  • react
  • llm-judged evals
  • terraform
  • cloud run
agent_service.py · one entry point, three callers
react chat ─┐                          ┌─ search_knowledge_base  bm25 + embeddings
cli chat   ─┼─▶ AgentService ─▶ ADK agent ─┼─ get_order_status      internal OMS
eval suite ─┘                          └─ knowledge-gap log    every refusal
                                     ▼
                       answer + per-fact citations
                       or: "the documentation does not cover this"

corpus   8 policy documents · 37 chunks
judge    LLM-as-judge over 19 cases, against the same service
19eval cases, llm-judged
per-factcitations
0 → Nscale-to-zero on cloud run

02multi-agent · safety

Five agents, one supervisor, and a veto no model can override

multi-agent-healthcare-triage · Python · OpenAI Agents SDK

An after-hours tele-triage prototype on synthetic data. Intake, risk, specialist and scheduler agents work over a shared blackboard under a supervisor that owns the disposition. The risk screener is structurally separate from the specialist, so one model's error cannot silently suppress a red flag, and the acuity is locked by code, not a model.

Anything at ESI 2 or above, or any red flag, stops at a human-clinician approval gate. Four levels of evaluation, from schema validity to end-to-end dispositions. Decision support, not a medical device.

  • openai agents sdk
  • supervisor + blackboard
  • independent risk veto
  • deterministic safety engine
  • human approval gate
  • mcp tool
  • four-level evals
topology · star, supervisor-mediated
                    SUPERVISOR (code: routing, veto, gate)
                          │
      ┌───────────┬───────┴────────┬──────────────┐
   intake      risk screener    specialist     scheduler
  narrative    red-flag screen   differential    capacity
      │        INDEPENDENT VETO   (advisory)         │
      └───────────┴────────────────┴──────────────┘
                          ▼
              blackboard · CaseFile  typed messages, one writer per section
                          ▼
         acuity locked by code ─▶ ESI ≤ 2 or red flag ⇒ a clinician approves
ESI 1–5disposition
4evaluation levels
humangate on high acuity

03single agent · guardrails

A course advisor that knows when to stop and ask a human

single-agent-sdk · Python · OpenAI Agents SDK

One agent over a small, fully visible world: eleven courses, a prerequisite table, a student profile, six policy rules. It checks prerequisites and policies with deterministic typed tools and returns a typed recommendation with risks, an approval flag and next steps.

Ask for something blocked and the run literally pauses for an advisor's approval. Try to talk it into bypassing policy and a named input guardrail trips. Traces and evals ship with it, plus the wiki of design notes that justifies every choice.

  • openai agents sdk
  • typed tools
  • structured output
  • input guardrail
  • approval escalation
  • traces
  • evals
one turn · what the model decides, what code decides, what a human decides
  "I'd like to add INSY 662 this winter. Is that all right?"
                  │
        input guardrail ── bypass attempt? ──▶ blocked POLICY_BYPASS_OR_OUT_OF_SCOPE
                  │
        agent ─▶ check_prerequisites()  deterministic
              ─▶ check_policies()       deterministic
                  │
        typed CourseRecommendation { courses, risks, requires_approval, next_steps }
                  │
        requires_approval ─▶ run pauses · advisor approves or declines
11courses in the fixture world
6policy rules
pauseon anything blocked

04mlops · forecasting

Fifteen-minute demand for every bike station in Montréal

bixi-demand-mlops-platform · Python · LightGBM, XGBoost, FLAML, Optuna, MLflow, AWS CDK · team of four

A course notebook turned into a resumable, cloud-native pipeline: departures and arrivals forecast separately for 1,100+ BIXI stations at 15-minute resolution, then combined into a net-flow rebalancing list of the stations about to run empty or overflow.

Leakage-safe features, target encoding fit on train only, multi-model selection with AutoML and Bayesian tuning, SHAP and LIME explainability, a fairness report, four kinds of drift monitoring, an MLflow registry, and the AWS stacks as code. Built with Rui Zhao, Ruihe Zhang and Sarah Liu.

  • lightgbm · xgboost
  • flaml automl
  • optuna
  • mlflow registry
  • shap · lime
  • drift monitoring
  • aws cdk
  • streamlit · fastapi
python -m bixi.pipeline --from ingest --targets both
 ingest ─▶ data ─▶ train ─▶ explain ─▶ fairness ─▶ drift ─▶ register
   │        │        │          │           │          │           │
 trips    15-min   lgbm/xgb   shap       report    feature      mlflow
 weather  features + flaml    lime                 target       alias:
          leave-   + optuna                        prediction   production
          one-out  best by                         concept
                   val rmse

 s3://insy684/  persistent source + backups     s3://<cdk bucket>/  run outputs, torn down
 stacks: BixiNetwork · BixiStorage · BixiMlflow · BixiBatch · BixiServe
1,100+stations
15 minresolution
×2departures and arrivals

05reinforcement learning

An agent that orders stock, and a baseline it is not allowed to cheat

deep-reinforcement-learning-retail-inventory-decisions · Python · Gymnasium, Stable-Baselines3

Single-product retail replenishment as a Markov decision process: lost sales, a lead time, stochastic demand. The headline agent is tabular Q-learning; the stretch agent is PPO. Both are judged against a tuned (s, S) policy that sees the same information, because beating a random policy proves nothing.

The write-up reports the numbers straight, including the discretization cost the tabular agent pays by design, and ends with the call a business would need: deploy, shadow, or reject.

  • mdp design
  • tabular q-learning
  • ppo
  • gymnasium
  • stable-baselines3
  • (s, s) baseline
  • seeded evaluation
results/metrics.json · 5 held-out seeds × 200 episodes · mean episodic profit
 policy                          profit        service   role
 ─────────────────────────────   ──────────    ───────   ─────────────────────────
 random                            540 ±  4     0.982    lower bound
 binned (s,S) = (20,30)          1461 ±  5     0.985    the fair bar (same state bins)
 q-learning (headline)          1432 ± 11     0.954    learned, off-policy
 exact (s,S) = (22,33)            1495 ±  5     0.975    headroom (finer state)
 ppo (stretch)                   1538 ±  8     0.960    learned, on-policy

 q-learning: 2.65× random · 95.8% of the exact tuned policy
99tabular states
2.65×over random
honestbaseline, seeded

06streaming · data engineering

Avro events from Kafka to Spark, in batch and as a stream

kafka-spark-streaming · Python · Confluent Cloud, Schema Registry, Databricks

A custom Avro schema registered in the Confluent Schema Registry, a producer that publishes events to a Kafka topic, and a Databricks notebook that reads the topic two ways, batch and structured streaming, decodes the Confluent wire format, transforms, re-encodes, and writes to a sink topic.

The tricky bit, documented so nobody has to rediscover it: Confluent does not put a bare Avro payload on the wire. Every message carries a magic byte and a schema id before the record.

  • apache kafka
  • confluent cloud
  • avro + schema registry
  • spark structured streaming
  • databricks
the confluent avro wire format
 src/produce.py            topic "kafka"           spark on databricks          topic "kafka_stream_out"
 20 Purchase events  ──▶   confluent cloud   ──▶   batch read + decode     ──▶   spark-written,
 avro-encoded                                     stream read + decode          avro-encoded
                                                  transform, re-encode

 on the wire, every message is:
 [ 1 magic byte 0x00 ][ 4-byte schema id, big-endian ][ avro binary payload ]
2read modes: batch, stream
1schema, registered
5 bytesthe header everyone forgets

07local llm · mcp

A calendar you can talk to, and nothing leaves the laptop

ai-calendar-assistant · Python · Ollama, Google Calendar API, Model Context Protocol

Natural-language calendar management with Llama 3.2 running locally through Ollama. A Model Context Protocol server exposes seven calendar tools (list, today, create, search, update, delete, availability) over OAuth2, so the same server also plugs into Claude Desktop and any MCP client.

No API cost, one to two second answers, and the only thing that touches the internet is the calendar sync itself. The most-starred repository on the account.

  • ollama · llama 3.2
  • model context protocol
  • google calendar api
  • oauth2
  • rich terminal ui
calendar_server.py · seven tools over mcp
 terminal ──▶ mcp client ──┬──▶ ollama · llama 3.2 3b   intent, orchestration, answer
                            │
                            └──▶ calendar mcp server
                                   list_events · get_today_events · create_event
                                   search_events · update_event · delete_event
                                   check_availability
                                          │  oauth2
                                          ▼
                                   google calendar
7tools over mcp
localmodel, no api key
★ 5on github

08product · ml

Which Montréal listing pays for itself on Airbnb

cashflow-mtl · JavaScript, Python · React, Flask, scikit-learn

A real-estate investment analyzer: add a property from Centris, get a revenue forecast from a random forest trained on 8,500 Montréal Airbnb listings, then cash-on-cash return, cap rate, monthly cash flow, a five-year projection, and a bank-ready PDF business plan.

The whole stack in one repository: a React dashboard, a Flask API, the model, the scraper. The model's numbers are printed where a lender would look for them.

  • react
  • flask
  • random forest
  • selenium · beautiful soup
  • pdf reports
model card
 model        random forest regression
 training     8,518 montréal airbnb listings
 features     latitude · longitude · bedrooms · bathrooms · square footage
            0.63
 mae          $486 / month

 listing ──▶ forecast revenue ──▶ cash-on-cash · cap rate · monthly cash flow · 5-year projection ──▶ pdf
8,518listings
0.63
pdfbank-ready plan

09product · ios

A habit tracker on the App Store, and the studio behind it

Easy Habit Tracker · Swift, SwiftUI, Core Data · published under Datify

One-tap logging, streaks, insights, unlimited habits, and nothing ever leaves the device: no accounts, no analytics, no ads. Shipped end to end, from the first Swift file to App Review.

Published under Datify, the small software studio I run for startups and small businesses at godatify.ai, where this app sits in the portfolio next to the client work.

  • swift
  • swiftui
  • core data
  • app store
  • privacy-first
listing
 app          Easy Habit Tracker
 platform     iOS · App Store
 stack        Swift · SwiftUI · Core Data
 data         on-device only · no accounts · no analytics · no ads
 studio       Datify · godatify.ai

 open ──▶ tap the habit ──▶ streak +1 ──▶ insights, when you want them
1 tapto log a habit
0 bytesleave the phone
habits, free

the rest of the account

Every other public repository

Coursework, hackathons, side projects and one App Store app. Each card is the repository.

microsoft-fabric-lakehouse-to-dashboard

Medallion pipeline on Microsoft Fabric: PySpark notebooks, Delta Lake bronze, silver and gold, a SQL warehouse and a Power BI dashboard, ready to deploy.

notebookspyspark · delta · power bi★ 1

quality-stream

Every HCPCS code per provider across Medicare and Medicaid: a chunked DuckDB pipeline over six gigabytes of CMS public claims, plus a Next.js provider report.

notebooksduckdb · next.js

doc_intel_pipeline

Legal document intelligence: ingest PDFs, classify, extract structured fields with Pydantic, across OpenAI, Gemini and local models orchestrated by LangGraph, prompts tuned with DSPy.

pythonlanggraph · dspy · pydantic

fulcrum-ai-agent

A LangGraph market-analysis agent for copper futures that fuses a Databricks lakehouse, Yahoo Finance and the U.S. EIA API, and reports exactly which tools it called.

notebookslanggraph · databricks★ 1

agentic-financial-analyst

Databricks hackathon entry: a financial-analyst agent with smart routing across metrics, M&A and SWOT tools, foundation-model insights, and a rules-based fallback when the LLM is down.

pythondatabricks · yahoo finance★ 1

insy669-glp1-text-analytics

Media versus public opinion on GLP-1 weight-loss drugs: Reddit, WebMD and Google News through a nine-stage NLP pipeline, reproducible in four commands. Team of five.

notebooksnlp · sentiment · topics

nwa

Six-month customer lifetime value: an end-to-end pipeline with SHAP explainability, causal inference with CausalML, segmentation and monitoring artifacts. Team of three.

notebooksclv · shap · causalml

capstone_uc3

Procurement signal stability and strategy optimization dashboard, the third use case of the McGill capstone with CAE, in Next.js.

typescriptnext.js · dashboard

airbnb_ml_price_prediction

Montréal Airbnb price prediction: the notebook, the random forest, and a Streamlit app with model performance, a price estimator and feature importance.

notebooksrandom forest · streamlit

time_series_forecasting

Time-series forecasting coursework in R.

r

logistic-regression-startup-exits

A logistic-regression model of which startups exit.

notebooks

final_submission_folder_OZ

A final course submission in R.

r

centris_chatbot

A chatbot over Centris real-estate listings.

python

also on the account: seven forks of course exercises (IBM full-stack, git, express, react), not listed because they are the course's work, not mine.