Building Cloud-Native Agentic Systems With Dapr Agents
Distributed application runtime (Dapr) is an event–driven, portable runtime that helps developers in building secure, reliable and scalable cloud–native applications. Among its popular offerings are actors, which are lightweight, highly concurrent entities and workflows, built on top of actors to orchestrate complex tasks.
The newest addition to the runtime is Dapr agents, through which developers are able to write production-grade agentic artificial intelligence (AI) systems that can run to completion, even within dynamic and inherently unpredictable cloud environments.
One of Dapr’s key advantages is its seamless integration with Kubernetes. Since Dapr natively supports Kubernetes, deploying agentic infrastructure to a Kubernetes runtime becomes straightforward and efficient. In addition, its rich built-in role-based access control (RBAC) support — which is particularly useful when agents interact with your application programming interfaces (APIs), the ability to scale transparently across multiple machines and robust failure recovery with minimal developer intervention make Dapr agents a promising infrastructure to rely on.
As part of this guide, we will explore different strategies to build agents using the Dapr agents framework.
Prerequisites
- Docker: It is required to run the Dockerized Dapr components
- Dapr CLI: The command line interface (CLI) makes it easy to install and run the Dapr artifacts locally.
- Dapr Agents: This is the framework required to build agents. Currently, it is available only in Python.
Simple Chat Client
To begin with, let’s create a simple chat application. We will use OpenAIChatClient from the agents framework to talk to the OpenAI models.
openai_chat.py
{code block: start}
from dapr_agents import OpenAIChatClient from dotenv import load_dotenv
load_dotenv()
llm = OpenAIChatClient()
response = llm.generate(“Tell me about Dapr Agentic Framework”) if len(response.get_content()) > 0:
print(“Response :”, response.get_content())
{code block: end}
In order to run this script, first create a .env file with the OpenAI API key. If you don’t have the key, create one from the API developer dashboard.
“`.env OPENAI_API_KEY=<your_api_key>
“`
Next, run the following commands:
- dapr init: Initializes all the Dapr components and the runtime
- pip install dapr-agents: Installs the Dapr-agent Python libraries
- pip install python-dotenv: Loads environment variables from the .env file
- python openai_chat.py: Runs the chat application
After executing the above commands, you will be able to see all the interactions Dapr is making with the large language model (LLM) in the command line. One major advantage of using Dapr is its ability to filter out personally identifiable information (PII), making conversations more secure.
Agent Toolcall
Agents extend language capabilities beyond text generation to real–world actions. By using them, you enable the model to interact with your services and APIs in a meaningful way. Dapr’s agentic framework provides the capabilities to create such agents.
The first step in the process is to create a tool. Tools can range from something as simple as performing an addition to something as complex as making an API call. For example, the following code snippet demonstrates how to create a tool that fetches weather information.
{code block: start}
from dapr_agents import tool
from pydantic import BaseModel, Field
class GetWeatherSchema():
city: str = Field(description=”city to get weather for”)
@tool(args_model=WeatherSchema) def retrieve_weather(city: str) -> str:
weatherData = weatherapi.getweather(city); // calling the weather api. return f”Weather for {city}: {weatherData}.”
tools = [retrieve_weather]
{code block: end}
- @tool decorator marks the function as a tool that can be invoked by an agent.
- @args_model=WeatherSchema projects the input parameters to be supplied to the retrieve_weather function, which is the name of the city in this case.
With the tools in place, it is time to pair them with an agent.
weather_agent.py
{code block: start} import asyncio
from weather import tools from dapr_agents import Agent
AIAgent = Agent( name=”WeatherAgent”, role=”Weather Advisor”,
goal=”You are responsible for retrieving weather for a location”, instructions=[ “Fetch the weather info” ],
tools=tools,
)
async def main():
await AIAgent.run(“Can you give me the weather details for Seattle, WA ?”)
if name == “ main “:
asyncio.run(main())
{code block: end}
In order to create an AI agent, we will leverage the agent class with the role, goal and instructions parameters.
Role and goal: Gives a purpose and drives clarity for the agent instructions: Represents actions this agent can perform
Tools: Provides a list of supported tools that the AI can leverage to perform the instructions.
Now that the tools and the agent are ready, let’s understand how they all stitch up together.
The workflow begins when the user submits a prompt. The prompt, along with the tools, is passed to the LLM using OpenAI’s function-calling format. This format is popular and widely used when language models need to interface with code or services. Once the model figures out which tools to use, it invokes them using the necessary arguments. So, in this case, the weather tool is called with ‘Seattle’ as the city parameter. The weather agent then uses the arguments to call the weather tool, and the resulting response is returned to the LLM. In the final step, the LLM summarizes the response and returns the result to the user.
Run the python weather_agent.py command to see how Dapr intelligently orchestrates calls between the agent and model provider.
Multi-Agent Workflows
So far, we have explored how a single agent with tool-calling capabilities can be used to solve a problem. However, real–world scenarios are much more complex and often require multiple agents to work together to complete a task. This is where multi-agent workflows come into the picture. Dapr provides three ways to build them:
- Round Robin: In this method, tasks are assigned sequentially in a fixed order to each agent. It is ideal for scenarios where participation from all the agents is desired. For example, consider having 10 worker agents to do the same job. To prevent overloading any single agent, work can be evenly distributed among them using the round robin strategy.
- Random: Agents are selected at random in this strategy. This can be useful in scenarios where all agents are capable of completing the task and there is no need for strict ordering or balancing.
- LLM-Based: This is the most common use case for organizations or developers, where a language model acts as the brain and chooses the agent based on the task at hand. For example, consider a scenario involving a weather agent and a location agent. When a user asks, ‘What’s the weather at my current location?’, the LLM first calls the location agent to determine the user’s city, then uses that information to invoke the weather agent.
orchestrator_setup.py
{code block: start}
from dapr_agents import RoundRobinOrchestrator from dotenv import load_dotenv
import asyncio
async def main():
try:
workflow_service = RoundRobinOrchestrator( name=”RoundRobinOrchestrator”, message_bus_name=”messagepubsub”, agents_registry_key=”agents_registry”,
).as_service(port=8004)
await workflow_service.start() if name == “ main “:
load_dotenv() asyncio.run(main())
{code block: end}
The above code snippet demonstrates how to set up the RoundRobinOrchestrator to orchestrate different agents.
The agents_registry_key is used to determine the different agents the orchestrator has access to. For example, when creating the weather and location agents, you would register them with the same key the orchestrator is registered with — in this case, ‘agent_registry’.
Final Thoughts
The majority of today’s workloads run in the cloud. While several agentic frameworks exist, few are truly cloud–native and designed specifically to address the challenges of operating in distributed, scalable environments. From transparent scaling to fault handling and durable execution, Dapr agents are purpose–built to solve these problems. Go ahead and explore the power of a cloud–native agentic framework today.