#Software Engineering

Articles about Software Engineering — exploring patterns, best practices, and real-world implementations in production systems.

94 posts tagged with software engineering. ← All posts

#A2A (5)#ADK (8)#AG-UI (6)#AI (9)#AI Agents (212)#AI Engineering (39)#AI Governance (16)#AI Red Teaming (8)#AI Safety (6)#AI Security (16)#AML (3)#API Design (9)#API Security (8)#APIs (37)#AWS (9)#Accounting (9)#Agent Skills (3)#Agentic AI (24)#Agentic Commerce (12)#Agents (4)#Amazon Bedrock (8)#Architecture (36)#Audit (3)#Automation (6)#Azure (11)#Azure AI Foundry (9)#Backend Engineering (220)#BigQuery (6)#CI/CD (7)#Capital Markets (14)#Card Payments (12)#Cards (13)#Career (7)#Checkpointing (4)#Claude Code (8)#Cloud Architecture (3)#Code Review (8)#Collaboration (4)#Communication (4)#Compliance (42)#Concurrency (23)#Consulting (3)#Cost Optimisation (5)#Credit (14)#Credit Risk (14)#Crypto (12)#Cryptocurrency (12)#Custody (9)#Data (4)#Data Structures (3)#Databases (14)#Deployment (3)#DevSecOps (10)#Developer Experience (3)#Distributed Systems (64)#Documentation (3)#Embeddings (11)#Engineering (7)#Engineering Culture (3)#Engineering Practices (16)#Evaluation (31)#FREE-AI (8)#FX (5)#FinOps (5)#FinTech (6)#Financial AI (14)#Financial Systems (122)#Fintech (116)#Foreign Exchange (5)#Forward Deployed Engineer (8)#Forward Deployed Engineering (8)#Fraud (10)#Function Tools (5)#GCP (5)#Go (220)#Google ADK (36)#Governance (46)#Granite (6)#GraphQL (3)#Guardrails (21)#HIPAA (3)#HTTP (3)#Harness Engineering (8)#Human-in-the-Loop (8)#IBM watsonx (8)#Integration (3)#Interfaces (3)#KYC (11)#KYC and AML (12)#Kubernetes (8)#LLM (5)#LLMs (45)#LangGraph (11)#Ledger (12)#Lending (14)#MCP (10)#MLOps (3)#Machine Learning (12)#Markets (4)#Memory (8)#Microservices (3)#Microsoft Agent Framework (150)#Middleware (6)#Migration (9)#Monitoring (3)#Multi-Agent (10)#Multi-Agent AI (14)#Multi-Agent Systems (49)#Multimodal (3)#NIM (5)#NVIDIA (8)#OWASP (7)#Observability (25)#Open Source (6)#OpenTelemetry (4)#Opinion (6)#Orchestration (10)#Payment Rails (16)#Payments (51)#Performance (6)#Privacy Engineering (3)#Product (4)#Production (6)#Programming (10)#Prompt Engineering (26)#Prompt Injection (7)#Providers (4)#Python (89)#Quality (3)#RAG (23)#RBI (3)#REST (5)#Rails (16)#Reconciliation (3)#Regulation (9)#Reliability (27)#Resilience (3)#Responsible AI (4)#Retrieval (3)#Risk (13)#SRE (4)#Scalability (3)#Security (63)#Sessions (3)#Settlement (9)#Software Architecture (9)#Software Engineering (94)#Spanner (4)#Streaming (21)#Structured Output (4)#System Design (8)#Testing (30)#Tool Use (9)#Tools (3)#Trading (8)#Treasury (6)#Type System (3)#Type Systems (3)#Vector Databases (8)#Vector Search (3)#Workflows (14)#gRPC (4)
Pratik Dhanave · ·12 min read

Production on watsonx

Taking a watsonx.ai system from a notebook to production in Python — deployment spaces, reliability with retries and fallbacks, cost and throughput control, observability wired to watsonx.governance, and a hardening checklist.

Run a watsonx system in production from Python: IBM Cloud vs Cloud Pak for Data, project_id vs deployment spaces, reliability (tenacity retries, IAM token refresh, fallback), token-based cost, observability wired to watsonx.governance monitors, and securing IAM credentials.

Pratik Dhanave · ·12 min read

Production on the NVIDIA Stack

