用途
该技能将所有库存按“多久没有售出”划分为账龄区间,并按区间计算持有成本敞口,帮助卖家优先安排降价或清仓决策。相比仅识别滞销品,它提供更细的账龄粒度。技能为只读,不执行任何变更操作。
前置条件
需要已认证的 Shopify CLI 会话:shopify store auth --store <domain> --scopes read_orders,read_products,read_inventory
API 权限范围:read_orders、read_products、read_inventory
参数
store(字符串,必填,无默认值):店铺域名。
buckets(字符串,可选,默认 0-30,31-60,61-90,91-180,181+):以逗号分隔的账龄区间(天)。
carrying_cost_pct(浮点数,可选,默认 25):年度持有成本占库存价值的百分比(行业平均 20-30%)。
vendor_filter(字符串,可选,无默认值):限定到特定供应商。
format(字符串,可选,默认 human):输出格式,human 或 json。
安全性
只读技能,不执行任何变更操作,可随时安全运行。
工作流程
-
查询 productVariants:输入 first: 250,选择 id、sku、inventoryQuantity、inventoryItem { id, unitCost }、product { title, vendor, status } 及分页游标;预期输出为所有变体的库存与成本数据。
-
筛选出 inventoryQuantity > 0 的变体。
-
查询 orders:输入 query: "created_at:>='<NOW - 365 days>'", first: 250,选择 createdAt、lineItems { variant { id }, quantity } 及分页游标;预期输出为销售历史,用于确定每个变体的最后售出日期。
-
对每个有库存的变体确定账龄:找到包含该变体的最近订单得到 last_sold_date;若从未售出,则使用产品创建日期作为替代;账龄 = 今天 - last_sold_date;归入相应账龄区间。
-
查询 inventoryItems:输入库存项 ID 以获取成本数据;预期输出为用于价值计算的单位成本。
-
按区间计算:总数量、总价值(数量 × 单位成本)、月度持有成本 =(价值 × carrying_cost_pct / 100)/ 12、占总库存价值的百分比。
GraphQL 操作
productVariants:query(已针对 api_version 2025-01 验证): query VariantsWithStock($query: String, $after: String) { productVariants(first: 250, after: $after, query: $query) { edges { node { id sku inventoryQuantity product { id title vendor status createdAt } inventoryItem { id unitCost { amount currencyCode } } } } pageInfo { hasNextPage endCursor } } }
orders:query(已针对 api_version 2025-01 验证): query RecentSales($query: String!, $after: String) { orders(first: 250, after: $after, query: $query) { edges { node { createdAt lineItems(first: 50) { edges { node { quantity variant { id } } } } } } pageInfo { hasNextPage endCursor } } }
inventoryItems:query(已针对 api_version 2025-01 验证): query InventoryItemCosts($ids: [ID!]!) { nodes(ids: $ids) { ... on InventoryItem { id unitCost { amount currencyCode } } } }
会话跟踪
Claude 必须在每个阶段输出以下内容,这是强制要求。
开始时输出: ╔══════════════════════════════════════════════╗ ║ SKILL: Inventory Aging Report ║ ║ Store: <store domain> ║ ║ Started: <YYYY-MM-DD HH:MM UTC> ║ ╚══════════════════════════════════════════════╝
每步之后输出: [N/TOTAL] <QUERY|MUTATION> <OperationName> → Params: <brief summary of key inputs> → Result: <count or outcome>
完成时输出(format: human 默认): ══════════════════════════════════════════════ INVENTORY AGING REPORT Total SKUs with stock: <n> Total inventory value: $<amount> ───────────────────────────── AGING BUCKETS: 0-30 days: <n> SKUs $<value> (<pct>%) ✅ Fresh 31-60 days: <n> SKUs $<value> (<pct>%) ⚠️ Watch 61-90 days: <n> SKUs $<value> (<pct>%) ⚠️ Aging 91-180 days: <n> SKUs $<value> (<pct>%) 🔴 Stale 181+ days: <n> SKUs $<value> (<pct>%) 🔴 Dead
Monthly carrying cost: $<amount> Annual carrying cost: $<amount>
Top aging items by value: "<product>" SKU:<sku> Age:<n>d Qty:<n> Value:$<n>
Output: inventory_aging_<date>.csv ══════════════════════════════════════════════
输出格式
CSV 文件 inventory_aging_<YYYY-MM-DD>.csv,列包括:variant_id, sku, product_title, vendor, quantity, unit_cost, total_value, last_sold_date, age_days, aging_bucket, monthly_carrying_cost
错误处理
THROTTLED:API 速率限制超出,等待 2 秒,最多重试 3 次。
Missing unitCost:无 COGS 数据,价值按 $0 处理,并标记为“cost unknown”。
No sales history:新产品或从未售出,使用产品创建日期作为账龄起点。
最佳实践
默认使用 carrying_cost_pct: 25(包含仓储、保险、机会成本、损耗)。
90+ 天区间的商品是降价的强候选,可使用 bulk-price-adjustment。
与 dead-stock-identifier 和 stock-velocity-report 交叉参考,获得完整库存健康视图。
每月运行以跟踪账龄趋势并衡量清仓效果。