AI Can Generate Code — And Interactive Coding Playgrounds Are Becoming Essential

AI tools like ChatGPT, GitHub Copilot, and Claude can now generate components, fix bugs, explain concepts, and even build small applications in seconds.

As AI changes software development, the way people learn coding is also changing — which is one of the reasons I started building interactive coding playgrounds at https://fwdtools.com/learn-to-code/

People no longer need to memorise syntax the same way they did years ago. But developers still need to:

  • Understand what code actually does
  • Experiment visually
  • Debug AI-generated output
  • Compare multiple approaches quickly
  • Learn concepts interactively
  • Tweak results in real time
  • Build intuition around frontend behavior

That is exactly where coding playgrounds become valuable.

Learning Is Becoming More Interactive

A lot of coding education still depends heavily on:

  • Long video tutorials
  • Passive watching
  • Large documentation pages
  • Multi-hour courses
  • Copy-pasting snippets without experimentation

Many learners today prefer faster feedback loops and hands-on exploration.

They want to:

  • Change code instantly
  • See visual results immediately
  • Experiment rapidly
  • Understand concepts visually
  • Learn directly in the browser

Interactive playgrounds support that style of learning naturally.

Why Interactive Learning Works Well

Interactive playgrounds reduce friction.

You change code → you instantly see the result.

That feedback loop helps learners understand relationships more naturally:

  • CSS property → visual change
  • React state → UI update
  • JavaScript logic → browser behavior
  • Animation values → motion differences

This creates faster experimentation and stronger intuition.

AI + Playgrounds

AI can generate:

  • HTML structures
  • React components
  • Tailwind layouts
  • Animations
  • API calls

Playgrounds help people:

  • Test variations quickly
  • Understand generated output
  • Modify code safely
  • Explore ideas visually
  • Learn through experimentation

That combination creates a powerful learning workflow.

Why I Started Building Interactive Learning Tools

Over the past few months, I started building free browser-based coding playgrounds and visual learning tools.

The goal is simple:

Make learning frontend development faster, more visual, and easier to experiment with.

The tools run directly in the browser with no installation required.

Current playgrounds include:

  • HTML Playground
  • CSS Playground
  • JavaScript Playground
  • React Playground
  • Tailwind Playground
  • GSAP Playground
  • SQL Playground
  • MongoDB Playground
  • Firebase Playground
  • GraphQL Playground
  • and more

More interactive playgrounds and visual coding tools are being added regularly.

Explore The Playgrounds

If you enjoy learning by experimenting directly in the browser, you can explore the playgrounds here:

https://fwdtools.com/learn-to-code/

Everything is free to use and designed for students, freelancers, frontend developers, and self-taught programmers exploring modern AI-assisted workflows.

Final Thoughts

AI is accelerating development workflows and changing how developers build software.

Interactive learning environments help people experiment, understand generated code, explore concepts visually, and learn through direct feedback.

That is why browser-based coding playgrounds and visual learning tools are becoming increasingly important for modern developers and students.

If you know students or beginner developers who may benefit from interactive coding playgrounds, feel free to share it.

Modern Web Guidance: Teaching AI Agents to Stop Coding Like It’s 2019

This is a submission for the Google I/O Writing Challenge

There’s a slightly embarrassing problem that almost everyone using AI coding agents has run into: your agent still codes like it’s 2019.

Ask it to build a modal, and it reaches for a <div> with JavaScript click handlers and messy z-index hacks. Ask it to build a tooltip, and it creates a whole positioning system from scratch. Ask it to add passkey login, and it starts rebuilding things the browser already handles on its own.

This isn’t really the agent’s fault. It was trained on the entire history of the web: millions of StackOverflow answers, GitHub repos, and old tutorials from a time when <dialog> didn’t exist, the Popover API wasn’t even a thing, and container queries sounded like science fiction. AI models don’t automatically know what’s current. They know what’s common.

That gap between what’s “common” and what’s “current” is exactly what Modern Web Guidance, announced at Google I/O 2026, is trying to fix.

What Is Modern Web Guidance?

Modern Web Guidance is basically a set of skills you add to your AI coding agent. Think of it as a rulebook that helps steer the agent away from outdated patterns and toward features browsers can already handle today.

It’s not a linter or another docs site. It works inside your AI agent and helps guide the code it generates.

