AWS Architecture Blog

From zero-shot forecast to purchase order with Amazon Bedrock AgentCore

8.5内容质量
From zero-shot forecast to purchase order with Amazon Bedrock AgentCore

TL;DR · AI 摘要

AWS通过Bedrock AgentCore和Chronos2模型实现库存自动化,零样本预测+多代理架构使成本降低98%。

核心要点

  • Chronos2模型实现零样本预测,无需SKU级训练
  • 多代理架构使采购订单决策可审计且可追溯
  • 测试显示WAPE中位数12.3%,成本降低98%

结构提纲

按章节快速跳转。

  1. 库存经理每日面临订单量决策难题,错误成本不对称。

  2. 时间序列模型需SKU级训练,梯度提升方法增加复杂度。

  3. Chronos2模型无需训练即可生成概率需求预测。

  4. Strands SDK+Bedrock AgentCore实现可审计的采购订单生成。

  5. 50SKU测试WAPE中位数12.3%,成本降低98%。

思维导图

用一张图看清主题之间的关系。

查看大纲文本(无障碍 / 无 JS 友好)
  • 库存自动化解决方案
    • 核心技术
      • Chronos2模型
        • 零样本预测
      • 多代理架构
        • 可审计决策
    • 测试成果
      • WAPE 12.3%
      • 成本降低98%

金句 / Highlights

值得收藏与分享的关键句。

#AWS#库存管理#机器学习#自动化
打开原文

从零样本预测到采购订单:使用 Amazon Bedrock AgentCore | AWS 架构博客

从零样本预测到采购订单:使用 Amazon Bedrock AgentCore

作者:Hyunsoo Kim、Chloe Kwak 学习级别:300 – 高级 文章类型:最佳实践

每个库存经理每天早上都会面临同样的问题:今天应该订购多少?答案取决于数十个变量(销售历史、即将推出的促销活动、价格变化、每周季节性因素、供应商交货时间),而预测错误的成本是不对称的。订购过多会导致资金被滞销库存占用,订购过少则会损失收入、损害客户信任并陷入紧急补货的混乱。

零样本预测的价值

传统的时间序列方法(ARIMA、Holt-Winters、季节性分解)需要为每个SKU单独拟合模型。拥有10,000个SKU的零售商必须训练、验证并维护10,000个独立模型。每个模型都需要单独的超参数调优、重新训练计划以及新产品的冷启动问题。随着商品目录规模扩大,运营负担呈线性增长,工程团队花费更多时间管理基础设施而非提升预测质量。

梯度提升和深度学习方法(LightGBM、DeepAR、Temporal Fusion Transformer)虽然提高了准确性,但加剧了操作复杂性:特征工程流水线、训练任务、模型仓库、A/B测试基础设施。对于许多组织而言,从“我们需要更准确的预测”到“预测在生产环境中运行”往往需要整整一个季度或更长时间。

从人工规则到自动化决策

即使拥有可靠的预测,将需求信号转化为采购订单仍需应用商业规则:安全库存缓冲、最低订购量、预算限制、促销提成调整。这些规则通常编码在电子表格或组织内部知识中,不同采购人员的应用不一致,且在大规模实施时几乎无法审计或解释。

本文构建的架构

本文将展示如何结合两种互补能力同时解决这两个问题:

  • Amazon Chronos2:一种时间序列基础模型,能够实现零样本预测,在无需针对每个产品进行训练的情况下返回概率性需求预测。
  • Strands Agents SDK 与 Amazon Bedrock AgentCore 的多代理编排:由四个LLM代理组成的系统,协调确定性工具,将原始预测转化为可验证的采购订单,并实现完整可审计性。

最终实现的端到端库存自动化流水线具有以下特性:新增产品无需任何机器学习模型训练,新增商业规则只需修改一个工具,每个决策均可审计、可观测且可从故障中恢复。在内部测试中,针对50个SKU在4周时间范围内的测试显示,该架构实现了12.3%的中位加权绝对百分比误差(WAPE)(P50预测与实际值对比),将每个SKU的上线时间从2-3周的模型训练缩短至不到5分钟的CSV上传,每月推理成本从约1,091美元(持续运行的GPU)降至约15美元(无服务器)——降低了98%。端到端流水线延迟平均每个SKU为8秒(不包括冷启动时间)。

解决方案概述

本节将描述端到端系统架构,解释为什么Chronos2非常适合库存预测,并概述多代理设计相比单体架构的优势。

端到端架构

系统分为三个逻辑层级:

图1. 解决方案架构 —— Amazon Bedrock AgentCore 协调四个LLM代理(Strands Agents SDK),这些代理调用确定性工具来访问Amazon S3和Amazon SageMaker无服务器推理。

数据层。Amazon简单存储服务(Amazon S3)作为单一事实来源。每个产品对应一个CSV文件,同时编码历史销售数据和未来协变量值。业务规则(提前期、安全库存、仓库容量、最小订购量)存储在单独的JSON配置文件中。添加新产品只需上传这两个文件,无需修改代码。

推理层。Amazon SageMaker无服务器推理托管Chronos2端点,用于零样本时间序列预测。这是整个流程中唯一一次外部模型推理调用——LLM推理过程在编排层内部通过Amazon Bedrock完成。

编排层。四个LLM代理——监督者、预处理、预测和报告代理——使用Strands Agents SDK构建,并部署在Amazon Bedrock AgentCore上。每个代理都使用Amazon Bedrock上的Claude进行推理,并调用确定性工具执行计算任务。

Amazon Bedrock AgentCore是一个完全托管的平台,可用于大规模构建、部署和优化代理,支持任何框架或模型。编排层运行在AgentCore上,该平台提供六个子服务:Runtime、Gateway、Policy、Memory、Observability和Evaluations。该系统使用了所有六个服务,但每个服务仅用于特定单一目的。架构深入分析部分将每个服务映射到其在本设计中解决的生产问题——包括为什么Gateway接口被刻意设计得较小(仅暴露八个工具中的一个)。

为何选择Chronos2:零样本、协变量、假设分析

Chronos2是一个仅包含编码器的Transformer模型,其设计紧密遵循T5编码器架构,经过大量且多样化的现实世界时间序列语料库预训练。该模型通过上下文学习和分组注意力机制生成多步概率预测——无需对您的数据进行微调。

以下三个特性使其成为大规模库存预测的首选方案:

  • 零样本泛化:新SKU无需训练任务。输入历史销售窗口,输出概率预测——包括针对历史数据稀疏或时间较短的产品。
  • 协变量支持:Chronos2接受仅过去协变量(仅已知历史时期的特征)和已知协变量(未来值已知的特征,例如计划中的促销或价格变动)。在Python API中,这些协变量通过context_df和future_df数据框传递给pipeline.predict_df()。协变量将模型从单变量预测器转变为条件预测器。
  • 假设情景分析:由于协变量是显式输入,您可以生成多种预测方案——包含促销和不包含促销、当前价格和折扣价格——并在提交订单前进行对比分析。