Taking an NVIDIA-stack LLM system from a working prototype to something you trust in production — reliability, cost and throughput, observability, and security — all from Python, with the OpenAI-compatible surface keeping the code stable whether you burst to the API Catalog or run your own NIM.

Run an NVIDIA-stack LLM system in production from Python: hosted vs self-hosted vs hybrid, reliability (client retries, tenacity backoff, readiness probes, fallback), the GPU-hours cost model, Prometheus observability across the pipeline, and securing nvapi-/NGC keys.

Pratik Dhanave · ·12 min read

Governance and Monitoring with watsonx.governance

Why enterprises pick watsonx for its governance story, what watsonx.governance actually gives a Python team, and how to wire monitoring, factsheets, and generative-quality metrics into an LLM feature — honestly, as the platform-heavy work it is.

Governance is why many enterprises pick watsonx: model inventory, automated factsheets, monitoring (quality, drift, bias, and generative metrics like faithfulness), explainability, and EU AI Act-aligned risk workflows — with the ibm-watsonx-gov evaluation SDK and what to log.

Pratik Dhanave · ·15 min read

Self-Hosting and Optimizing Inference

When to graduate from the hosted API Catalog to inference you run yourself — deploying a NIM container, reaching for Triton and its Python client, the TensorRT-LLM levers that raise throughput and cut latency, and the one base_url change that carries your Python client across unchanged.

Move from the hosted API Catalog to self-hosted inference: run a NIM container (your Python client works unchanged by swapping base_url), use Triton directly via tritonclient, and understand the TensorRT-LLM levers — quantization, in-flight batching, paged KV cache, tensor parallelism.

Pratik Dhanave · ·11 min read

Guardrails and Granite Guardian

Adding safety to a watsonx app in Python with two complementary layers — the built-in HAP and PII moderations that watsonx.ai applies to generation, and IBM's dedicated Granite Guardian risk-detection models run as classifiers around your main model to catch harm, jailbreaks, and RAG hallucination before a response reaches a user.

Add safety to a watsonx app in Python with two layers: built-in HAP/PII moderations on generation, and Granite Guardian — IBM's dedicated risk models — run as a classifier to screen input and check RAG groundedness, wrapped in a guarded-generate flow.

Pratik Dhanave · ·11 min read

Guardrails with NeMo Guardrails

Adding a safety layer to an NVIDIA-stack Python app with NeMo Guardrails — and why running it in-process, with no HTTP boundary, is the quiet advantage Python gives you over a separate guardrails server.

Add safety with NeMo Guardrails, in-process in Python: the rail types (input/output/dialog/retrieval), the config.yml + Colang model, loading with RailsConfig/LLMRails backed by a NIM model, and detecting when a rail trips instead of treating a refusal as a normal answer.

Pratik Dhanave · ·12 min read

RAG on watsonx

Assembling a full retrieval-augmented generation pipeline in Python on watsonx.ai — ingest and chunk documents, embed them with slate, retrieve by cosine, rerank for precision, then generate a grounded, cited answer with a Granite model, shown both from scratch and with langchain-ibm.

Build a full RAG pipeline in Python on watsonx: chunk (with Docling for parsing), embed and store, retrieve, rerank, and generate a grounded, cited answer with a Granite model — shown both from scratch and via the idiomatic langchain-ibm assembly, with notes on scaling to watsonx.data/Milvus.

Pratik Dhanave · ·14 min read

RAG on the NVIDIA Stack

Assembling a full retrieval-augmented generation pipeline in Python — chunk and embed with NeMo Retriever, shortlist by cosine, sharpen with a reranker, then ground a ChatNVIDIA answer that cites its sources — first from scratch, then the idiomatic LangChain wiring.

Build a full RAG pipeline in Python on NVIDIA's stack: chunk and embed with NeMo Retriever, shortlist by cosine, rerank, then generate a grounded, cited answer with ChatNVIDIA — shown both from scratch and the idiomatic LangChain assembly, with notes on scaling to a vector DB.

Pratik Dhanave · ·12 min read

Embeddings and Reranking with watsonx

Building RAG's retrieval core with watsonx.ai from Python — turning a corpus into vectors with IBM's slate embedding models, scoring a query against them, and then sharpening the shortlist with a reranking model so the LLM gets the right passages, not just plausible ones.

Use watsonx.ai's slate embedding models and reranking from Python to build RAG's retrieval core: embed_documents vs embed_query, numpy cosine scoring, and a two-stage retrieve-then-rerank pipeline — plus the langchain-ibm WatsonxEmbeddings/WatsonxRerank path.

