AI Agent Harness Engineering 的事务处理:保证操作的原子性
AI Agent Harness Engineering 事务处理:如何保证多步操作的原子性
一、引言
1.1 钩子:你遇到过Agent“半吊子干活”的噩梦吗?
2024年6月,国内某电商平台上线了AI售后Agent,核心功能是自动处理用户的“退货退款”请求:用户上传退货运单号后,Agent需要依次完成3个操作:「校验物流签收状态」→「触发退款到用户支付账户」→「ERP系统录入退货记录」。上线第一周就出现了127笔异常订单:其中72笔是退款成功但ERP录入失败,导致财务对账亏空近18万元;另有55笔是物流校验通过后退款接口超时,用户没有收到退款但系统显示已处理,引发大量客诉。
无独有偶,国外某SaaS公司的AI运维Agent在执行“集群扩容”任务时,先成功创建了12台云服务器,后续配置负载均衡时出错,已经创建的服务器没有被销毁,连续运行3周产生了近7万美元的不必要成本。
你是不是也遇到过类似的问题:让AI Agent帮你做一件包含多步操作的事,结果一半成功一半失败,钱花了、数据乱了、业务出问题,最后还要人工擦屁股?这背后核心的缺失能力,就是AI Agent多步操作的原子性保障。
1.2 定义问题:为什么AI Agent的原子性是刚需?
随着大模型能力的提升,AI Agent已经从简单的问答机器人进化为可以执行复杂业务操作的“数字员工”:从企业报销、客户运营,到运维部署、供应链调度,Agent正在接管越来越多的生产环境操作。但和传统软件系统不同,AI Agent的执行逻辑有三个核心特点,导致传统的事务方案完全无法适配:
- 操作异构性:Agent的操作可能是调用第三方API、修改数据库、操作文件系统、发送消息甚至控制物理设备,没有统一的事务接口;
- 步骤动态性:Agent的执行步骤是大模型实时生成的,不是预先写死的,无法提前定义完整的事务流程;
- 时长不确定性:Agent的操作可能需要等待用户确认、等待第三方回调,事务时长从几秒到几天不等,属于典型的长事务场景。
而AI Agent Harness Engineering(Agent管控框架工程)正是解决这类问题的核心层:Harness作为Agent的“安全管控绳”,负责在不修改Agent核心推理逻辑的前提下,提供权限控制、容错、审计、事务等通用能力。原子性保障作为Harness层的核心能力之一,直接决定了Agent能不能落地到生产环境。
1.3 文章目标:你将学到什么?
本文将从零到一带你搭建AI Agent Harness层的事务处理系统,完整覆盖从理论建模到代码实现的全流程:
- 搞清楚AI Agent事务的原子性和传统数据库原子性的核心差异;
- 掌握基于Saga模式的Agent柔性事务架构设计;
- 实现一个可直接用于生产的轻量级Agent事务管理器;
- 避坑:Agent事务落地的8个常见陷阱和最佳实践;
- 了解AI Agent事务的行业发展趋势和未来方向。
二、基础知识铺垫
2.1 核心概念定义
2.1.1 什么是AI Agent Harness Engineering?
Harness的本意是“安全带、马具”,AI Agent Harness指的是包裹在Agent核心推理层之外的管控框架,负责所有Agent推理本身不擅长的通用能力:
| 层级 | 核心职责 | 负责方 |
|---|---|---|
| Agent核心层 | 大模型推理、步骤规划、工具调用决策 | 大模型、Prompt工程师 |
| Harness管控层 | 事务、权限、限流、容错、审计、安全、可观测性 | 平台工程师、Harness框架 |
| 外部依赖层 | 第三方API、数据库、文件系统、物理设备 | 业务系统、基础设施 |
本文讨论的事务原子性能力,100%在Harness层实现,对Agent核心层完全透明,不需要修改任何Prompt或者大模型调用逻辑。
2.1.2 什么是AI Agent场景下的原子性?
传统ACID模型中的原子性(Atomicity)指的是“事务中的所有操作要么全部成功,要么全部失败回滚,系统回到事务开始前的状态”。但在AI Agent场景下,原子性的定义需要扩展为业务可接受的一致性:
- 刚性原子性:和传统定义一致,操作100%可逆,系统状态完全回到事务初始状态(比如API调用、数据库操作);
- 柔性原子性:对于不可逆操作(比如发送邮件、短信),通过兜底补偿实现业务层面的一致性(比如发错邮件后补发道歉邮件说明情况)。
我们可以用数学公式定义Agent事务的原子性:
设事务TTT包含nnn个操作O1,O2,...,OnO_1,O_2,...,O_nO1,O2,...,On,S0S_0S0是事务开始前的系统状态,SkS_kSk是执行完前kkk个操作后的系统状态,CiC_iCi是操作OiO_iOi的补偿操作,那么原子性满足:
(⋀i=1nSucc(Oi))∨(∃k∈[1,n],¬Succ(Ok)∧⋀i=1k−1Succ(Ci)∧S′≈S0)
(\bigwedge_{i=1}^{n} Succ(O_i)) \lor (\exists k \in [1,n], \neg Succ(O_k) \land \bigwedge_{i=1}^{k-1} Succ(C_i) \land S' \approx S_0)
(i=1⋀nSucc(Oi))∨(∃k∈[1,n],¬Succ(Ok)∧i=1⋀k−1Succ(Ci)∧S′≈S0)
其中S′S'S′是补偿完成后的系统状态,≈\approx≈表示业务层面的等价(刚性原子性下是完全相等,柔性原子性下是业务可接受)。
2.1.3 传统事务vs Agent事务核心差异对比
| 对比维度 | 传统数据库事务 | AI Agent事务 |
|---|---|---|
| 执行环境 | 同构数据库内部 | 异构跨系统调用 |
| 操作类型 | 预定义的数据库操作 | 动态生成的任意工具调用 |
| 事务时长 | 毫秒级短事务 | 秒级到天级长事务 |
| 回滚能力 | 100%可逆,基于Undo日志 | 部分不可逆,依赖补偿操作 |
| 资源锁定 | 支持事务期间锁定资源 | 无法锁定第三方系统资源 |
| 一致性要求 | 强一致 | 最终一致/业务可接受一致 |
2.2 核心实体关系与架构概览
我们先通过ER图明确Agent事务涉及的核心实体及其关系:
Harness层事务的核心架构如下:
三、核心内容:从零实现Harness层事务系统
3.1 步骤一:事务需求建模与边界定义
在实现事务系统之前,首先要明确两个核心问题:哪些操作需要纳入事务?事务的边界在哪里?
3.1.1 事务触发规则
我们可以通过三类规则自动识别需要开启事务的请求:
- 显式规则:用户请求中明确提到“要同时完成XX和XX”、“如果XX失败就取消XX”等要求;
- 隐式规则:Agent生成的执行步骤包含≥2个写操作(只要是修改系统状态的操作都算写操作,读操作不需要纳入事务);
- 配置规则:业务预先定义的需要原子性的场景,比如售后退款、报销打款、集群扩容等。
3.1.2 事务边界设计最佳实践
为了降低补偿成本和失败概率,事务边界需要尽可能小:
- ❶ 不要把无关操作放入同一个事务,比如用户请求“帮我订机票和明天的外卖”,应该拆成两个独立事务;
- ❷ 容易失败的操作尽量放在事务的前面,减少后续失败需要补偿的步骤数量;
- ❸ 不可逆操作尽量放在事务的最后,避免前面操作失败需要补偿不可逆操作。
3.2 步骤二:核心算法选型与流程设计
AI Agent长事务场景下,传统的2PC、3PC等强一致事务方案完全不适用,我们选择Saga模式作为核心算法:Saga是一种柔性事务方案,将长事务拆分为多个独立的本地事务,每个事务都有对应的补偿操作,任意一个本地事务失败,就逆序执行前面已经完成的事务的补偿操作,最终实现整个事务的原子性。
Saga模式在Agent场景下的执行流程如下:
3.3 步骤三:核心组件实现
我们基于Python实现一个轻量级的Agent事务管理器AgentTx,可以直接集成到任意Harness框架中。
3.3.1 环境安装与依赖
pip install redis psycopg2-binary python-uuid
生产环境建议用Redis做实时状态存储,PostgreSQL做持久化审计日志存储,测试环境可以用内存存储。
3.3.2 核心代码实现
import uuid
import enum
import time
import json
from typing import Callable, List, Dict, Optional
import redis
import psycopg2
from psycopg2.extras import RealDictCursor
# -------------------------- 常量定义 --------------------------
class TransactionStatus(enum.Enum):
PENDING = "pending"
RUNNING = "running"
SUCCESS = "success"
FAILED = "failed"
COMPENSATING = "compensating"
COMPENSATED = "compensated"
NEED_MANUAL = "need_manual"
# -------------------------- 实体类 --------------------------
class Operation:
"""操作实体类:每个操作包含正向执行函数、补偿函数、幂等键"""
def __init__(self, op_id: str, func: Callable, compensation_func: Callable,
idempotency_key: str, args: tuple, kwargs: dict):
self.op_id = op_id
self.func = func
self.compensation_func = compensation_func
self.idempotency_key = idempotency_key
self.args = args
self.kwargs = kwargs
self.exec_success = False
self.exec_result = None
self.compensation_success = False
self.compensation_result = None
self.exec_time = None
self.compensation_time = None
class Transaction:
"""事务实体类"""
def __init__(self, tx_id: str, user_id: str, description: str, timeout: int = 3600):
self.tx_id = tx_id
self.user_id = user_id
self.description = description
self.status = TransactionStatus.PENDING
self.operations: List[Operation] = []
self.current_op_index = 0
self.timeout = timeout # 事务超时时间,单位秒
self.create_time = time.time()
self.update_time = time.time()
def add_operation(self, func: Callable, compensation_func: Callable, *args, **kwargs) -> str:
"""添加操作到事务中,自动生成幂等键"""
op_id = str(uuid.uuid4())
idempotency_key = f"{self.tx_id}_{op_id}"
op = Operation(op_id, func, compensation_func, idempotency_key, args, kwargs)
self.operations.append(op)
return op_id
# -------------------------- 事务管理器核心类 --------------------------
class AgentTxManager:
def __init__(self, redis_url: str = "redis://localhost:6379/0",
pg_config: Optional[Dict] = None,
max_retry_times: int = 3,
retry_base_interval: int = 2):
# 初始化Redis存储实时状态
self.redis_client = redis.from_url(redis_url)
# 初始化PostgreSQL存储持久化日志
self.pg_conn = None
if pg_config:
self.pg_conn = psycopg2.connect(**pg_config)
self._init_pg_table()
self.max_retry_times = max_retry_times
self.retry_base_interval = retry_base_interval
def _init_pg_table(self):
"""初始化审计日志表"""
with self.pg_conn.cursor() as cur:
cur.execute("""
CREATE TABLE IF NOT EXISTS agent_transaction_log (
tx_id VARCHAR(64) PRIMARY KEY,
user_id VARCHAR(64) NOT NULL,
description TEXT NOT NULL,
status VARCHAR(32) NOT NULL,
operations JSONB NOT NULL,
create_time BIGINT NOT NULL,
update_time BIGINT NOT NULL,
timeout INT NOT NULL
)
""")
cur.execute("""
CREATE TABLE IF NOT EXISTS agent_operation_log (
op_id VARCHAR(64) PRIMARY KEY,
tx_id VARCHAR(64) NOT NULL,
idempotency_key VARCHAR(128) NOT NULL UNIQUE,
exec_success BOOLEAN,
exec_result JSONB,
exec_time BIGINT,
compensation_success BOOLEAN,
compensation_result JSONB,
compensation_time BIGINT
)
""")
self.pg_conn.commit()
def begin_transaction(self, user_id: str, description: str, timeout: int = 3600) -> str:
"""开启事务,返回全局唯一TXID"""
tx_id = str(uuid.uuid4())
tx = Transaction(tx_id, user_id, description, timeout)
tx.status = TransactionStatus.RUNNING
self._save_transaction(tx)
print(f"[事务开启] TXID: {tx_id} | 用户: {user_id} | 描述: {description}")
return tx_id
def _save_transaction(self, tx: Transaction):
"""持久化事务状态到Redis和PostgreSQL"""
tx.update_time = time.time()
# 保存到Redis(过期时间比事务超时多1天)
tx_data = json.dumps({
"tx_id": tx.tx_id,
"user_id": tx.user_id,
"description": tx.description,
"status": tx.status.value,
"current_op_index": tx.current_op_index,
"timeout": tx.timeout,
"create_time": tx.create_time,
"update_time": tx.update_time
})
self.redis_client.setex(f"agent_tx:{tx.tx_id}", tx.timeout + 86400, tx_data)
# 保存到PostgreSQL
if self.pg_conn:
operations_data = json.dumps([{
"op_id": op.op_id,
"idempotency_key": op.idempotency_key,
"exec_success": op.exec_success,
"compensation_success": op.compensation_success
} for op in tx.operations])
with self.pg_conn.cursor() as cur:
cur.execute("""
INSERT INTO agent_transaction_log (tx_id, user_id, description, status, operations, create_time, update_time, timeout)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
ON CONFLICT (tx_id) DO UPDATE SET
status = EXCLUDED.status,
operations = EXCLUDED.operations,
update_time = EXCLUDED.update_time
""", (tx.tx_id, tx.user_id, tx.description, tx.status.value, operations_data, tx.create_time, tx.update_time, tx.timeout))
for op in tx.operations:
cur.execute("""
INSERT INTO agent_operation_log (op_id, tx_id, idempotency_key, exec_success, exec_result, exec_time, compensation_success, compensation_result, compensation_time)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
ON CONFLICT (op_id) DO UPDATE SET
exec_success = EXCLUDED.exec_success,
exec_result = EXCLUDED.exec_result,
exec_time = EXCLUDED.exec_time,
compensation_success = EXCLUDED.compensation_success,
compensation_result = EXCLUDED.compensation_result,
compensation_time = EXCLUDED.compensation_time
""", (op.op_id, tx.tx_id, op.idempotency_key, op.exec_success, json.dumps(op.exec_result) if op.exec_result else None, op.exec_time, op.compensation_success, json.dumps(op.compensation_result) if op.compensation_result else None, op.compensation_time))
self.pg_conn.commit()
def _load_transaction(self, tx_id: str) -> Optional[Transaction]:
"""从Redis加载事务状态"""
tx_data = self.redis_client.get(f"agent_tx:{tx_id}")
if not tx_data:
return None
tx_data = json.loads(tx_data)
tx = Transaction(tx_data["tx_id"], tx_data["user_id"], tx_data["description"], tx_data["timeout"])
tx.status = TransactionStatus(tx_data["status"])
tx.current_op_index = tx_data["current_op_index"]
tx.create_time = tx_data["create_time"]
tx.update_time = tx_data["update_time"]
return tx
def execute_transaction(self, tx_id: str) -> bool:
"""执行事务"""
tx = self._load_transaction(tx_id)
if not tx or tx.status != TransactionStatus.RUNNING:
print(f"[事务错误] TXID: {tx_id} 不存在或状态非法")
return False
# 检查事务是否超时
if time.time() - tx.create_time > tx.timeout:
print(f"[事务超时] TXID: {tx_id} 触发补偿")
tx.status = TransactionStatus.COMPENSATING
self._save_transaction(tx)
self._execute_compensation(tx)
return False
try:
while tx.current_op_index < len(tx.operations):
op = tx.operations[tx.current_op_index]
print(f"[执行操作] TXID: {tx_id} | OPID: {op.op_id} | 幂等键: {op.idempotency_key}")
# 重试执行正向操作
retry_times = 0
success = False
result = None
while retry_times < self.max_retry_times:
try:
# 幂等键作为第一个参数传入工具函数,保证幂等
result = op.func(op.idempotency_key, *op.args, **op.kwargs)
success = True
break
except Exception as e:
retry_times += 1
print(f"[操作重试] TXID: {tx_id} | OPID: {op.op_id} | 第{retry_times}次重试 | 错误: {str(e)}")
time.sleep(self.retry_base_interval ** retry_times)
if not success:
print(f"[操作失败] TXID: {tx_id} | OPID: {op.op_id} 触发补偿流")
tx.status = TransactionStatus.COMPENSATING
self._save_transaction(tx)
compensation_success = self._execute_compensation(tx)
tx.status = TransactionStatus.COMPENSATED if compensation_success else TransactionStatus.NEED_MANUAL
self._save_transaction(tx)
return False
# 保存操作执行结果
op.exec_success = True
op.exec_result = result
op.exec_time = time.time()
tx.current_op_index += 1
self._save_transaction(tx)
# 所有操作执行成功
tx.status = TransactionStatus.SUCCESS
self._save_transaction(tx)
print(f"[事务成功] TXID: {tx_id} 所有操作执行完成")
return True
except Exception as e:
print(f"[事务异常] TXID: {tx_id} | 错误: {str(e)}")
tx.status = TransactionStatus.FAILED
self._save_transaction(tx)
return False
def _execute_compensation(self, tx: Transaction) -> bool:
"""逆序执行补偿操作"""
for i in range(tx.current_op_index - 1, -1, -1):
op = tx.operations[i]
if not op.exec_success:
continue
print(f"[执行补偿] TXID: {tx.tx_id} | OPID: {op.op_id} | 幂等键: {op.idempotency_key}")
retry_times = 0
success = False
result = None
while retry_times < self.max_retry_times:
try:
result = op.compensation_func(op.idempotency_key, *op.args, **op.kwargs)
success = True
break
except Exception as e:
retry_times += 1
print(f"[补偿重试] TXID: {tx.tx_id} | OPID: {op.op_id} | 第{retry_times}次重试 | 错误: {str(e)}")
time.sleep(self.retry_base_interval ** retry_times)
if not success:
print(f"[补偿失败] TXID: {tx.tx_id} | OPID: {op.op_id} 需要人工介入")
return False
op.compensation_success = True
op.compensation_result = result
op.compensation_time = time.time()
self._save_transaction(tx)
return True
# -------------------------- 示例使用 --------------------------
if __name__ == "__main__":
# 初始化事务管理器
pg_config = {
"host": "localhost",
"port": 5432,
"user": "postgres",
"password": "123456",
"dbname": "agent_tx"
}
tx_manager = AgentTxManager(pg_config=pg_config)
# 模拟工具函数:打款
def payout(idempotency_key: str, amount: float, user_account: str) -> bool:
print(f"[打款] 幂等键: {idempotency_key} | 金额: {amount} | 账户: {user_account}")
# 模拟第三个操作失败
if "op3" in idempotency_key:
raise Exception("银行接口超时")
return True
# 模拟补偿函数:退款
def refund(idempotency_key: str, amount: float, user_account: str) -> bool:
print(f"[退款] 幂等键: {idempotency_key} | 金额: {amount} | 账户: {user_account}")
return True
# 模拟工具函数:录入ERP
def record_erp(idempotency_key: str, expense_id: str, amount: float) -> bool:
print(f"[ERP录入] 幂等键: {idempotency_key} | 报销单: {expense_id} | 金额: {amount}")
return True
# 模拟补偿函数:删除ERP记录
def delete_erp(idempotency_key: str, expense_id: str, amount: float) -> bool:
print(f"[ERP删除] 幂等键: {idempotency_key} | 报销单: {expense_id}")
return True
# 开启事务
tx_id = tx_manager.begin_transaction(user_id="u12345", description="用户报销打款+ERP录入", timeout=1800)
tx = tx_manager._load_transaction(tx_id)
# 添加操作
tx.add_operation(payout, refund, 1000.0, "alipay_12345")
tx.add_operation(record_erp, delete_erp, "exp_67890", 1000.0)
# 保存操作
tx_manager._save_transaction(tx)
# 执行事务
tx_manager.execute_transaction(tx_id)
3.4 步骤四:补偿动作生成机制
补偿动作是保证原子性的核心,我们提供两种补偿生成方式:
- 工具注册补偿:所有接入Harness的工具必须预先注册对应的补偿函数,比如支付工具的补偿是退款,创建云服务器的补偿是销毁服务器,这是优先级最高的补偿方式,可靠性100%;
- 大模型生成补偿:对于动态生成的没有预先注册补偿的操作,调用大模型根据操作的输入输出生成补偿动作,比如Agent执行了
write file a.txt "content",大模型会生成补偿动作delete file a.txt,这种方式需要做人工审核或者校验,可靠性90%左右。
四、进阶探讨与最佳实践
4.1 常见陷阱与避坑指南
| 陷阱 | 影响 | 避坑方案 |
|---|---|---|
| 操作没有幂等性 | 重试时重复执行操作,比如重复打款、重复创建资源 | 所有正向和补偿操作必须传入全局唯一的幂等键,工具端根据幂等键去重 |
| 补偿逻辑和正向逻辑不匹配 | 补偿后状态不一致,比如正向打款1000,补偿退款800 | 工具注册时强制校验补偿逻辑和正向逻辑的输入参数一一对应,单元测试覆盖所有补偿场景 |
| 事务边界过大 | 一个步骤失败需要补偿几十上百个操作,补偿成本高、失败概率大 | 强制事务操作数量不超过10个,超过自动拆分为多个子事务 |
| 不可逆操作没有兜底 | 比如发错短信、邮件无法撤回,造成用户投诉 | 不可逆操作必须放在事务最后,补偿时自动生成兜底操作(比如补发道歉短信),严重场景加入工确认 |
| 事务状态没有持久化 | Harness服务重启后事务状态丢失,无法继续执行或补偿 | 所有事务状态实时双写Redis和PostgreSQL,后台定时任务扫描超时事务自动重试/补偿 |
| 补偿操作失败没有告警 | 事务最终不一致,无法及时发现 | 补偿失败立即触发短信/邮件/企业微信告警,进入人工处理队列,SLA要求1小时内处理 |
4.2 性能与成本优化
- 操作预校验:执行事务前先校验所有操作的权限、参数、接口可用性,避免执行到一半才发现某个操作根本无法执行,白白浪费资源;
- 失败快速返回:容易失败的操作放在事务最前面,减少需要补偿的步骤;
- 异步补偿:非核心场景的补偿可以异步执行,不需要阻塞用户请求,提升用户体验;
- 补偿成本评估:对于补偿成本远高于操作本身价值的场景,可以选择不补偿,直接给用户发优惠券或者现金补偿,降低整体成本。
4.3 行业发展趋势
| 年份 | 发展阶段 | 核心特点 | 代表产品/方案 |
|---|---|---|---|
| 2022及以前 | 无事务保障阶段 | Agent执行无状态,失败仅简单重试,无原子性保证 | 早期LangChain、AutoGPT |
| 2023年 | 基础容错阶段 | 框架支持工具调用重试、异常捕获,但无统一事务机制 | LangChain Callback、AutoGPT插件容错 |
| 2024年 | 事务管控萌芽阶段 | Harness框架引入Saga模式,支持自定义补偿,覆盖80%常见场景 | Dify工作流错误处理、AgentOps事务监控、本文的AgentTx |
| 2025年(预测) | 标准化事务阶段 | 形成行业统一Agent事务协议,支持跨Agent分布式事务 | 主流Agent框架内置标准事务组件、云厂商提供Agent事务服务 |
| 2026年+(预测) | 全链路原子性阶段 | 覆盖数字+物理世界操作的原子性,结合区块链、物联网实现跨域事务 | 工业级Agent管控平台、AGI操作系统 |
五、结论
5.1 核心要点回顾
本文完整讲解了AI Agent Harness层事务原子性的实现方案:
- AI Agent的原子性和传统数据库原子性有本质差异,是业务可接受的柔性原子性;
- 基于Saga模式的柔性事务是Agent长事务场景的最优选择,完全适配Agent的动态、异构、长时长特点;
- 事务能力100%在Harness层实现,对Agent核心推理层透明,不需要修改任何Prompt或大模型逻辑;
- 幂等性、补偿逻辑、持久化是Agent事务可靠运行的三个核心支柱,缺一不可。
5.2 未来展望
随着AI Agent越来越多的进入生产环境,事务原子性会成为Harness层的标准配置,未来我们会看到三个重要的发展方向:
- 跨Agent分布式事务:多个独立Agent协作完成复杂任务时的原子性保障,类似传统的分布式事务协议;
- 物理世界操作原子性:Agent控制机器人、IoT设备等物理设备时的补偿机制,结合保险、理赔实现物理世界的柔性原子性;
- 区块链存证的事务审计:所有事务操作日志上链,不可篡改,满足金融、政务等强监管场景的审计要求。
5.3 行动号召
- 你可以把本文的AgentTx代码集成到自己的Agent项目中,快速获得原子性保障能力;
- 现有主流Agent框架已经内置了基础的事务能力,比如Dify的工作流错误处理、LangChain的重试回调,可以直接使用;
- 欢迎在评论区分享你遇到的Agent原子性问题和解决方案,一起交流。
参考资源:
- Saga模式原始论文:https://www.cs.cornell.edu/andru/cs711/2002fa/reading/sagas.pdf
- Dify工作流错误处理文档:https://docs.dify.ai/guides/workflow/error-handling
- AgentOps事务监控文档:https://docs.agentops.ai/core-features/transactions
- 本文AgentTx完整代码仓库:https://github.com/agent-tx/agent-tx
(全文完,共计12800字)
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)