Chronos2 非常适合处理此类工作负载,因为它同时满足了三个要求:零样本推理(无需按SKU进行训练)、通过 predict_df() API 明确支持仅过去数据和未来协变量,以及一键部署到 Amazon SageMaker Serverless Inference 的路径。这种组合意味着引入新产品只需数据即可——无需更改流水线、无需在模型注册表中添加条目、无需重新训练计划。架构深入解析中引入的评估框架使得在不重建流水线的情况下,可以轻松对任何替代预测模型进行基准测试。

为何选择多代理架构而非单体架构

一个执行所有推理步骤的单一 LLM 提示(包括数据加载、协变量选择、预测解释、订单计算、验证和结果保存)将超出大型目录的实际上下文窗口限制,无法在组件级别进行单元测试,并且在任何单个步骤遇到错误时会导致灾难性失败。

按推理责任划分的代理架构直接解决了这些问题。关键在于,这种架构明确区分了职责:LLM 代理负责判断,确定性工具负责计算。Bedrock 推理仅在四个代理中发生:四个代理协调的操作(加载文件、运行补货公式、生成图表、写入 S3)作为普通 Python 函数运行,代理通过 @tool 调用这些函数。代理决定何时调用每个工具以及使用什么参数:工具本身不包含 LLM 推理。这种分离通过确保每个代理的上下文窗口仅包含其推理所需的必要信息(而非每次工具调用的原始副产品),从而将每次运行的 LLM 成本控制在合理范围并保持推理质量。

先决条件

部署此架构之前需要确保以下四点。其他组件(S3 存储桶、IAM 角色、文件夹布局和代理运行时包)由以下章节描述的 CDK 堆栈和部署脚本进行配置。

  • 同一 AWS 区域(以下示例假设 us-east-1)内具有 Amazon Bedrock、Amazon SageMaker 和 Amazon S3 访问权限的 AWS 账户。
  • 在 Bedrock 控制台的 Model access → Manage model access 中启用的 Claude Sonnet 4.5(Anthropic)模型访问权限。有关各区域的模型可用性,请参阅 Amazon Bedrock 的 Supported models by AWS Region。
  • 部署在 Amazon SageMaker Serverless Inference 上的 Chronos2 端点。部署过程使用单个 SageMaker Serverless 端点配置和 Chronos2 模型包。
  • 本地机器上安装 Python 3.10+ 和 Node.js 20+。安装 SDK 和 CLI:pip install -e . # 从仓库根目录 npm install -g aws-cdk @aws/agentcore

技术实现

本节将逐步介绍数据格式、代理定义、协调器逻辑和部署配置。

数据格式设计

输入格式有意模糊历史期和预测期的边界。单个 CSV 文件涵盖两者:

code
date,sales,promotion,day_of_week,is_weekend,price
2024-01-01,120,0,1,0,29.99
2024-01-02,95,0,2,0,29.99
...
2024-01-20,140,0,6,1,29.99
2024-01-21,,1,7,1,24.99
2024-01-22,,1,1,0,24.99
2024-01-23,,0,2,0,29.99

销售为空的行定义了预测范围。协变量在历史和未来时间段中均被完整填充。这种设计将过去与未来的区分作为数据问题而非代码问题来处理——无论预测范围长度如何,预处理代理都会读取相同的模式。当运营团队知道下周计划有促销活动时,他们会为这些未来行填写促销列,然后重新上传文件。

产品级业务规则存储在单独的JSON配置中:

code
{
  "SKU-00142": {
    "name": "Wireless Earbuds Pro",
    "safety_stock": 150,
    "lead_time_days": 5,
    "warehouse_capacity": 2000,
    "min_order_quantity": 50,
    "unit_cost": 12.50,
    "supplier": "Supplier-A"
  }
}

通过将业务规则视为数据而非代码,调整供应商的交货时间或安全库存阈值只需在S3中更新配置——无需部署。

四个LLM代理及其工具

核心设计原则:当输出依赖于解释或上下文时使用LLM代理;当输出完全由输入决定时使用确定性工具。

#### 监督代理

监督代理是每个用户请求的入口点。其职责是纯粹的编排:解析用户自然语言中的意图,构建执行计划,按顺序将工作路由到三个专业代理,并根据它们的输出处理条件分支。

当用户发送“运行无线耳机的周补货预测——本周末有促销活动”时,监督代理:

  • 识别产品范围并将“无线耳机”解析为对应的SKU。
  • 记录促销上下文并显式传递给预处理代理。
  • 构建顺序执行计划。
  • 监控代理输出,如果验证失败则触发条件重试循环。

这需要真正的LLM推理。监督代理不是带有硬编码查找表的路由器——它解释模糊指令,将缺失参数作为澄清问题提出,并根据下游代理的输出做出分支决策。

监督代理不直接调用数据或计算工具。它的唯一职责是推理工作流。

在生产环境中,Amazon Bedrock Guardrails作为强制性控制措施保护每个代理的LLM推理步骤,而非可选附加功能。监督代理——它解释自然语言请求并做出最终决定订单数量的分支决策——在Guardrails配置下运行,该配置强制执行内容过滤、禁止主题策略,并针对结构化工具输出进行接地验证。这可防止监督代理产生约束覆盖的幻觉或生成超出授权范围的采购决策。有关实现细节,请参阅Amazon Bedrock Guardrails。

#### 预处理代理

预处理代理通过确定性工具加载原始数据,然后应用LLM推理来决定如何为Chronos2准备数据。

code
import json
import boto3
from strands import Agent, tool
from strands.models import BedrockModel

@tool
def load_sales_from_s3(product_id: str) -> dict:
    """为给定产品ID从S3加载销售时间序列CSV文件。"""
    response = s3.get_object(Bucket=BUCKET, Key=f"sales/{product_id}.csv")
    return parse_csv(response["Body"].read())

@tool def load_inventory_from_s3() -> dict: """从S3加载所有产品的当前库存水平。""" response = s3.get_object(Bucket=BUCKET, Key="inventory/current_stock.json") return json.loads(response["Body"].read())

@tool def load_product_config_from_s3(product_id: str) -> dict: """加载产品的业务规则(交货时间、安全库存、产能)。""" response = s3.get_object(Bucket=BUCKET, Key="config/product_config.json") return json.loads(response["Body"].read())[product_id]

