用途
在多个地点之间发现库存同步差异,具体是指变体的可用数量为负数,或已承诺数量大于在手数量。这类情况表明 Shopify 的承诺计数器与实际物理库存之间出现漂移。常见原因包括:第三方物流(3PL)延迟登记退货、仓储管理系统(WMS)的扣减与 Shopify 的承诺计数叠加、或多店铺同步问题。
该技能为只读操作,不执行任何数据变更。它可替代手工库存对账表格,也无需在 Shopify 后台逐个地点单独查看。
主要能力
- 查询所有活跃地点(is_active:true),最多 first: 50 个。
- 若提供 location_ids 参数,则仅审计指定地点;默认审计所有活跃地点。
- 通过 location.inventoryLevels 按地点获取每个变体的库存水平,包括 available、committed、onHand 数量。
- 计算差异,收集被标记的变体。
- 默认标记 available < 0 的变体(flag_negative_available,默认 true)。
- 默认标记 committed > on_hand 的变体(flag_committed_exceeds_onhand,默认 true)。
- 可选包含未启用库存跟踪的变体(include_untracked,默认 false)。
使用方式
前置条件
-
执行登录命令:
shopify auth login --store <domain> -
API 权限范围:read_products、read_inventory、read_locations
参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| store | string | 是 | — | 店铺域名(例如 mystore.myshopify.com) |
| format | string | 否 | human | 输出格式:human 或 json |
| dry_run | bool | 否 | false | 预览操作而不执行变更 |
| location_ids | array | 否 | — | 要审计的特定地点 GID(默认:所有活跃地点) |
| flag_negative_available | bool | 否 | true | 标记 available < 0 的变体 |
| flag_committed_exceeds_onhand | bool | 否 | true | 标记 committed > on_hand 的变体 |
| include_untracked | bool | 否 | false | 包含已禁用库存跟踪的变体 |
工作流程
-
OPERATION: locations — 查询
- 输入:first: 50, query: "is_active:true"
- 预期输出:活跃地点 ID 与名称列表;若提供 location_ids 参数则据此过滤。
-
OPERATION: inventoryItems — 查询(通过 location.inventoryLevels)
- 输入:每个地点获取各变体的库存水平,包括 available、committed、onHand 数量。
- 预期输出:按地点整理的库存矩阵;计算差异;收集被标记的变体。
GraphQL 操作
以下查询已针对 api_version 2025-01 验证:
# locations:query
query ActiveLocations($first: Int!) {
locations(first: $first, query: "is_active:true") {
edges {
node {
id
name
isActive
inventoryLevels(first: 250) {
edges {
node {
id
available
item {
id
sku
tracked
variant {
id
displayName
product {
id
title
}
}
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
}
# inventoryItems:query
query InventoryItemLevels($id: ID!, $after: String) {
location(id: $id) {
id
name
inventoryLevels(first: 250, after: $after) {
edges {
node {
id
available
item {
id
sku
tracked
inventoryLevel(locationId: $id) {
available
incoming
}
variant {
id
displayName
inventoryQuantity
product {
id
title
}
}
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
注意:frontmatter 中的 inventoryItems:query 表示通过地点库存水平查询库存项目数据。Shopify Admin API 通过 location.inventoryLevels 按地点呈现库存。
会话跟踪
每个阶段必须输出以下内容(强制要求)。
开始时输出:
╔══════════════════════════════════════════════╗
║ SKILL: multi-location-inventory-audit ║
║ 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,默认):
══════════════════════════════════════════════
OUTCOME SUMMARY
Locations audited: <n>
Variants scanned: <n>
Discrepancies found: <n>
Negative available: <n>
Committed > On Hand: <n>
Errors: 0
Output: inventory-audit-<date>.csv
══════════════════════════════════════════════
完成时输出(format: json):
{
"skill": "multi-location-inventory-audit",
"store": "<domain>",
"started_at": "<ISO8601>",
"completed_at": "<ISO8601>",
"dry_run": false,
"steps": [
{ "step": 1, "operation": "ActiveLocations", "type": "query", "params_summary": "first: 50, is_active: true", "result_summary": "<n> locations", "skipped": false },
{ "step": 2, "operation": "InventoryItemLevels", "type": "query", "params_summary": "per location, first: 250", "result_summary": "<n> variants scanned", "skipped": false }
],
"outcome": {
"locations_audited": 0,
"variants_scanned": 0,
"discrepancies_found": 0,
"negative_available_count": 0,
"committed_exceeds_onhand_count": 0,
"errors": 0,
"output_file": "inventory-audit-<date>.csv"
}
}
输出格式
生成 CSV 文件 inventory-audit-<YYYY-MM-DD>.csv,列包括:location_name、product_title、variant_title、sku、available、flag。
同时显示内联汇总表,列包括:Location、Variants Scanned、Discrepancies、Negative Available、Committed > On Hand。
错误处理
| 错误 | 原因 | 恢复方式 |
|---|---|---|
| 未返回任何地点 | 未找到活跃地点 | 在 Shopify 后台确认至少有一个活跃地点 |
| 某地点的 inventoryLevels 为空 | 该地点未分配库存 | 对于仅发货或虚拟地点属于预期情况 |
| 速率限制(429) | 库存量大且地点多 | 将每个地点的分页大小降至 100 |
| 所有变体的 item.tracked 均为 false | 店铺使用未跟踪库存 | 启用跟踪或设置 include_untracked: true |
最佳实践
- 每周运行一次此审计——库存漂移会逐渐累积,在叠加之前最容易修复。
- 可用数量为负并不总是代表真正的问题——在闪购期间可能合法出现。进行手动更正前,请结合订单量交叉核对。
- 将 CSV 输出与 inventory-adjustment 技能配合使用,在审计发现差异后立即应用更正。
- 在第三方物流(3PL)退货批次入账前后分别运行审计,以衡量退货库存是否被正确计入。
- 通过筛选单个 location_id 进行针对性审计(例如仅主仓库),以减少大型商品目录下的 API 调用次数。