It launched in early preview on May 19 with over 100 use cases focused on accessibility, performance, and security. It already works with tools like Antigravity, Claude Code, GitHub Copilot CLI, Gemini CLI, and more, with WebStorm support announced for the near future. Setup is simple:

npx modern-web-guidance@latest install

One command, and your agent starts using more modern web patterns by default.

The Problem It’s Actually Solving

Before getting into how it works, it’s worth talking about why this even matters.

The web platform has changed a lot over the last few years. We got:

  • The <dialog> element (and the ability to animate it with native CSS)
  • The Popover API: simple, accessible overlays without extra JavaScript
  • CSS Anchor Positioning: UI that stays attached to elements without JS math
  • Container Queries: components that react to their own size, not the whole page
  • View Transitions API: smooth page and UI transitions in just a few lines
  • Passkeys / WebAuthn: secure login that the browser handles for you

These aren’t obscure experimental features. They’re widely available, well supported, and better than the patterns they replace. But AI agents still default to the old ones because that’s what they’ve seen the most.

The result? Codebases built with AI assistance often carry five-year-old technical debt, shipped at today’s speed.

Modern Web Guidance tries to fix this. It tells the agent: when the user asks for a modal, use <dialog>. When they ask for a tooltip, use the Popover API and CSS Anchor Positioning. When they ask for a login form, think about passkeys.

Trying It Out

I installed Modern Web Guidance via the CLI and tried a few prompts to see how much it actually changes the output.

Before (without guidance): asking an agent to “build a modal with smooth open/close animations” usually gives you something like this: a <div class="modal-overlay">, display: none toggled with JavaScript, opacity transitions on a z-index: 9999 container, and a document.addEventListener('keydown') for Escape handling.

It works. It’s also the kind of code a senior web developer would flag in a code review and replace.

After (with guidance): the same prompt produces a <dialog> element, animated with @starting-style and allow-discrete. Accessibility? Handled by the browser.

The output is not just cleaner, it’s less code doing more things correctly.

I ran a similar test with tooltip/popover UI, and the guidance pushed the agent toward the Popover API with CSS Anchor Positioning. That removes a whole class of JavaScript that used to be needed just to keep tooltips attached to their triggers while scrolling.

The Baseline Integration Is the Clever Part

What makes Modern Web Guidance more interesting than just a list of best practices is its integration with Baseline.

Baseline is a web platform initiative that defines clear tiers of browser support: Newly Available (supported in all major browsers in the last ~30 months) and Widely Available. It gives developers a simple way to know if a feature is safe to use.

Modern Web Guidance ties into this directly. When it suggests a feature, it’s tagged with a Baseline level. If your app needs to support older browsers, it includes the right fallbacks automatically. If you’re building for modern browsers only, it just uses the latest features without hesitation.

This means the guidance isn’t static. As the web platform changes and features move from Newly Available to Widely Available, the skills get updated. You’re not managing rules, you’re just subscribing to them.

An Honest Critique

Modern Web Guidance is genuinely good, but it’s worth being clear-eyed about what it is and what it isn’t.

It’s still early. It ships with over 100 use cases. The web platform has thousands of patterns and APIs, so this will feel limited pretty quickly if you go into less common areas like advanced WebGL, complex Service Worker setups, or niche CSS layouts. The team is accepting GitHub contributions, which makes sense, but it also means the real value of this tool will depend on community input over the next few months, not just what is shipped at I/O.

It assumes your agent actually follows it. Modern Web Guidance works by adding context to your agent’s session, such as skills, CLAUDE.md files, or similar setups. But how well an agent follows that context vs. ignoring it and falling back to what it learned before can vary a lot. It’s not a strict rule; it’s more like a strong suggestion.

The web standards community is becoming the arbiter of what “modern” means, and that’s more complicated than it sounds. To be fair, this isn’t just a Google project. The repo lists the Google Chrome team, Microsoft Edge team, and the wider web community as co-maintainers. That matters, as it’s closer to a shared platform effort than a single company product.

But that also makes things more interesting, not less. When a cross-browser group defines what “modern web best practices” look like and bakes that into guidance used inside AI tools, it quietly shapes how millions of developers write code.

The guidance is well-intentioned and aligned with standards. But it’s still a curated view of the web, created by a specific set of organizations. It shouldn’t be treated as neutral; it should be understood and questioned like any other opinionated layer.

Should You Install It?

Yes, no hesitation, if you’re building anything that runs in the browser with an AI coding agent.