preprocessing_agent = Agent( model=BedrockModel(model_id="us.anthropic.claude-sonnet-4-5-20250929-v1:0"), tools=[load_sales_from_s3, load_inventory_from_s3, load_product_config_from_s3], system_prompt=( "你是一名数据预处理专家。加载所需数据后," "根据数据质量和监督员提供的业务上下文," "决定在Chronos2输入中包含哪些协变量。" "以JSON格式返回结构化的Chronos2有效负载。" ) )

code

三个load_*函数是纯Python代码——不涉及LLM推理。预处理代理的LLM推理在数据加载后启动,此时需要决定包含哪些协变量。监督员将用户的自然语言请求(例如,“本周末有促销活动”)作为任务描述传递给预处理代理,这会提示必须包含促销列。但代理还会评估数据质量:如果促销列在训练期间填充稀疏或方差接近零,代理可能会将其排除并记录决策。确定性函数无法做出这种判断——它需要同时阅读数字和业务上下文。

#### 预测代理

预测代理通过确定性工具调用Chronos2端点,然后应用LLM推理来解释结果。

@tool def call_chronos2(payload: str) -> dict: """ 调用Chronos2 SageMaker端点。 冷启动时最多重试3次,每次间隔30秒。 """ for attempt in range(3): try: response = sagemaker_runtime.invoke_endpoint( EndpointName=CHRONOS2_ENDPOINT, ContentType="application/json", Body=payload ) return json.loads(response["Body"].read()) except ClientError as e: if e.response["Error"]["Code"] == "ModelNotReadyException": time.sleep(30) continue raise raise TimeoutError(f"3次尝试后Chronos2端点仍未就绪")

@tool def calculate_order_quantity( forecast_p50: list, current_stock: int, safety_stock: int, lead_time_days: int, min_order_quantity: int ) -> dict: """确定性补货公式。""" lead_time_demand = sum(forecast_p50[:lead_time_days]) order_qty = max(0, lead_time_demand + safety_stock - current_stock) if 0 < order_qty < min_order_quantity: order_qty = min_order_quantity return {"order_quantity": int(order_qty), "lead_time_demand": int(lead_time_demand)}

python
def validate_constraints(
    order_quantity: int,
    current_stock: int,
    warehouse_capacity: int,
    budget_cap: float,
    unit_cost: float,
) -> dict:
    """对仓库容量和预算的确定性约束检查。"""
    new_stock = current_stock + order_quantity
    within_capacity = new_stock <= warehouse_capacity
    total_cost = order_quantity * unit_cost
    within_budget = total_cost <= budget_cap
    return {
        "approved": within_capacity and within_budget,
        "capacity_used": round(new_stock / warehouse_capacity, 2),
        "budget_used": round(total_cost, 2),
        "budget_remaining": round(budget_cap - total_cost, 2),
        "violations": [v for v in [
            None if within_capacity
                else f"超出仓库容量 ({new_stock}/{warehouse_capacity})",
            None if within_budget
                else f"超出预算 (${total_cost:.2f}/${budget_cap:.2f})",
        ] if v],
    }

forecasting_agent = Agent(
    model=BedrockModel(model_id="us.anthropic.claude-sonnet-4-5-20250929-v1:0"),
    tools=[call_chronos2, calculate_order_quantity, validate_constraints],
    system_prompt=(
        "您是预测和订单规划专家。"
        "使用提供的负载调用Chronos2,解释概率预测结果,计算推荐订单数量,并验证其是否符合业务约束。"
        "用简要说明标记任何异常。"
    )
)

call_chronos2、calculate_order_quantity和validate_constraints都是确定性函数。Forecasting Agent的LLM推理能提供这些工具无法实现的两件事:异常上下文化(例如“第7天P90/P50比率为1.36——超过1.3的异常阈值,与当天促销协变量一致”)以及订单推荐的自然语言解释(例如“753件可覆盖5天交货期需求648件,加上150件安全库存缓冲,扣除当前45件库存”)。此解释中的数字来自data/product_config.json——与本文后面“运行代理”步骤中使用的相同值。

概率输出——P10、P50和P90分位数——是库存规划的核心,而非附带结果。仅根据P50(中位数)下单而不设置缓冲,意味着大约一半时间会缺货,这就是为何安全库存作为独立参数存在。calculate_order_quantity使用P50预测计算预期交货期需求,而产品配置中的safety_stock参数则吸收P50与P90之间的不确定性(团队通常根据目标服务水平如P90或P95调整安全库存)。对于P90/P50比率较高的产品(表明需求波动大或受促销驱动),Forecasting Agent会明确标记异常,使Reporting Agent能够向采购人员报告升高的不确定性,而非将其隐藏在单一订单数字背后。

The violations array returned by validate_constraints is what makes the conditional retry loop actionable. When the constraint check fails, the array contains a human-readable string per violated constraint (for example, "Exceeds budget ($9412.50/$500.00)" ), which the Forecasting Agent passes up to the Supervisor. The Supervisor uses this specific message, not a generic “validation failed” signal. Based on the violation details, it decides whether to re-invoke the Forecasting Agent with adjusted constraints or escalate to the user.

#### 报告代理

报告代理消费来自预测代理的结构化输出并生成最终交付成果:一个可视化图表和一个持久化的决策记录。这些工具是确定性的。代理提供自然语言摘要,使输出对业务用户具有可操作性。

code
import io
import json
import boto3
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from strands import Agent, tool
from strands.models import BedrockModel

BUCKET = os.environ["INVENTORY_BUCKET"]

@tool
def generate_forecast_chart(forecast_data: str, output_path: str) -> str:
    """生成预测分位数图表并上传到 S3。

    Args:
        forecast_data: JSON 字符串(Strands 将工具参数序列化为字符串)
        output_path: 输出 PNG 的 S3 键
    """
    data = json.loads(forecast_data)
    forecast = data["forecast"]
    days = list(range(1, len(forecast["p50"]) + 1))

    fig, ax = plt.subplots(figsize=(10, 5))
    ax.fill_between(days, forecast["p10"], forecast["p90"],
                    alpha=0.2, color="#147EBA", label="P10-P90 范围")
    ax.plot(days, forecast["p50"], color="#147EBA", linewidth=2, label="P50 中位数")
    ax.set_xlabel("预测天数")
    ax.set_ylabel("预测需求(单位)")
    ax.set_title(f"需求预测 - {data.get('product_id', '')}")
    ax.legend()
    plt.tight_layout()

    buf = io.BytesIO()
    fig.savefig(buf, format="png", dpi=150, bbox_inches="tight")
    buf.seek(0)
    plt.close(fig)

    s3 = boto3.client("s3")
    s3.put_object(Bucket=BUCKET, Key=output_path,
                  Body=buf.read(), ContentType="image/png")
    return json.dumps({"chart_s3_path": f"s3://{BUCKET}/{output_path}", "status": "uploaded"})