Pratik Dhanave · ·13 min read

Embeddings and Reranking with NeMo Retriever

Building RAG's retrieval core in Python — turning a corpus and a query into vectors with NeMo Retriever embedding NIMs, scoring by cosine similarity, then sharpening the shortlist with a cross-encoder reranker NIM.

Use NeMo Retriever from Python to build RAG's retrieval core: NVIDIAEmbeddings (embed_documents vs embed_query for the asymmetric passage/query distinction) with cosine scoring, and NVIDIARerank.compress_documents for a two-stage retrieve-then-rerank pipeline.

Pratik Dhanave · ·11 min read

Tool Calling with watsonx

Letting a Granite model on watsonx.ai invoke your Python functions — the full request-and-response loop with the first-party `ibm-watsonx-ai` chat API, plus the shorter LangChain path with `ChatWatsonx.bind_tools`.

Function/tool calling against watsonx.ai Granite models in Python: the chat() round-trip loop (json.loads the arguments, echo tool_call_id, cap iterations), handling multiple tool calls, and the LangChain ChatWatsonx.bind_tools path — Granite models are tool-trained.

Pratik Dhanave · ·12 min read

Tool Calling with NIM

Driving function calling against NVIDIA NIM models from Python — the full request-execute-respond loop with the plain `openai` client, then the same thing automated by `ChatNVIDIA.bind_tools`.

Function/tool calling against NIM models in Python: the openai round-trip loop (json.loads the arguments string, echo tool_call_id, cap the iterations) and the LangChain ChatNVIDIA.bind_tools path — with the honest caveat that model support varies.

Pratik Dhanave · ·10 min read

Calling watsonx.ai from Python

Your first real inference calls with the ibm-watsonx-ai SDK — credentials, ModelInference, the generate and chat APIs, streaming, token usage, error handling, and the langchain-ibm path.

Make your first watsonx.ai calls in Python: credentials (IAM key + project_id + regional url), ModelInference with generate_text vs the modern chat API, decoding methods and parameters, streaming, token usage, and the langchain-ibm ChatWatsonx path.

Pratik Dhanave · ·10 min read

Calling NIM from Python

Your first real NVIDIA NIM calls in Python, two idiomatic ways: the plain OpenAI SDK pointed at NVIDIA's endpoint, and the official LangChain integration — with error handling, streaming, and the one change that makes the same code run against a self-hosted model.

Make your first NIM calls in Python two ways: the standard openai client pointed at the API Catalog with an nvapi- key, and the official ChatNVIDIA from langchain-nvidia-ai-endpoints — with streaming, token usage, typed errors, and the base_url swap to a self-hosted NIM.

Pratik Dhanave · ·10 min read

Getting Started with Microsoft Agent Framework (Python)

From the smallest possible agent to a browsable service — the core loop, the four ways to run it, how memory and tools attach, and two ways to put a server in front of it.

From the smallest possible agent to a browsable service — the core loop, the four ways to run it, how memory and tools attach, and two ways to put a server in front of it.

Pratik Dhanave · ·11 min read

Memory, Context & Session State in Microsoft Agent Framework (Python)

A complete guide to what an agent remembers — from a single conversation held in a session, to durable facts injected on every run, to the per-request values that reach a tool without ever touching the model's schema.

A complete guide to what an agent remembers — from a single conversation held in a session, to durable facts injected on every run, to the per-request values that reach a tool without ever...

Pratik Dhanave · ·13 min read

Building Workflows in Microsoft Agent Framework (Python): The Core Model

From a single decorated async function to an explicit graph of executors and agent nodes — the core workflow model in Microsoft Agent Framework, and the two APIs that express it.

From a single decorated async function to an explicit graph of executors and agent nodes — the core workflow model in Microsoft Agent Framework, and the two APIs that express it.

Pratik Dhanave · ·14 min read

Advanced Workflows in Microsoft Agent Framework (Python)

Once you can wire a chain of executors, the graph earns its keep: concurrency, durable state, composition, and control — the patterns that turn a toy pipeline into a system that survives a crash.

Once you can wire a chain of executors, the graph earns its keep: concurrency, durable state, composition, and control — the patterns that turn a toy pipeline into a system that survives a crash.

Pratik Dhanave · ·8 min read

Human-in-the-Loop & Workflow Observability in Microsoft Agent Framework (Python)