The bigger picture is more interesting, though: Modern Web Guidance is an early sign of what happens when the people who build the web platform also shape how AI writes web code. That feedback loop, from spec authors to agent guidance to shipped code, could help the web actually catch up to what it already supports.

For too long, great web platform features have gone unused because the ecosystem, including AI, keeps reaching for older solutions out of habit. If Modern Web Guidance works as intended, that gap will start closing faster.

And that’s a meaningful thing to ship.

Getting Started

You can install it at developer.chrome.com/docs/modern-web-guidance

# Recommended (auto-updates)
npx modern-web-guidance@latest install

# Claude Code
/plugin marketplace add GoogleChrome/modern-web-guidance
/plugin install modern-web-guidance@googlechrome
/reload-plugins

# Gemini CLI
gemini extensions install https://github.com/GoogleChrome/modern-web-guidance --auto-update

# Antigravity CLI
agy plugin install https://github.com/GoogleChrome/modern-web-guidance

# GitHub CLI
gh skill install GoogleChrome/modern-web-guidance

The source is open on GitHub at github.com/GoogleChrome/modern-web-guidance-src, contributions and feedback are welcome while it’s in early preview.

Announced at Google I/O 2026 on May 19, 2026, and currently in early preview.

The Discipline We Forgot We Had

Process automation is older than software. The teams that remember will be the ones still shipping.

                    Photo by Thao LEE on Unsplash

Fourth in a short series. The first piece argued that the gap between AI-agents-in-pilots and AI-agents-in-production is being closed by a quiet infrastructure rebuild. The second showed what that infrastructure looks like. The third was about the failure modes the dashboard does not show. This piece is the constructive counterpoint: what installing the missing discipline actually consists of, and why teams that install it will be the ones still shipping when the hype rotates.

An older engineer I know — the kind of person who has seen three industry waves come and go — told me, when I asked him what he thought about the agentic moment, that he was struck mostly by how much of the conversation he had heard before.

“Every five years,” he said, “we discover that the way to coordinate work in a large organisation is to write down what the work is. We rediscover this with a slightly different vocabulary every time. The vocabulary changes. The discovery is the same.”

I have been thinking about that for a few weeks, and I think he is right. There is a discipline of process automation that is older than software — older, in some forms, than electricity. We have been forgetting and rediscovering pieces of it for the better part of a century. The agentic hype, in particular, is convincing teams to skip the rediscovery this time around. Which is a problem, because the discipline is what keeps the wheels on.

This piece is about what the discipline actually is.

Five layers a production process needs

If you take an experienced operations engineer — someone who has shipped real workflows in regulated industries, and lived with what they shipped — and you ask them what makes the difference between a process that survives and a process that breaks, you will get a list that has been more or less the same since the 1970s.

Figure 1. The unfashionable list. Each layer holds the ones above it up.

At the bottom is audit completeness. Every decision the process made — by which agent, on what input, against which version of the rules, with what outcome — is captured in one place, by name. Not in three log files, not in two tools, not in a Slack channel. One record. The kind of thing you can hand to a regulator without rewriting it first.

Above that is declared structure. The process exists as a thing you can read and a thing you can run, and these are the same thing. An analyst reads the diagram. An engineer reads the source. They are looking at the same artifact. Nobody has to translate.

Above that is typed contracts. Each step has an input shape and an output shape, both checked. If the upstream step changes its output and the downstream step is not updated, the system refuses to run. It does not silently pass the wrong shape forward and let production discover it.

Above that is bounded scope. Each step in the process is allowed to touch a specific, declared set of tools, data, and external systems. Nothing else. If the score-the-claim step tries to send an email, the runtime refuses, regardless of how plausible the email is.

At the top is cost SLOs in the source. The economic envelope of the process — what it is allowed to cost per run, per day, per month — is part of the program. Not a dashboard the finance team monitors. Part of the program.

Each layer is a claim the next layer rests on. If the audit log is incomplete, the structure means nothing — you cannot demonstrate which version of the process actually ran. If the structure is undeclared, the contracts mean nothing — there is no shared understanding to type-check against. If the contracts are unenforced, the scope means nothing — agents will pass arguments to tools that those tools were never built to accept. And if the scope is unbounded, the cost SLO means nothing — the process can spend money in ways the budget never anticipated.