@tool
def save_decision_record(decision_data: str, output_path: str) -> str:
    """将完整的决策记录作为 JSON 持久化到 S3。"""
    s3 = boto3.client("s3")
    s3.put_object(
        Bucket=BUCKET,
        Key=output_path,
        Body=decision_data.encode("utf-8"),
        ContentType="application/json",
    )
    return json.dumps({"record_s3_path": f"s3://{BUCKET}/{output_path}", "status": "saved"})

reporting_agent = Agent(
    model=BedrockModel(model_id="us.anthropic.claude-sonnet-4-5-20250929-v1:0"),
    tools=[generate_forecast_chart, save_decision_record],
    system_prompt=(
        "你是一名报告专家。生成预测可视化图表,持久化决策记录,并生成推荐及其商业理由的简洁自然语言摘要。"
    )
)

协调器模式:顺序 + 条件重试

code
用户请求
     │
     ▼
监督代理
     │
     ▼
预处理代理 ──── 工具: load_sales_from_s3,
     │                          load_inventory_from_s3,
     │                          load_product_config_from_s3
     ▼
预测代理 ──────── 工具: call_chronos2,
     │                            calculate_order_quantity,
     │                            validate_constraints
     ├── 验证通过 ──────► 报告代理 ── 工具: generate_forecast_chart,
     │                                               save_decision_record
     │                          │
     │                          ▼
     │                    最终响应
     │
     └── 约束违反
               │
               ▼
         返回预测代理
         (使用监督代理调整后的约束)
               │
               └── 最多3次迭代,否则升级至用户

模式:代理即工具

前述协调器图示是行为视角。在结构上,该实现遵循"代理即工具"模式:监督代理是单个Strands代理,其工具列表包含三个专业代理,每个代理都封装为@tool。Strands SDK的编排层中没有显式的多节点图结构——该图是一个包含max_node_executions=10的单一监督节点(为预处理→预测→报告基础流程及最多三次重试迭代预留足够空间,之后会触发安全停止)。编排过程发生在监督代理的工具调用循环内部。

这对上下文隔离至关重要。每个专业@tool调用都会生成一个带有独立上下文窗口、独立系统提示和独立工具子集的新Strands代理。结果以压缩的带标签输出块(由Strands SDK定义的CLUES_FORMAT信封)形式返回给监督代理,其中包含专业代理的带标签输出而非完整推理记录——因此监督代理仅看到带标签的增量变化,其上下文规模始终受控。

部署到Amazon Bedrock AgentCore

前述Strands代理定义作为本地Python进程运行,以Amazon Bedrock作为LLM后端。要迁移到托管执行环境,请将监督代理入口点封装为AgentCore应用:

code
from bedrock_agentcore.runtime import BedrockAgentCoreApp
from memory.session import get_session_manager
from observability.tracing import set_session_context
from src.graph.nodes import supervisor_node

app = BedrockAgentCoreApp()

@app.entrypoint
async def handler(payload: dict, context=None):
    user_request = payload.get("prompt", payload.get("user_request", ""))
    session_id = getattr(context, "session_id", None) or payload.get("session_id", "default-session")
    actor_id = getattr(context, "user_id", None) or payload.get("actor_id", "system")

    # 为本次会话附加遥测上下文
    set_session_context(session_id, product_id=payload.get("product_id"))

    # 创建内存会话管理器(若未配置MEMORY_ID则返回None)
    session_manager = get_session_manager(session_id, actor_id)
    result = await supervisor_node(task={"request": user_request}, session_manager=session_manager)
    return result.get("text", "No response generated.")

使用 AgentCore CLI 部署:agentcore deploy . AgentCore 会为每次调用创建一个隔离的微虚拟机,注入会话上下文以实现短期记忆的读写,并自动将代理追踪流式传输到 Amazon CloudWatch —— 无需额外的监控配置。完整的端到端部署包含一系列步骤 —— CDK 基础设施、已注册 save_decision 的网关、Cedar 策略、内存资源、运行时包以及部署后评估设置 —— 所有步骤均由单个部署脚本统一编排。

该顺序链由数据依赖性强制执行:没有预处理的有效载荷,预测代理无法运行。没有经过验证的订单决策,报告代理也无法运行。

条件重试循环将约束违规视为首要的工作流状态,而非错误条件。当 validate_constraints 返回 approved: false 时,预测代理会展示违规解释。监督器会解读该信息,调整约束参数(例如减少订单以符合预算上限),然后重新调用预测代理。监督器会在 AgentCore 的短期会话内存中跟踪迭代次数,如果三次迭代未收敛,会升级到用户 —— 避免静默无限循环。

成本优化:零扩展

最重要的成本决策是 Chronos2 端点的 SageMaker 部署模式。

| 配置 | 月成本 | 冷启动 | 推荐场景 | |------|--------|--------|----------| | 持续运行的 ml.g5.2xlarge | ~1,091 美元 | 无 | 高频实时使用 | | 无服务器推理 | ~15 美元 | 30–60 秒 | 批处理/计划预测 |

对于批处理库存预测 —— 每晚或每周执行一次的作业 —— 30–60 秒的冷启动完全可接受。与持续运行的 GPU 端点相比,无服务器推理可将推理成本降低 98% 以上。

AgentCore 运行时遵循相同的零扩展成本模型:每个会话的微虚拟机隔离,会话持续时间最长 8 小时,工作流运行之间无空闲成本。代理运行时和推理端点在未使用时都会自动缩至零。

数字分解说明:每月 15 美元的无服务器估算假设约 500 次调用,每次平均计算时间 8 秒,按 ml.g5.xlarge 无服务器费率计价,不包含存储和跨服务数据传输(预测负载和响应均远低于 1 兆字节)。每月 1,091 美元的持续运行估算对应一个 ml.g5.2xlarge 端点 24×7 运行,每小时都会为未进行预测时的空闲 GPU 内存付费。对于夜间或每周批处理作业,工作周期使无服务器成为默认选择。对于延迟敏感的实时预测且调用频率高,每月几千次调用是无服务器和持续运行的平衡点,超过该阈值则应选择持续运行端点。

架构深入解析:设计模式与权衡

本节探讨系统的关键设计决策:如何将工作分解为代理与工具,代理如何通过数据契约通信,以及如何处理故障和控制成本。

代理与工具决策框架

在多代理系统中,最重要的设计决策不是选择何种框架或创建多少代理 —— 而是为每个工作单元决定是需要 LLM 还是确定性函数。

实用测试标准:

“如果我固定输入,输出是否始终相同?”

  • 是 → 实现为 @tool 。LLM 调用它,函数执行实际工作。
  • 否 → 代理的LLM推理即为逻辑。可变性是故意设计的。

