Dapr(Distributed Application Runtime,分布式应用运行时) 是由微软发起并开源、现属于 CNCF(云原生计算基金会)托管的孵化项目。它是一个可插拔的、事件驱动的运行时,旨在让开发人员能够轻松构建弹性、无状态和有状态的微服务应用程序。
为什么需要 Dapr?(痛点与背景)
在传统的微服务架构开发中,开发人员通常会面临以下核心痛点:
- 分布式系统的复杂性(重复造轮子): 构建微服务时,开发人员不得不处理许多共性问题,如服务间调用、状态管理、消息发布/订阅、配置管理、安全认证等。为了解决这些问题,通常需要引入各种 SDK 和第三方库(例如 Spring Cloud 组件、各种消息队列和数据库的特定 SDK)。
- 严重的厂商/技术栈绑定(Vendor Lock-in): 如果代码中直接使用了 AWS DynamoDB 的 SDK 来管理状态,或者使用了 Azure Service Bus 来做消息队列,当企业决定将应用迁移到其他云平台(使用 Redis 或 RabbitMQ)时,需要重构大量的底层代码。
- 多语言支持困难: 许多优秀的分布式框架(如 Spring Cloud)对 Java 支持极好,但如果团队想用 Go、Python 或 Node.js 编写部分微服务,就需要寻找对应语言的生态,或者面临底层基础设施无法复用的困境。
Dapr 的核心出发点是:让开发人员专注于业务逻辑,而将所有分布式的共性需求(如状态、消息、调用)抽离出来,交给运行时来处理。
Dapr 是什么?(核心架构与概念)
Dapr 是一个面向开发人员的、具有自包含 API 的分布式应用运行时。