Most teams shipping AI agents in 2026 have, at best, two of these five. Often one. Often zero. They make up the difference with vigilance and pagers. It works for a while. It does not scale.

The two-language problem

To see why this matters, consider the most common shape of an enterprise AI deployment, in any industry, anywhere in the world.

Figure 2. The two-language problem. The more important your workflow, the more this gap will cost you.

On one side, in a git repository, lives the code. Engineers wrote it. It is tested, reviewed, deployed, instrumented. When it changes, the change is reviewed. When something goes wrong, you can git blame your way back to the moment.

On the other side, in a Confluence page or a PDF or a SharePoint folder, lives the policy. Compliance wrote it. Legal approved it. It is the document the regulator will ask for in the audit. It says what is required. It says what is forbidden. It is the law of the land for this workflow.

Between them is a gap, and into that gap fall every important failure your enterprise will have over the next three years.

The reason is mechanical. Code and policy are written in two different languages, lived in two different systems, owned by two different organisations. The two systems do not talk to each other. The code cannot verify the policy. The policy cannot constrain the code. When the policy changes, the change has to be translated into code by hand, by someone who hopefully understood both. When the code changes, the change has to be reviewed against the policy by hand, by someone who hopefully read both.

This works, in the sense that nothing immediately catches fire. It also has a one-hundred-percent failure rate over a long enough horizon. The policy and the code drift. Edge cases the policy contemplates are not in the code. Edge cases the code handles are not in the policy. The drift is silent until something happens — a regulator’s question, a customer’s complaint, a Tuesday — and you discover that what you do is not what you said you would do.

Every team that has run a workflow in production for more than two years knows this in their bones. They know that the audit went well last time because someone remembered to update the policy. They know that the small incident in March happened because the engineer didn’t read the latest version. They know that the next problem will happen because nobody can hold both documents in their head at the same time.

The fix is not better documentation. The fix is to stop having two artifacts.

The same thing, in one source

Imagine, for a moment, that the policy and the code lived in the same source file. Not next to each other. Not linked. The same source file.

Figure 3. What it looks like when the workflow, the policy, and the budget all share one source.

The workflow declaration sits next to a governance rule that constrains it. The governance rule sits next to a budget that bounds them both. All three are written in the same syntax. All three are read by the same compiler. All three are checked against each other before anything ships.

If the workflow changes in a way that violates the policy, the build fails. Not at runtime — at build time, before anything is deployed. If the budget is exceeded by the workflow’s expected cost, the build fails. If a step references a tool that the policy disallows, the build fails. The compiler is the contract between engineering and compliance. It cannot be bypassed by someone forgetting to update a Confluence page.

This is not a science fiction proposal. This is how every serious software discipline has worked for half a century. Type systems. Schema validation. Formal contracts in distributed systems. The compiler-as-discipline pattern is older than most of the people writing AI agents today. The novelty is applying it to process as well as code, to policy as well as logic, to cost as well as correctness.

The pushback I get when I describe this is always the same: “but our policy is too complicated to encode.” And it is true that natural-language policy is more expressive than any formal system. It is also true that natural-language policy is less defensible than any formal system. The choice is not between formal-but-impoverished and rich-but-vague. The choice is between enforced and unenforced. Most policies, in practice, are not as complex as they sound; they are written in legalese to defend their authors. The actual logic — what amounts get reviewed, by whom, under what conditions — fits in a few dozen lines of declarative source.

The teams that learn to do this will be the teams that ship faster, not slower. They will not need three meetings to understand whether a change is compliant. The compiler will tell them. They will not need a quarterly compliance review to find drift. There will be no drift to find.

Where the bug gets caught

There is a strange asymmetry in the cost of bugs that anyone who has worked in software for long enough will have an intuitive feel for, and that almost no one outside software has been told about explicitly.

Figure 4. The same bug, caught in three different places.

A bug caught at compile time costs essentially nothing. The author sees a red squiggle, fixes it, moves on. The bug never enters the system. There is no incident, no rollback, no post-mortem. Most engineers do not even count compile-time errors as bugs. They are part of the act of writing.

A bug caught at deployment time costs a deployment. Maybe an evening. Maybe a rollback and a hotfix. Annoying, but contained. The damage is internal — engineering pays the cost, the customer never sees it.

A bug that escapes into production costs whatever the bug actually does. If it sends a wire to the wrong account, it costs the wire plus the recovery plus the regulatory disclosure plus the trust. If it deletes a customer’s data, it costs the data plus the trust plus the lawsuit plus possibly the company. The cost in production is not bounded by anything. It is bounded by what the world makes of the bug.

