一致性才是新的延迟:AI Agent 如何选择数据层复制模型

2026-08-18 37 预计阅读时间: 1 分钟
来源: aws.amazon.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.

预计阅读时间:10 分钟

当 AI Agent 还只是回答问题时,几百毫秒的复制延迟可能只是用户偶尔看到旧数据。但当 Agent 开始执行扣款、修改权限、创建工单或更新库存时,数据层的一致性会直接决定它是否可靠。

一个 Agent 的上下文并不只来自模型推理,还来自数据库查询、工具调用和前一步操作的结果。如果这些读取落后于写入,Agent 可能基于已经过期的事实继续行动。此时,问题看起来像“模型判断错误”,实际根因可能是复制延迟。

复制延迟为什么会污染 Agent 上下文

考虑一个简单流程:

  1. Agent 将订单状态更新为 paid
  2. 随后查询订单,确认是否已经支付。
  3. 根据查询结果发货或发送通知。

如果第二步读取的是存在复制延迟的副本,Agent 仍可能得到 pending。它可能重复发起支付、告诉用户付款失败,或者在重试逻辑中执行相互冲突的操作。

传统应用通常可以通过缓存失效、重试或最终一致性来吸收这类差异。Agent 的问题更复杂:模型会把工具返回的数据当作当前上下文的一部分,并据此生成下一步动作。一次过期读取可能被扩散到后续多轮推理中。

因此,评估 AI Agent 的数据层时,不能只问“查询延迟是多少”,还要问:

  • 写入之后,关键读取多久能够看到新值?
  • Agent 是否需要读取自己刚刚写入的数据?
  • 冲突是否可以合并,还是必须拒绝其中一个操作?
  • 在副本暂时不可用时,系统应该阻塞、降级还是继续执行?

按任务选择一致性模型

不同操作需要的并不是同一种一致性。可以先按业务后果分类。

需要读己之写的行动流程

例如更新用户订阅后立即生成发票,或者修改库存后马上确认预留结果。这类流程至少需要保证同一个 Agent 工作流能够看到自己的最新写入。

对于 Amazon Aurora,可以让关键读取走主实例,或者在应用层明确区分写连接和读连接。Aurora 的读副本适合扩展读取,但不能默认它们在写入后立即可见。

import os
import time
import psycopg

write_dsn = os.environ["DATABASE_WRITE_DSN"]
read_dsn = os.environ["DATABASE_READ_DSN"]
order_id = "order-123"

with psycopg.connect(write_dsn) as conn:
    with conn.cursor() as cur:
        cur.execute(
            "UPDATE orders SET status = %s WHERE id = %s",
            ("paid", order_id),
        )
    conn.commit()

# 需要确认刚才的写入时,读取主实例,避免读到滞后的副本。
with psycopg.connect(read_dsn) as conn:
    with conn.cursor() as cur:
        cur.execute("SELECT status FROM orders WHERE id = %s", (order_id,))
        status = cur.fetchone()[0]

if status != "paid":
    raise RuntimeError(f"order {order_id} is not visible after the write")

这里的 DATABASE_READ_DSN 应该指向承担强一致关键读取的连接端点,而不是任意读副本。生产系统还应把事务、超时、重试和幂等键一起设计,避免“为了等一致性”重复执行副作用操作。

需要条件写入和明确冲突的状态机

Amazon DynamoDB 更适合以键值访问、条件写入和高并发状态更新为核心的 Agent 工具。例如,Agent 只能在订单仍为 pending 时执行一次确认操作,可以使用条件表达式保护状态转换:

aws dynamodb update-item \
  --table-name Orders \
  --key '{"order_id":{"S":"order-123"}}' \
  --update-expression 'SET #s = :paid, updated_at = :now' \
  --condition-expression '#s = :pending' \
  --expression-attribute-names '{"#s":"status"}' \
  --expression-attribute-values '{" :paid":{"S":"paid"},":pending":{"S":"pending"},":now":{"S":"2025-01-01T12:00:00Z"}}' \
  --return-values ALL_NEW

