Mohammad Nazrul Ansari
AI Engineer & Full-Stack Developer
Mumbai, India · Dubai, UAE — available for interviews now (remote/video); can relocate to the UAE within 15 days
Profile
AI & Full-Stack Engineer with 5+ years of experience building and deploying production-grade LLM applications, AI agents, algorithmic trading systems and scalable web platforms. Experienced in designing end-to-end AI solutions using Python, FastAPI, LangChain, LangGraph, OpenAI, Claude and Next.js — from backend architecture to intuitive user interfaces. Also builds classical machine learning and data systems end to end: distributed PySpark feature pipelines over millions of records, gradient-boosted models tracked in MLflow, probability calibration, cost-weighted decision thresholds and drift monitoring. Built products across HealthTech, FinTech, Real Estate and SaaS, while also delivering secure Web3 applications, smart contracts and token standards. Contributes bug reports and fixes to the open-source AI libraries I build on — currently qdrant-client, langchain, LlamaIndex and Outlines.
Open Source Contributions
7 bugs found, reported and patched across four widely-used AI libraries — each with a reproduction, a minimal fix and regression tests that fail without it. Five merged upstream: four into qdrant-client, one of them shipped in v1.19.0, and one into langchain-ai/langchain; the rest are open pull requests.
An error message that named the one index it rejectsMerged
qdrant/qdrant-client- The slice guard accepts 0 <= index < total, so the largest valid index is total - 1. The message advertised the range as 0..total — naming the single value the guard refuses, so a caller correcting against the message lands back on the same error.
- The message came across unchanged when a maintainer moved the guard into validate_filter() on my own PR #1369. A review bot flagged it seven minutes before that merge and neither of us read the comment. I found it two days later re-reading the merged code — which is the habit worth having, not the fix.
A filter that removed itself — min_should returned the whole collectionMerged
qdrant/qdrant-client- min_should is evaluated in local mode as matches >= min_count, so any min_count at or below zero is trivially true for every point: the filter returned the entire collection instead of being refused. A real server answers 422.
- Returning everything is the worst direction for a filter to fail in. Nothing looks broken — tests pass, the page populates, and a clause meant to scope results silently stops scoping them.
- Fixed with a validate_filter() helper called once before the scan rather than inside the per-point comparison, recursing into nested clauses. The known limitation — scroll returns early on an empty collection, before any filter code runs — is stated in the PR.
Two filter conditions returned the wrong points in local modeMerged
qdrant/qdrant-client- MatchExcept treated an explicit null as a value that differs from everything, so it matched points the server excluded. It is the only negated match condition, and the only one without a type guard.
- Separately, an empty should clause matched nothing rather than everything, because any([]) is False while the sibling must and must_not clauses use all() and are vacuously true.
- Both found by running identical filters against local mode and a real Qdrant 1.19.0 server and diffing the matched ids, and both fixed with congruence tests that fail without the change.
values_count matched points that no single value satisfiedMerged · shipped v1.19.0
qdrant/qdrant-client- Four range bounds were checked independently across all counts, so two different values could each satisfy half a range and the point matched — where the real server rejected it.
- Fixed with one expression matching the server's semantics, plus a congruence regression test running the same query against local mode and a live server.
- Merged +74 / −9 and shipped in v1.19.0. A competing fix for the same bug, submitted two days later, was closed in favour of this one.
DeepSeek prompt-cache hits never reached usage metadataMerged
langchain-ai/langchain- ChatDeepSeek inherits usage parsing from BaseChatOpenAI, which reads cache hits from a nested prompt_tokens_details.cached_tokens. DeepSeek never populates that field — it reports a top-level prompt_cache_hit_tokens — so anyone measuring their cache savings saw a flat line that was the reporting, not the cache.
- The streaming mapping sits outside the choices branch, because DeepSeek sends usage in a trailing chunk carrying no choices and the obvious placement never runs. That is the part you only find by streaming a real response.
- Only hits are mapped: DeepSeek defines prompt_tokens as hits plus misses, so reporting a miss as cache_creation would invent activity that never happened. Eight unit tests; approved and merged on first review.
Open pull requests
- chroma-core/chromaadd() alone rejected None metadata that update() and upsert() both accept, failing beneath validation in the storage layer with a different error per client — TypeError locally, a deserialisation error over HTTP.PR #7581 ↗
- dottxt-ai/outlinesto_regex wrapped every term in a capturing group, renumbering the groups inside it, so a user pattern carrying a numbered backreference failed to compile at all while a named one worked.PR #1993 ↗
- run-llama/llama_indexsimilarity_top_k=0 was tested for truthiness, making an explicit zero indistinguishable from "no limit" — so it returned the entire index, the exact opposite of the request. I withdrew my fix in favour of two earlier pull requests covering the same bug; the issue is still open upstream.Issue #22508 ↗
- run-llama/llama_indexA try/except intended as a compatibility check also wrapped task execution, so run_async_tasks swallowed real failures and toggling a progress bar changed error semantics.Issue #22493 ↗PR #22520 ↗
Write-up of the qdrant-client fix: Two Values, Half a Range Each →
Skills
Languages
AI & LLMs
Machine Learning & Data Engineering
Blockchain & Web3
Algorithmic Trading
Frontend & Mobile
Backend & APIs
Databases & Data
AI-Native Development
Tools
Key Projects
Flight Delay Intelligence
Live demo ↗github.com/nazsats/flight-delay-intelligence ↗Distributed ML over 1.6M flights, built for decisions rather than scores
PySpark · LightGBM · MLflow · scikit-learn · FastAPI · Streamlit · LangGraph · Docker
- ▸Analysed 319,395 delayed US flights and found the headline result contradicts the assumption: weather causes 7% of delay minutes, while 39.8% come from an aircraft that was already late earlier in its rotation. Security, the thing passengers queue longest for, is 0.2%.
- ▸Engineered features on Apache Spark in a container — window functions, broadcast joins, partitioned Parquet — with every rolling aggregate shifted one day back and a strictly chronological split, so a flight's inputs can never contain its own outcome.
- ▸Trained and versioned a LightGBM classifier in MLflow, then optimised for decision quality rather than leaderboard position: isotonic calibration cut expected calibration error 2.5×, and the alert threshold is derived from the relative cost of a missed delay versus a false alarm rather than the 0.5 default, lifting recall on genuine delays to 77%.
- ▸Made the headline finding traceable rather than only citable. The download had trimmed away the aircraft identifier, so a knock-on delay could be counted and never followed; retaining it turned rotation analysis into a sort — partition by tail number, order by scheduled departure, and the buffer between one leg landing and the next departing is what absorbs a delay.
- ▸Simulating that on the busiest real rotation: ninety minutes injected into a Hawaiian inter-island aircraft flying fourteen legs on 28–39 minute turnarounds propagates to twelve of them and produces 1,187 minutes of cascade, an amplification of 13.2×. The simulation refuses to propagate across a discontinuity where a cancelled leg is missing from the data, because that gap is not a turnaround.
- ▸Kept the 0.672 AUC deliberately honest — the model predicts before pushback, so it never sees departure delay. Shipped PSI drift detection, SARIMA demand forecasting, and a two-agent LangGraph system: a router choosing between an analyst over aggregate history and a cascade specialist over rotations, with every figure returned from code and an explicit refusal when the data cannot support one.
Nazsats AI Store Builder
Live demo ↗github.com/nazsats/nazsats-ai-store-builder ↗One sentence to a complete storefront, in twenty seconds
Next.js 15 · NestJS 11 · PostgreSQL 16 · Prisma 7 · OpenAI structured outputs · Zod
- ▸Built an AI store builder that turns a one-sentence brief into a full storefront — brand, palette, typography, hero, categories, an eight-product catalogue in AED, and About/Contact pages — with live preview and inline editing.
- ▸Designed the pipeline so the model returns a schema-validated blueprint rather than code: prompt → LLM → StoreBlueprint (Zod) → assembler → deterministic React renderer. Model output is data, never executable, so prompt injection cannot yield XSS.
- ▸That boundary bought inline field-level editing, relational persistence, undo/redo as JSON snapshots, provider portability behind one adapter, and a test suite that runs with no API key — 83 tests passing.
- ▸Shipped as a monorepo with shared domain packages, Google sign-in, a REST surface, and automated screenshot capture driving headless Chrome so the docs never drift from the product.
AI blood report analyser — web & mobile
Next.js 16 · TypeScript · GPT-4o Vision · React Native (Expo) · Firebase
- ▸Built a health platform that analyses PDF and image blood reports with GPT-4o Vision in under 30 seconds, extracting biomarkers and flagging out-of-range values.
- ▸Generated personalised wellness protocols — meal plans, supplement stacks and lifestyle recommendations — from each user's blood chemistry, with health-score trend tracking across reports.
- ▸Added an AI meal analyser giving photo-based calorie, macro and micronutrient breakdowns with per-user daily logs.
- ▸Shipped a React Native companion app for scanning reports by camera, gallery or PDF, with marker-by-marker action plans and six health calculators.
- ▸Secured the platform with Firebase Auth and granular Firestore security rules.
Dubai AI Broker Assistant
github.com/nazsats/dubai-real-estate ↗Multi-tenant AI SaaS for real-estate agencies
Python · FastAPI · SQLAlchemy · PostgreSQL · Claude API · LangChain · Next.js
- ▸Built an agentic Claude backend with tool-calling: natural-language property search, lead-to-listing matching with reasoning, and ready-to-send pitches written in the client's own language.
- ▸Designed an async FastAPI + SQLAlchemy backend on PostgreSQL with true multi-tenancy, JWT auth and role-based access.
- ▸Developed a Next.js dashboard with a kanban pipeline, an interactive UAE market map and nine analytics chart types, fed by live listing ingestion and scraping pipelines.
Copy for LLM
github.com/nazsats/copy-for-llm ↗VS Code extension
TypeScript · VS Code Extension API
- ▸Built a VS Code extension that copies a selection together with its file path and line range, formatted for pasting into an AI chat — removing a small friction repeated dozens of times a day.
- ▸Handles multi-cursor selections as ordered blocks, falls back to the whole file when nothing is selected, and can dump every open tab as a single context block with a size warning.
- ▸Zero runtime dependencies, an 11 KB package, and a tagged release workflow targeting both the VS Code Marketplace and Open VSX.
Other Work
nazsats.com
This site — Next.js 16 with a Supabase-auth admin CMS, one-click AI draft generation, GitHub REST + GraphQL integrations and a hardened security layer (RLS, XSS sanitisation, CSP). Includes a public dashboard tracking my coding hours, languages and streaks from real editor telemetry, synced nightly.
CatCents
GameFi & DAO platform on Monad testnet (Founder, 2023–present). Solidity contracts for minting, burning and reward boosting; React/Next.js dashboard for wallet connection, quests and governance. 30,000+ member community.
Froggy Folios
Bitcoin Ordinals NFT collection with a competitive mini-game platform, leaderboards and whitelist checker.
Bao Bao · Skellies Lab · Test Tube · Smith NFT
NFT mint dashboards and wallet integrations across Aptos, Bera and Injective, including utility NFTs with staking rewards.
Work Experience
Lead AI Engineer & Full-Stack Developer
2021 – PresentNazsats
- ▸Delivered 20+ AI-powered applications, LLM solutions and full-stack platforms from architecture to deployment.
- ▸Built secure FastAPI, Flask and Node.js APIs with authentication, RBAC and scalable backend architectures.
- ▸Developed AI-powered data pipelines and intelligent search systems using real-estate datasets.
- ▸Delivered blockchain-based applications and smart contract solutions for Web3 clients.
Sports Analyst
Jun 2021 – Oct 2021Hudl, Bangalore
- ▸Analysed American football games, tagged in-game events and produced performance datasets used for team and player evaluation.
Content Writer
Jun 2020 – Jun 2021Strux Inc, Mumbai
- ▸Wrote 50+ SEO-optimised articles across a wide range of client industries, adapting tone and depth to each brand's audience.
- ▸Drove 20,000+ page views through clear, well-researched, beginner-friendly content.
Education
M.Sc. Information Technology (AI specialisation)
2020 – 2022SVKM's UPG College · CGPA 9.93
B.Sc. Information Technology
2017 – 2020SVKM's UPG College · CGPA 7.7
Achievements & Leadership
- ▸Raised $50,000+ through NFT launches and Web3 ecosystem incentives.
- ▸Grew and managed online communities of 200,000+ members across Telegram, Twitter and Discord.
- ▸Drove 500,000+ weekly visits to a project website through community and marketing efforts.
- ▸Delivered a guest lecture on AI to students at L. S. Raheja College, Mumbai (2026).
- ▸President, Rotaract Club of UPG (2019–2020) — led 10+ events with 500+ participants.
- ▸NSS Volunteer (120+ hours) — blood donation and cancer awareness campaigns.
- ▸Competition wins: Best Out of Waste (1st), Science & Innovation (2nd), Street Play (3rd).