How to pause a workflow for a human decision, package a whole workflow as an agent, and see exactly what a run did — through OpenTelemetry spans and a rendered graph — in Microsoft Agent Framework.

How to pause a workflow for a human decision, package a whole workflow as an agent, and see exactly what a run did — through OpenTelemetry spans and a rendered graph — in Microsoft Agent Framework.

Pratik Dhanave · ·11 min read

Multi-Agent Orchestration in Microsoft Agent Framework (Python)

A complete guide to coordinating many agents — from a fixed pipeline, to parallel fan-out, to a self-routing mesh, to a planner that decides who acts next, to publishing an agent as a network service other agents can call.

A complete guide to coordinating many agents — from a fixed pipeline, to parallel fan-out, to a self-routing mesh, to a planner that decides who acts next, to publishing an agent as a network...

Pratik Dhanave · ·9 min read

Models, Providers & Endpoints in Microsoft Agent Framework (Python)

A complete guide to where a Microsoft Agent Framework agent gets its model — from direct Foundry inference to OpenAI-compatible endpoints, service-managed agents, hand-rolled providers, and container hosting.

A complete guide to where a Microsoft Agent Framework agent gets its model — from direct Foundry inference to OpenAI-compatible endpoints, service-managed agents, hand-rolled providers, and...

Pratik Dhanave · ·10 min read

Advanced I/O, RAG & Evaluation in Microsoft Agent Framework (Python)

Once an agent can call tools, the next questions are what it can read, what it returns, how long it can run, where its facts come from, how it's defined, and whether it actually works — this guide answers all seven.

Once an agent can call tools, the next questions are what it can read, what it returns, how long it can run, where its facts come from, how it's defined, and whether it actually works — this guide...

Pratik Dhanave · ·8 min read

DevUI & Durable Agents in Microsoft Agent Framework (Python)

A guide to the two hosting concerns every agent eventually hits — seeing it run in a local chat window with a live call inspector, and keeping its state alive across crashes on Durable Task infrastructure.

A guide to the two hosting concerns every agent eventually hits — seeing it run in a local chat window with a live call inspector, and keeping its state alive across crashes on Durable Task...

Pratik Dhanave · ·10 min read

The IBM watsonx Platform

A Python engineer's map of IBM watsonx — what watsonx.ai, watsonx.governance, watsonx.data and watsonx Orchestrate actually are, why enterprises pick them, and the smallest amount of `ibm-watsonx-ai` code that gets a foundation model answering you.

The opener to a series on building LLM and agent applications on IBM watsonx from Python: how watsonx.ai (Granite + third-party models), watsonx.governance, watsonx.data and Orchestrate fit together, and why the ibm-watsonx-ai SDK and langchain-ibm make it Python-native.

Pratik Dhanave · ·8 min read

The NVIDIA AI Stack

A Python engineer's map of NVIDIA's AI platform — NIM inference, NeMo Retriever, NeMo Guardrails, and Triton with TensorRT-LLM — and why the same code runs against the hosted API Catalog or your own self-hosted microservice.

The opener to a series on building LLM and agent applications on NVIDIA's AI stack from Python: how NIM, the API Catalog, NeMo Retriever, NeMo Guardrails, Triton and TensorRT-LLM fit together — and why the openai client and langchain-nvidia-ai-endpoints make it Python-native.

Pratik Dhanave · ·10 min read

Tools in Microsoft Agent Framework (Python): Functions, Hosted Tools, MCP, Skills & CodeAct

A complete guide to giving a Microsoft Agent Framework agent the ability to act — from a plain Python function the model can call, to provider-hosted sandboxes, remote MCP servers, and higher-level packaging patterns like Skills and CodeAct.

A complete guide to giving a Microsoft Agent Framework agent the ability to act: function tools, provider-hosted tools (code interpreter, file search, web search), local and hosted MCP, plus Skills and CodeAct — with the code and gotchas for each.

Pratik Dhanave · ·6 min read

"maximum recursion depth exceeded": A Durable-Workflow Checkpointing War Story

Passing an SDK client through a checkpointed agent workflow crashed on circular references. The fix reshaped how I cross @step boundaries.

Threading an SDK client through a checkpointed workflow crashed with maximum recursion depth exceeded. The checkpoint boundary is a serialization boundary: JSON only, values and keys, and anything non-serializable gets injected out-of-band at the composition root.

Pratik Dhanave · ·5 min read

