How to Build Advanced Generative AI Agents

The tools, frameworks, and protocols we use to build AI agents, agentic workflows, and intelligent applications.

Alton Wells
Alton Wells
30 views
How to Build Advanced Generative AI Agents

This is an opinionated, incomplete, imperfect, subject to change, vibe based, list of tools and services we use at Generative to build both customer facing applications and internal agents. We have no perfect practice, we experiment and change things all the time, we like to try new tools because we think its important. We're likely missing stuff from this list, there's probably better ways to do things, we just care about what works for us.

We are definitely missing tools for integrations, for testing, for monitoring, for a dozen other categories that a more responsible team would have locked down by now. We are missing entire classes of tooling that we have not gotten to yet. We know. If you see a gap, it is probably a real gap and not an intentional omission. We are building in public and this is an honest snapshot, not a polished architecture diagram.

If something here is wrong or you are using something better, tell us. We mean that.


TL;DR — Just Want the Links?

Skip the philosophy. Here is everything we use, linked. Click what interests you.

Coding & Development Claude Code · Codex · Cursor · v0.dev · Conductor.build

AI Frameworks & SDKs Mastra · Vercel AI SDK · OpenAI Agents SDK · Agents SDK

Protocols & Standards MCP · AG-UI · A2UI · MCP Apps

Databases & Backend Supabase · Convex · Redis / Upstash

Deployment & Infrastructure Vercel · Railway · Fly.io · Inngest

Application Frameworks Next.js · Bun · FastAPI · Tauri · Electron · Expo

Communication Resend · AgentMail · Photon / Spectrum

UI & Components shadcn/ui · Tailwind CSS · React Email

Auth & Payments Supabase Auth · Clerk · Stripe

MCP Servers We Configure Supabase MCP · Mastra Docs MCP · Context7 (honestly a lot of others)

Notable Libraries Zod · Drizzle ORM · Hono · Turborepo · LangGraph · LangFuse · Pinecone · Sentry · PostHog · Docker


Get insights like this in your inbox

Join our newsletter for deep dives on AI, technology, and building the future. No spam, unsubscribe anytime.

ModelsShmodles

Before we get into the stack, the single most important thing we believe about building agents:

We do not care about models.

We are not an Anthropic shop. We are not an OpenAI shop. We are not a Google shop. We are a "whatever works" shop. Models are commoditizing faster than anyone wants to admit, and the team that marries a specific model is the team that gets left behind when the next one leapfrogs it three months later.

We use Claude Code and Codex side by side. We run agents on Claude, on GPT, on Gemini, on whatever Mastra supports that week. We switch models between projects and sometimes between features in the same project. The model is a variable, not a constant.

What we are married to is delivering incredible experiences for our customers and ourselves, who are sometimes the same people. The model that does that best today might not be the model that does it best tomorrow. That is fine. That is the point. Build for the interface, not the engine behind it.

This is why the protocol layer matters so much more than the model layer. MCP, AG-UI, A2UI — these are model-agnostic. They work with anything. That is the kind of commitment we are willing to make.

How We Think About the Stack

We organize everything into layers, not because it is a particularly original framework, but because it helps us think about what goes where when things break. And things break.

The layers, from the inside out:

Intelligence. The agents, the protocols that let them talk to things, and the frameworks that wire them together.

Infrastructure. Where data lives, where code runs, what keeps it all from falling over at 3am.

Application. The frameworks we actually build products with. The stuff users touch.

Tooling. Everything that makes the first three layers less painful to work with.

We think of this as middle-out. You start with the intelligence layer and the infrastructure layer simultaneously, and the application and tooling layers emerge from the decisions you make there. You do not pick a frontend framework and then figure out how to make agents work inside it. You figure out what the agent needs to do, and then you pick the framework that gets out of the way.

This sounds obvious. It is not how most teams build.

Intelligence

We do not have a primary coding tool. We have five, and we use all of them constantly.

Claude Code in the terminal for heavy lifting — reading entire codebases, multi-file refactors, git workflows, debugging sessions that go deep. Codex for the same class of work when we want a second opinion or when a different model handles a specific task better. Cursor for tab completions, inline edits, and the quick stuff that does not need a full agent session. v0.dev for rapid UI prototyping — generate React and Tailwind components from natural language, export with npx shadcn@latest add, refine in Cursor. Conductor.build when we need multiple agents working in parallel on different features, each in isolated git worktrees, with a dashboard showing what every agent is doing.

The workflow is not linear. We bounce between these tools constantly. Start a feature in v0, export to Cursor, hand the complex logic to Claude Code, spin up a parallel Codex instance in Conductor for the backend work. Whatever gets the job done.

