AG2 Beta: Stronger Foundation for Real-World Agents

The original AutoGen and later AG2 architecture helped define the early agent ecosystem. It enabled real systems, shaped how many developers thought about agent orchestration, and gave us firsthand experience building and operating agent applications in practice.
That experience also made the limits of the original design clearer over time. As the agent ecosystem matured, expectations changed. Agents increasingly needed to fit into real application environments with concurrent users, explicit session boundaries, platform identities, persistence layers, and integration points that could not be treated as incidental details.
We found that some of these needs were challenging to address cleanly inside the original framework model. In many cases, shipping more production-suitable behavior meant adding complexity around the edges instead of improving the core abstraction itself, taking the focus of developers away from building agentic capabilities. That is a big part of why we decided to create AG2 Beta: a new framework track built around lessons we learned from the original AG2 to better support modern, real-world agentic systems.
You can read more about the motivation behind AG2 Beta in the AG2 Beta overview.
One of the clearest examples of that shift is conversation state.
The Problem with Stateful Agent Instances#
In the previous implementation, an agent instance effectively carried the active conversation with it. That was convenient for small examples, but it became impractical in real applications:
- one agent instance could not be cleanly reused across concurrent users
- isolating conversations required extra coordination outside the agent API
- integrating agents into chat platforms, web apps, and background workers was hard
These gaps appear when you move from demos to production.
In a real-world application, the agent definition should be reusable. The conversation should be isolated. The application should decide how sessions are created, persisted, resumed, and discarded.
The Core Idea: MemoryStream#
AG2 Beta introduces MemoryStream as the conversation boundary.
Instead of storing the current conversation history on the agent instance, you create a fresh stream for each conversation. To continue that conversation, you pass the same stream into the next ask() call.
That provides a better model for real systems:
- the agent definition is reusable
- each conversation is isolated by its own stream
- concurrent users can share the same agent safely while keeping separate histories
- the application can decide when to persist or discard a conversation
If you want to explore the details of how streams work as the event bus behind a conversation, see Events Streaming.
Basic Example: One Agent, Two Sequential Turns#
Here is the simplest form of the new model:
The important detail is not the model call, it is the ownership of state.
The same agent instance serves both conversations. The memory lives in stream_a and stream_b, not in the agent itself. That is the key property that makes the API significantly easier to embed into real applications.
From Sequential Turns to Real Applications#
This architecture becomes even more useful when the agent is connected to a real communication channel.
To demonstrate that, here's a Telegram-based integration. The structure is intentionally simple:
- keep one reusable agent definition
- create one
MemoryStreamper Telegram chat - pass the same stream back into
agent.ask(...)on each new message
That is enough to turn the same agent into a multi-user ambient application without mixing conversation histories.
The first, minimal, version focuses on the session boundary and message flow. We pass user_id into the conversation variables so the next iteration of the conversation can use that identity inside tools.
The resulting interaction looks like this in Telegram: one chat, one stream, and each new message continues the same conversation context.

Adding Long-Term Memory on Top#
Short-term conversation state is handled by MemoryStream, but real assistants often need more than that. They also need a lightweight way to recall what happened earlier, even after the in-memory conversation is cleared.
The Telegram example shows one practical pattern:
- keep the live conversation in a
MemoryStream - save the completed conversation to a per-user file such as
./memory/<user_id>/YYYY-MM-DD.md - expose a tool that can load that saved history back into context when needed
The next snippet adds to the previous to do this, showing the additional pieces needed for long-term memory: a tool that can read saved history, a /clear command that persists the current stream before dropping it, and a helper that writes the conversation transcript to disk.
After calling /clear, the bot can still recover the saved context through the history-loading tool:

Taken together, the two snippets describe the full pattern: the first establishes per-chat conversation streams, and the second adds persistence and recall on top of that same structure. It does not require a complex orchestration layer to feel production-shaped.
The application (Telegram Bot) owns session lifecycle. The agent owns reasoning and tool use. MemoryStream bridges the two.
`ambient.py` — full source (click to expand)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | |
Why This Matters#
This design is a better fit for how real applications are actually built:
- Chat sessions, web sessions, and background jobs already have their own identity model
- session state often needs to be persisted independently from the agent definition
- developers need a simple way to resume, archive, or discard conversations
That is why MemoryStream is an important primitive in AG2 Beta. It moves conversation ownership to the same layer that manages users and sessions.
A Pattern You May Recognize from OpenClaw#
If you have looked at OpenClaw, this architecture should feel familiar.
The shared idea is simple: keep the runtime session outside the reusable agent definition. The application manages per-user or per-channel conversation state, while the agent logic stays portable.
Start with Single-Agent Systems#
Right now, AG2 Beta is especially strong for single-agent applications and integrations. That is deliberate.
We want to make the most common real-world cases easy first:
- one reusable agent
- one conversation stream per user or session
- optional persistence and memory tools when the application needs them
That model is already enough to power ambient assistants, bots, web co-pilots, and background workers in a clean way.
Note
Ready for multi-agent workflows? They're on the way, but you can start experimenting with Beta agents in existing AG2 workflows right now. Beta agents can be converted to ConversableAgents using as_conversable(). This allows them to be used in existing group chats, sequential workflows, and with handoffs. See the AG2 Compatibility guide for the current integration path.
You can introduce new agents from the Beta API right into your current AG2 chat topologies.
Try AG2 Beta#
AG2 Beta is available today inside the ag2 package. Just pip install ag2 like you already do and check out the docs.
Here's a suggested mental model to get started:
- Define one reusable agent
- Create a new
MemoryStreamfor each conversation - Pass the same stream back into each new turn
- Add persistence only where your application actually needs it
It's a small API shift, but it unlocks a strong foundation for real-world systems.
If your current agent application needs isolated conversations, concurrent users, or lightweight long-term memory, give AG2 Beta a try!