移动电商应用并不是上线一次就结束了。商品、活动和店铺配置持续变化,商家需要反复刷新应用内容。Reactiv 使用 Amazon Bedrock AgentCore 构建了一套多智能体 AI Scheduler,让 Shopify 商家的移动应用按计划自主刷新,将商家配置时间缩短了 80%,并把系统投入生产的速度提高了 33%。
这两个数字的重点不只是“模型更快”,而是原本需要商家或运营人员手工完成的配置、调度与检查,被压缩成了一条可重复执行的自动化链路。
多智能体的价值在于拆分职责,而不是增加角色数量
一个调度任务表面上可能只是“每天刷新一次应用”,实际执行时通常包含多种决策:
- 当前店铺是否到了刷新时间;
- 哪些数据或页面需要更新;
- 本次变更是否符合发布规则;
- Shopify 或下游服务调用失败后如何重试;
- 更新结果是否完整,是否需要回滚或人工审核。
如果把这些工作全部交给一个智能体,它既要规划,又要持有执行权限,还要验证自己的结果。这样的设计难以测试,也容易扩大错误影响范围。
更稳妥的多智能体结构可以这样划分:
- Scheduler Agent:识别到期任务,生成稳定的任务 ID。
- Planner Agent:根据商家配置和当前状态生成刷新计划。
- Policy Agent:检查计划是否包含禁止操作、越权操作或高风险发布。
- Execution Agent:调用 Shopify 或 Reactiv 后端接口执行更新。
- Verifier Agent:读取执行结果,检查应用是否刷新成功。
这里的关键不是让五个模型自由对话,而是为每一步定义清晰的输入、输出和权限。AgentCore 可以承载或协调智能体能力,而真正的写入凭证、租户隔离和发布规则仍应由确定性的后端代码控制。
80% 的配置时间来自哪里
自动化调度带来的收益通常来自工作流压缩,而不是单次 API 调用的性能提升。过去商家可能需要选择页面、配置内容、确认时间、检查结果;引入 AI Scheduler 后,这些输入可以被转化为结构化任务,并按计划重复执行。
一个适合生产系统的任务载荷应尽量简单,例如:
{
"merchant_id": "shop_123",
"scheduled_for": "2025-03-08T09:00:00Z",
"timezone": "America/Toronto",
"refresh_scope": ["catalog", "home_feed"],
"publish_mode": "review_required",
"correlation_id": "shop_123-20250308T090000Z"
}
其中 correlation_id 不只是日志字段。它还可以作为幂等键,防止调度器重试、消息重复投递或网络超时导致同一版本被发布两次。
对于 33% 的生产提速,也应从工程边界理解:当调度、规划、执行和验证拥有稳定接口后,团队可以分别测试与替换各个组件,不必等一个庞大的端到端智能体全部完成后再上线。
可以这样实践:先跑通一个确定性的多智能体骨架
下面的示例不是 Reactiv 的源码,也没有假设 AgentCore 的具体 SDK 接口。它是一个可以直接运行的本地骨架,用四个独立角色模拟计划、策略检查、执行和验证,并通过文件保存幂等状态。
运行前只需要 Python 3.10 或更高版本:
cat > scheduler.py <<'PY'
from dataclasses import dataclass, asdict
from datetime import datetime, timezone
from pathlib import Path
import hashlib
import json
STATE_FILE = Path(".scheduler-state.json")
ALLOWED_ACTIONS = {"sync_catalog", "rebuild_home_feed", "publish_if_valid"}
@dataclass(frozen=True)
class RefreshJob:
merchant_id: str
scheduled_for: str
refresh_scope: tuple[str, ...]
publish_mode: str = "review_required"
@property
def idempotency_key(self) -> str:
payload = f"{self.merchant_id}:{self.scheduled_for}"
return hashlib.sha256(payload.encode()).hexdigest()[:20]
class PlannerAgent:
def plan(self, job: RefreshJob) -> dict:
actions = []
if "catalog" in job.refresh_scope:
actions.append("sync_catalog")
if "home_feed" in job.refresh_scope:
actions.append("rebuild_home_feed")
actions.append("publish_if_valid")
return {"job": asdict(job), "actions": actions}
class PolicyAgent:
def approve(self, plan: dict) -> None:
unknown = set(plan["actions"]) - ALLOWED_ACTIONS
if unknown:
raise ValueError(f"Blocked actions: {sorted(unknown)}")
if plan["job"]["publish_mode"] not in {"review_required", "automatic"}:
raise ValueError("Unsupported publish mode")
class ExecutionAgent:
def execute(self, plan: dict) -> dict:
# Production: replace this block with an authenticated backend call.
print("Executing:", json.dumps(plan, indent=2))
return {
"status": "completed",
"actions_completed": plan["actions"],
"version": "preview-001"
}
class VerifierAgent:
def verify(self, plan: dict, result: dict) -> None:
expected = set(plan["actions"])
completed = set(result.get("actions_completed", []))
if result.get("status") != "completed" or expected != completed:
raise RuntimeError("Refresh verification failed")
def load_completed() -> set[str]:
if not STATE_FILE.exists():
return set()
return set(json.loads(STATE_FILE.read_text()))
def save_completed(keys: set[str]) -> None:
STATE_FILE.write_text(json.dumps(sorted(keys), indent=2))
def run(job: RefreshJob) -> None:
completed = load_completed()
if job.idempotency_key in completed:
print(f"Skipped duplicate job: {job.idempotency_key}")
return
plan = PlannerAgent().plan(job)
PolicyAgent().approve(plan)
result = ExecutionAgent().execute(plan)
VerifierAgent().verify(plan, result)
completed.add(job.idempotency_key)
save_completed(completed)
print(f"Verified job: {job.idempotency_key}")
if __name__ == "__main__":
scheduled_for = datetime.now(timezone.utc).replace(
minute=0, second=0, microsecond=0
).isoformat()
run(RefreshJob(
merchant_id="shop_123",
scheduled_for=scheduled_for,
refresh_scope=("catalog", "home_feed")
))
PY
python scheduler.py
python scheduler.py
第二次执行会因为幂等键相同而跳过任务。接入真实系统时,可以逐步替换其中的边界:
- 将
PlannerAgent.plan()替换为对 AgentCore 中规划智能体的调用; - 让调度服务只传递商家 ID、计划时间和关联 ID;
- 由
ExecutionAgent调用持有 Shopify 凭证的内部服务,而不是把凭证交给模型; - 让
VerifierAgent查询真实应用版本、构建状态或发布结果; - 将本地状态文件替换为支持条件写入的持久化存储。
上线前不要忽略自治系统的刹车装置
定时任务与生成式 AI 结合后,一个错误可能被自动重复执行。生产环境至少应检查以下项目:
- 幂等性:同一商家、同一计划时间只能生成一次有效发布。
- 最小权限:规划智能体不应直接持有店铺写权限。
- 租户隔离:缓存、记忆、日志和工具调用必须绑定
merchant_id。 - 超时与重试:仅对可恢复错误重试,并设置最大次数和死信队列。
- 人工审批:主题结构、价格展示或大范围发布可以保留审核门槛。
- 输入防护:商品描述等商家内容可能包含提示注入文本,不能被当作系统指令。
- 可观测性:记录计划、工具调用、模型版本、执行结果和人工覆盖操作。
- 成本控制:确定性的时间判断和幂等检查应由代码完成,不必每次都调用模型。
Reactiv 的案例说明,多智能体系统最有价值的地方并不是让 AI 接管所有逻辑,而是把高频、重复、需要一定判断力的商家配置流程变成可调度的自动化。采用类似架构时,建议先选一个低风险刷新场景,跑通“计划—检查—执行—验证”闭环,再逐步扩大自动发布范围。