For building agents that ship as products, we use Mastra. It is a TypeScript framework from the team that built Gatsby, and it does the thing that matters most: it gives you agents, tools, workflows, RAG, memory, and evals in one package without requiring you to learn a second language or glue together six different libraries. It is built on top of the Vercel AI SDK, which means useChat() just works on the frontend. We have tried LangGraph and LangChain. They are fine. Mastra fits how we think.

The Protocol Layer

This is where things get interesting, and honestly, a little confusing. There are now three protocols that matter and they do different things:

MCP is how agents access tools and data. It is the universal plug. Supabase ships one. Mastra ships one. Inngest ships one. We configure MCP servers for every project so our coding tools can talk directly to the database and the documentation without us copy-pasting context.

AG-UI is how agents talk to frontends. It is an event-based protocol that streams messages, tool calls, state patches, and lifecycle signals between any agent backend and any user-facing application. It was born out of CopilotKit and now has first-party support from AWS, Microsoft, Oracle, and Google. If MCP is the agent's hands, AG-UI is its mouth.

A2UI is how agents describe user interfaces. It is a declarative spec from Google that lets agents emit structured component trees — cards, forms, lists — that the frontend renders natively. The same JSON payload works in React, Flutter, SwiftUI. If AG-UI is the mouth, A2UI is the language it speaks when it needs to show you something more than text.

There is also MCP Apps, which is the open-ended version of agent-delivered UI. Agents return interactive HTML in sandboxed iframes. More flexible, harder to control.

CopilotKit ties a lot of this together on the frontend side. It gives you drop-in React and Next.js components for agent interactions — chat panels, copilot sidebars, headless mode — all connected via AG-UI. We use it when we need agents to live inside an application rather than in a terminal.

This whole space is what people are calling Generative UI — the idea that agents produce interfaces at runtime instead of developers hand-coding every screen. There are three flavors: Static (agent picks from pre-built components), Declarative (agent emits structured specs like A2UI), and Open-Ended (agent returns raw HTML). CopilotKit supports all three. We lean toward static and declarative because we care about consistency more than we care about flexibility.

Infrastructure

Supabase is the default. Postgres, auth, real-time subscriptions, Row-Level Security, edge functions. It does too many things, which is usually a warning sign, but in this case all of those things are genuinely good. The MCP server means our agents can query the database directly during development. We do not connect it to production. We are not insane.

When Supabase is not the right fit, usually for highly reactive applications where everything needs to update in real time, we reach for Convex. It is a real-time document database that is entirely TypeScript. No SQL. Reactive useQuery() hooks. Server functions that feel like writing frontend code. The tradeoff is you need to bring your own auth, usually Clerk.

For caching and job queues, Redis via Upstash. Serverless, generous free tier, REST API. We do not run our own Redis. Life is too short.

Deployment is split. Vercel for anything Next.js. Railway for everything else — Bun servers, Python APIs, Redis instances, Postgres databases. Railway is the thing Heroku should have become. Fly.io when we need containers at the edge, which is less often than you would think.

The piece we added most recently and probably should have added sooner is Inngest. Durable workflow orchestration. You write multi-step functions with step.run(), and each step automatically retries, persists state, and resumes from failure. No queues to configure, no workers to deploy. It replaced a lot of brittle cron-and-pray infrastructure that we are embarrassed to have had in the first place.

Application

Next.js is the center of gravity. App Router, server components, API routes, Turbopack. We have not found a reason to use anything else for web applications. Every project starts with npx create-next-app@latest and the defaults are the right defaults.

Bun shows up as a separate backend server when we need one. It is 3-5x faster than Node on startup, has native TypeScript support, and the built-in test runner is underrated. We explored a monorepo pattern with Next.js on Vercel and Bun on Fly.io connected by a shared types package, and it worked well enough that we kept doing it.

FastAPI for Python backends. When the AI pipeline is Python-native, which is less often than it used to be now that Mastra exists, but still happens.

For desktop, we are watching Tauri v2 closely. Rust-based, tiny bundles, strong sandbox, and v2 added mobile support. If we ship a desktop product, it will probably be Tauri. Electron is the fallback. Heavier, but the Claude Code Agent SDK runs natively in its main process with zero friction, which matters if you are building a coding agent harness.

Expo for mobile. React Native with file-based routing, cloud builds, and over-the-air updates. The fastest path from web developer to shipping on iOS and Android.