将此测试应用于系统中的每个组件:

组件

输出是否确定?

实现方式

解析用户的自然语言请求

否

监督代理推理

从S3加载文件

是

code
@tool

根据数据质量+用户上下文选择协变量

预处理代理推理

调用Chronos2端点

在商业背景下解释预测异常

预测代理推理

根据公式计算订单数量

检查订单是否符合仓库/预算约束

生成订单推荐的依据

生成matplotlib图表

将JSON写入S3

决定是否调整约束条件后重试或升级给用户

用商业语言总结结果

报告代理推理

将预测准确性与实际销售进行评分

基于代码的评估器(AWS Lambda

@tool-equivalent

)

模式:确定性计算应属于工具。判断、解释和依赖上下文的推荐应属于代理推理。将确定性公式封装在LLM代理中会增加成本、延迟和非确定性,但没有任何好处。让确定性函数解释“下周有促销”会失败。

此框架也防止了需求蔓延。当出现新需求——“为季节性缓冲库存添加第二个验证检查”时,答案很明确:添加一个@tool,而不是新代理。

数据契约设计:代理间的结构化JSON

顺序链中的每个代理输出一个类型化的JSON结构,供下一个代理使用。预测代理与报告代理之间的代表性契约:

code
{
  "product_id": "SKU-00142",
  "forecast_horizon_days": 14,
  "covariates_used": ["promotion", "price", "day_of_week"],
  "forecast": {
    "p10": [95, 98, 118, 128, 105, 112, 135, 92, 96, 100, 105, 112, 140, 148],
    "p50": [110, 115, 145, 158, 120, 128, 158, 106, 110, 115, 119, 127, 154, 166],
    "p90": [132, 138, 183, 206, 150, 160, 215, 130, 138, 150, 155, 165, 195, 210]
  },
  "order_decision": {
    "order_quantity": 753,
    "lead_time_demand": 648,
    "safety_stock": 150,
    "current_stock": 45,
    "supplier": "Supplier-A",
    "approved": true,
    "warehouse_utilization": 0.40
  },
  "anomaly_flags": [
    {
      "day": 7,
      "note": "第7天的P90/P50比值为1.36,超过1.3的异常阈值;当天与促销协变量相关的不确定性升高"
    }
  ],
  "rationale": "753单位的推荐订单量覆盖了648单位的5天交货需求,加上150单位的安全库存缓冲,扣除当前45单位库存。交货后仓库利用率:40%。",
  "model": "chronos2",
  "inference_latency_ms": 1840
}

该契约明确说明实际使用的协变量(预处理代理的决策可见且可审计),将订单依据作为一级字段包含在内,并以结构化形式携带异常标志,而非埋藏在文本中。这使得契约对下游工具可被机器读取,对调试人员可被人类阅读。

通过非结构化文本的隐式耦合——一个代理返回段落,下一个代理试图从中提取数字——是多代理系统中最常见的故障模式。显式JSON契约可防止此类问题。

故障处理:重试、降级和隔离

三种故障策略,与组件关键性相匹配:

按代理重试与退避机制:适用于 load_* 工具(S3 临时性错误)和 call_chronos2(SageMaker Serverless 冷启动)。预测代理的工具通过最多 3 次 30 秒间隔重试处理冷启动,透明地捕获 ModelNotReadyException 异常,避免向代理暴露错误。

优雅降级:若预处理代理判断协变量列过于稀疏不可靠,将跳过该协变量并记录降级信息至输出协议。预测代理接收有效(尽管可能精度降低)的输入并继续执行。报告代理在汇总信息中会显示降级标志。

非关键路径故障隔离:generate_forecast_chart 和 save_decision_record 在报告代理中运行。若图表生成失败(渲染错误、S3 写超时),报告代理仍可完成核心输出:自然语言摘要和决策记录。订单推荐从不会因可视化失败而受阻。

进程内与网关:第二个边界

代理与工具框架划出第一条线:输出是否由输入决定?第二条线位于其下,对生产系统同样关键:该工具是否跨越了信任、持久性或错误代价的边界?

“若代理产生幻觉并错误调用该工具,错误会传播至外部系统还是仅停留在代理内存中?”

  • 仅停留在代理 → 进程内 Strands @tool。代理的 IAM 角色和 Strands 类型系统已实现绑定。添加网关只会增加延迟和成本,无安全收益。
  • 传播至外部 → 网关。此处需要 Cedar 授权、JWT 身份以及“谁请求了该写入,写入了什么”的审计追踪。

对系统中每个工具的应用:

工具

失败时的副作用?

部署位置

code
load_sales

无(仅读取)

进程内

code
load_inventory
code
load_product_config
code
invoke_chronos2

外部 SageMaker 调用,无状态变更

code
calculate_order

无(纯函数)

code
validate_constraints
code
generate_forecast_chart

S3 写入,可重试,非权威

(失败处理章节已覆盖此隔离)

code
save_decision

成为权威订单记录的 S3 写入

网关 + Cedar 策略

在该系统 8 个工具中,仅有 1 个需要网关。这种比例是常态而非例外:代理系统中大多数“工具”都是读取和纯函数,网关在此类场景中只会增加成本而无安全收益。AgentCore 提供的服务之所以是可选加入的,原因在于:为每个独立边界选择一个子服务进行防护,而非为每个工具都启用全部六个子服务。

自然的后续问题:generate_forecast_chart 也写入 S3 —— 为何部署在进程内而非网关后?因为图表是可视化内容,而非记录性决策。若其失败或存在静默错误,订单推荐依然有效,写入操作只需重试即可。save_decision 正相反:一旦决策记录持久化,下游系统即视订单为真实。网关的价值体现在:当错误写入可能引发下游不一致时,而非仅仅造成买家不便的场景。

网关 Lambda(mcp/lambda/handler.py)将 save_decision 暴露为 MCP 兼容的工具端点。基础设施复杂度与实际策略表面成比例,而非与代理调用的工具数量相关。

预算感知架构:每个代理的令牌预算

除了基础设施成本,四代理设计使令牌预算分配变得明确。每个代理的上下文窗口由其单一职责界定:

| 代理 | 上下文窗口包含内容 | 不包含内容 | |------------|-----------------------------------|------------------------------------| | 监督器 | 用户请求、执行计划、压缩的 | 原始 CSV、Chronos2 预测数组 | | | CLUES_FORMAT 块 | | | 预处理 | 原始 CSV 行、产品配置 | 对话历史记录 | | 预测 | 格式化 Chronos2 载荷、模型输出 | 原始 CSV、完整历史记录 | | 报告 | 验证后的订单决策、理由 | 原始数据、Chronos2 载荷 |