Each layer outward is roughly an order of magnitude more expensive than the one inside it. This is not a precise number. The point is the shape: the cost of catching a bug is exponential in how late you catch it.

Most agentic systems being shipped today do not have a compile step at all. The platform interprets a configuration. The configuration is checked, in some places, but not as a whole. The checks are at runtime, at deployment time, sometimes only when production traffic hits a particular path. The cost shape of bugs in these systems is therefore the worst possible shape: most bugs are caught in production, where they are most expensive.

This is a choice the platforms make. It is a defensible choice for a research prototype. It is an indefensible choice for a workflow that processes claims, transfers money, or makes hiring decisions. The teams that pick the platform without a compile step will, on average, pay an order of magnitude more for their bugs than teams that pick the platform with one. Over a few years, this difference shows up in everything: cost-of-incidents, time-to-recover, regulatory standing, engineering morale.

It is one of those things that is not visible until it is. And then it is the only thing that matters.

Cost is a number the program knows about

Here is a small thing that is, when you sit with it, an enormous thing.

In every conventional engineering discipline — civil, mechanical, electrical, chemical — the cost envelope of a system is part of the system’s specification. A bridge has a cost. A circuit has a power budget. A process plant has a throughput target. These are not numbers a finance team monitors after construction. They are constraints the design has to honour, in the design phase, on paper, before anything is built.

In software, somehow, this got lost.

Figure 5. The budget is part of the program graph, not a sidecar.

Most software systems, including the agentic systems being built today, treat cost as an emergent property. The system runs. Bills accrue. A dashboard somewhere — or, in the worst cases, an invoice at the end of the month — reports what the system spent. The finance team adjusts. The engineering team apologises. Nobody is held accountable, because nobody wrote down what the cost was supposed to be in the first place.

The fix is to make cost a typed quantity in the program. A first-class construct. A budget node that the workflow references, that the runtime enforces, that the compiler validates. When a step is added that pushes the projected cost above the declared budget, the build fails. When a run starts to exceed its budget, it pauses, alerts, and refuses to continue without explicit approval. The runtime knows what the program is supposed to cost. The program is the source of truth.

This single change does more for FinOps discipline than every dashboard ever built. Because the question stops being “how much did we spend?” — a question that can only be answered after the fact, by an exhausted analyst with three browser tabs open — and becomes “what did we say we’d spend?” — a question with one answer, in the source.

If you want to know whether a team takes its production agents seriously, look for this. If their budget lives in a spreadsheet, they have a hobby. If their budget lives in the source they shipped, they have a system.

What the agentic hype is selling you

Now, with all of this in view, look honestly at what the major agent platforms are selling in 2026.

They are selling you a notebook with extra steps. They are selling you a configuration file in a YAML dialect that nobody compiles, that nobody type-checks, that nobody validates against your governance, that nobody bounds against your budget. They are selling you a beautiful drag-and-drop canvas that produces a workflow that lives only in their database, that you cannot version-control, that you cannot review in a pull request, that you cannot enforce a policy against.

They are selling you, in short, the absence of every layer in the diagram above.

This is not because the people who build these platforms are foolish. They are not. It is because the platforms were built for the demo era — where the goal is to make a thing that produces an impressive output in a controlled setting, fast. They are excellent at this. They are not built for the era we are now actually entering, where the goal is to run a thousand of these things a day in production, on workflows that touch real money and real people and that you have to defend in a hearing.

The platforms will, eventually, grow into this. Some of them are starting to. But the gap between what they ship today and what production-grade process automation requires is much larger than the marketing suggests, and it will be filled by teams who choose the unfashionable option.

The hype cycle has a predictable rhythm. The new thing is exciting because it skips the boring parts. Then production reveals that the boring parts were load-bearing. Then the boring parts get added back, one at a time, painfully, by the teams that survive long enough to need them. The teams that wait for the hype to install the boring parts on their behalf wait a long time, because hype does not install boring parts. Hype installs new features.

The teams that install the boring parts themselves, in advance — that pick the platform with the compiler, that demand the typed contracts, that put the budget in the source — those teams will be the ones still shipping in 2030. They will look, today, like they are moving slowly. In three years they will look like they were moving exactly the right speed.

A craft, not a product

