AI Agents

Build agents that actually ship.

Union gives agent teams the durable orchestration layer to run multi-agent systems, manage tool use, and deploy agentic workflows, with built-in fault tolerance, observability, and human-in-the-loop controls. Agents do not just run on Union. They can call it: provisioning, retries, and fan-out are ordinary Python.

Try the devbox

A free, local sandbox to
explore the Union.ai platform.

Chat with an engineer

Trusted by leading AI agent teams

Built on Flyte

Open source at the core.

Union is built on Flyte, the open-source AI runtime we create and maintain under the Linux Foundation AI & Data.

4000+

companies using Flyte today

17M+

Flyte SDK downloads

Infrastructure as Context

Except blocks can change the hardware.

An agent picks its own tools at runtime, so you cannot size the box for a plan you have not seen yet. One branch reads a short page, the next loads a model or parses a document that will not fit. Union hands you a typed error instead of a stack trace, so the step that blows memory comes back as an exception you can catch and re-run on a bigger box. And because provisioning is just a call, the agent can be the one making it.

  • Typed infrastructure errors. `OOMError`, `TaskInterruptedError`, `TaskTimeoutError`,` ImagePullBackOffError`. Failures you can branch on.
  • Resources changed at runtime. `.override(resources=...)` re-runs the same tool call with different memory, CPU, or accelerator.
  • Every tool in its own container. Call OpenAI, Anthropic, or Gemini, or serve your own models with vLLM or SGLang, each with its own image, secrets, and hardware.
  • The handler does not have to be human. Provisioning is an ordinary Python call, so the same API you write a retry policy against is one an agent can call while a run is in flight.
Function-Level Checkpointing

Recover. Fork. Replay.

Agentic workflows run for hours and make hundreds of LLM calls. One bad API response an hour deep should not cost you the whole run, and it should not cost you the tokens either. Union records what finished as the run happens, outside the node doing the work, so a bad step in an agent run is where the next run starts.

  • Recover what failed. Point `recover` at a prior run. Completed tool calls are reused and only what failed or changed runs again, even without caching enabled.
  • Fork from any step. `flyte.rerun` starts a prior run again at the step you pick, with a new prompt, a different model, or a corrected tool.
  • Pause without burning compute. Human-in-the-loop gates wait indefinitely for approval, then continue from exactly where they stopped.
Durable Artifacts

Outputs that outlive the run.

An agent's output should not be a string that vanishes when the process exits. Artifacts are typed, versioned values that persist past the run that made them, so a synthesis becomes the typed input to the next workflow, or to the app serving it, without re-running the agents that produced it.

  • Passed between workflows and apps. One pipeline's research output is another's typed input, without re-running the producer.
  • Versioned, not overwritten. A new version is a new artifact, so a downstream run resolves to the exact output it acted on.
  • Events, not polling. `flyte.OnArtifact` fires a run whenever a new version lands, with no cron hacks in between.
Run History & Versioning

Reproduce a run from months ago.

A non-deterministic system is only debuggable if you can see what it actually did. Every run keeps what it takes to reproduce a result: the code that executed, the infrastructure it ran on, and the configuration applied to both. For agent workloads that same record doubles as the trace of every step the agent chose for itself.

  • Observability for agents. Every step a non-deterministic workflow took is on the record, including the ones it chose itself.
  • Inputs and outputs per run. Open an execution from months ago and see every prompt that went in and every response that came back.
  • The code that ran, not the code today. Each run resolves to its own code bundle and container image, down to the model and prompt version.
Fan-Out & Scale

Fan out on durable asyncio.

Parallel research agents, debate loops, and manager-worker hierarchies are all native Python async. `asyncio.gather` when you want the whole panel at once, `flyte.map.aio` when you want bounded concurrency over a long list, each agent in its own isolated container.

  • Concurrency you can cap. `flyte.map.aio(fn, items, concurrency=500)` bounds how many run at once, for a fan-out wider than the cluster.
  • Retries with pacing. `retries=5`, or a `RetryStrategy` with exponential backoff so a rate-limited LLM API gets time to come back.
  • Planner, ReAct, debate, manager-worker. The coordination is ordinary async composition, so the pattern is yours to write rather than a framework to fight.
Pure Python

Multi-agent workflows in pure Python.

Parallel research agents, debate loops, and human approval, with no framework lock-in. Write it in async Python, run it durably on Union.

import asyncioimport flytefrom flyteplugins.openai.agents import function_toolfrom flyteplugins import hitl env = flyte.TaskEnvironment(    secrets=[flyte.Secret(key="openai_key", as_env_var="OPENAI_API_KEY")],) @env.task()@function_toolasync def web_search(query: str) -> str:    return await tavily.search(query) @env.task(retries=3, cache="auto")async def research_analyst(topic: str, angle: str) -> str:    agent = Agent(tools=[web_search], model="gpt-4o")    return await agent.run(f"Research {topic} from {angle} perspective") @env.task(retries=3)async def debate_and_synthesize(reports: list[str]) -> str:    # Agents critique each other's findings    bull = Agent(model="gpt-4o", system="Argue the bullish case")    bear = Agent(model="gpt-4o", system="Argue the bearish case")    for _ in range(3):  # debate rounds        reports = [await bull.run(reports), await bear.run(reports)]    return await synthesize(reports) async def research_pipeline(topic: str):    # Fan out analysts in parallel    reports = await asyncio.gather(        research_analyst(topic=topic, angle="market"),        research_analyst(topic=topic, angle="technical"),        research_analyst(topic=topic, angle="sentiment"),    )    synthesis = await debate_and_synthesize(reports)    # Human approves before publishing    approval = await hitl.new_event.aio("approve", data_type=bool)    if await approval.wait.aio():        return await publish(synthesis)

Parallel research agents

Three analyst agents fan out in parallel, each with tool access and retries. Results converge for the next stage.

Multi-round debate

Bull and bear agents critique each other's findings across rounds, then synthesize into a balanced conclusion.

Human-in-the-loop gate

Pipeline pauses for human approval before publishing. The workflow is durable, so it waits indefinitely without wasting compute.

From the Blog

Learn more about AI agents on Union.

Patterns, tutorials, and production stories for building agentic systems.

Ready to ship your first production agent?

Get started in minutes with Union's free tier, or talk to our team about enterprise agent infrastructure.

Try the devbox

A free, local sandbox to
explore the Union.ai platform.

Chat with an engineer