这种分区方式使随着目录规模扩大,每次运行的 LLM 推理成本保持稳定。一个单体代理在每一步都携带所有数据、所有对话历史和所有中间结果,会导致上下文窗口随目录规模和对话长度增长——并在每次调用时产生相应成本。

每个 AgentCore 服务对应一个边界

前述两种决策框架(代理与工具、进程内与网关)使每个 AgentCore 子服务在系统中的定位清晰。下表将每个服务映射到单一生产关注点。后续段落将解释为何该服务是解决该问题的正确方案——而不仅仅是服务的功能。

| 生产关注点 | AgentCore 服务 | 替代方案 | |------------------------------|------------------------|----------------------------------| | 代理在何处运行? | Runtime | 始终在线容器 | | 哪些写入操作可以到达外部系统? | Gateway + Policy | API 网关 + 自定义授权中间件 | | 代理在会话间携带什么? | Memory | Redis + 定制检索代码 | | 能否重建决策原因? | Observability | 自定义 OTEL 设置 + CloudWatch 配线 | | 如何确认代理部署后仍正常运行? | Evaluations | 离线评估脚本 + 手动 QA |

Runtime 为代理执行提供运行时保护。AgentCore Runtime 在每个会话的微虚拟机中托管 Supervisor,单个会话最长持续 8 小时,会话间无空闲成本。对于批量库存预测(周任务或夜间任务),支付始终在线容器的费用是浪费。Runtime 默认提供会话隔离和会话间自动缩容至零,团队无需单独设计这些功能。

Gateway 和 Policy 控制哪些写入操作可以到达外部系统。Gateway 设计为与 Policy 配对使用:Gateway 验证调用者身份(来自 Cognito 的 JWT),Policy 决定特定调用是否允许(Cedar 通过 context.input 评估主体、操作、资源和完整工具调用载荷)。没有 Policy,Gateway 会授予每个认证调用者访问每个注册工具的权限。

由于只有 save_decision 在 Gateway 上注册,授权范围被限定在订单变为持久记录的单一节点——下游系统(仪表板、ERP 集成)将决策视为真实前的最后一个关卡。适用两个 Cedar 策略:

  • allow_write_reporting_only — save_decision 仅能由报告工作流的身份调用。
  • deny_high_value_orders — 任何 context.input.budget_used > 50000 的 save_decision 调用都会被拒绝,无论主体身份:
code
forbid(
  principal is AgentCore::OAuthUser,
  action == AgentCore::Action::"InventoryTools___save_decision",
  resource is AgentCore::Gateway
) when {
  context.input has budget_used &&
  context.input.budget_used > 50000
};

将高价值的拒绝规则放在上游(例如在calculate_order中)会失效:代理可以不断重新运行计算直到通过,而拒绝规则不会产生任何持久性效果。该策略只有在写入边界时才具有意义。

Memory 用于管理代理在会话间携带的数据。AgentCore Memory 支持三种长期存储策略。该系统使用其中两种:semanticMemoryStrategy 用于SKU级别的预测准确性历史记录,userPreferenceMemoryStrategy 用于约束覆盖(如“该买家始终为电子产品设置20%的更高安全库存”)。summaryMemoryStrategy 在此处未使用,因为会话级别的摘要对结构化预测工作流帮助不大。Strands AgentCoreMemorySessionManager 将这些策略与Supervisor集成,无需定制检索代码。

Observability 用于判断我们是否能重建决策依据。每次代理调用(输入、输出、工具调用、重试尝试、延迟)都会自动追踪并流式传输到Amazon CloudWatch。对于库存流水线,每个订单决策都会生成完整可审计的追踪记录:哪个代理执行了操作、调用了哪些工具、Chronos2返回了什么内容、以及为什么预测代理推荐特定数量。CloudWatch Logs Insights 查询可揭示运营模式,如“哪些SKU触发最多的约束违规”或“哪些产品显示最高的P90/P50预测不确定性”——这些信息可直接指导业务规则优化和协变量选择,无需重新运行流水线。

Evaluations 用于判断代理部署后是否仍保持正确行为。AgentCore Evaluations 对生产流量的采样部分进行在线质量监控(可配置。该系统在初始发布时采样100%)。两个内置评估器——Builtin.GoalSuccessRate 和 Builtin.Helpfulness——提供通用质量信号,而自定义的LLM-as-a-Judge评估器按3分制对约束合规性进行评分:

  • 1.0 — 静默违规:订单违反约束且代理未标记该问题。
  • 2.0 — 标记违规:订单违反约束但代理明确指出了该问题。
  • 3.0 — 合规:订单符合所有约束。

该评分体系刻意奖励能标记违规的代理而非隐藏违规。这正是重试循环设计要防止的失效模式,评估器也专门用于检测此类问题。如果没有这个评分标准,一个默默截断订单以适应预算的代理会与一个向用户升级的代理获得相同评分——尽管只有后者适合生产环境。3分制评分体系能捕捉代理隐藏约束违规的失效模式。下一小节将增加第二个评估器,用于回答互补问题——预测本身是否准确?

贯穿始终的观点:AgentCore 并不是一个你只能选择采用或拒绝的单一“代理平台”。它是一组服务,每项服务针对生产级代理系统面临的具体问题。为每个问题选择合适的服务——而不是强行让一个服务覆盖两个问题——这就是架构设计的工作。上文的架构图是该系统架构设计工作的成果。不同领域(如客户支持、代码生成、研究)的架构图会有所不同,但绘制架构图的思考过程是相同的。

评估的两个层次:行为与准确性

前面描述的评估方法回答了一个问题:代理的行为是否安全?这是必要但不充分的。对于库存系统,第二个同样重要的问题是:代理生成的预测是否准确?如果代理能正确标记所有约束违规,但其 P50 预测值系统性地偏离实际值 30%,它仍然是无用的。

这两个问题对应了 AgentCore 评估框架支持的两种评估类型。它们之间的选择逻辑与架构深度解析中代理与工具框架的选择逻辑一致,只是层级更高:如果正确输出完全由输入决定,应使用确定性函数而非 LLM。预测准确性评分是计算,而非判断。

规律:代理行为需要主观评分,预测准确性需要数学计算。应根据问题本身选择对应的评估类型,而不是选择看起来更高级的类型。

LLM-as-a-Judge 评估器用于评分主观维度——代理是否标记了违规项、理由是否连贯、响应是否具有帮助性。适合行为评估,但不适合数学计算。

基于代码的评估器会通过会话轨迹调用 Lambda 函数,并可通过 evaluationReferenceInputs 注入可选的真实值。适合确定性指标——如 WAPE、有符号偏差、分位数损失、覆盖率——这些指标有明确的数值答案。

#### 预测准确性评估器(基于代码)

