Skip to main content

Blogs

Python Code Quality CI Pipeline with uv and Ruff

·928 words·5 mins
You can create a Python Code Quality CI pipeline using uv, Ruff, and ty within 5 minutes. TL;DR Replace pip + requirements.txt with uv for fast, reproducible installs. Replace Flake8 + Black + isort with ruff — one tool, 10–100× faster. Add ty for type checking (Astral’s faster mypy replacement). Total CI time: ~30s. GitHub Actions config fits in 20 lines. Most of us begin a Python project with high hopes. We set up a clean virtual environment, organize a requirements file, and plan to add a linter—then forget.

RAG for Knowledge-Intensive Tasks

·842 words·4 mins
Picture this: You’re asking an AI about cancer treatments. It sounds super confident and gives you detailed answers. But here’s the problem — it just made up a medical study that doesn’t exist. TL;DR RAG fixes LLM hallucinations by grounding answers in retrieved documents. Pipeline: chunk documents → embed → store in vector index → retrieve at query time → generate. Use RAG for knowledge-intensive tasks (legal, medical, finance) where accuracy is non-negotiable. Evaluate with RAGAS or custom metrics: faithfulness, answer relevancy, context recall. That’s not just embarrassing. When we’re talking about healthcare, finance, or legal advice, these AI “hallucinations” can be downright dangerous.

Ruff: Modern Python Linter & Formatter Walkthrough

·1016 words·5 mins
TL;DR Ruff replaces Flake8, Black, isort, and pydocstyle — one tool, 10–100× faster (written in Rust). Install: uv add --dev ruff or pip install ruff. Run: ruff check . (lint) and ruff format . (format). Add pre-commit hooks + GitHub Actions to enforce on every commit and PR. Pair with the Python CI Pipeline guide for the full uv + Ruff + ty setup. Writing clean, readable code is essential for collaboration and maintainability. Linters and formatters help us keep our codebase consistent and easy to understand.

System Architecture — A Comprehensive, Practical Guide

·1562 words·8 mins
Designing and evolving system architecture is about making informed trade‑offs. This guide provides a practical, opinionated walkthrough of the core concepts, patterns, and decisions you need to build scalable, reliable, and cost‑efficient systems—plus answers to the most common questions engineers and architects ask.

Handle Missing Values in Pandas Without Losing Information

·1090 words·6 mins
Missing values are inevitable in real-world datasets. This guide covers proven methods to handle missing data in pandas without compromising data integrity or analytical accuracy. TL;DR Use df.isnull().sum() to audit missing values before doing anything. Drop rows/columns only when missingness is random and < 5% of data. Fill with mean/median for numerical columns with low missingness. Forward/backward fill for time series; interpolation for smooth numerical sequences. Never fill categoricals with mean — use mode or a dedicated “Unknown” category. What Are Missing Values in Pandas # Missing values in pandas are represented as NaN (Not a Number), None, or NaT (Not a Time) for datetime objects. These occur due to:

Document Summarization: Eval First

·823 words·4 mins
Document summarization is a critical NLP task that helps users quickly grasp key information from long documents. But how do you know if your model is actually working? This guide shows a workflow that starts with evaluation and acceptance criteria before touching models — the approach that got a finance report summarizer from prototype to production in three weeks.

NLP Entity Matching with Fuzzy Search

·1100 words·6 mins
Product catalogs rarely match 1:1. Supplier A calls it “Apple iPhone 13 Pro 256GB Space Grey” while your system has “iPhone 13 Pro - 256 - Gray”. String equality fails. This guide covers a three-stage approach combining lexical, surface, and semantic similarity to match entities at scale with minimal false positives.

RAG with LangChain: Architecture, Code, and Metrics

·1260 words·6 mins
RAG is a design pattern, not a product. LangChain supports it out of the box. This guide shows a production-ready RAG setup in LangChain with architecture, retrieval choices, runnable code, evaluation metrics, and trade-offs from my client projects. TL;DR # Short answer: LangChain doesn’t “contain” RAG; it provides the building blocks to implement RAG cleanly. You wire up chunking, embeddings, vector store, and a retrieval-aware prompt chain. What you get below: Architecture diagram, runnable code (LangChain 0.2+), evaluation harness, parameter trade-offs, and when to avoid LangChain for leaner stacks. Related deep dives: Foundations of RAG → RAG for Knowledge-Intensive Tasks. Lightweight pipelines → LightRAG: Lean RAG with Benchmarks. Who should read this # You’re building an internal knowledge assistant, support bot, or compliance Q&A system. You need answers that cite real documents with predictable latency and cost. You want a minimal, maintainable RAG in LangChain with evaluation, not a toy demo. The problem I solved in production # When I implemented an extractive summarizer for financial and compliance reports, two pain points surfaced:

LightRAG: Lean RAG with Benchmarks

·884 words·5 mins
LightRAG is a minimal RAG toolkit that strips away heavy abstractions. Here’s a complete build with code, performance numbers versus a LangChain baseline, and when LightRAG is the right choice. TL;DR LightRAG is a minimal RAG stack: FAISS + embeddings + prompt composition, ~120 lines. ~20% faster p50 latency vs LangChain on small corpora (≤ 500 chunks) due to fewer abstractions. Best for: serverless/edge deployments, small teams, single-purpose Q&A. Use LangChain instead when you need agents, tracing, callbacks, or multi-step workflows. Don’t skip data quality: clean text, handle missing values, validate numeric tables before indexing. Why LightRAG # For small, self-hosted RAG services, I often don’t need callbacks, agents, or complex runtime graphs. I need:

Difference between reshape() and flatten() in NumPy

·1442 words·7 mins
NumPy’s reshape() and flatten() are both used for array manipulation, but they serve different purposes and have distinct behaviors. This guide explains when and how to use each method effectively. TL;DR reshape() returns a view (no copy) when possible — memory-efficient, changes affect original. flatten() always returns a copy — safe to modify independently. Use ravel() instead of flatten() when you want a view (like reshape(-1)) to save memory. Use reshape(-1) to flatten without copying; use flatten() only when you need an independent 1D copy. What is reshape() in NumPy # The reshape() method changes the shape of an array without changing its data. It returns a new view of the array with a different shape when possible.