Agent Config: Defining an ADK Agent in YAML, No Code Required

How ADK's config loader turns a declarative YAML file into a fully-built agent — and why treating an agent as data changes who gets to edit it.

Defining an agent declaratively in YAML and loading it via from_config — the loader reads, resolves, and validates the config into a built agent, so config-as-data works without writing code.

Pratik Dhanave · ·5 min read

Context Caching in ADK: Stop Paying for the Same Tokens Every Turn

How caching a large, stable prompt prefix cuts latency and cost — and the ADK config that decides when it pays off.

Context caching cuts latency and cost by caching large, stable context — system prompt, reference docs, tool definitions — so repeated calls don't re-send and re-process the same tokens.

Pratik Dhanave · ·5 min read

Planners & Thinking: Making an ADK Agent Reason Before It Acts

Post 23 of 26 in "Google ADK, Concept by Concept" — how a planner turns one-shot answers into inspectable plan-then-act reasoning.

Structuring an agent's reasoning: planners that make the model plan-then-act (ReAct-style), the built-in thinking feature, and how a planner improves multi-step tool use over naive prompting.

Pratik Dhanave · ·6 min read

Human-in-the-Loop, Tools, and the Send API

The higher-level building blocks LangGraph stacks on top of the graph engine — pausing for a human, running an agent loop, calling tools, and fanning out dynamically.

The building blocks on top of the core graph: interrupt() to pause for human input, create_react_agent and ToolNode for tool-using agents, and the Send API for dynamic parallel fan-out with a reducer fan-in.

Pratik Dhanave · ·6 min read

Command: Update State and Pick the Next Node in One Return

How a single `Command` object folds a state update and a routing decision together — and the tiny lowering that makes `goto` just another guarded edge.

Command lets a node return a state update and a goto in one object, moving the routing decision inside the node. It is the cleanest way to express supervisor handoffs and dynamic control flow.

Pratik Dhanave · ·6 min read

Cycles and the Agent Loop: Branch, Act, Loop Back

The single most important pattern in LangGraph — a branch plus a back-edge, and the `recursion_limit` that keeps it from running forever.

Branching plus a back-edge is a cycle, and that cycle IS the agent loop: model proposes tool calls, tools run, control returns to the model, repeat until done. Plus recursion_limit, the guardrail that stops a runaway loop.

Pratik Dhanave · ·6 min read

Grounding & RAG in ADK: Answers Anchored in Real Data

Post 18 of 26 in "Google ADK, Concept by Concept" — retrieval tools, grounding metadata, rendering citations, and the retrieve→augment→generate loop.

Grounding answers in real data: retrieval tools, grounding metadata returned with responses, rendering citations from that metadata, and the retrieve-augment-generate RAG pattern in ADK.

Pratik Dhanave · ·5 min read

Observability in ADK: Seeing Inside a Running Agent

How OpenTelemetry traces, structured logs, and token metrics turn an agent's event stream into something you can debug in production.

Seeing inside a running agent: OpenTelemetry tracing with spans for agent, model, and tool steps, structured logging, and exporting traces to debug latency and tool-call trajectories.

Pratik Dhanave · ·5 min read

State, Channels, and Reducers: How LangGraph Merges Updates

The one idea that makes everything else in LangGraph click: nodes don't pass messages, they update a shared state — and reducers decide how.

State is a typed dict of channels; each channel has an optional reducer. No reducer overwrites; a reducer (like add_messages or operator.add) combines. This is the single idea the rest of LangGraph is built on.

Pratik Dhanave · ·6 min read

Deploying an ADK Agent: One Command to Cloud Run and Agent Engine

How `adk deploy` builds, pushes, and ships an agent in a single step — and the ack-after-invocation rule that keeps event-driven agents reliable.

Deploying an agent: adk deploy with its cloud_run and agent_engine subcommands, containerizing the app, and reliability rules like ack-after-invocation so failures are redelivered, not dropped.

Pratik Dhanave · ·6 min read

LangGraph Is a Pregel Program: Shared State vs Message Passing

The foundational mental model — why "the graph" is a Pregel program, and how shared state differs from message passing.

LangGraph is shared-state, not message-passing, and both models descend from Google's Pregel/BSP: work advances in supersteps that end at a synchronization barrier. Get this mental model first and the whole API stops being magic.

Pratik Dhanave · ·5 min read

Runtime & Events in ADK: The Runner, the Invocation, and the Event Stream