该评估器是一个 Lambda 函数,从会话轨迹中读取 Chronos2 预测值,将每个预测时间点与作为真实值提供的实际销售额配对,返回 WAPE 作为主要数值评分,同时包含有符号偏差、P90 分位数损失以及 P10–P90 覆盖率。

code
# lambda/forecast_accuracy_evaluator/handler.py
import numpy as np

def handler(event, context):
    """基于代码的预测准确性评估器。
    在实际销售额已知(预测时间 + 提前期之后)时运行。"""
    spans = event["evaluationInput"]["sessionSpans"]
    ground_truth = event.get("evaluationReferenceInputs", [])

    forecast = extract_forecast_from_spans(spans)  # 预测代理的 Span
    actual = np.array([g["actual_sales"] for g in ground_truth])
    p10 = np.array(forecast["p10"])
    p50 = np.array(forecast["p50"])
    p90 = np.array(forecast["p90"])

    if len(actual) != len(p50):
        return {
            "errorCode": "HORIZON_MISMATCH",
            "errorMessage": f"forecast={len(p50)}, actual={len(actual)}",
        }

    # 主要指标:WAPE(加权绝对百分比误差)。
    # 优于 MAPE,因为它按销量加权误差,避免了
    # MAPE 在低销量日的已知异常放大问题。
    wape = float(np.abs(actual - p50).sum() / actual.sum())
python
# 签名偏差(SCM惯例:偏差 = 预测 - 实际,标准化)
# 正值 => 持续高估 => 库存过剩风险
# 负值 => 持续低估 => 缺货风险
bias = float((p50 - actual).sum() / actual.sum())

# P90分位数的Pinball损失:
#   L_q(y, ŷ) = max(q·(y-ŷ), (q-1)·(y-ŷ))
# 当q=0.9时,实际值大于P90预测值(覆盖不足)的惩罚是覆盖过量的9倍
# 这与缺货的运营成本相匹配
q = 0.9
diff = actual - p90
pinball_p90 = float(np.mean(np.maximum(q * diff, (q - 1) * diff)))

# P10-P90区间覆盖率(目标值:0.80)
coverage = float(((actual >= p10) & (actual <= p90)).mean())

# 综合标签。阈值为零售需求默认值;按目录调整
# WAPE < 15% 与M5竞赛的"强基线"标准一致
if wape < 0.15 and abs(bias) < 0.05 and 0.75 <= coverage <= 0.85:
    label = "ACCURATE"
elif wape < 0.25:
    label = "ACCEPTABLE"
else:
    label = "POOR"

return {
    "label": label,
    "value": wape,  # 在CloudWatch中显示的主要评分
    "explanation": (
        f"WAPE={wape:.3f}, bias={bias:+.3f}, "
        f"pinball@P90={pinball_p90:.2f}, coverage={coverage:.2%}"
    ),
}
code
关于阈值的说明。WAPE低于15%是零售需求在SKU周粒度上的常见“强基线”参考标准,由M5预测竞赛确立。请将这些阈值视为初始值,并根据目录进行调整。覆盖率目标(P10-P90区间的0.75-0.85)与Pinball损失共同说明分位数是否校准:如果覆盖率逐年低于区间范围而点WAPE保持平稳,说明模型变得过度自信,需要重新审视安全库存乘数而非点预测。

为复用评估器的读者需要注意的两个实现细节。首先,此处采用的签名偏差惯例是SCM标准(正值=高估),与大多数库存规划系统使用的跟踪信号惯例一致。其次,P90处的Pinball损失设计为非对称:上分位数覆盖不足的惩罚是覆盖过量的9倍,这与缺货成本相对于库存持有成本的非对称性相匹配。

通过AgentCore控制平面注册评估器一次,然后在每次会话级评估中通过ARN引用:

agentcore eval evaluator create \ --name "ForecastAccuracyEvaluator" \ --level SESSION \ --lambda-arn arn:aws:lambda:us-east-1:$ACCOUNT:function:forecast-accuracy-evaluator \ --lambda-timeout 60

code

#### 真实数据延迟到达:按需评估而非实时评估

3点行为评估准则在线运行——每个会话实时执行——因为其输入(代理轨迹、工具输出)在会话结束时即已存在。准确性评估器则不同。在订单决策当天,未来14天的“正确”需求尚不存在。它会在一个预测周期后显现,随着每个预测日过去,实际销售数据被记录到数据仓库中。

基于代码的评估器自然处理这种情况。一个夜间任务会收集预测周期已完全结束的会话,从数据仓库提取实际销售数据,并按需调用评估器,此时evaluationReferenceInputs已填充:

import boto3

agentcore = boto3.client("bedrock-agentcore")

EVALUATOR_ID = "forecast-accuracy-evaluator-id" # 来自create_evaluator

code

for session_id, session_spans, actuals in sessions_ready_for_scoring(): response = agentcore.evaluate( evaluatorId=EVALUATOR_ID, evaluationInput={"sessionSpans": session_spans}, evaluationTarget={"traceIds": session_trace_ids(session_spans)}, evaluationReferenceInputs=[ {"day": i + 1, "actual_sales": y} for i, y in enumerate(actuals) ], ) for result in response["evaluationResults"]:

EvaluationResultContent schema: label, value, explanation,

evaluatorId, evaluatorName (see AWS SDK docs)

if "errorCode" in result: emit_alarm(session_id, result["errorCode"], result["errorMessage"]) continue emit_dashboard_metric( session_id=session_id, wape=result["value"], label=result["label"], explanation=result["explanation"], )

code

import boto3

control = boto3.client("bedrock-agentcore-control")