核心设计模式:Sidecar
Dapr 采用 Sidecar 架构。这意味着 Dapr 作为一个独立的进程(在 Kubernetes 中作为一个独立的容器)与应用程序并行运行。
- 应用程序不需要集成复杂的分布式 SDK,只需要通过轻量级的 HTTP 或 gRPC 标准协议与本地的 Dapr Sidecar 进行通信。
- 无论是 Java、Go、Python、.NET 还是 Rust,只要能发送 HTTP/gRPC 请求,就能直接使用 Dapr 的能力。
核心概念:Building Blocks(构建块)与 Components(组件)
Dapr 将分布式系统的能力抽象成了多个构建块(Building Blocks)。每个构建块对外暴露统一、标准化的 API,而底层则由可插拔的组件(Components)来实现:
- 服务调用(Service-to-Service Invocation): 提供安全、具有重试机制的反向代理与服务发现,让服务之间可以轻松相互调用。
- 状态管理(State Management): 统一的键值对(Key-Value)存储接口。可以用同一套 API 读写数据,底层组件可以自由切换为 Redis、MongoDB、CosmosDB 或 PostgreSQL。
- 发布/订阅(Publish and Subscribe): 统一的消息发布与订阅接口。底层可以自由切换为 Kafka、RabbitMQ、MQTT 或 AWS SNS/SQS。
- 输入/输出绑定(Bindings): 统一触发事件(如定时任务)或与外部系统(如 MySQL、Twilio、GitHub)交互的接口。
- Actors 模式: 专为并发、分布式状态打造的独立计算与状态单元。
- 工作流(Workflows): 编排长期运行的业务流程(Dapr v1.10+ 引入)。
- 配置(Configuration)与密码(Secrets): 统一访问系统配置和敏感凭据(如 HashiCorp Vault、Kubernetes Secrets)。
总结来说: Dapr 是应用与底层基础设施(如数据库、消息队列)之间的“隔离层”或“操作系统”。
怎么使用 Dapr?(开发与落地)
使用 Dapr 的典型流程通常分为本地开发和生产部署两步:
本地开发准备
首先,需要在本地安装 Dapr CLI(命令行工具),并通过初始化命令启动 Dapr 的本地开发环境(通常会默认启动一个 Redis 容器作为状态存储和 pub/sub 代理):
# 安装 Dapr CLI 后初始化
dapr init
编写代码(以状态管理为例)
由于 Dapr 暴露的是标准 HTTP API,代码可以非常简单。
保存状态(Go 示例,纯 HTTP 请求): 不需要引入 Redis SDK,只需要向 Dapr Sidecar 发送一个 POST 请求:
// 假设 Dapr 监听在本地 3500 端口,状态存储组件名为 "statestore" url := "http://localhost:3500/v1.0/state/statestore" jsonData := `[{"key": "weapon", "value": "Death Star"}]` resp, _ := http.Post(url, "application/json", bytes.NewBuffer([]byte(jsonData)))获取状态(使用 Dapr 官方提供的轻量级 SDK - 以 Python 为例): 虽然可以用原生 HTTP,但 Dapr 也为各语言提供了轻量级的 SDK 封装,方便结构化编写:
from dapr.clients import DaprClient with DaprClient() as d: # 获取 key 为 "weapon" 的数据 result = d.get_state(store_name='statestore', key='weapon') print(f"Result: {result.data}")
本地启动应用与 Dapr Sidecar
使用 Dapr CLI 来拉起应用进程和 Dapr 边车进程:
dapr run --app-id myapp --app-port 5000 --dapr-http-port 3500 python app.py
配置底层组件(无侵入切换)
Dapr 的精髓在于,如果想把底层的 Redis 换成 MySQL,完全不需要修改任何一行代码,只需要修改一个 YAML 配置文件(components/statestore.yaml):
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.redis # 如果想换成 MySQL,只需改为 state.mysql 并配置对应连接串
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""
生产部署(通常在 Kubernetes 中)
在 Kubernetes 环境中,Dapr 提供了 Sidecar Injector 控制器。只需要在部署应用的 Deployment YAML 中加入简单的 Annotations(注解):
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
template:
metadata:
annotations:
dapr.io/enabled: "true" # 告诉 Dapr 注入 Sidecar
dapr.io/app-id: "myapp" # 服务唯一标识
dapr.io/app-port: "5000" # 应用监听的端口
Kubernetes 会自动把 Dapr 容器和应用容器打包在同一个 Pod 里,无缝接管所有的分布式流量与能力。
Dapr Durable Agents
Dapr Agents(以及其核心的 DurableAgent 类)是 Dapr 社区在 2025 年前后推出的、专门针对 AI Agent 场景的开源开发框架(目前首发主要支持 Python)。
简单来说,它是将 LLM 的推理/行动能力(Agentic AI) 与 Dapr 强大的云原生分布式基础设施(特别是 Dapr Workflow) 进行深度融合的产物。旨在解决当前主流 AI 智能体框架(如 LangChain、CrewAI)在生产环境中普遍存在的脆弱性、缺乏状态持久化、难以应对长周期和节点崩溃等痛点。
以下从核心痛点、实现原理和架构优势三个维度为您拆解 Dapr Durable Agents:
为什么需要 Dapr Durable Agents?
在构建生产级的 AI Agent(如自动化代码审计、长流程跨境电商供应链调度)时,开发者会发现传统的 Agent 框架存在致命的“落地难”问题:
- 执行状态脆弱(Ephemeral Execution): LLM 的思考(Reasoning)和工具调用(Tool Calling)通常是一个多步循环(ReAct 模式)。如果在执行到第 5 步(比如调用某个耗时很长的外部 API)时,服务器节点崩溃或者网络中断,Agent 的整个上下文和执行进度就全丢了,必须从头再来。这在生产中不仅低效,还会白白消耗大量的 Token 成本。
- 缺乏长周期支持(Long-running Gaps): 很多企业级 Agent 的生命周期长达数天甚至数周(例如“等待财务人工审批”或“等待定时器触发”)。现有的 Agent 框架很难优雅地在内存中挂起数天,并在被唤醒后精准恢复到当时的状态。
- 缺乏状态一致性与可观测性: 复杂的 Multi-Agent 协作中,Agent 之间的通信状态、记忆(Memory)持久化往往需要开发者手写大量的 Redis/数据库读写胶水代码,且缺乏开箱即用的分布式追踪(Telemetry)。
核心实现机制:将 LLM 推理循环转化为“确定性工作流”
在前文中我们提到,Dapr Workflow 利用事件溯源(Event Sourcing)和确定性重放(Deterministic Replay)实现了微服务工作流的不死之身。Dapr Durable Agents 的核心精髓,就是把 Agent 的思考和行动生命周期,完全托管给了 Dapr Workflow。
推理步骤的“Activity 化”
在 DurableAgent 中,LLM 的每一次提示词生成(Prompt Generation)、每一次大模型推断(LLM Inference)、以及每一次工具调用(Tool Invocation),底层的执行逻辑都会被 Dapr 封装成一个 Dapr Workflow Activity。
状态的“容错重放”
- 当 Agent 调用 LLM 决定执行
Tool_A成功后,这个结果会被写入底层隐藏的 Workflow Actor 历史日志中。 - 如果在执行下一步
Tool_B时服务器宕机,Dapr 重新拉起该 Agent 实例后,Agent 的编排器会从头“重放”。 - 重放时,前一步的 LLM 决策和
Tool_A的执行结果会直接从历史日志中读取(不重复消耗 Token,也不重复调用工具),从而让 Agent 神奇地直接回到宕机前的那一步继续往下走。
核心架构能力
通过延伸 DurableAgent,Dapr 赋予了 AI Agent 极强的云原生属性:
- 耐久性与容错(Durability & Fault Tolerance): 保证 Agent 任务无论面对网络抖动、 pod 漂移还是节点崩溃,都必定会执行到终点(Execute to Completion)。
- 透明的持久化记忆(Persistent Memory): Agent 的短期记忆(上下文窗口)和长期记忆被自动托管在 Dapr State Store 中,无需关心底层的 Redis 或 PostgreSQL 怎么配置。
- 内置的定时与挂起(Durable Timers): 允许 Agent 代码中直接写“等待 2 天后再次重试该 Tool”,或在需要人工介入时触发
WaitForExternalEvent,此时 Agent 彻底释放内存,直到事件到达或时间到期才被精准唤醒。 - 原生支持 Multi-Agent 工作流模式: 能够极其轻松地实现经典的 Agent 编排模式(如任务链 Task Chaining、扇入/扇出 Fan-out/Fan-in、评审流 Evaluator-Optimizer)。
代码范式与直观感受
在 Dapr Agents 框架中,一个具备耐久性的 Agent 开发通常非常符合直观。以下是一个概念性的伪代码片段:
from dapr.agents import Agent, DurableAgent, Tool
# 定义 Agent 的工具(底层的 Activity)
@Tool
def fetch_system_logs(component: str) -> str:
# 真实去扒日志的业务逻辑
return "error inside middleware..."
# 声明一个富有耐久能力的 Agent
class SREAgent(DurableAgent):
def __init__(self):
super().__init__(
name="SREAgent",
instructions="你是一个资深的云原生运维专家...",
llm_config={"model": "gpt-4o"},
tools=[fetch_system_logs]
)
# 触发 Agent(底层会自动启动 Dapr Workflow 进行编排托管)
agent = SREAgent()
result = agent.execute("帮我分析本地集群中网关组件的错误并给出修复建议")
当你调用 agent.execute 时,Dapr 会在后台创建一个持久化的工作流。即便 fetch_system_logs 执行期间网络卡死,Dapr 的重试策略和弹性机制也会接管,确保 Agent 在系统恢复后能不丢进度地继续分析推理。
总结
- 微服务维度的 Dapr: 改变了微服务的开发范式。它通过 Sidecar 架构 将分布式能力变成了一种公共基础设施,让开发者可以编写云原生、跨语言、平台无关的轻量级微服务,极大降低了分布式系统的开发和运维门槛。
- AI Agent 维度的 Dapr: Dapr Durable Agents 并不是在挑战大模型本身的推理算法,而是在重构大模型应用的分布式运行时。 它将复杂的 AI 智能体应用落地带入了“工业化时代”:让开发者能够像写普通的本地循环代码一样写 Agent 逻辑,而把高可用、强一致性状态、长周期挂起以及多智能体分布式通信等所有的“脏活累活”,全部交给了底层的 Dapr 运行时。