上面的命令中,实际使用时应删除 " :paid" 中意外的空格,正确的 JSON 片段如下:

{
  ":paid": {"S": "paid"},
  ":pending": {"S": "pending"},
  ":now": {"S": "2025-01-01T12:00:00Z"}
}

如果条件不满足,操作会失败,而不是静默覆盖其他写入。Agent 工具可以把这种失败转换成结构化结果,例如 already_processedstate_changed,让模型重新读取状态后决定下一步。对于需要跨区域访问的场景,还要明确选择 DynamoDB 的读取一致性选项,并根据区域、延迟和可用性要求验证实际行为。

适合高吞吐写入、可以接受最终一致性的事件和时序数据

Amazon Keyspaces 面向 Cassandra 兼容的宽列访问模式,适合高吞吐、按分区键读取的事件、日志和时序数据。它可以承载 Agent 的观测记录、工具调用历史或状态变更事件,但不应自动被当作强一致的交易事实源。

例如,Agent 可以先把工具调用事件写入 Keyspaces,再由异步流程聚合到供决策使用的状态表:

CREATE TABLE IF NOT EXISTS agent_events (
    agent_id text,
    event_day date,
    event_time timestamp,
    event_id uuid,
    event_type text,
    payload text,
    PRIMARY KEY ((agent_id, event_day), event_time, event_id)
) WITH CLUSTERING ORDER BY (event_time DESC);

INSERT INTO agent_events (
    agent_id, event_day, event_time, event_id, event_type, payload
) VALUES (
    'agent-7', '2025-01-01', '2025-01-01T12:00:00Z',
    550e8400-e29b-41d4-a716-446655440000,
    'tool_call', '{"tool":"check_inventory","sku":"sku-42"}'
);

库存扣减、权限授予等不可逆操作不应仅依赖刚写入的事件记录来判断结果。事件流可以是审计和异步处理的基础,但真正的决策读取应来自具有合适一致性保证的状态存储。

给 Agent 增加一致性感知

数据层的复制模型只是基础设施选择,Agent 编排层也需要显式表达读取要求。一个实用做法是为工具定义一致性级别:

{
  "name": "get_order_status",
  "description": "Read the latest order status before a side-effecting action",
  "parameters": {
    "type": "object",
    "properties": {
      "order_id": {"type": "string"},
      "consistency": {
        "type": "string",
        "enum": ["eventual", "session", "strong"]
      }
    },
    "required": ["order_id", "consistency"]
  }
}

工具实现可以根据 consistency 选择主库、带条件的读取路径、指定区域的副本,或返回“数据尚未收敛”的明确状态。不要让模型自行猜测某个数据库端点是否已经同步;这应当是工具契约的一部分。

还可以把写入版本返回给后续读取,例如使用版本号、更新时间或单调递增的事件序列。读取接口在发现结果版本低于要求时,应等待、切换读取路径,或者让 Agent 暂停副作用操作。

落地时的检查清单

  • 把只读问答、状态确认和副作用操作分开评估。
  • 对“写入后立即读取”的链路定义可测量的可见性目标。
  • Aurora 中为关键确认读取选择合适的实例或连接端点。
  • DynamoDB 中使用条件写入保护状态机,并把失败设计成可处理的业务结果。
  • Keyspaces 中保存事件和时序数据时,避免把最终一致的查询当作交易真相。
  • 给 Agent 工具声明一致性要求,而不是把数据库细节留给模型推断。
  • 通过故障注入测试复制延迟、读副本落后、跨区域网络抖动和重复工具调用。

AI Agent 的可靠性不只取决于模型是否“聪明”。当它开始改变现实世界的状态时,数据库在什么时候让它看到什么,和延迟本身一样重要。正确的做法不是为所有请求强行选择最高一致性,而是让每个任务的风险、数据模型和复制机制相互匹配。


相关推荐