I want to close on something that the previous three pieces have circled around without quite saying.

Process automation is a craft. It is older than the software industry. It is older than the computer industry. It has roots in the time-and-motion studies of the early twentieth century, and before that in the trade guilds, and before that in the apprenticeship traditions of every settled civilisation that ever had to coordinate work across more than one room.

Crafts have a particular shape. They have practitioners who get better with time. They have apprentices who are taught by the people who came before. They have standards that are enforced not by management but by the practitioners themselves, refusing to ship work that does not meet them. They have a sense of what is right and what is sloppy that does not need to be justified to outsiders, because the outsiders cannot tell, and the practitioners can.

The agentic moment is, among other things, a moment when this craft is being threatened by people who do not know it exists. They believe they are inventing process automation from scratch. They are not. They are reinventing it badly, with worse tools, in a hurry, for a market that does not yet know enough to demand otherwise.

The job of anyone who has been around long enough to remember is to keep the craft alive. To insist that the boring parts are load-bearing. To choose, at every fork, the platform that compiles over the platform that interprets, the system that types over the system that hopes, the source that is auditable over the source that is convenient. To pay the small short-term price for the large long-term sanity.

This is not a heroic posture. It is a workmanlike one. There is no glory in it, and there is no Twitter audience for it, and there is no conference circuit for it. There is only the quiet satisfaction, three years on, of looking at a system that is still shipping, that has not had its catastrophe, that the regulators have not flagged, that the customers have not left — and knowing that this is not luck. It is the result of discipline, applied early, when it was unfashionable.

The previous piece in this series ended with the line look at the shape.

I want to end this one with the older line that the discipline of engineering keeps coming back to, because every generation has to learn it again.

Build it like it has to last.

The series ends here, for now. If you found these useful, the previous pieces are linked at the top. The discipline they describe is older than I am, and will outlast all of us. The job is to remember it.

I Built a 3-Agent AI Research Crew in 250 Lines of Python (LangGraph + Free Gemini)

You’ve seen the demos. “Look, our AI hired a research team and wrote you a 50-page report while you brushed your teeth!” Cool. Now show me the code.

It turns out the code is small. Embarrassingly small. The whole pattern — the thing every multi-agent framework on the market sells you a SaaS license for — is three functions piped through a typed dict. Once you see it, you can’t unsee it.

So today we’re going to build it. From scratch. In about 250 lines of Python. The crew has three specialists:

  • A Researcher who actually hits the web for real facts.
  • A Writer who turns those facts into a draft briefing.
  • An Editor who polishes the draft into something you’d send to a colleague.

You give it a topic. It hands you back a markdown report. And — this is the part the YouTubers skip — the entire stack is free. No OpenAI, no Anthropic, no Tavily, no credit card. Just one free Google API key.

Live demo — click a starter, watch the three stages turn green. Source on GitHub, step-by-step commits.

The lesson under the hype

If you remember nothing else, remember this: a multi-agent system is a state machine where each transition is an LLM call.

That’s it. That’s the whole field.

You define a shared blob of state — let’s call it CrewState. The graph has nodes. Each node is just a function that reads the state, does some work (often by calling an LLM), and returns a partial dict. The framework merges that dict back into the state and decides which node runs next.

       ┌────────────┐    ┌──────────┐    ┌────────┐
TOPIC ─▶│ Researcher │───▶│  Writer  │───▶│ Editor │───▶ REPORT
       │  (DDG API) │    │ (Gemini) │    │(Gemini)│
       └────────────┘    └──────────┘    └────────┘
                  shared CrewState flows through all three

When LangGraph’s authors built v0.1, they were essentially asking: what if we took LangChain’s “Chain” abstraction but let it have cycles, branches, and persistent state? That’s the whole pitch. The graph is the agent.

The state object: where everyone meets

LangGraph is opinionated about one thing: every node has to agree on the shape of the data flowing through. So we type it. Once.

from typing import TypedDict

class Fact(TypedDict):
    source: str
    title: str
    snippet: str

class CrewState(TypedDict, total=False):
    topic: str
    facts: list[Fact]
    draft: str
    final_report: str
    error: str

total=False is the magic. It means every field is optional. The graph starts with only topic set. As each node finishes, it adds its key (facts, then draft, then final_report). LangGraph merges the partial dict back into the state before the next node runs.

