There is a new trend in almost every corner of the internet, and it revolves around AI Agents. In case you are new to this topic, an AI Agent is an implementation of LLM communication, where an LLM is provided with tools, accesses, and decision-making abilities. Think of it as a remote working freelancer.
This technology and concept are powerful by themselves, but joining those Agents in teams is where they get insanely powerful. Those teams are usually called “Workflows”. You provide a task to workflow, and your Agents work together to provide you with a satisfying result.
What are AI Agent Workflows?
I am sure you understand the concept of Agents working together. In the real world, we have well-known organizational structures in place, and we don’t even think about them. We will implement and talk about those structures (or ‘workflows’) in a moment. If you want a bit more in-depth explanation, the read this fantastic article from Anthropic.
Getting started with AI Agent Workflows is easier than you think
It’s easy to think that implementing such an agent workflow must be a very complex and technical task. Of course, some technicality is required. But if you have any experience with programming (a.k.a. run a hello world with typescript project) and you know English (assuming you read this article, you can), then, believe it or not, you are good to go.
There are a lot of resources and frameworks on the internet that can help, but in this article, I am going to present a solution created with AI SDK from Vercel.
Building AI Workflows step-by-step
We will be working on a simple node project with AI SDK as a dependency. So start up a new project, and feel free to follow along. Our setup is extremely simple.
Think of a situation where you’d like to apply for a loan. You start at Agent A, and after that, your application is passed along to Agent B for initial screening. Agent B can either deny you a loan or pass it along for a more in-depth check, etc. It’s all processed synchronously, one step at a time.
We will start with the first point of contact: the agent receiving a conversation with a client and then passing it along for further inspection. We will implement an agent that gathers information with a different workflow later.
constfirstResponse=awaitgenerateObject({
model,
system:
'You are a first point of contact for a loan company. Your job is to turn client conversation into loan application.',
This agent prepares a nice object for us to work with further down the chain.
Now that we have that, we can implement a “gate.” A gate is an agent that decides whether to continue or stop the chain based on the input values and system prompts.
constgateResponse=awaitgenerateObject({
model,
system:
'You are a loan specialist. Based on the given json file with client data, your job is to decide if a client can be further processed.',
schema: z.object({
is_client_accepted: z.boolean(),
denial_reason: z
.string()
.optional()
.describe('If client is rejected, you need to give a reason.'),
And it looks like my application passed through the gate!
Believe it or not, but this is the chain workflow. We get the response from one model, and then pass it to the next one. Repeat ad infinitum, and your chain can be as complex or as simple as you need.
Routing
You must have called a call center or customer support at some point in your life. Imagine meeting Agent A, who decides who to contact you with. You can be ‘routed’ to Agent B, C, or D. After they resolve your issue, your call ends.
This time, we will start by making the Agents to whom our call will be dispatched. Here are our Tech, Account, and Finance specialists:
In this example, our specialists are simple system prompts. You could, however, improve that with their own tool calls, or other improvements. As an example, this is enough.
Now that we have our specialists, let’s prepare our dispatcher.
constroutingResponse=awaitgenerateObject({
model,
system:
'You are a first point of contact for a call center. Your job is to redirect the client to a correct agent.',
schema: z.object({
agent_type: z.enum(agentTypes),
}),
messages: [
{
role: 'user',
content: `
Hi! I want to cancel my subscription now! I am very unhappy and mad.
Now, our Agent is correctly passing clients to the required specialist. That’s the idea behind Routing Agents. Of course, there are different techniques and different models, but this will work as a simple implementation.
Parallelization
Think of a translation task. You rarely have one person who speaks three languages, not to mention more. So, you pass your article to Agents A, B, and C, who are specialists in their respective languages. After they finish work, you receive an article in multiple languages.
So first, let’s create our specialists who will work in parallel and pass each of them the same message. Remember that the keyword here is “parallel.”
constuserMessage: CoreMessage={
role: 'user',
content: `
In this article we will cover AI Agents workflows. We hope to provide an explanation, but be aware, that in-depth explanation
would be too long for all of them. So this time, we will focus on the idea behind workflows. In future, we can make separate articles
and implement a more complex case, or even a working application for each of them.
`,
}
constgermanResponse=generateText({
model,
system:
'You are German Translator. Your job is to translate text received from user, and translate it to German. Respond only with translation!',
messages: [userMessage],
})
constspanishResponse=generateText({
model,
system:
'You are Spanish Translator. Your job is to translate text received from user, and translate it to Spanish. Respond only with translation!',
messages: [userMessage],
})
constpolishResponse=generateText({
model,
system:
'You are Polish Translator. Your job is to translate text received from user, and translate it to Polish. Respond only with translation!',
Here, we trigger all our translators at once. Now, we need an Agent that Anthropic article calls an Aggregator. So, let’s ask him to make small corrections and give us all the translations.
constaggregateResponse=awaitgenerateObject({
model,
system: `You are tasked with aggregating translations of an article.
You can provide additional tweaks and fixes to formatting or translation.
You will receive a message with original, and then translations done with previous agents`,
And with that code, in a much shorter amount of time, we received all the translations:
You might wonder why I passed all of those translations to the Agent in the end, instead of just pushing them into object. Well, as much I love AI Agents, they still can hallucinate, and add some boilerplate to the translation, like “Happy to help with translation, here it is:”. Aggregating Agents at the end grants us additional protection.
Orchestrator-Workers
Let’s think of a project team. Our team will consist of a QA, a Developer, and a DevOps. We pass our feature request to our virtual Tech Lead, and he splits the tasks for estimation. Later, they estimate their tasks and get back to the Scrum Master to give us the final estimation in man days. Let’s start with the Tech Lead!
constpmMessage: CoreMessage={
role: 'user',
content: `I want to add a simple account details screen in our NextJS application.`,
}
consttechLeadResponse=awaitgenerateObject({
model,
system: `
You are a tech lead. You receive a message from the PM,
Your job is to delegate tasks to your team made of a QA, Developer and DevOps.
And now, let’s run our workflow. Our Tech Lead prepares the tasks for the team:
After that, our team gives their estimations and reasoning behind it:
At the end, the Scrum Master compiles all the results into a report:
Should man days be summed? I’m not sure about it. Maybe we should find a better Scrum Master or explain the details of his work a little bit better! Whether we are happy with that result or not, this is how this workflow can be implemented. It’s basically a mix of routing and parallelization.
Evaluator-Optimizer
Writing an article is never an easy task. So you give it to Agent A - and to ensure that the paper is of good quality, you also employ Agent B to evaluate and provide feedback. Those two Agents work until Agent B is finally happy with the work and gives you the results.
Let’s create our writer, Kewin, who is tasked with writing an article about AI Agents. He has an additional extreme condition to fulfil: He has to write his article in five sentences!
constmessages: CoreMessage[]=[{role: 'user',content: "Let's see your first draft!"}]
constkewinsArticle=awaitgenerateText({
model,
system: `
You are a writer. You write articles about AI.
Your task is to write an article about AI agents, and to do it in only 5 sentences!
You might get additional feedback from your supervisor!
It looks like our writer is much better than we expected! He convinced his supervisor in just two tries! This is how the Evaluator-Optimizer works in practice.
Summary
As you noticed, I allowed myself some freedom in choosing a case. However, all the rules and ideas are present in those implementations. You can freely expand and make them more complex or simplify them. You can also join them together and use in any configuration you need. Workflows are a powerful way of getting your AI Agents to cooperate to finish more complex tasks - and I encourage you to try them yourself, e.g., by playing with the examples from this article.
Integrating AI into your React Native workflow?
We help teams leverage AI to accelerate development and deliver smarter user experiences.
Building a Software Factory: Write Specs an Agent Can Build From
Learn how to research requirements, resolve open decisions, and write testable specs that AI coding agents can implement without the planning conversation.
Nov 4·Article
Large-Scale Migrations With Coding Agents: Planning, Verification, and Rollback
Plan codebase migrations with coding agents using reviewable requirements, verification checks, staged rollouts, and defined rollback criteria.
Nov 2·Article
Conversational Banking: From Customer Questions to Authorized Actions
Explore conversational banking architecture through a card-dispute example, covering tool access, authorization, execution, observability, and human handoff.
Oct 28·Article
Building a Software Factory: The Night My Agents Waited for Me
Learn how permissions, review limits, and missing product decisions stalled two overnight coding agent runs, and how their maintainer revised the workflow.
Oct 22·Article
Your AI Coding Agent Still Needs an Architecture
Use explicit contracts, behavior tests, and dependency checks to guide AI coding agents and review their changes through a TypeScript favorites example.
Oct 15·Live Stream
Who Left the Agents Running? React Native Software Factories
Join Kewin Wereszczyński and Szymon Chmal to explore what can go wrong in a React Native software factory overnight and the controls that keep agents on track.
Oct 14·Podcast
When Coding Gets Faster, What Breaks Next?
Matt Hargett explains how AI moves bottlenecks across testing, deployment, infrastructure, support, and the rest of software delivery.
Oct 12·Podcast
AI Coding Agents and Hermes With Tzvetan Mikov
Tzvetan Mikov discusses AI coding agents, context switching, low-level engine optimization, reviewing specs and tests, and his plans for Hermes X.
Oct 12·Podcast
State Machines for AI Agents With David Khourshid
David Khourshid explains state machines for AI agents, human approval steps, tracing, and handling invalid model outputs in agent workflows.
Oct 9·Article
How to Maximize AI SDLC? Measure the Outer Business Loop, Not the Inner Developer Loop
Connect AI-assisted development to measurable business outcomes. Matt Hargett shares a checklist for assessing user exposure, results, and delivery costs.
Oct 7·Talk
Automating Mobile QA with Cloud Agents
Michał Pierzchała shows how cloud-based QA agents can test real iOS and Android user flows and bring screenshots, recordings, and logs into pull requests.
Oct 1·Live Stream
Can Jev Make AI Agent Decisions Faster?
Explore Jev with Kewin Wereszczyński and Szymon Chmal: how it works, its approach to faster agent decisions, and possible local alternatives.
Mar 19·Tutorial
The Hard Way vs. The React Native AI SDK Way: Stop Writing Custom Modules for Every Model
Learn how React Native AI uses a unified provider model to switch between cloud and on-device LLMs without rewriting application logic, enabling reliable AI experiences online and offline.
Mar 12·Tutorial
Build Smarter Apps: Tool Calling & AI Orchestration Explained
Learn how on-device models in React Native can call tools, interact with external APIs, and return structured outputs you can use directly in application logic.
Mar 5·Tutorial
MLC LLM + React Native: On-Device AI Without the Pain
Learn how to run third-party on-device LLMs in React Native using MLC LLM. Choose your models, run them efficiently across platforms, and keep a unified JavaScript API with React Native AI.
Feb 24·Tutorial
Intelligent Fallbacks with Apple Intelligence in React Native
Learn how to use Apple’s built-in Foundation Models in React Native apps, reduce memory usage, and enable fast, fully on-device AI with React Native AI Apple.
Feb 10·Tutorial
What Is the React Native AI SDK? A Complete Intro & Quickstart
Learn why on-device AI matters for React Native apps, how local LLMs behave offline, and what problems React Native AI is designed to solve from day one.
Jan 29·Tutorial
Implementing an Android TurboModule with Kotlin
Learn how to implement a React Native TurboModule on Android, from the TypeScript spec and Codegen to the Kotlin implementation and package registration.
Jan 19·Tutorial
Working with Different Threads in Swift TurboModules
Learn how JavaScript, native module, background, and main threads interact in React Native TurboModules, and how to use GCD queues to run async work safely in Swift.
Jan 9·Tutorial
How to Add Type-Safe Constants to Swift TurboModules
Learn how to expose typed, immutable constants from a Swift TurboModule using Codegen, and get full end-to-end type safety between native and JavaScript.
Dec 30·Tutorial
Adding Event Emitters to Your TurboModule in Swift
Learn how to emit native events from a Swift TurboModule and subscribe to them in JavaScript, including proper memory management and Codegen integration.
Dec 22·Tutorial
Writing Your First TurboModule in Swift
Learn how to build a fully working TurboModule in Swift, integrate it with Codegen, and bridge it through Objective‑C inside an Expo app.