The Dapr team is excited to introduce Dapr Agents, a framework built on top of Dapr, combining stateful workflow coordination with advanced Agentic AI capabilities.
Dapr Agents provides a robust and enterprise-ready solution for developing systems of agents:
- Reliably runs thousands of agents on a single CPU core
- Automatically retries complex agentic workflows and ensures each task completes successfully
- Natively deploys and operates on Kubernetes
- Enables data ingestion from documents, databases, and unstructured sources directly into an agent
- Built-in support for secure and observable multi-agent systems
- Vendor-neutral, eliminating risks associated with licensing changes and IP infringement
- Built on Dapr, an enterprise-trusted framework supporting observability, security, and resiliency at scale, used by governments and businesses worldwide
What is Dapr
Dapr (Distributed Application Runtime) is an open-source, event-driven runtime designed to simplify building resilient, distributed, and cloud-native applications. It provides a set of APIs that abstract complex microservices challenges such as service-to-service communication, state management, pub/sub messaging, workflow orchestration, and secret management. Dapr is platform-agnostic, running on Kubernetes, VMs, or any cloud, and integrates seamlessly with multiple programming languages and frameworks. By enabling developers to focus on business logic rather than infrastructure concerns, Dapr enhances scalability, reliability, and maintainability for modern applications.
Now that we understand what Dapr is and what it can be used for, lets learn how to build our first Dapr AI agnet
Build Your First Dapr AI Agent
In Dapr Agents, an agent is an autonomous entity powered by a large language model (LLM), acting as its reasoning engine. These agents utilize the LLM’s knowledge to process information, reason in natural language, and dynamically interact with their environment. They leverage tools—external capabilities that allow agents to perform actions beyond their built-in reasoning.
Tools enable agents to:
- Identify the right tools for a given task
- Format arguments dynamically
- Execute the tools autonomously
- Pass results back to the LLM for further processing
By annotating functions with @tool and optionally defining argument schemas, you can transform Python functions into agent tools that can be dynamically invoked within workflows.
Example: Code Review Agent
Let’s create a code review agent that integrates with the GitHub API to fetch code and feed it into an LLM for review. This agent has two tools: get_pr_code (to fetch code) and perform_review (to review code using an LLM).
import logging import asyncio import requests from dotenv import load_dotenv from dapr_agents.llm.dapr import DaprChatClient from dapr_agents import AssistantAgent, tool # Load environment variables load_dotenv() logging.basicConfig(level=logging.INFO) @tool def get_pr_code(repository: str, pr: str) -> str: """Fetch the code for a given PR""" response = requests.get(f"https://api.github.com/repos/{repository}/pulls/{pr}/files") files = response.json() code = {file["filename"]: requests.get(file["raw_url"]).text for file in files} return code @tool def perform_review(code: str) -> str: """Review code""" response = DaprChatClient().generate(f"Review the following code: {code}") return response.get_content() # Define Code Review Agent code_review_agent = AssistantAgent( name="CodeReviewAgent", role="Review PRs", instructions=["Review code in a pull request, then return comments and/or suggestions"], tools=[get_pr_code, perform_review], message_bus_name="messagepubsub", state_store_name="workflowstatestore", agents_registry_store_name="agentstatestore", service_port=8001, ) # Start Agent Workflow Service await code_review_agent.start()
To initiate the agentic workflow, send a task request:
workflow_url = "http://localhost:8001/RunWorkflow" task_payload = {"task": "Review PR https://github.com/dapr/dapr/pull/1234"} requests.post(workflow_url, json=task_payload)
Dapr Agents ensures all tasks in an agentic workflow complete reliably. These agents are resilient to process crashes, node scaling, and network interruptions, seamlessly distributing across Kubernetes pods or VMs.
LLM Task Workflows
Dapr Agents also enables LLM-based Task Workflows, which allow developers to structure workflows where LLMs provide reasoning at specific steps. Unlike event-driven systems, these workflows follow a deterministic order defined in Python functions.
Example: Trip Planning Workflow
from dapr_agents.workflow import WorkflowApp, workflow, task from dapr_agents.types import DaprWorkflowContext from dotenv import load_dotenv # Load environment variables load_dotenv() @workflow(name='mytrip_workflow') def plan_trip(ctx: DaprWorkflowContext, locations: list) -> str: forecast = yield ctx.call_activity(determine_forecast, input=(locations[0])) trip_details = yield ctx.call_activity(create_itinerary, input=(forecast)) return trip_details @task(description="Get the weather forecast for the next 5 days in {location}") def determine_forecast(location: str) -> str: pass @task(description="Create an itinerary based on the weather {forecast}") def create_itinerary(forecast: str) -> str: pass wfapp = WorkflowApp() results = wfapp.run_and_monitor_workflow(workflow="mytrip_workflow", input=(["Gotham"])) print(f"Your itinerary is: {results}")
In this example:
- plan_trip calls two tasks in sequence
- Tasks are durable, can be retried, and use LLM inference to assist in reasoning
- The Dapr Task chaining pattern makes workflows flexible and scalable
Multi-Agent Workflows
Dapr Agents supports multi-agent workflows, where agents dynamically respond to events. Agents communicate through Dapr’s pub/sub messaging system, enabling collaborative problem-solving.
Example: Autonomous Agents (LOTR Edition)
# Define Agent #1 hobbit_service = AssistantAgent( role="Hobbit", name="Frodo", goal="Carry the One Ring to Mount Doom", message_bus_name="kafka", state_store_name="postgres", agents_registry_store_name="postgres", service_port=8001, daprGrpcPort=50001 ) # Define Agent #2 elf_service = AssistantAgent( role="Elf", name="Legolas", goal="Protect the Ringbearer and scout ahead", message_bus_name="kafka", state_store_name="postgres", agents_registry_store_name="postgres", service_port=8002, daprGrpcPort=50002 ) await hobbit_service.start() await elf_service.start()
Orchestration Service
workflow_service = LLMOrchestrator( name="LLMOrchestrator", message_bus_name="kafka", state_store_name="postgres", agents_registry_store_name="postgres", service_port=8003, daprGrpcPort=50003) await workflow_service.start()
Running the Multi-Agent Workflow
workflow_url = "http://localhost:8003/RunWorkflow" task_payload = {"task": "How to get to Mordor?"} requests.post(workflow_url, json=task_payload)
Why Dapr Agents?
Dapr Agents is designed for enterprise-grade AI workloads, featuring:
- Resilient multi-agent interactions
- Highly scalable workflows
- Infrastructure-agnostic design
- Cost-efficient execution (Scale to Zero)
- Native observability with Prometheus & OpenTelemetry
Dapr Agents was pioneered by Roberto “Cyb3rWard0g” Rodriguez at Microsoft, originally developed as Floki for security AI research. To get started today: Dapr Agents GitHub.
Source: https://www.cncf.io/blog/2025/03/12/announcing-dapr-ai-agents/