让 AI Agent 的执行可恢复、可验证:Diagrid Catalyst 2.0 的架构启示

2026-08-26 37 预计阅读时间: 1 分钟
来源: infoq.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:11 分钟

AI Agent 真正进入生产环境后,难点往往不在于能否调用模型,而在于一次跨越多个工具、服务和步骤的任务,能否在进程崩溃、网络超时或人工介入后继续执行,并且让团队确认这段执行历史没有被悄悄改写。Diagrid Catalyst 2.0 的重点,正是把 Dapr 提供的恢复能力、签名工作流历史和执行证明引入 Agent 工作流。

这类能力改变了架构讨论的重点:Agent 不再只是一个带工具调用循环的应用,而更像一个需要持久化状态、可审计事件和明确恢复语义的分布式工作流。

Durable Execution 解决的不是“记住上下文”

普通 Agent 通常把消息列表保存在数据库中,失败后重新把上下文交给模型。这种方式只能恢复对话内容,不能可靠恢复执行过程。模型可能重新调用已经成功的支付接口、重复发送通知,或者在外部副作用已经发生后选择另一条路径。

Durable execution 关注的是更窄也更关键的问题:

  • 哪些步骤已经完成,结果是什么?
  • 哪些步骤可以安全重试?
  • 外部副作用是否具备幂等键?
  • 工作流在第几个检查点停止?
  • 恢复时应该重放历史,还是从某个持久化状态继续?

可以把一次 Agent 任务抽象成一串带状态的活动:

plan -> read_customer -> create_invoice -> send_email -> completed
                 |
                 +-- retryable failure

其中 create_invoicesend_email 可能已经触发外部副作用。仅仅重新运行 Python 函数并不等于恢复。生产实现需要为活动保存输入、输出、状态和幂等标识,并让重试策略与业务语义匹配。

Dapr 的分布式原语可以帮助应用组织状态存储、服务调用、发布订阅和工作流执行,但具体恢复行为仍取决于工作流引擎、存储后端和活动实现。架构评估时不能只看“支持 durable”这个标签。

可验证执行:从日志走向证据

传统日志主要回答“系统当时打印了什么”。签名工作流历史则试图回答“这份历史是否仍然可信”。如果每个事件都关联前一个事件的摘要,并由可信密钥签名,就可以形成一条不可轻易篡改的执行链。一个简化的事件结构如下:

{
  "workflow_id": "invoice-8472",
  "sequence": 3,
  "event_type": "activity.completed",
  "activity": "create_invoice",
  "result_hash": "sha256:...",
  "previous_event_hash": "sha256:...",
  "signature": "base64:..."
}

这类历史可以服务于审计、故障调查和合规证明,但它不自动证明业务结果正确。签名只能证明某个持有私钥的组件签署了某个事件;它不能证明工具返回的数据真实,也不能证明 Agent 的决策符合公司的业务规则。因此,执行证明应与工具授权、输入校验、策略检查和人工审批结合使用。

密钥生命周期同样重要。生产系统需要明确签名密钥由谁托管、如何轮换、如何撤销,以及验证方如何获取对应公钥。把私钥放进应用镜像或普通环境变量,会让“可验证”失去实际价值。

与框架原生能力和工作流引擎比较

Catalyst 2.0 覆盖多个 Agent 框架,这对希望保留现有框架的团队有吸引力。但跨框架层也会引入抽象边界,至少需要比较以下三类方案:

方案 优势 需要核验的问题
Agent 框架原生持久化 接入简单,保留框架语义 崩溃恢复、重试和副作用管理是否完整
Diagrid Catalyst 2.0 通过 Dapr 组织恢复、历史和执行证明,并覆盖多个框架 框架适配范围、延迟、运维复杂度和证据格式
成熟工作流引擎 状态机、重试、定时器和可观测性通常较成熟 Agent 集成成本、模型调用封装和平台运营成本

不要只用一次成功演示做选择。至少应设计包含以下情况的基准:模型调用超时、活动进程被杀、重复投递、状态存储短暂不可用、工具成功但响应丢失、签名验证失败,以及人工审批等待数小时。要记录恢复延迟、重复副作用数量、状态存储成本、端到端延迟和运维操作步骤。

一个可改造的最小工作流示例