How an agent actually runs — a Runner drives an invocation and hands you back a stream of events, not a single answer.

How ADK runs an agent: the Runner drives an invocation that yields a stream of Event objects — content, tool calls, state deltas, control signals. The event loop explains streaming, callbacks, and state.

Pratik Dhanave · ·5 min read

Context in ADK: The Objects Passed Into Your Tools and Callbacks

ReadonlyContext, CallbackContext, ToolContext, InvocationContext — and why the read-only vs mutable distinction is a feature, not a limitation.

The context objects ADK passes into tools and callbacks — InvocationContext, ToolContext, CallbackContext, ReadonlyContext — what each exposes and why the read-only vs mutable split matters.

Pratik Dhanave · ·3 min read

Hosting and the Capstone App — Microsoft Agent Framework in Python

Turning agents into a service you can run and expose, then a full DocQA app that ties the whole series together.

Host Microsoft Agent Framework agents with DevUI, A2A, MCP, and AG-UI, then build DocQA — a grounded, cited multi-agent app that ties the whole Python series together.

Pratik Dhanave · ·5 min read

Artifacts: Where ADK Agents Put Their Files

Session state is for small text and JSON. When your agent produces a PNG, a PDF, or a WAV, it belongs in the artifact store — binary-native, versioned, and out of the session record.

Artifacts are binary/file data agents produce or consume: ArtifactService saves and versions named artifacts, loaded and saved via context, keeping large blobs out of session state.

Pratik Dhanave · ·9 min read

Closures and Scope: LEGB, nonlocal, and global

How Python decides what a name means — the LEGB lookup rule, what a closure actually captures, the late-binding loop trap and its fixes, and when you genuinely need `nonlocal` or `global`.

How Python decides what a name means — the LEGB lookup rule, what a closure actually captures, the late-binding loop trap and its fixes, and when you genuinely need `nonlocal` or `global`.

Pratik Dhanave · ·3 min read

Orchestration Patterns — Microsoft Agent Framework in Python

Five prebuilt multi-agent shapes — Sequential, Concurrent, Group Chat, Handoff, Magentic — and when each beats hand-wiring a graph.

Sequential, Concurrent, Group Chat, Handoff, Magentic — the five prebuilt Microsoft Agent Framework orchestrations in Python and when each beats hand-wiring a graph.

Pratik Dhanave · ·11 min read

Functions: Arguments, *args, **kwargs, and Defaults

A working guide to Python's function signatures — positional and keyword arguments, default values and the mutable-default trap, arbitrary-argument packing and call-site unpacking, keyword-only and positional-only parameters, and treating functions as first-class values.

A working guide to Python's function signatures — positional and keyword arguments, default values and the mutable-default trap, packing with *args/**kwargs, unpacking at call sites, keyword-only and...

Pratik Dhanave · ·5 min read

Sessions & State in ADK: The Memory Inside a Conversation

A `Session` is the conversation; `state` is the key-value bag agents and tools read and write — and the prefix on a key decides how long it lives.

A Session holds a conversation; state is a scoped key-value store (session/user/app/temp) read and written by tools, injected into instructions via {state} templating, and persisted by SessionService.

Pratik Dhanave · ·11 min read

Control Flow: if, for, while, and match

How Python decides what runs next — conditionals and the ternary, for-each iteration done idiomatically, while loops, break/continue and the surprising loop-else, structural pattern matching with match/case, and where truthiness and comprehensions fit in.

How Python decides what runs next — conditionals and the ternary, for-each iteration done idiomatically, while loops, break/continue and the surprising loop-else, structural pattern matching with...

Pratik Dhanave · ·12 min read

Functions, Closures, and Variadics

How Go treats functions as ordinary values — and what that buys you: the (result, error) idiom, variadic APIs, closures over shared state, and the decorator/middleware/option patterns that fall out of passing functions around.

How Go treats functions as ordinary values — and what that buys you: the (result, error) idiom, variadic APIs, closures over shared state, and the decorator/middleware/option patterns that fall out of...

Pratik Dhanave · ·5 min read

Tools in ADK: Turning Functions into Agent Capabilities

How a plain function becomes a callable tool, how ToolContext reaches session state, and how long-running tools pause a run for a human.

Tools give agents capabilities: a plain function becomes a tool with its signature as the schema, plus ToolContext, built-in tools, and long-running/human-in-the-loop tools across Python and Go.

