This project, VAgentComm, is an implementation of a multi-agent system using Dapr Virtual Actors. It focuses on demonstrating core cloud-native agentic patterns such as actor-to-actor communication, event-driven state management, and dynamic actor creation. It is built based on the principles and architecture laid out in Step 3 of the Dapr Agentic Cloud Ascent (DACA) learning path.
VAgentComm provides a solid architectural foundation showcasing how decoupled, stateful actors can collaborate to handle complex workflows, such as managing conversations and contextual memory.
VAgentComm models a conversational processing pipeline involving three key types of Dapr Virtual Actors:
ChatAgent: Acts as the entry point and orchestrator. It receives user input, maintains the conversation history for a specific user (actor_id), delegates the task of generating a response to theResponseAgent, and publishes an event upon completing a conversation turn.ResponseAgent: A specialized actor dynamically created by theChatAgent. Its primary role is to construct a response based on the user's input and contextual information retrieved from theMemoryAgentActor. It also maintains a simple count of the messages it has processed.MemoryAgentActor: An event-driven actor that manages a simple memory store for each user (actor_id). It subscribes toConversationUpdatedevents published by theChatAgentand updates its internal state (memory) based on the event data. Other actors, like theResponseAgent, can query it for this stored memory.
The system leverages Dapr's State Management for actor state persistence, Actor Proxies for asynchronous invocation between actors, and Pub/Sub for a decoupled, event-driven approach to memory updates.
- Demonstrate Actor Communication: Implement and showcase asynchronous invocation patterns between different Dapr Virtual Actor instances using Actor Proxies.
- Dynamic Actor Creation: Illustrate how external interactions or parent actors can dynamically create child actors (
ResponseAgent,MemoryAgentActor) tailored to specific users or tasks. - Event-Driven State Management: Show how Dapr Pub/Sub can be used in conjunction with actors to implement event-driven updates to actor state (specifically, updating memory).
- Fault Isolation: Highlight the resilience provided by the actor model, where independent state and execution prevent failures in one actor instance from cascading to others.
- Context Awareness Foundation: Establish the architectural pattern for providing context (via the
MemoryAgentActor) that can be utilized by processing actors (ResponseAgent) to influence behavior. - Build a Robust Architecture: Provide a practical, runnable example of a multi-actor system that serves as a robust base for building more sophisticated agentic applications.
- Three interconnected Dapr Virtual Actor types:
ChatAgent,ResponseAgent, andMemoryAgentActor. Guardrails to user and agent context related to topic. - Dynamic, per-user/session instantiation of
ResponseAgentandMemoryAgentActordriven by interactions. - Asynchronous method invocation between actors (
ChatAgent->ResponseAgent,ResponseAgent->MemoryAgentActor, Pub/Sub Subscriber ->MemoryAgentActor) using Dapr Actor Proxies. - Event publication (
ConversationUpdated) from theChatAgentto a Dapr Pub/Sub topic (user-chat). - Event subscription handled by the application's
/subscribeendpoint, which in turn triggers the relevantMemoryAgentActorinstance. - State persistence for
ChatAgenthistory,ResponseAgentcount, andMemoryAgentActormemory using a configured Dapr State Store. - Fault isolation and single-threaded execution guarantee provided by the Dapr Actor runtime.
- FastAPI web server providing REST endpoints for:
- Initiating a conversation turn and triggering the agent workflow (
POST /chat/{actor_id}). - Retrieving the conversation history for a user (
GET /chat/{actor_id}/history). - Checking the message count for a
ResponseAgentinstance (GET /response/{actor_id}/count). - Retrieving the current memory state for a
MemoryAgentActorinstance (GET /memory/{actor_id}). - Receiving Dapr Pub/Sub events (
POST /subscribe).
- Initiating a conversation turn and triggering the agent workflow (
- Python: The main programming language.
- FastAPI: Used for building the web server and handling Dapr callbacks and endpoints.
- Dapr: The core framework providing Virtual Actors, State Management, and Pub/Sub building blocks.
- Dapr Python SDK (
dapr,dapr-ext-fastapi)
- Dapr Python SDK (
- Redis: Used as the backing store for Dapr State Store and Pub/Sub components (requires a running Redis instance accessible to Dapr).
- Tilt (Optional but Recommended): For streamlined local development setup, including starting Dapr, Redis, and the application.
- uv (Optional): A fast Python package installer.
Before setting up and running VAgentComm, ensure you have the following installed:
- Docker/Rancher (for running kubernetes cluster, Redis and Dapr components)
- Python 3.8+
- A Python package manager (
uv,pip,poetry, etc.) - Tilt (Optional - if you want to use the provided
Tiltfile) - Basic understanding of Dapr concepts (State Management, Pub/Sub, Actors) is helpful.
-
Clone the Repository:
git clone ... cd vagent_comm -
Add Env Vars: Create a .env file and add GEMINI_API_KEY - feel free to use kubernetes secret for it. For simplicity here we are using .env.
The easiest way to run VAgentComm locally is using Tilt, which orchestrates the Dapr sidecar, Redis, and the application based on a Tiltfile.
-
Using Tilt (Recommended): Open docjer desktop/rancher desktop. If you are not using nerdctl runtime (we get this in rancher as well) then just comment this line from Tiltfile:
load('ext://nerdctl', 'nerdctl_build')Tile works with both docker and containerd runtimes. Ensure you have a
Tiltfileconfigured for your project. From the project root:tilt up
Tilt will start the necessary infrastructure and your application, providing a dashboard for monitoring. The application will typically be accessible on
http://localhost:8000.- Tilt UI: http://localhost:10350/
- Dapr Dashboard: http://localhost:8080
- Agents: http://localhost:8000/docs
Once the application and Dapr sidecar are running, you can interact with the system using the FastAPI endpoints. Open your browser to the interactive API documentation:
Use the endpoints in the default group to test the multi-agent flow:
-
Send a message:
POST /chat/{actor_id}(e.g.,/chat/user1)- Request Body:
{"role": "user", "content": "Tell me something."} - This initiates the workflow:
ChatAgentreceives input, delegates toResponseAgent(creating it if it doesn't exist),ResponseAgentqueriesMemoryAgentActor(creating it if it doesn't exist), generates a response,ChatAgentupdates history, andChatAgentpublishes an event.
-
Check History:
GET /chat/{actor_id}/history(e.g.,/chat/user1/history)- Retrieve the conversation history managed by the
ChatAgent.
-
Check Response Count:
GET /response/{actor_id}/count(e.g.,/response/user1/count)- See how many messages the specific
ResponseAgentinstance has processed.
-
Check Memory:
GET /memory/{actor_id}(e.g.,/memory/user1)- Retrieve the memory state stored and updated by the
MemoryAgentActorfor this user.
The /subscribe endpoint is automatically invoked by Dapr's Pub/Sub component whenever a message arrives on the configured topic (user-chat). It processes the event payload to trigger the MemoryAgentActor.UpdateMemory method.
-
Dapr Logs: View the logs of your application and the Dapr sidecar using the Dapr CLI.
dapr logs -a vagentcomm-app
(Replace
vagentcomm-appwith your application's Dapr app-id) -
Dapr Dashboard: Access the dashboard to monitor running actor instances, component status, and more.
Navigate to the Actors tab to see the active instances of
ChatAgent,ResponseAgent, andMemoryAgentActorfor each user ID you interact with.
This project provides a strong foundation. Here are some potential next steps and areas for expansion:
- AI Agent SDK Integration Enhancement: Explore and manage more complex agent behaviors within the
ResponseAgentor by introducing new agent types. - Advanced Memory Management: Implement more sophisticated memory handling in
MemoryAgentActor, such as summarization, sliding window context, or different types of memory stores (e.g., vector databases). - Add More Agents: Introduce new actor types for specific tasks, such as a
SentimentAgent,TranslationAgent,ToolCallingAgent, etc., demonstrating more complex multi-agent choreography. - Error Handling & Resilience: Enhance error handling and explore Dapr resilience features for retries and circuit breakers.
- Observability: Add detailed tracing and metrics using Dapr's observability building block.
- Deployment: Deploy the application and Dapr components to a cloud environment (Kubernetes, GKE, etc.).
- Add Conversational UI Interface like chainlit.