下面的示例用 Python 表达 durable Agent 的核心结构。它是一个框架无关的最小实现,假设 store 提供持久化检查点,send_email 支持幂等键。接入具体 Agent 框架或 Dapr 工作流 SDK 时,可以把 run_activitycheckpoint 替换成对应 API。

运行前需要把通知服务替换为真实实现;示例中的内存字典只用于展示流程,进程退出后不会保留状态。

from dataclasses import dataclass, field
from typing import Any
import hashlib
import json


@dataclass
class WorkflowState:
    completed: dict[str, Any] = field(default_factory=dict)
    events: list[dict[str, Any]] = field(default_factory=list)


store: dict[str, WorkflowState] = {}


def checkpoint(workflow_id: str, state: WorkflowState) -> None:
    # 生产环境应写入持久化状态存储,并使用事务或版本号防止并发覆盖。
    store[workflow_id] = state


def run_activity(
    workflow_id: str,
    state: WorkflowState,
    name: str,
    input_data: dict[str, Any],
    fn,
) -> Any:
    if name in state.completed:
        return state.completed[name]

    result = fn(input_data)
    previous = state.events[-1]["hash"] if state.events else "genesis"
    event = {
        "activity": name,
        "input": input_data,
        "result": result,
        "previous": previous,
    }
    event["hash"] = hashlib.sha256(
        json.dumps(event, sort_keys=True).encode()
    ).hexdigest()
    state.events.append(event)
    state.completed[name] = result
    checkpoint(workflow_id, state)
    return result


def create_invoice(data: dict[str, Any]) -> dict[str, str]:
    # 真实服务应使用 data["idempotency_key"] 防止重复开票。
    return {"invoice_id": f"inv-{data['customer_id']}"}


def send_email(data: dict[str, Any]) -> str:
    # 真实服务应按 idempotency_key 去重。
    return f"sent:{data['invoice_id']}:{data['idempotency_key']}"


def run_invoice_agent(workflow_id: str, customer_id: str) -> WorkflowState:
    state = store.setdefault(workflow_id, WorkflowState())
    invoice = run_activity(
        workflow_id, state, "create_invoice",
        {"customer_id": customer_id,
         "idempotency_key": workflow_id},
        create_invoice,
    )
    run_activity(
        workflow_id, state, "send_email",
        {"invoice_id": invoice["invoice_id"],
         "idempotency_key": workflow_id},
        send_email,
    )
    return state


if __name__ == "__main__":
    result = run_invoice_agent("invoice-8472", "customer-19")
    print(json.dumps(result.events, indent=2))

这个实现展示了三个关键约束:已完成活动不会因为恢复而重复执行;每个检查点都带有前序事件摘要;外部副作用使用工作流级幂等键。真实系统还需要把哈希链升级为非对称签名,并处理并发、版本迁移、超时、补偿操作和密钥轮换。

落地前的检查清单

在选择 Catalyst 2.0 或其他 durable workflow 方案前,可以按下面的顺序验证:

  1. 列出 Agent 的每个外部副作用,并为每个副作用定义幂等策略或补偿动作。
  2. 明确检查点保存什么:模型消息、工具参数、工具结果、策略判断,还是完整事件历史。
  3. 用故障注入测试进程终止、网络分区、超时和重复投递,而不是只测试正常路径。
  4. 核对签名算法、密钥托管、公钥分发、轮换和验证失败后的处理。
  5. 比较框架原生能力、Catalyst 适配层和成熟工作流引擎的延迟、成本及运维负担。
  6. 要求基准数据说明测试规模、模型、工具数量、存储配置和恢复目标。

Catalyst 2.0 的价值主张适合被理解为一组生产工程能力:让 Agent 更容易恢复,让执行历史更容易核验。是否值得采用,取决于这些能力能否覆盖团队最危险的失败模式,并且以可接受的延迟、成本和运营复杂度交付。

结语

Agent 的可靠性最终不是由提示词长度决定的,而是由状态、重试、副作用、证据和运维流程共同决定的。durable execution 可以减少故障后的人工接管,签名历史可以提高审计可信度,但二者都不能替代幂等设计、权限控制和真实的故障测试。把这些边界测清楚,再决定采用 Catalyst、框架原生能力还是成熟工作流引擎,通常比追逐单一功能名称更稳妥。


相关推荐