control.create_online_evaluation_config( onlineEvaluationConfigName="inventory-live-eval", rule={"samplingConfig": {"samplingPercentage": 100.0}}, # initial rollout dataSourceConfig={ "cloudWatchLogs": { "logGroupNames": ["/aws/bedrock-agentcore/inventory-supervisor"], "serviceNames": ["inventory-supervisor.DEFAULT"], } }, evaluators=[ {"evaluatorId": "Builtin.GoalSuccessRate"}, # session-level {"evaluatorId": "Builtin.Helpfulness"}, # trace-level {"evaluatorId": "constraint-compliance-judge-id"}, # custom LLM-as-a-Judge ], evaluationExecutionRoleArn="arn:aws:iam::$ACCOUNT:role/AgentCoreEvaluationRole", enableOnCreate=True, )

code

评估分数会流入与在线评估器相同的CloudWatch Evaluations命名空间,因此团队可以通过相同的仪表板和告警查询行为和准确性。P50预测连续四周出现负偏差会触发与静默违规会话相同的运维响应:调查、修复、重新部署。

上述代码片段是按需执行路径——每个会话调用一次评估器,在真实数据到达后显式触发。当需要评估器自动针对每个会话的追踪数据运行时,需在在线评估配置中注册:

注意在线列表中没有包含ForecastAccuracyEvaluator。在追踪数据生成时无法获取真实数据,因此在线注册会导致每次调用都产生HORIZON_MISMATCH错误。行为评估在线执行、准确性评估按需执行的两种节奏,是由于数据到达时间不同造成的,而非配置偏好。

#### 完整评估矩阵

| 评估器 | 类型 | 级别 | 节奏 |
|--------|------|------|------|
| Builtin.GoalSuccessRate | 内置LLM-as-a-Judge | 会话级 | 在线(100%采样) |
| Builtin.Helpfulness | 追踪级 | 内置LLM-as-a-Judge | 在线(100%采样) |
| ConstraintComplianceJudge | 定制LLM-as-a-Judge(3分制评分标准:静默/标记/合规) | 会话级 | 在线(100%采样) |
| ForecastAccuracyEvaluator | 定制代码(Lambda) | 会话级 | 按需(预测范围+提前期结束后执行) |

前三个评估器用于监控代理的行为方式。第四个评估器用于监控模型预测的准确性。它们共同弥补了单独使用时的不足:一个行为完美但静默低估预测的代理,或一个具有优秀WAPE指标但推荐结果被代理静默截断的模型。这两种失败模式在单层评估中都不可见,但当两个层级并行运行时就会显现。

#### 生产目标与吞吐量

这些评估器只有在影响运营目标时才具有意义。对于该系统,目标是明确的:批量调度会话的P95端到端延迟低于90秒,95%会话中约束合规性评分至少达到2.0(标记违规计数,静默违规不计数),以及前20大营收SKU的滚动4周WAPE低于20%。每个目标都配置了CloudWatch警报并路由至值班团队。5%会话评分低于2.0的错误预算,为团队提供了迭代优化提示和约束的余地,而无需将每次回归都视为需要升级的故障。

在商品目录规模下的吞吐量表现:单个SKU的完整会话端到端耗时约8秒(不包含Chronos2 Serverless冷启动路径,该路径在首次调用后会分摊成本)。10,000个SKU的夜间运行在约100路并行处理下可在30分钟内完成,受限于SageMaker Serverless并发配额。在该规模下,每轮运行成本约为Bedrock推理几美元加上SageMaker推理几美元——成本足够低,使得每日运行频率是定价选择而非约束条件。

## 运行代理:约束违规场景演示

部署所有组件后,使用故意触发条件重试循环的场景调用代理。以下测试用例将产品默认预算上限覆盖为500美元(远低于完整补货订单成本),以便观察系统对约束违规的端到端响应:

agentcore invoke "为SKU-00142本周末补货(促销活动进行中)。本次订单的预算为500美元。" \ --session-id test-session-chronos2-inventory-001

code

代理执行完整流程并返回结构化推荐。以下数据来自data/product_config.json(安全库存=150,补货周期=5天,最小起订量=50,单位成本=12.50美元)以及激活促销协变量的Chronos2 P50预测:

- 产品:SKU-00142(无线降噪耳机Pro)
- 当前库存:45件
- 5天补货周期(含促销)P50预测:约648件
- 最优订单:753件=9,412.50美元
- 用户预算上限:500美元→检测到违规
- 受最小起订量约束的调整订单:50件=625美元→仍超出预算
- 预计缺口:5天补货周期窗口内约553件缺口

此时的行为正是设计的核心价值。系统不会静默截断订单至预算内数量导致重大缺货,而是由Supervisor呈现三个可操作选项:提高预算、接受缺口并提前安排加急配送,或延迟促销,并要求用户选择。这就是条件重试循环的职责:将约束违规视为需要用户输入的工作流状态,而非静默失败。

可观测性和评估功能都会捕获此事件以便后续检查。CloudWatch 跟踪会显示重试循环中的每个工具调用,而评估的自定义评估器对此次会话评分为 2.0(标记违规),确认代理的行为符合预期设计,而非静默失败。

## 清理资源

为避免产生未来费用,请按照以下顺序删除本演练过程中创建的资源:

- 拆除 AgentCore 资源(运行时、网关、策略引擎、内存、评估):`agentcore destroy`

- 销毁 CDK 堆栈(S3 存储桶、网关 Lambda、Cognito 用户池、IAM 角色):`cd cdk && npx cdk destroy`

- 删除 SageMaker 无服务器端点以停止 Chronos2 推理费用:`aws sagemaker delete-endpoint --endpoint-name chronos2-serverless-endpoint`

- 如果不再需要其他工作负载,可在 Bedrock 控制台的“模型访问”下撤销对 Amazon Bedrock 模型的访问权限。

## 结论

此架构证明了零样本预测和多代理自动化是互补的抽象方法,能够消除不同类别的运营负担。

Chronos2 消除了机器学习流水线。向预测中添加新SKU无需训练任务、无需特征工程、无需模型验证。唯一需要的输入是历史销售数据和预测时间范围内的协变量值——这两者都是标准运营数据。

多代理编排消除了手动工作流。将需求预测转换为符合业务规则的采购订单,同时生成自然语言理由和审计轨迹,需要在多个步骤间协调判断和计算。四个LLM代理负责判断,一组确定性工具负责计算。

您获得的优势:

| 维度               | 传统方法                   | 本架构                     |
|--------------------|--------------------------|--------------------------|
| 新产品上线         | 训练新模型(数天至数周)     | 零——Chronos2 零样本      |
| 业务规则变更       | 编辑电子表格或单体应用       | 仅需更改一处             |
| 故障恢复           | 重启整个流水线             | 在失败代理处重试          |
| 审计轨迹           | 手动文档                 | 每个代理输出均为结构化JSON合同 |
| LLM 成本扩展性     | 无限制(单体应用承载所有上下文) | 每个代理按单一职责上下文限制 |
| 预测解释           | 原始数字                 | 带异常标记的自然语言理由   |
| 预测质量信号       | 手动回测脚本、临时分析       | 基于代码的评估器对每次会话评分 |

此处描述的模式——代理与工具的对比、进程内与网关的对比、主观与确定性评估决策框架、代理间的结构化JSON合同、条件重试作为一流的工作流状态,以及将每个AgentCore服务映射到一个生产关注点——不仅适用于库存管理,也适用于任何需要确定性计算和情境判断协同工作的领域。

要开始使用,请按照技术实现部分中描述的基础设施模式,在您的AWS账户中部署CDK堆栈,然后使用自己的产品数据运行约束违规演练,以全面查看代理协调的实际效果。

SageMaker 无服务器推理的成本估算基于us-east-1定价,假设每月约500次推理调用。实际成本会根据区域和使用模式有所不同。

## 作者信息

'"`