Pratik Dhanave · ·3 min read

Workflow Mechanics — Microsoft Agent Framework in Python

The graph model underneath every multi-agent app: executors as nodes, edges as data flow, and typed events streaming out as it runs.

The Microsoft Agent Framework workflow model in Python: executors as nodes, edges as data flow, switch-case routing, and typed streaming events - learned model-free.

Pratik Dhanave · ·12 min read

Strings, Bytes, and Unicode

Why Python draws a hard line between text and raw bytes, how the encode/decode boundary works, and the string-handling habits that keep that line from cutting you.

Why Python draws a hard line between text and raw bytes, how the encode/decode boundary works, and the string-handling habits that keep that line from cutting you.

Pratik Dhanave · ·12 min read

Control Flow and defer

Go's control flow is deliberately small — one loop keyword, a switch that doesn't fall through, an `if` that can scope its own variable — and then there's `defer`, the one construct that repays close reading. A tour of the whole surface, with the sharp edges labelled.

Go's control flow is deliberately small — one loop keyword, a switch that doesn't fall through, an `if` that can scope its own variable — and then there's `defer`, the one construct that repays close...

Pratik Dhanave · ·5 min read

Multi-Agent Systems in ADK: Coordinators, sub_agents, and LLM-Driven Delegation

How one agent routes work to specialists — and why the description field is the most important string you write.

Agent hierarchies and LLM-driven delegation: sub_agents, how the description field drives auto-transfer, and coordinator/dispatcher patterns — contrasted with deterministic workflow agents.

Pratik Dhanave · ·3 min read

Observability, Safety, and Providers — Microsoft Agent Framework in Python

Turn agent runs into OpenTelemetry spans, block prompt injection with information-flow control, and swap model providers behind one Agent API.

Turn Microsoft Agent Framework agent runs into OpenTelemetry spans, block prompt injection with information-flow control, and swap model providers behind one Agent API.

Pratik Dhanave · ·13 min read

Numbers, Booleans, and None

A working guide to Python's scalar types — arbitrary-precision integers, IEEE-754 floats and the 0.1 + 0.2 trap, when to reach for Decimal and Fraction, the operators that surprise you with negatives, why a boolean is secretly an integer, and how truthiness and None actually work.

A working guide to Python's scalar types — arbitrary-precision integers, IEEE-754 floats and the 0.1 + 0.2 trap, when to reach for Decimal and Fraction, the operators that surprise you with negatives, why a...

Pratik Dhanave · ·12 min read

Variables, Constants, and iota

How Go's declaration forms, scope rules, and its unusual constant system fit together — including the untyped-constant model that makes numeric literals feel effortless, and the `iota` patterns that turn enums and bit-flags into a few tidy lines.

How Go's declaration forms, scope rules, and its unusual constant system fit together — including the untyped-constant model that makes numeric literals feel effortless, and the `iota` patterns that turn...

Pratik Dhanave · ·12 min read

The Data Model: Objects, Names, and Binding

The single mental model that explains most of Python's surprises — everything is an object with an identity, a type, and a value; a name is a reference bound to an object, not a box that holds one; and assignment binds, it never copies.

The single mental model that explains most of Python's surprises — everything is an object with an identity, a type, and a value; a name is a reference bound to an object, not a box that holds one; and...

Pratik Dhanave · ·10 min read

Types, Values, and Zero Values

How Go's type system actually behaves — predeclared types, the zero-value guarantee that removes a whole class of null bugs, the "no implicit conversions" rule and why it exists, and the difference between a named type and a mere alias.

How Go's type system actually behaves — predeclared types, the zero-value guarantee that removes a whole class of null bugs, the "no implicit conversions" rule and why it exists, and the difference between...

Pratik Dhanave · ·11 min read

Python's Philosophy and Toolchain

What actually makes Python distinctive — the design values that shape the language, how it runs, and the everyday tools you'll live in. The first post in a series that treats readability and correctness as features, not afterthoughts.

What actually makes Python *Python* — the design values that shape the language, how it runs, and the everyday tools you'll live in. The first post in a series that treats readability and correctness as...

All posts on this site are written by Pratik Dhanave, an Agentic AI Architect with 7+ years building production distributed systems, multi-agent AI platforms, and cloud-native infrastructure. About the author → Each article includes working code, architecture diagrams, and references to the specific frameworks and standards discussed. Browse all posts or explore related topics using the tag cloud above.