For email, Resend. You build templates as React Email components and send them via API. It is exactly as simple as that should be. For agent-native email, where the agent itself needs an inbox, AgentMail. It is Gmail for AI agents. Full two-way conversations, threading, semantic search, all via API. YC-backed, just raised $6M.

Photon and its Spectrum SDK handle agent messaging across platforms. iMessage, Telegram, WhatsApp, Slack, Discord, Instagram. If you need an agent to live where humans already talk, Photon is the bridge.

Tooling

Cursor is the IDE. VS Code fork with AI built in. We run Claude Code's extension inside it, plus tab completions for the quick stuff. The two tools complement each other better than either works alone.

Conductor.build is the Mac app for running multiple Claude Code and Codex instances in parallel, each in isolated git worktrees. When you have three features to build and they do not touch each other, you spin up three agents and let them work simultaneously. It sounds excessive until you try it.

shadcn/ui is not a dependency. It copies accessible, well-built React components into your project. You own the code. npx shadcn@latest init and you are done.

Stripe for payments. Clerk for auth when not using Supabase. Turborepo for monorepos when the project grows past a single app.

TypeScript everywhere. ESLint. Tailwind. Zod for runtime validation. Drizzle for type-safe SQL. These are not exciting choices. They are correct choices.

MCP Servers We Configure on Every Project

This is the part that compounds. Every project gets these MCP servers configured at the start, either in .mcp.json or via claude mcp add. They give our coding agents direct access to documentation and infrastructure without us having to explain context manually.

Supabase MCP — query tables, manage schema, run SQL, fetch config.

Mastra Docs MCP — full Mastra documentation, code examples, API reference. Prevents hallucination when writing agent code.

Context7 — this one is critical. Context7 by Upstash pulls up-to-date, version-specific documentation for over 9,000 libraries and injects it directly into the agent's context. Append "use context7" to any prompt and your agent gets current docs instead of hallucinating APIs from six months ago. We use it aggressively to build our own MCP knowledge base for our agents. It is the difference between an agent that knows Next.js 13 patterns from training data and an agent that knows the actual Next.js 15 API.

Next.js DevTools MCP — project context and debugging.

The compound effect of having all of these configured is significant. Your coding agent goes from a smart assistant that knows TypeScript to a smart assistant that knows your entire stack, with current documentation for every library you use. The difference is not incremental.

What We Know We Are Missing

This list has gaps. Real ones. Not artful omissions.

We do not have a proper integration layer. No Zapier, no Make, no dedicated webhook management, no event bus between services beyond what Inngest handles. When we need two systems to talk to each other, we write a route handler and call it good enough. It is not good enough.

We do not have proper observability. Well, we we do. We just dont use it as much as we should. Sorry Mastra.

We do not have a real vector storage story. Were also pretty sure vector search should die. We have high hopes for other solutions. We use Mastra's built-in RAG primitives but have not committed to a dedicated vector database like Pinecone for production workloads.

Error monitoring is spotty. Sentry is on the list. It is not configured on everything it should be configured on.

Analytics is inconsistent. PostHog is free and good and we should use it more.

Testing is our weakest area. Mastra has evals built in. We should use them. We mostly do not. Our agent testing story is essentially "run it and see if it seems right," which is as embarrassing to write as it is to live.

We are probably missing tools for SMS and notifications, for CRM integration, for calendar management, for document processing, for a dozen other categories that we have not needed yet or have been hacking around with scripts. If your reaction to this list is "how do you not have X," the answer is probably that we have not gotten to it yet and we know. Or we've gotten to it and forgot to add it to the list.

We are being honest about all of this because pretending you have everything figured out is how you end up with a stack that looks good on a blog post and a github repo with no commit history.

A Closing Note

We wrote this partly for ourselves. When everything is moving this fast, writing down what you use forces you to think about why you use it. Several things on this list will be different in six months. Some of the tools that feel essential today will be replaced by something we have not heard of yet. Entire categories we have not mentioned will turn out to be critical.

That is fine. The point was never to find the perfect stack. The point is to build things that work with tools that do not get in the way, and to be honest about what you know and what you do not.

If something on this list is wrong, or if you are using something better, we genuinely want to hear about it. That is not a polite closing. We mean it. The only way to stay current is to stay curious, and the only way to stay curious is to assume you are always missing something.

Because you are. We are. Everyone is.


Alton Wells is the founder of Generative, Inc. He writes about AI, building, and what comes next.

Get insights like this in your inbox. Join our newsletter for deep dives on AI, technology, and building the future. No spam, unsubscribe anytime.

Get insights like this in your inbox

Join our newsletter for deep dives on AI, technology, and building the future. No spam, unsubscribe anytime.