Notice what’s missing: any reference to LLMs, prompts, or agents. The state is data, not behaviour. Keeping it that way is what makes the whole pattern testable — you can swap any agent for a stub that just returns {"draft": "lorem ipsum"} and the graph still runs.

Agent 1: The Researcher (or, why your LLM needs to leave the house)

The single biggest mistake beginners make with LLM apps is asking the model to remember things. Don’t. The model’s job is to transform inputs into outputs. The inputs come from your code, calling real APIs.

That’s why the Researcher does the search first, then hands the results to the LLM. Not the other way around.

from duckduckgo_search import DDGS

def researcher_node(state: CrewState) -> dict:
    topic = state.get("topic", "").strip()
    with DDGS() as ddgs:
        raw = list(ddgs.text(topic, max_results=5, region="wt-wt"))
    facts = [
        {"source": r.get("href", ""), "title": r.get("title", ""), "snippet": r.get("body", "")}
        for r in raw
    ]
    return {"facts": facts}

That’s the whole researcher. Twelve lines. No LLM call. DuckDuckGo’s API is free, no key, no signup — perfect for a tutorial. (For production, swap to Tavily or Serper; the pattern doesn’t change.)

Why grounded search instead of asking Gemini “what do you know about X?”

Because Gemini will lie about URLs. Every single LLM ever shipped will invent URLs that look real but 404. Don’t ask the model for facts. Ask it to summarise facts you got from a tool.

Agents 2 + 3: Why two? Why not one big prompt?

Here’s the part that feels wasteful at first. We have research notes. We want a polished report. Surely one prompt — “Write a polished briefing about $TOPIC using these facts” — can do it?

Try it. It produces mediocre output. Always.

The reason is divided attention. Asking a model to simultaneously generate prose AND fix its own structural problems means it does both badly. So we split:

  • The Writer has one job: produce a 400-500 word draft. Hedges allowed. Markdown sloppy. Just get words on the page.
  • The Editor has one job: read the draft, fix the structure, prepend a title, cut the flab, ship the final.

This is how human newsrooms work. Reporters file rough drafts; copy editors polish them. Both roles exist because both add value. Multi-agent design is just the same idea applied to LLM calls.

def writer_node(state):
    facts_block = "n".join(f"- {f['title']}: {f['snippet']} ({f['source']})" for f in state["facts"])
    response = llm.invoke([
        SystemMessage(content="You are a technical writer. 400-500 words, plain markdown..."),
        HumanMessage(content=f"Topic: {state['topic']}nnFacts:n{facts_block}nnWrite the draft."),
    ])
    return {"draft": response.content.strip()}

def editor_node(state):
    response = llm.invoke([
        SystemMessage(content="You are a senior editor. Polish, don't rewrite. Add an H1 title..."),
        HumanMessage(content=f"DRAFT TO POLISH:nn{state['draft']}"),
    ])
    return {"final_report": response.content.strip()}

System message = how to behave. Human message = what to do. Mixing them produces worse output. This is the single most underrated trick in prompt engineering.

Wiring it: the actual LangGraph part

After all that setup, the LangGraph code is comically short:

from langgraph.graph import START, END, StateGraph

g = StateGraph(CrewState)
g.add_node("researcher", researcher_node)
g.add_node("writer", writer_node)
g.add_node("editor", editor_node)
g.add_edge(START, "researcher")
g.add_edge("researcher", "writer")
g.add_edge("writer", "editor")
g.add_edge("editor", END)

crew = g.compile()
result = crew.invoke({"topic": "How CRISPR works"})
print(result["final_report"])

That’s the whole thing. Eight lines define the agent crew. compile() turns the declarative graph into an executor that runs your nodes in order, merging state between them. Once compiled, the same crew object handles every request — it’s stateless across invocations, because the state lives in the dict you pass in.

Streaming: because waiting 8 seconds for a spinner feels broken

The sync version works, but the UX is sad. The user clicks a button. A spinner appears. Eight to ten seconds pass. The whole report appears at once.

LangGraph has a stream() method that yields after each node finishes. Same total latency, dramatically better feel:

for update in crew.stream({"topic": topic}, stream_mode="updates"):
    for node_name, partial in update.items():
        yield {"node": node_name, "data": partial}

stream_mode="updates" emits only the diff returned by the node that ran (cheaper than "values", which emits the whole state). Pipe that through FastAPI’s Server-Sent Events and the React frontend can render researcher facts as soon as they arrive — while the writer is still drafting. The Render free tier sleeps after 15 minutes, so first hit takes ~30 seconds to wake up; subsequent hits feel instant.

Why this is THE concept to understand before everything else

Every “wow look at this” AI demo from the next six months is going to be a variation on this exact pattern. Replace the Researcher with a code-aware agent and you get Cursor’s compose mode. Replace the Editor with a fact-checker and you get Perplexity’s pipeline. Replace the linear edges with conditional edges and a feedback loop and you get autonomous agent loops like AutoGPT.

The pattern doesn’t change. State + nodes + edges. Three functions, three arrows, one dict. Everything else is marketing.

Once you see it, you can read any “agentic” framework’s docs in five minutes flat. CrewAI, AutoGen, LangGraph, Pydantic AI — they all collapse to the same shape. The differences are syntactic sugar around the same core idea.

What to try next

Clone the repo and run it locally. It takes about three commands. Then break it:

  • Add a fourth agent — a fact-checker that flags suspicious claims in the editor’s output and sends it back for revision. (Hint: add_conditional_edges.)
  • Swap Gemini for local Llama via Ollama. Same .invoke() interface, zero network cost.
  • Replace DuckDuckGo with a vector search over your own documents. Now you’ve built RAG.

The same 250 lines, with three different tweaks, give you three completely different products. That is why understanding multi-agent orchestration matters. The hard part isn’t the agents — it’s seeing the pattern clearly enough to recognise it everywhere.

This is Day 37 of 50 days of from-zero builds. A new technology every day. The full live demo is at langgraph-from-zero.vercel.app; the source is on GitHub. Beginners welcome — every commit teaches one concept.

PostgreSQL MCP: Let Claude query your databases in plain English

Install guide and config at curatedmcp.com

PostgreSQL MCP: Let Claude query your databases in plain English

Tired of context-switching between your IDE and database tools? PostgreSQL MCP brings your Postgres database directly into Claude, Cursor, or Windsurf—letting you write natural language queries that get translated to SQL automatically.

What It Does

PostgreSQL MCP bridges the gap between AI agents and your Postgres databases. Instead of manually writing SQL, you describe what you need in plain English. The server translates it to SQL, executes it safely, and returns formatted results—all within your AI conversation.

The server handles schema introspection automatically, so Claude understands your table structure without you manually documenting it. Want to explore a database? Ask Claude. Need analytics queries? Describe the analysis. Building a report? Let Claude write the queries.

Key safety features matter in production: read-only mode prevents accidental mutations, connection pooling with PgBouncer support handles concurrency, and sandboxed execution keeps queries isolated. Query history and EXPLAIN plans help you optimize slow queries without leaving your chat window.

How to Install

npx @modelcontextprotocol/server-postgres

Add this to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on Mac):

{
  "mcpServers": {
    "postgresql-mcp": {
      "command": "npx @modelcontextprotocol/server-postgres",
      "env": {
        "DATABASE_URL": "postgresql://user:password@localhost:5432/dbname"
      }
    }
  }
}

Restart Claude Desktop, and you’re live.

Real-World Use Cases

  • Debug production data issues: “Find all failed transactions from yesterday and show me the error patterns.” Claude writes the query, you get instant insights.
  • Generate reports inside Cursor: Chat with your codebase and database simultaneously. “Show me monthly revenue trends and help me write the SQL for our analytics dashboard.”
  • Explore unfamiliar schemas: Onboarding to a legacy system? Let Claude navigate the database structure, show relationships, and help you understand what data actually exists.

Full install guides for Claude Desktop, Cursor, Windsurf, and more at CuratedMCP.

Building digital products and Android apps under IteraTrail

Hey everyone 👋

I’m a former MERN stack developer currently building digital products, productivity tools, and Android apps under IteraTrail.

Over the past few months, I’ve been exploring AI-assisted development workflows and combining them with my development background to create practical tools that solve everyday problems more efficiently.

Currently, we’re expanding the IteraTrail ecosystem through:
• Web-based utility and productivity tools
• Android applications
• Creator-focused digital experiences
• Workflow and utility systems

Some apps are already live in production, while others are in active testing and development.

One of the projects we’re actively building is IteraSuite – part of a broader ecosystem focused on accessible and useful digital tools.

Still early in the journey, but excited to keep building, learning, and improving consistently.

Would love to connect with fellow builders, creators, and developers here.