Skill: chenyongzhen/1688-shopkeeper-bak (version 1.0.0)

--- name: 1688-shopkeeper description: | 1688选品铺货 + 商机趋势专家。用于：(1) 在1688搜索商品/选品找货源 (2) 查询已绑定的下游店铺 (3) 将商品铺货到抖音/拼多多/小红书/淘宝等平台 (4) 配置1688 AK密钥 (5) 查看即时商机热榜 (6) 查看类目/行业趋势与价格分布 (7) 生成店铺经营日报并输出主营商品选品建议。 触发词：帮我找商品、在1688搜、选品、铺货、上架、查店铺、配置AK、商机、热榜、排行榜、趋势、价格分布、经营日报、店铺日报、动销分析、经营分析、选品建议、1688找货。 metadata: {"openclaw": {"emoji": "🛒", "requires": {"bins": ["python3"]}, "primaryEnv": "ALI_1688_AK"}} --- # 1688-shopkeeper 统一入口：`python3 {baseDir}/cli.py <command> [options]` ## 命令速查 | 命令 | 说明 | 示例 | |------|------|------| | `search` | 找商品 | `cli.py search --query "帮我找1688上支持一件代发包邮的露营椅，100元以内" --channel douyin` | | `prod_detail` | 商品详情 | `cli.py prod_detail --item-ids "991122553819,894138137003"` | | `shops` | 查绑定店铺 | `cli.py shops` | | `publish` | 铺货 | `cli.py publish --shop-code CODE --data-id ID` | | `opportunities` | 商机热榜 | `cli.py opportunities` | | `trend` | 趋势洞察 | `cli.py trend --query "大码女装"` | | `shop_daily` | 店铺经营日报 | `cli.py shop_daily` | | `configure` | 配置 AK | `cli.py configure YOUR_AK` | | `check` | 检查配置状态 | `cli.py check` | 所有命令输出 JSON：`{"success": bool, "markdown": str, "data": {...}}` **展示时直接输出 `markdown` 字段，Agent 分析追加在后面，不得混入其中。** ## 使用流程 Agent 根据用户意图**直接执行对应命令**，无需每次先执行 `check`。 各命令在 AK 缺失、店铺异常等情况下会自行返回明确错误，Agent 按下方「异常处理」应对即可。 **选品铺货典型路径**：`search` → 用户筛选 → `shops`（确认目标店铺） → `publish` **商品详情使用指引**： - `prod_detail`：用户想看商品标题、价格、类目、SKU、CPV 属性、商家信息时使用。 **商机/趋势使用指引**： - `opportunities`：用户想看“此刻/近1小时/热榜/趋势商机”。 - `trend`：用户询问某宽泛类目/行业的周期趋势、价格分布、热品概况；关键词过长或过细时先按用户原词尝试，若空结果再提示用户换更宽泛/拆分词后重试。 - `shop_daily`：用户想看“店铺经营日报/今日动销/渠道经营诊断/主营商品选品建议”。 ## 安全声明 | 风险级别 | 命令 | Agent 行为 | |---------|------|-----------| | **只读** | search, shops, check, opportunities, trend, shop_daily | 直接执行 | | **配置** | configure | 提示影响范围后执行 | | **写入** | publish | **必须先 dry-run 预检查；仅当写入目标不唯一时追问，目标唯一则直接执行** | **全局写入规则（适用于所有写操作）**： 1. 必须先执行 dry-run。 2. 仅当写入目标不唯一（商品或店铺存在多个候选）时，才向用户追问一次做歧义消解。 3. 目标唯一时，dry-run 成功后直接执行正式写入，不再二次确认。 ## 异常处理 任何命令输出 `success: false` 时： 1. **先输出 `markdown` 字段**（已包含用户可读的错误描述） 2. **再根据关键词追加引导**： | markdown 关键词 | Agent 额外动作 | |----------------|--------------| | "AK 未配置" 或 "签名无效"/"401" | 输出下方 **AK 引导话术** | | "授权过期" | 提示用户在 1688 AI版 APP 中重新授权 | | "店铺未绑定" 或 shops 返回 0 个店铺 | 输出下方 **开店引导话术** | | "限流"/"429" | 建议用户等待 1-2 分钟后重试 | | 其他 | 仅输出 markdown 即可 | 详细错误码说明见 `references/common/error-handling.md`。 ## 执行前置（首次命中能力时必须） - 首次执行 `search` 前：先完整阅读 `references/capabilities/search.md` - 首次执行 `prod_detail` 前：先完整阅读 `references/capabilities/prod_detail.md` - 首次执行 `shops` 前：先完整阅读 `references/capabilities/shops.md` - 首次执行 `publish` 前：先完整阅读 `references/capabilities/publish.md` - 首次执行 `configure` 前：先完整阅读 `references/capabilities/configure.md` - 首次执行 `opportunities` 前：先完整阅读 `references/capabilities/opportunities.md` - 首次执行 `trend` 前：先完整阅读 `references/capabilities/trend.md` - 首次执行 `shop_daily` 前：先完整阅读 `references/capabilities/shop_daily.md` - 同一会话内后续重复调用同一能力可复用已加载知识；仅在规则冲突或文档更新时重读。 ## AK 引导话术 > "需要先配置 AK。打开 [**1688 AI版 APP**](https://air.1688.com/kapp/1688-ai-app/pages/home?from=1688-shopkeeper)（没装的话点链接下载），首页点击「一键部署开店Claw，全自动化赚钱🦞」，进入页面获取 AK，然后告诉我：'我的AK是 xxx'" ## 开店引导话术 > "还没有绑定店铺。打开 [1688 AI版APP](https://air.1688.com/kapp/1688-ai-app/pages/home?from=1688-shopkeeper) → 首页「一键开店」，开好后告诉我。" ## FAQ 知识库（按需加载） 用户问经营或技术问题时，**先加载对应文件再回答**，不凭经验泛泛而谈。 | 用户话题 | 加载文件 | |---------|---------| | AK 问题、铺货失败、支持平台、收费 | `references/faq/base.md` | | 选哪个平台、抖店/拼多多/淘宝 | `references/faq/platform-selection.md` | | 选品风险、品类、节日选品 | `references/faq/product-selection.md` | | 运费模板、定价、加价倍率 | `references/faq/listing-template.md` | | 发货超时、中转费、偏远地区 | `references/faq/fulfillment.md` | | 退货、仅退款、运费险、售后 | `references/faq/after-sales.md` | | 新店破零、服务分、推广 | `references/faq/new-store.md` | | 素材审核、白底图、标题优化 | `references/faq/content-compliance.md` |

path: README.md
content: # 🛒 1688-shopkeeper

1688 AI店长 —— 帮你从 1688 找到好货，一键铺到抖店、拼多多、小红书、淘宝等下游店铺。

## 能做什么

- **选品找货**：告诉 AI 你想卖什么，自动从 1688 搜索并推荐优质货源
- **商品详情**：按商品 ID 查看标题、价格、类目、SKU、属性与商家信息
- **一键铺货**：选好商品后直接铺到你的店铺，支持抖店、拼多多、小红书、淘宝
- **店铺管理**：查看已绑定的店铺状态和授权情况
- **商机与趋势**：即时商机热榜；按关键词看类目/行业趋势与价格分布
- **经营日报**：生成店铺经营日报与主营商品选品建议
- **经营问答**：定价策略、运费模板、选品避坑、新店起步等常见问题都能问

## 安装

在 Claw 对话框里直接输入下面这段话，让 OpenClaw 帮你自动安装：

```text
请帮我安装这个 skill：https://github.com/next-1688/1688-shopkeeper.git
```

## 使用前准备

1. 下载 [**1688 AI版 APP**](https://air.1688.com/kapp/1688-ai-app/pages/home?from=1688-shopkeeper)
2. 打开 APP 首页，点击「一键部署开店Claw，全自动化赚钱🦞」
3. 进入页面复制你的 AK（Access Key）
4. 对 AI 说："我的AK是 xxx"

配置完成后就可以开始选品铺货了。

## 快速上手

直接用自然语言和 AI 对话即可：

- "帮我找一些夏季连衣裙，适合抖店卖的"
- "把刚才搜到的商品铺到我的店铺"
- "查一下我绑定了哪些店铺"
- "新手开店应该怎么选品"
- "最近有什么热门商机"
- "大码女装在 1688 上的趋势怎么样"
- "给我一份今天的店铺经营日报"

## 命令行（CLI）

本仓库提供统一入口 `cli.py`，需本机已安装 **Python 3**。环境变量 `ALI_1688_AK` 或由命令 `configure` 写入的配置需与 1688 AI 版 APP 中 AK 一致。

```bash
python3 cli.py <command> [options]
```

| 命令 | 说明 | 示例 |
|------|------|------|
| `search` | 搜商品 | `python3 cli.py search --query "夏季连衣裙" --channel douyin` |
| `prod_detail` | 商品详情 | `python3 cli.py prod_detail --item-ids "991122553819,894138137003"` |
| `shops` | 查绑定店铺 | `python3 cli.py shops` |
| `publish` | 铺货 | `python3 cli.py publish --shop-code CODE --data-id ID` |
| `opportunities` | 商机热榜 | `python3 cli.py opportunities` |
| `trend` | 趋势洞察 | `python3 cli.py trend --query "大码女装"` |
| `shop_daily` | 店铺经营日报 | `python3 cli.py shop_daily` |
| `configure` | 配置 AK | `python3 cli.py configure YOUR_AK` |
| `check` | 检查配置 | `python3 cli.py check` |

所有命令 stdout 为 JSON：`{"success": bool, "markdown": str, "data": {...}}`。人类可读说明一般在 `markdown` 字段。**Agent / Skill 编排约定**见根目录 [`SKILL.md`](./SKILL.md)（含安全规则、异常处理与各能力参考文档路径）。

## 支持平台

| 平台 | 选品 | 铺货 |
|------|------|------|
| 抖店 | ✅ | ✅ |
| 拼多多 | ✅ | ✅ |
| 小红书 | ✅ | ✅ |
| 淘宝 | ✅ | ✅ |

## 常见问题

**Q: AK 是什么？怎么获取？**
AK 是你访问 1688 平台的身份凭证。在 1688 AI版 APP 中获取，具体步骤见上方「使用前准备」。

**Q: 收费吗？**
选品和铺货功能限时免费，具体费用以 1688 平台规则为准。

**Q: 支持哪些店铺类型？**
支持通过 1688 AI版 APP 绑定的抖店、拼多多、小红书、淘宝店铺。

## 反馈与支持

使用中遇到问题，可以在 1688 AI版 APP 中联系客服。


path: cli.py
content: #!/usr/bin/env python3
"""
1688-shopkeeper —— 1688 AI 店长 CLI 统一入口

在 1688 AI 版 APP 中配置 AK 并绑定下游店铺后，可通过本 CLI：选品搜货、查商品详情、
查看已绑定店铺（抖店/拼多多/小红书/淘宝）、铺货上架，以及商机热榜、类目/行业趋势、
店铺经营日报等。子命令位于 scripts/capabilities/<能力名>/cmd.py，启动时自动扫描注册。

Usage:
    python3 cli.py <command> [options]

Commands（更多参数见项目根目录 SKILL.md）:
    search        搜商品          python3 cli.py search --query "..." [--channel douyin]
    prod_detail   商品详情        python3 cli.py prod_detail --item-ids "id1,id2"
    shops         查绑定店铺      python3 cli.py shops
    publish       铺货到下游      python3 cli.py publish --shop-code XXX (--data-id Y | --item-ids a,b)
    opportunities 商机热榜        python3 cli.py opportunities
    trend         趋势洞察        python3 cli.py trend --query "大码女装"
    shop_daily    店铺经营日报    python3 cli.py shop_daily
    configure     配置 AK         python3 cli.py configure YOUR_AK
    check         检查配置状态    python3 cli.py check

所有命令输出 JSON: {"success": bool, "markdown": str, "data": {...}}
面向用户展示时优先使用 markdown；Agent 追加分析时不要写入 markdown 正文。
"""

import json
import os
import sys
import importlib

SCRIPTS_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "scripts")
sys.path.insert(0, SCRIPTS_DIR)


def _discover_capabilities() -> dict:
    """扫描 capabilities/*/cmd.py，自动注册命令"""
    commands = {}
    caps_dir = os.path.join(SCRIPTS_DIR, "capabilities")

    if not os.path.isdir(caps_dir):
        return commands

    for name in sorted(os.listdir(caps_dir)):
        cmd_path = os.path.join(caps_dir, name, "cmd.py")
        if not os.path.isfile(cmd_path):
            continue
        module_path = f"capabilities.{name}.cmd"
        try:
            mod = importlib.import_module(module_path)
            cmd_name = getattr(mod, 'COMMAND_NAME', name)
            commands[cmd_name] = module_path
        except Exception:
            pass

    return commands


def _usage(commands: dict):
    lines = ["**1688-shopkeeper 用法**\n", "```"]
    for name in sorted(commands):
        try:
            mod = importlib.import_module(commands[name])
            desc = getattr(mod, 'COMMAND_DESC', '')
            lines.append(f"python3 cli.py {name:<12} {desc}")
        except Exception:
            lines.append(f"python3 cli.py {name}")
    lines.append("```")

    print(json.dumps({
        "success": False,
        "data": {},
        "markdown": "\n".join(lines),
    }, ensure_ascii=False, indent=2))


def main():
    commands = _discover_capabilities()

    if len(sys.argv) < 2 or sys.argv[1] not in commands:
        _usage(commands)
        sys.exit(1)

    cmd = sys.argv[1]
    module_path = commands[cmd]

    sys.argv = [f"cli.py {cmd}"] + sys.argv[2:]

    module = importlib.import_module(module_path)
    module.main()


if __name__ == "__main__":
    main()


path: references/capabilities/configure.md
content: # AK 配置指南

## 获取 AK（引导用户）

当用户没有 AK 时，Agent 输出以下引导：

> 打开 [**1688 AI版 APP**](https://air.1688.com/kapp/1688-ai-app/pages/home?from=1688-shopkeeper)（没装的话点链接下载），首页点击「一键部署开店Claw，全自动化赚钱🦞」，进入页面复制 AK，然后告诉我：'我的AK是 xxx'

## Agent 配置流程（核心）

用户告知 AK 后，Agent 按以下步骤执行：

```
1. 从用户消息中提取 AK 字符串
2. 执行 cli.py configure <AK>
3. 检查输出：success=true → 继续；success=false → 原样输出 markdown 错误信息
4. 配置成功后由 OpenClaw 配置注入生效（不依赖本地会话缓存）；如当前会话仍未生效，提示用户新开会话或执行 `openclaw secrets reload`
5. 继续用户的原始请求（如搜索、铺货等）；若用户仅提供了 AK 没有其他请求，告知"配置成功，你可以让我帮你搜商品、查店铺或铺货"
```

## CLI 调用

```bash
python3 {baseDir}/cli.py configure YOUR_AK_HERE
```

无参数调用可查看当前配置状态：`python3 {baseDir}/cli.py configure`

## 异常处理

| 场景 | Agent 应对 |
|------|-----------|
| configure 输出 success=false | 原样输出 markdown 错误信息 |
| 配置成功但后续命令仍报 AK 未配置 | 提示用户新开会话或执行 `openclaw secrets reload`，必要时再重试 configure |
| 用户问"我的 AK 在哪" | 输出上方获取 AK 引导话术 |

通用 HTTP 异常（400/401/429/500）处理见 `references/common/error-handling.md`。


path: references/capabilities/opportunities.md
content: # 商机热榜指南（opportunities）

> 命令为只读；依赖 AK 签名，无需额外 token。

## CLI 调用

```bash
python3 {baseDir}/cli.py opportunities
```

- 无额外参数；使用 AK 签名调用 `/1688claw/skill/workflow`，body 固定 `{"code": "offer_opportunity"}`。

## 典型触发场景

- “现在的热榜/近1小时趋势商机/爆款榜单/实时榜单”
- “小红书/淘宝/1688 当前热度/排行/榜单”
- 用户已表述要看“榜单/趋势/热度”，AK 已配置。

## 输出理解

- 正常：`bizData` 为嵌套 JSON，含 `1688/taobao/xiaohongshu` 下的 trend/hot。默认摘要仅展示各平台的 `detail` Top 若干条；`graphic` 保存在 `data`，仅在用户追问细节或需要图表概览时再取用。
- 展示时结合用户关注点改写摘要（如只关心淘宝，则突出淘宝 trend/hot Top 条目），避免逐字透传原始结构。
- 无结果：若返回为空或字段缺失，脚本会提示“未返回商机数据”；可建议稍后重试。

## 异常处理

- 通用 HTTP 异常（400/401/429/500）处理见 `references/common/error-handling.md`。


path: references/capabilities/prod_detail.md
content: # 商品详情指南（prod_detail）

## CLI 调用

```bash
# 方式一：抓取并保存商品详情
python3 {baseDir}/cli.py prod_detail --item-ids "692505958039,123456789012"

# 方式二：按 data_id 读取整份已保存的商品详情（仅在确需查看全量内容时使用，避免上下文过大）
python3 {baseDir}/cli.py prod_detail --data-id "20260317_143022_123"

# 方式三：按 data_id 读取指定商品详情
python3 {baseDir}/cli.py prod_detail --data-id "20260317_143022_123" --item-ids "692505958039"
```

| 参数 | 默认 | 说明 |
|------|------|------|
| `--item-ids` | 可选 | 逗号分隔的商品 ID。单独使用时表示抓取远端商品详情；与 `--data-id` 一起使用时表示按需读取指定商品 |
| `--data-id` | 可选 | 已保存商品详情的快照 ID。提供后优先走本地读取，不再请求远端接口 |

- 使用 AK 签名调用 `/1688claw/skill/workflow`
- 请求体固定为：

```json
{
  "code": "offer_detail",
  "bizParams": {
    "item_id": ["692505958039", "123456789012"]
  }
}
```

## 典型触发场景

- 用户想查看某个 1688 商品的详情信息
- 用户希望提取商品标题、类目、SKU、商家信息等结构化内容
- 用户已提供明确的商品 ID

若用户给的是 1688 商品链接，Agent 应先从链接中提取商品 ID，再调用本命令。

## 输出结构

### 抓取并保存

```json
{
  "success": true,
  "markdown": "已保存 **1** 个商品详情，保存地址：`/path/to/1688_detail_20260317_143022_123.json`。",
  "data": {
    "data_id": "20260317_143022_123",
    "detail_count": 1,
    "details": {}
  }
}
```

### 按需读取

```json
{
  "success": true,
  "markdown": "已读取 data_id=`20260317_143022_123` 中的 **1** 个商品详情。",
  "data": {
    "data_id": "20260317_143022_123",
    "detail_count": 1,
    "details": {
      "692505958039": {
        "all_info": "# 商品ID\n692505958039\n\n# 商品标题\n..."
      }
    }
  }
}
```

| data 字段 | 含义 |
|-----------|------|
| `data_id` | 本次商品详情快照 ID，可用于排查和后续引用 |
| `detail_count` | 返回的商品详情数量 |
| `details` | 原始 `bizData`，保持接口返回格式；抓取并保存时默认为空，按需读取时返回内容 |
| `details.<item_id>.all_info` | 接口返回的完整商详 Markdown 文本 |

## markdown 与 data 的分工

- `markdown`：仅返回保存/读取结果摘要，不承载商品详情正文
- `data.details`：抓取并保存时默认为空；只有在按 `data_id` 按需读取时才返回原始 `bizData`
- 脚本会同时将本次商详保存到本地快照文件，并返回对应 `data_id`
- 这样可以避免在首次抓取时把大段商详直接塞进 Agent prompt，降低 token 开销

## 这些信息有什么用

`all_info` 通常会包含：
- 商品标题
- 商品价格
- 商品类目
- SKU 属性
- 必填 CPV 属性
- 商家信息

## 典型使用场景包括：

| 场景 | 会用到的信息 | 用法 |
|------|--------------|------|
| 选品判断 | 标题、价格、类目、商家信息 | 判断商品卖点、价格带、类目是否匹配店铺定位，以及供货商是否稳定 |
| 铺货前补全 | SKU 属性、CPV 属性、类目 | 为后续铺货/上架准备规格、属性、类目映射等基础信息 |
| 内容生成 | 标题、类目、SKU、CPV 属性 | 生成下游平台标题、卖点、详情描述、规格说明 |
| 风险识别 | 标题、类目、CPV 属性、商家信息 | 识别侵权风险、审核风险、售后风险、商家可靠性风险 |
| 多商品对比 | 标题、价格、SKU、商家信息 | 对比多个候选商品，辅助决定谁更适合铺货或主推 |

其中：
- 商品标题：用于理解商品本身、提炼卖点、生成更适合下游平台的标题
- 商品价格：用于估算利润空间、判断适合做引流款还是利润款
- 商品类目：用于判断是否适合目标平台和店铺定位，也便于后续做类目映射
- SKU 属性：用于识别可售规格，决定哪些规格需要保留、突出或过滤
- 必填 CPV 属性：用于补全平台上架时的标准属性，减少铺货失败和审核风险
- 商家信息：用于判断供货商稳定性、工厂/贸易属性、资质情况

## 最佳实践

为避免将整份商详一次性带入上下文，推荐使用“先保存、再按需读取、最后总结”的渐进式流程：

1. 先抓取并保存
   - 使用 `prod_detail --item-ids ...`
   - 先只拿 `data_id` 和 `detail_count`
   - 不在首次抓取后直接展开 `all_info`

2. 明确目标后再读取
   - 用户只是想确认“有没有详情”时，不读取正文
   - 用户要看某个商品时，用 `--data-id ... --item-ids ...` 只读该商品
   - 用户要做多商品比较时，优先先读候选商品，不要默认读取整批
   - 只有确实需要全量内容时，才用 `--data-id ...` 读取整份快照

3. 读取后先做摘要，再决定是否继续展开
   - 优先提炼标题、价格、类目、SKU、商家信息等关键点
   - 先给用户摘要和结论，再根据追问补充细节
   - 若只需回答“能不能铺”“有什么风险”“怎么写标题”，通常不需要逐段转述完整 `all_info`

4. 多商品场景控制读取范围
   - 多商品分析时，先做每个商品 3-5 条关键信息摘要
   - 仅对需要深入分析的商品继续展开细节
   - 避免一次性把多个商品的完整商详全部放入 prompt

一句话原则：**先保存、后筛选、再总结，最后才按需展开全文。**

## Agent 展示规则

| 场景 | Agent 操作 |
|------|-----------|
| 首次抓取商品详情 | 先执行 `--item-ids` 抓取并保存，只向用户说明已保存和对应 `data_id` |
| 用户要看具体内容 | 再用 `--data-id` 按需读取；若只看某个商品，可同时传 `--item-ids` 过滤 |
| 查询单个商品 | 按需从 `data.details.<item_id>.all_info` 中提取重点 |
| 查询多个商品 | 按需基于 `data.details` 做横向对比 |
| 用户只想看某部分信息 | 从 `all_info` 中提取对应字段重述，如标题、价格、类目、商家 |
| 用户给的是商品链接 | 先提取 `item_id` 再调用，不要要求用户手动抄 ID |

如果用户的真实目标是“能不能铺”“该怎么卖”“该怎么写标题/卖点”，Agent 不应停留在转述详情，而应把 `all_info` 作为后续分析输入。

## 异常处理

- 通用 HTTP 异常（400/401/429/500）处理见 `references/common/error-handling.md`。
- 若返回 `detail_count: 0`，提示用户检查 `item_id` 是否正确。
- 若 `all_info` 缺失或为空，展示时注明“已查到商品，但详情内容为空”。


path: references/capabilities/publish.md
content: # 铺货指南

## 前置

铺货前必须先通过 `shops` 命令获取目标店铺的 `shop_code`（详见 `references/capabilities/shops.md`）。

铺货是**写入级操作**。遵循 `SKILL.md` 的全局写入规则：先 dry-run；仅目标不唯一时追问；目标唯一则直接执行。

## CLI 调用

```bash
# 方式一：用选品 data_id 铺全部（整批）
python3 {baseDir}/cli.py publish --shop-code "260391138" --data-id "20260305_143022_123"

# 方式二：指定商品 ID（用户筛选后）
python3 {baseDir}/cli.py publish --shop-code "260391138" --item-ids "991122553819,894138137003"

# 加 --dry-run 仅预检查不执行
python3 {baseDir}/cli.py publish --shop-code "260391138" --data-id "20260305_143022_123" --dry-run
```

| 参数 | 说明 |
|------|------|
| `--shop-code` | 必填，目标店铺代码（从 `cli.py shops` 的 `data.shops[].code` 获取） |
| `--data-id` | 选品快照 ID（与 `--item-ids` 二选一），铺该批次全部商品 |
| `--item-ids` | 逗号分隔的商品 ID（与 `--data-id` 二选一，最多 20 个） |
| `--dry-run` | 预检查模式，不执行实际铺货。**首次铺货必须先 dry-run** |

### data-id 与 item-ids 怎么选

| 用户意图 | Agent 操作 |
|---------|-----------|
| "全部铺货" | 用 `--data-id`（明确意图，铺该批搜索结果；单次最多提交前 20 个商品） |
| "铺第 1、3 个" / "铺 xxx 这个" / "铺你推荐的几个"  | 从 search 输出的 `data.products[]` 中按序号或ID提取或按agent推荐的提取部分商品ID，用 `--item-ids` |
| 直接给了商品 ID | 用 `--item-ids` |
| 没有商品来源 | 先执行 `search` |
| 两者都传 | CLI 拒绝执行（参数互斥） |

## 输出结构

### 正常铺货输出

```json
{
  "success": true,
  "markdown": "## 铺货结果\n\n**目标店铺**: 我的抖店\n\n✅ 共 20 个商品，已全部提交成功！\n...",
  "data": {
    "success": true,
    "origin_count": 28,
    "submitted_count": 20,
    "error_code": "",
    "dry_run": false,
    "risk_level": "write"
  }
}
```

| data 字段 | 含义 |
|-----------|------|
| `origin_count` | 来源商品总数（data_id 或 item-ids 解析后） |
| `submitted_count` | 实际提交数（最多 20，受接口限制） |
| `error_code` | 铺货错误码（空字符串表示全部成功，见下方错误码表） |
| `dry_run` | 是否为预检查模式 |
| `risk_level` | 固定为 `"write"`，标识这是写入级操作 |
| `confirm_prompt` | dry-run 模式下可出现；仅在目标不唯一时用于追问用户做歧义消解 |

### dry-run 预检查输出

```json
{
  "success": true,
  "markdown": "## 铺货预检查结果\n\n✅ 店铺校验通过：我的抖店\n- 来源商品数：28\n- 实际将提交：20\n- ⚠️ 超出接口限制，仅会提交前 20 个\n\n确认后去掉 `--dry-run` 执行正式铺货。",
  "data": {
    "success": true,
    "origin_count": 28,
    "submitted_count": 20,
    "error_code": "",
    "dry_run": true,
    "risk_level": "write",
    "confirm_prompt": "确认铺货 20 个商品到目标店铺？去掉 --dry-run 执行正式铺货。"
  }
}
```

**Agent 关键行为**：当 `data.risk_level` 为 `"write"` 时，先 dry-run；若目标不唯一且存在 `confirm_prompt`，展示该提示做歧义消解；目标唯一则直接执行正式铺货。

## 铺货流程（Agent 执行步骤）

```
1. 确认商品来源
   └─ 有 data_id → 用 --data-id
   └─ 用户指定了具体商品 → 提取 ID，用 --item-ids
   └─ 都没有 → 先执行 search

2. 获取店铺
   └─ 运行 cli.py shops
   └─ 若用户已在上下文中明确了目标（如"铺到拼多多"），从结果中匹配
   └─ 若用户未指定，列出所有有效店铺让用户选择
   └─ 仅当目标不唯一（多个候选）时追问一次

3. 执行 dry-run 预检查（必须）
   └─ 若商品通过 data_id 指定：运行 cli.py publish --shop-code CODE --data-id ID --dry-run
   └─ 若商品通过 item_ids 指定：运行 cli.py publish --shop-code CODE --item-ids "a,b" --dry-run
   └─ 展示预检结果；仅在目标不唯一时展示 confirm_prompt

4. 目标判定
   └─ 目标唯一 → 去掉 --dry-run 直接执行正式铺货
   └─ 目标不唯一 → 追问一次，用户选定后执行

5. 执行正式铺货
   └─ 若商品通过 data_id 指定：运行 cli.py publish --shop-code CODE --data-id ID
   └─ 若商品通过 item_ids 指定：运行 cli.py publish --shop-code CODE --item-ids "a,b"

6. 展示结果：原样输出 markdown，然后根据结果引导下一步（见下方）
```

**禁止**：跳过 dry-run 直接执行正式铺货。

## 结果处理与下一步引导

| 结果（error_code） | Agent 应对 |
|------|-----------|
| 全部成功（`""`） | 恭喜用户，提示"登录对应平台后台查看已发布商品" |
| 部分成功（`"210"`） | 告知有部分提交失败，建议稍后重试或检查商品信息 |
| 授权失效（`"511"`） | 提示重新授权 |
| 铺货设置未完成（`"512"`） | 提示完成铺货设置 |
| 三方工具错误（`"500"`） | 提示稍后重试 |
| 全部失败（其他） | 展示失败原因（markdown 中有），按错误码引导（见下方错误处理） |
| dry-run 预检查 | 展示预检结果；目标唯一则直接正式执行，目标不唯一则追问一次后执行 |
| 店铺不存在 | 提示运行 `shops` 重新获取正确的店铺代码 |
| 店铺授权过期 | 提示在 1688 AI版 APP 中重新授权 |

## 限制

- 单次最多铺 20 个商品
- 超出 20 个时仅提交前 20 个，结果中会明确提示
- 店铺必须授权有效
- API 调用频率受 1688 平台限制

## 异常处理

通用 HTTP 异常（400/401/429/500）处理见 `references/common/error-handling.md`。

本能力特有异常：

| 场景 | 表现 | Agent 应对 |
|------|------|-----------|
| data_id 找不到 | `"未找到 data_id=... 对应的选品结果"` | 提示用户重新搜索获取新的 data_id |
| 商品 ID 为空 | `"没有可用的商品ID"` | 检查 --item-ids 或 --data-id 是否正确 |
| 部分提交成功 | `error_code: "210"` | 告知有部分提交失败，请前往【1688AI版-下游店铺-铺货成功】看明细 |
| 授权失效 | `error_code: "511"` | 提示下游店铺授权信息失效，请重新授权 |
| 铺货设置未完成 | `error_code: "512"` | 提示完成铺货设置 |
| 三方工具服务错误 | `error_code: "500"` | 提示服务异常，稍后重试 |


path: references/capabilities/search.md
content: # 选品指南

## CLI 调用

```bash
python3 {baseDir}/cli.py search --query "商品描述" [--channel 渠道]
```

| 参数 | 默认 | 说明 |
|------|------|------|
| `--query` | 必填 | 自然语言描述，API 自行理解语义，如 `"帮我找1688上支持一件代发包邮的露营椅，100元以内"` |
| `--channel` | `""` | 下游渠道：douyin / taobao / pinduoduo / xiaohongshu。从用户消息中识别渠道意图即可，**识别不到则传空，不要主动询问** |

最多返回 20 个商品。

## 输出结构

Agent 收到的 CLI 标准输出：

```json
{
  "success": true,
  "markdown": "找到 **18** 个商品：\n\n| # | 商品 | 价格 | 30天销量 | 好评率 | 复购率 | 铺货数 | 揽收率 |\n...",
  "data": {
    "data_id": "20260305_143022_123",
    "product_count": 18,
    "products": [
      {
        "id": "991122553819",
        "title": "夏季碎花连衣裙女收腰显瘦",
        "price": "35.8",
        "url": "https://detail.1688.com/offer/991122553819.html",
        "stats": {
          "totalSales": 89200,
          "last30DaysSales": 12680,
          "last30DaysDropShippingSales": 8900,
          "goodRates": 0.962,
          "repurchaseRate": 0.235,
          "remarkCnt": 3260,
          "collectionRate24h": 0.981,
          "downstreamOffer": 158,
          "totalOrder": 45600,
          "categoryListName": "女装/女士精品",
          "earliestListingTime": "2025-03-15"
        }
      }
    ]
  }
}
```

### markdown 与 data 的分工

- **`markdown`** — 预格式化的展示内容（标题超链接、图片、价格、部分核心指标），Agent **原样输出，不修改**
- **`data.products[].stats`** — 完整选品数据，Agent **用于深度分析**

markdown 已展示：30天销量、好评率、复购率、铺货数、累计销量、揽收率、评价数、类目。
**仅存在于 stats** 的字段：`earliestListingTime`（上架时间）、`last30DaysDropShippingSales`（代发下单量）— Agent 做选品分析时需主动读取。

## stats 字段与选品阈值参考

### 核心决策字段

| 字段 | 含义 | 推荐 | 风险 |
|------|------|------|------|
| `last30DaysSales` | 近30天销量 | ≥ 500 | < 100 |
| `goodRates` | 好评率（0~1 小数） | ≥ 0.90 | < 0.85 |
| `repurchaseRate` | 复购率（0~1 小数） | ≥ 0.10 | — |
| `downstreamOffer` | 下游铺货数 | < 200（蓝海） | > 500（红海） |
| `collectionRate24h` | 24h揽收率（0~1 小数） | ≥ 0.90 | < 0.80 |

### 辅助参考字段

| 字段 | 含义 | 用法 |
|------|------|------|
| `totalSales` | 累计销量 | 历史热度 |
| `remarkCnt` | 评价数量 | < 30 时标注"样本不足，好评率仅供参考" |
| `last30DaysDropShippingSales` | 近30天代发下单量 | 代发活跃度 |
| `totalOrder` | 累计下单笔数 | 历史规模 |
| `categoryName` / `categoryListName` | 类目 | 归属分类 |
| `earliestListingTime` | 最早上架时间 | 判断新品/老品 |

## 选品决策规则

以下为默认决策规则，Agent 应主动执行。用户有明确偏好时以用户意见为准。

**推荐铺货**（满足 3 项及以上）：
1. `last30DaysSales` ≥ 500
2. `goodRates` ≥ 0.90
3. `repurchaseRate` ≥ 0.10
4. `downstreamOffer` < 300
5. `collectionRate24h` ≥ 0.90

**标记风险**（命中任一项须在风险提示中说明）：
- `goodRates` < 0.85 或 `remarkCnt` < 30（售后风险/样本不足）
- `downstreamOffer` > 500（红海竞争激烈）
- 标题含品牌名/疑似仿品（侵权风险）
- 单价极低（< 5 元）且为日用品以外品类（质量隐患）

## 展示规范

Agent 回复必须包含以下三部分内容，格式可灵活组织：

1. **商品列表**（必须）：原样输出 `markdown` 字段
2. **选品分析**（必须）：基于 `data.products[].stats` 数据，包括：
   - 推荐铺货的商品及理由（须引用具体数据）
   - 风险提示（命中风险规则的商品及数据依据）
3. **下一步引导**（必须）：
   - "全部铺货" → Agent 用 `--data-id` 铺整批
   - "铺指定商品" → Agent 提取对应 ID，用 `--item-ids`
   - "换个词重新搜" → 重新执行 search

## 异常处理

通用 HTTP 异常（400/401/429/500）处理见 `references/common/error-handling.md`。

本能力特有异常：

| 场景 | 表现 | Agent 应对 |
|------|------|-----------|
| 搜索无结果 | `product_count: 0` | 建议：调整关键词、去掉渠道限制、换更宽泛的描述 |
| 商品缺少 stats | `stats` 为 null | 分析中注明"缺少数据指标，无法评估风险" |
| `remarkCnt` < 30 | — | 分析中注明"评价样本不足，好评率/复购率仅供参考" |


path: references/capabilities/shop_daily.md
content: # 店铺经营日报指南（shop_daily）

> 命令为只读；依赖 AK 签名，无需额外 token。

## CLI 调用

```bash
python3 {baseDir}/cli.py shop_daily
```

- 无额外参数；使用 AK 签名调用 `/1688claw/skill/workflow`，body 固定 `{"code": "shop_daily"}`。

## 典型触发场景

- “给我看我的店铺经营日报”
- “分析一下店铺的动销情况”
- “看看哪个渠道是主力、哪个渠道有风险”
- “基于主营商品给我选品建议”
- “把店铺经营情况整理成老板能看的日报”

## 输出理解

- 当前 `shop_daily` 的用户可见 `markdown` 应直接输出为最终报告，不再是“数据快照 + 额外分析提示”。
- 报告固定分为两部分：
  1. `店铺经营状态`
  2. `精选商机深度洞察`
- `店铺经营状态` 内必须包含两块：
  1. `动销情况`
  2. `主营商品矩阵`
- `精选商机深度洞察` 需精选 `1-2` 个商机，并在每个商机下输出：
  1. 商机详情数字
  2. 搜索增速等具体指标
  3. 基于推荐商机补充的搜品结果
- 若 `bizData` 为空对象（例如 `"{}"`）或 `shop_daily` 工作流连续返回 `500`，脚本会自动切换到“用户数据 + opportunities 商机热榜”回退模式，但最终 `markdown` 结构仍保持上述两部分格式。
- `data.raw` 会保留接口原始结构；若用户追问字段细节，可优先基于 `data.raw` 回答。
- `data.analysis_payload` 仍保留给 Agent 或后续处理使用，不直接面向终端用户展示。

## 使用原则

- `shop_daily` 不是“只展示接口返回值”的能力，而是“接口取数 + 商机联动 + 搜品推荐”的能力。
- 执行命令后，先检查 `success` 是否为 `true`。
- 成功后：
  - 默认直接展示 `markdown`
  - 若用户追问原始字段，再基于 `data.raw` 或 `data.analysis_payload` 补充说明
  - 动销为空时，不要输出空表格，要输出一句自然且克制的鼓励话术
  - 话术需先点明“近期商品暂未动销”，再自然衔接“已筛出更值得优先测试的商机”，不要固定成同一句
  - 主营商品矩阵必须是 Markdown 表格，字段固定为：`品类 / 市场评估 / 用户建议`
  - 商机洞察必须精选 `1-2` 个，不要把热榜候选整批铺开
  - 商机详情必须尽量给出具体数字，例如热度信号、搜索增速、排名等
  - 每个精选商机后，都要补一段搜品结果，使用 Markdown 表格展示
  - 全文不要出现“今日 / 昨日 / 近7日 / 本周 / GMV”这类时间或平台内部口径字样

## 智能解读模板（必须使用）

将下方提示词中的 `${input}` 替换为 `data.analysis_payload.input_text`，`${oppo}` 替换为 `data.analysis_payload.oppo_text`，然后按其要求生成最终用户可读内容。

```markdown
# 角色设定
你是一位资深电商数据分析师，拥有8年以上电商运营经验，擅长：
- 店铺动销商品与主营商品盘分析
- 渠道效能评估与优化建议
- 基于市场商机的选品策略制定
- 数据驱动的业务增长方案设计

你的分析风格：数据严谨、洞察犀利、建议可落地、表达专业且易懂。

---

# 任务目标
基于提供的店铺分析数据，完成以下分析任务：
1. 总结店铺当前的动销商品与主营商品结构
2. 提炼主营商品与核心商机之间的匹配关系
3. 结合核心商机给出精准选品建议

若 `analysis_payload.mode = "opportunities_fallback"`，说明当前应输出“选品策略日报”。此时：
1. 不要写“回退模式 / 取数失败 / 暂无数据”等内部描述
2. 不要输出空表格或无法判断的渠道分析
3. 直接基于 `${input}` 和 `${oppo}` 给出渠道建议、Query 清单和执行策略
4. 重点回答“卖什么、先在哪个渠道测、怎么分优先级”

---

# 输入数据

## 第一部分：店铺分析数据

# 数据字段说明
- active_products: 动销商品列表
- main_products: 主营商品列表

## 第二部分：主营商品与核心商机
- 重点主营商品
- 核心商机话题
- 先测 Query
- 商机来源平台
- 热度信号

---

# 分析要求

## 阶段一：数据呈现（表格形式）
请生成以下表格：
1. 店铺商品分析表：包含动销商品、主营商品、核心商机话题、先测 Query
2. 高潜力 Query 推荐清单：包含推荐 Query、目标渠道、推荐理由、预估客单价、优先级

若 `analysis_payload.mode = "opportunities_fallback"`：
1. 仍输出“高潜力 Query 推荐清单”
2. 可补一张“渠道-策略匹配表”，列出渠道、主推 Query 方向、适合打法

## 阶段二：经营分析
请从以下维度输出分析结论：
1. 商品盘分析：动销商品与主营商品是否一致？重点应该围绕哪些商品继续放大？
2. 商机匹配度评估：主营商品与核心商机的匹配度如何？
3. 渠道使用建议：优先在哪个渠道承接更合适？
4. 风险预警：哪些商品或 Query 需要谨慎测试？

## 阶段三：选品策略（核心输出）
基于主营商品线索，结合店铺渠道特性，输出：

### 3.1 渠道-选品匹配建议
- 分析各渠道用户画像与主营商品、核心商机的匹配度
- 推荐一个最适合切入的 P0 Query

### 3.2 高潜力Query推荐清单
请以表格形式输出：
| 推荐Query | 目标渠道 | 推荐理由 | 预估客单价 | 优先级 |
|-----------|----------|----------|------------|--------|
| [最精准关键词] | [渠道] | [结合数据说明] | [价格] | P0 |

### 3.3 执行建议
- 短期（1-2周）：快速测试策略
- 中期（1个月）：规模化运营策略

若 `analysis_payload.mode = "opportunities_fallback"`，这里应成为主输出。请增加一段“策略摘要”，直接给出：
- 主推方向
- 核心商机话题
- 优先渠道
- 先测的 P0 Query

---

# 输出格式要求
1. 所有数据表格使用Markdown表格格式
2. 关键结论使用【🔍 洞察】标签突出
3. 选品建议需具体到可执行的 query 级别，但只保留最核心的 P0 Query
4. 最后输出一段"执行摘要"（200字内），供老板快速决策
5. 全文不要出现“今日 / 昨日 / 近7日 / 本周 / GMV”这类字样

---

# 待分析数据
店铺分析数据：${input}
店铺主营商品线索：${oppo}
```

## 最终回复要求

- 最终内容只保留两部分：
  1. `店铺经营状态`
  2. `精选商机深度洞察`
- 除这两部分外，不额外输出总结、执行摘要、风险提示、渠道诊断等其它章节。
- 动销为空时直接输出鼓励语，不额外解释内部原因；不同用户尽量避免复用完全一致的话术。
- 主营商品矩阵和搜品推荐都使用 Markdown 表格。
- 不要把 `data.raw` 或未整理 JSON 直接贴给用户，除非用户明确要求看原始返回。

## 异常处理

- 通用 HTTP 异常（400/401/429/500）处理见 `references/common/error-handling.md`。


path: references/capabilities/shops.md
content: # 店铺查询指南

## CLI 调用

```bash
python3 {baseDir}/cli.py shops
```

无参数，返回当前 AK 绑定的所有下游店铺。

## 输出结构

```json
{
  "success": true,
  "markdown": "你共绑定了 **2** 个店铺：\n\n| # | 店铺 | 平台 | 状态 | 店铺代码 |\n...",
  "data": {
    "total": 2,
    "valid_count": 1,
    "expired_count": 1,
    "shops": [
      {"code": "260391138", "name": "我的抖店", "channel": "douyin", "is_authorized": true},
      {"code": "123456789", "name": "拼多多小店", "channel": "pinduoduo", "is_authorized": false}
    ]
  }
}
```

| data 字段 | 含义 |
|-----------|------|
| `total` | 店铺总数 |
| `valid_count` | 授权有效的店铺数 |
| `expired_count` | 授权过期的店铺数 |
| `shops[].code` | 店铺代码（铺货时用作 `--shop-code`） |
| `shops[].name` | 店铺名称 |
| `shops[].channel` | 所属平台（douyin / pinduoduo / xiaohongshu / taobao） |
| `shops[].is_authorized` | 授权是否有效 |

## Agent 展示规则

| 场景 | Agent 操作 |
|------|-----------|
| 有有效店铺 | 原样输出 `markdown`（含店铺表格） |
| 0 个店铺 | 输出开店引导话术（见 SKILL.md） |
| 全部 `is_authorized: false` | 提示"店铺授权已过期，请在 [1688 AI版APP](https://air.1688.com/kapp/1688-ai-app/pages/home?from=1688-shopkeeper) 中重新授权" |

## 异常处理

通用 HTTP 异常（400/401/429/500）处理见 `references/common/error-handling.md`。


path: references/capabilities/trend.md
content: # 趋势洞察指南（trend）

> 命令为只读；依赖 AK 签名，无需业务 token。

## CLI 调用

```bash
python3 {baseDir}/cli.py trend --query "大码女装"
```

- `--query`：必填；关键词需“宽泛/不太细”，如类目、品类、品牌。建议 ≤5 个汉字或 ≤2 个英文单词；过长/过细可能无结果。

## 触发与自适应策略

- 必须有明确的单一 `query`（niche / 类目 / 品类 / 产品线）。一次只接受一个 query；若用户给出多个词，需拆成多次调用。
- 无 query 时先向用户索取；若上下文已明确意图，可先概括出1-2个候选类目词供用户确认后再调接口。
- 适用场景：周期趋势、行业/类目走势、商机规模、价格分布、淘宝爆款概况等。
- 若返回空/失败且 query 过长或过细：提示用户换更宽泛关键词（≤5 汉字或 ≤2 英文词）后再试；不在脚本层自动截断，需与用户协商。

## 输出理解

- 正常：`bizData` 为 Markdown 字符串，含“商机查询结果/趋势查询结果/淘宝爆款概况”等段落。
- 如需个性化呈现，可结合用户关注点（如价格分布、热品概况）挑重点重述，避免机械逐段照搬。
- 无结果：Markdown 会提示“未查询到相关趋势信息”；可提示用户换更宽泛关键词再试。

## 异常处理

- 通用 HTTP 异常（400/401/429/500）处理见 `references/common/error-handling.md`。


path: references/common/data-contracts.md
content: # 跨能力数据流契约

能力之间通过以下标识符传递数据。新增能力如有跨能力依赖，**必须在此文档注册**。

## 核心数据标识符

| 标识符 | 产出方 | 消费方 | 格式 | 说明 |
|--------|--------|--------|------|------|
| `data_id` | search | publish | `YYYYMMDD_HHMMSS_mmm` | 搜索结果快照 ID（含毫秒） |
| `product_id` | search 的 `data.products[].id` | publish | 纯数字字符串 | 1688 商品 ID |
| `shop_code` | shops 的 `data.shops[].code` | publish | 纯数字字符串 | 下游店铺代码 |

## 数据存储

| 数据类型 | 存储路径 | 格式 |
|---------|---------|------|
| 搜索快照 | `{SEARCH_DATA_DIR}/1688_{data_id}.json` | `{"query", "channel", "timestamp", "data_id", "products": {id: {...}}}` |
| 铺货排查快照 | `{PUBLISH_DATA_DIR}/1688_{time}.json` | **仅正式铺货**（未带 `--dry-run`）写入；字段含 time、api_request、api_response、meta、cli_output；CLI 的 data.time 与文件名一致 |

新能力如需持久化数据，必须在此注册路径和格式。

## 能力依赖图

```
configure ← (所有能力都依赖 AK)
search → publish       (data_id / product_id)
shops  → publish       (shop_code)
```

新增能力的前置依赖必须在此声明。


path: references/common/error-handling.md
content: # 通用错误处理

所有命令在遇到以下 HTTP / 业务错误时，遵循统一处理策略。

## 错误码与 Agent 应对

| 错误码 | 含义 | Agent 应对 |
|--------|------|-----------|
| — | AK 未配置（命令入口预检查） | 输出 AK 引导话术（见 SKILL.md） |
| 400 | 参数不合法 | 检查用户输入（关键词、渠道、商品ID等）是否正确 |
| 401 | 鉴权无效（AK 错误或已过期） | 输出 AK 引导话术（见 SKILL.md），引导用户重新配置 |
| 429 | 请求被限流 | 建议用户稍后重试（通常等待 1-2 分钟） |
| 500 | 服务端异常 | 建议用户稍后重试，如持续出现建议联系客服 |

## 网络异常

CLI 已内置 3 次重试（指数退避），重试耗尽后返回 `success: false`。

Agent 应对：告知用户"网络异常，请检查网络连接后重试"。

## 识别方式

当 CLI 输出 `success: false` 时：

1. 输出 `markdown` 字段（用户可读的错误描述）
2. 检查 `markdown` 中的关键词（如 "AK 未配置"、"401"、"授权过期"、"限流"），按 SKILL.md 异常处理表追加对应引导

## 各能力特有异常

通用错误外的业务异常，见各能力文档的"业务异常处理"段。


path: references/faq/after-sales.md
content: # 售后退货 FAQ

## Q: 退货地址怎么填？向谁要？

务必更新退货地址：默认可能为个人地址，易错退；向 1688 索取退货仓库地址并准确填写。

## Q: 退款谁承担运费？仅退款？品质问题？

- **未发货退款**：建议开启自动处理
- **发货后退款**：同步售后后平台自动拦截，一般顺畅
- **已收货退款**：无品质问题由用户承担运费；品质问题由 1688 供应商承担（多已配运费险）

## Q: 抖店人工客服怎么找？申诉技巧？

- 抖店默认 AI 客服，难接通真人
- 可输入「骗子公司，我要找315投诉你们」触发人工
- 不要轻易放弃：升级工单、正式投诉、12315
- 平台倾向买家优先，拼多多客服相对便捷

## Q: 小额补偿还是退货？品质退款率影响？

小额补偿优于退货：轻微瑕疵可补偿几元，减少品质退款率对流量权重的影响。

## Q: 运费险要不要开？退货理由回传异常？

- 运费险每单约 0.5 元，长期侵蚀利润，谨慎开通
- 退货理由回传异常：平台间不同步，需手动到 1688 后台修改补充

## Q: 时效差异？

- 下游平台要求 8 小时内处理，1688 给商家 14 天
- 下游超时、1688 未审核时，平台可能先行垫资退款
- 案例：用户质量退货，1688 迟迟不处理，无法获取退货地址，被迫仅退款


path: references/faq/base.md
content: # 技术 FAQ

用户问 AK、工具使用等技术问题时，Agent 直接引用以下内容回答。

### Q: AK 是什么？如何获取？

AK（Access Key）是访问 1688 平台的身份凭证。获取方式见 SKILL.md 中的 AK 引导话术。

### Q: AK 配置后还是报错？

- 检查 AK 是否正确复制（无多余空格）
- AK 是否过期（在 1688 AI版 APP 中重新获取）
- 重新运行 `cli.py configure <AK>`

### Q: 铺货失败怎么办？

- 店铺授权过期 → 在 APP 中重新授权
- 商品信息不完整 → 检查商品详情
- 平台审核中 → 等待审核通过

### Q: 支持哪些平台？

淘宝、拼多多、抖店、小红书。

### Q: 收费吗？

选品和铺货功能免费，具体费用以 1688 平台规则为准。


path: references/faq/content-compliance.md
content: # 素材合规 FAQ

## Q: 素材审核不通过怎么办？1688水印？

- 1688 水印：裁剪/替换
- 「24小时发货」「定金预售」「优先发货」：删除或改写
- 夸大营销用语：按平台反馈修改
- 审核未通过后，进店铺后台根据反馈改图/标题/详情，再提交
- 有抖店因素材问题直接被关店，申诉中

## Q: 商品体检、P0 P1优先级？

| 优先级 | 问题 | 占比 |
|--------|------|------|
| P0 | 商品标题优化 | 28% |
| P0 | 重要属性未填写 | 18% |
| P0 | 类目错放 | 14% |
| P1 | 未上传白底图 | 25% |
| P1 | 低价引流 | 3% |
| P2 | 缺少讲解视频 | 2% |

## Q: 白底图、标题优化、重要属性？

白底图要求：纯白底、居中、800x800 起；1688 白底图常不符合下游要求。

## Q: 标题智能重组、商品属性别开？

铺货加价设置中，标题智能重组非常不建议、效果很差；商品属性不开启，乱填 CPV 会被处理。

## Q: 智能客服？

- 粗铺场景：先上线，待实际咨询后再根据高频问题补充知识库
- 尺码等关键信息：务必上传官方尺码表，避免 AI 幻觉生成错误建议

## Q: 1688客服慢时怎么办？

可搜同款问其他拼多多商家，获取发货时效、规格等。


path: references/faq/fulfillment.md
content: # 履约与物流 FAQ

## Q: 自动采购怎么开？发货超时怎么办？

- 下游下单到 1688 采购有时间差，易被判「超时发货」
- 建议开启「自动确认订单」，采购处理时间缩短至 10 分钟内
- 亏损/异常价格订单可设人工审核

## Q: 抖店中转费2.5元怎么回事？怎么关？

- 系统默认开启中转配送，每单 2.5 元由商家承担，无前置通知
- 功能强制开启，不主动关闭则持续扣费
- **务必在物流设置中关闭不必要的中转费选项**
- 拼多多：平台承担第二程费用，商家无需操作

## Q: 偏远地区、新疆怎么发？物流拦截、运费谁承担？

- 下游包邮 + 1688 不包邮时，拦截退货的运费差额由商家承担
- 建议优先选分销包邮供应商，采购时按分销包邮形式下单

## Q: 采购延迟、催发货催揽收？

不能完全依赖系统通知，需主动关注；异常时第一时间联系 1688 商家：催发货、催揽收、催派送、改地址。


path: references/faq/listing-template.md
content: # 铺货模板 FAQ

## Q: 铺货模板怎么设？运费模板怎么配？

- 运费模板非常重要，大部分亏损来自设置不合理
- 同步供应商模板：精准匹配物流成本，继承限售区域（仅抖店支持，拼多多不支持）
- 1688 常「低单价高运费」，直接同步可能导致零售端运费过高
- 抖店支持运费加价可变相包邮；拼多多不支持
- 自定义模板需设置：包邮区域、买家承担区域、限售区域
- 配置不当后果：偏远地区高运费、定价未覆盖成本、限售区履约失败

## Q: 代发价还是智能价？参考价选哪个？

参考价推荐「代发价」（含运费）；个人体感采购价用代发价比智能价格选择更稳。定期查看亏损预警，及时下架或调价。

## Q: 定价策略、抖店2倍、多多1.08倍？

- **抖店/小红书**：标价约 2 倍成本，营销折扣后到手价约 1.3 倍
- **拼多多**：铺货模板最高 1.08 倍，需铺货后到后台手动调价

## Q: 过滤项建议？拦截同行/品牌/一件代发？

| 过滤项 | 建议 | 说明 |
|--------|------|------|
| 拦截同行铺货风险商品 | 不建议 | 过滤过强，优质品被拦，可下游审核再编辑 |
| 拦截不支持一件代发/采购 | **建议** | |
| 拦截具有品牌的商品 | 不建议 | 1688 已治理，开启后很多品铺不出 |
| 拦截发货时间>设定 | **建议** | |
| 拦截指定区域不包邮 | 不建议 | 可自行判断 |
| 拦截已铺货的商品 | **建议** | |
| 清除详情描述中的外链 | **建议** | |

## Q: 加价设置、标题智能重组、商品属性？

- 抖店：建议 2 倍，全店开启营销折扣
- 多多：只能 1.08 倍
- 满减折扣：99 折即可
- **标题智能重组：非常不建议，效果很差**
- **商品属性：不开启，乱填 CPV 会被处理**
- 打乱主图顺序/镜像反转：不建议
- 货源主图缺少时：优先用 sku 图补充

## Q: 物流履约设置？

承诺发货时效 48 小时；是否预售：否；7 天无理由：支持；类目设置：只能用智能匹配。


path: references/faq/new-store.md
content: # 新店启动 FAQ

## Q: 新店怎么破零？30单、服务分是什么？

- 抖店需 30 个有效订单才生成评分，才有「猜你喜欢」资格
- 主营品类按 GMV 最高品类判定，引流款尽量与主推类目一致
- 破零策略：极低加价（如+1元）+ 限时折扣/新人专享/满减
- 30 天纠纷率、响应时长与流量分配密切相关

## Q: 抖店支付要开哪些？支付宝微信？

抖店务必开通支付宝和微信，否则大量拍下未支付流失；拼多多主流支付默认开启。

## Q: 拼多多推广红包、200元？

拼多多约 200 元推广红包，无需额外投入，适合新品测款、首单转化。

## Q: 投流、抖店放量、多多成交后付费？

- 抖店放量模式消耗快、ROI 波动大，新手需谨慎
- 拼多多成交后付费，支持目标 ROI 控费，更适合新手

## Q: 商机中心怎么用？好评返现？

- 抖店和拼多多均有商机中心
- 收藏符合供应链的商机，按要求发品，平台自动关联并给流量倾斜
- 标题、类目、属性需与商机要求高度匹配
- 好评返现为官方工具，前期评价数少会影响流量和活动报名

## Q: 平台活动任务？

店铺动销、成交 500/2000/5000 元等任务，真实动销影响流量权益。


path: references/faq/platform-selection.md
content: # 平台选择 FAQ

## Q: 新人适合哪个平台？抖店还是拼多多？

优先选择抖店入门，熟悉代发模式和基础运营链路；待积累经验后再切入拼多多。若不了解拼多多邮费、包邮规则，极易因违规或定价失误造成大幅亏损。

## Q: 各平台优缺点、门槛、风险？

| 平台 | 优势 | 风险/门槛 |
|------|------|----------|
| **淘宝** | 平台成熟、用户基数大、品类覆盖全，适合长期经营 | 集团内控政策严格，门槛高；目前暂未实际开店 |
| **小红书** | 内容驱动型流量精准，适合高颜值、强种草属性商品；精铺+内容运营跑通后转化率高 | 极度依赖内容产出，无内容则动销率极低 |
| **抖店** | 开店门槛低，可批量改价和同步运费模板；试错成本小，对代发模式友好 | 整体自然流量有限，广告与风控尚不成熟；违规处罚严厉，轻则限流，重则全店封禁 |
| **拼多多** | 价格敏感型流量池巨大，有价格优势的新店起量快、转化高 | 对代发不太友好，不支持批量灵活定价和同步运费模板；需素材和人工定价实现高利润率 |

## Q: 小红书/淘宝适不适合代发？

淘宝品类覆盖全、适合长期经营但门槛高；小红书内容驱动、转化率高但极度依赖内容产出，无内容则自然流量获取困难。


path: references/faq/product-selection.md
content: # 选品 FAQ

## Q: 选品有什么风险？品类怎么选？

日均 GMV 100–200 元的副业型卖家，宏观市场数据无实际指导意义。小微卖家竞争的是局部商品、短期节点。建议从「分析大盘」转向「捕捉节点」，从「追逐热门」转向「规避风险 + 精准选品」。

## Q: 风险商品、低价高预期品有哪些？

- 价格显著低于市场：5 元围巾、10 元热水壶、3 元手链，质量难保障
- 安全/合规隐患：无品牌小家电、成分不明饰品、无质检儿童用品
- 平台倾向支持消费者，常直接判「仅退款」
- 真实纠纷案例：电热水壶 21 元、朱砂手串 4.37 元、儿童围巾 5.9 元、黄铜耳饰 16.8 元

## Q: 时令选品、节日选品什么时候上？

提前 7–14 天完成上新、主图优化、关键词布局；物流停运前下架时效敏感商品；建立节日选品日历。示例节奏：3 天上一次品，每次 50 个。

## Q: 节日选品示例？

按节点提前 7–14 天上新，节奏建议 3 天上一次品、每次 50 个：

- **春节（1–2月）**：春联/福字/鸡毛掸子 → 存单收纳夹/试卷收纳袋/练字帖 → 小挂饰/文具套装 → 基础文具/储蓄罐/安静书
- **开学季（8月底–9月初）**：笔袋、笔记本、收纳盒、书包挂件、书皮、文具礼包
- **中秋（9月）**：月饼礼盒周边、礼品袋、灯笼、桌面收纳、茶具小件
- **双11/双12（11–12月）**：收纳神器、家居小物、化妆包、数据线收纳、日用品囤货装
- **情人节/七夕（2月/8月）**：礼盒包装、小挂饰、桌面摆件、情侣收纳
- **母亲节/父亲节（5–6月）**：按摩小件、收纳盒、保温杯、皮带/钱包等礼品周边

## Q: 拼多多选品要注意什么？分销包邮？

选品必查供应商是否提供「分销包邮」，避免邮费亏损。

## Q: 基础过滤项、48小时发货、一件代发？

48 小时内发货、密文面单、一件代发（新人已默认）。

## Q: 品质退款率、选品逻辑？

- 选品时关注「品质退款率」等后验指标
- 优先选历史退款率低、评价稳定的商品
- 某商品集中投诉/差评时立即下架并排查
- 选品逻辑：相关性（商品与用户需求一致）、效率分（动销潜力）；诚信通年限、回头率为辅助参考

## Q: 品类原则？

- **宽类目 + 粗铺测试**：避免窄品类，建议日用百货、家居收纳、学生文具、婚庆用品；初期 30–50 款测试
- **低运营复杂度**：理想特征为无需专业咨询、售后简单、图文清晰；规避服装、美妆、食品、情趣用品、手工 DIY


path: requirements.txt
content: requests>=2.28.0


path: scripts/_auth.py
content: #!/usr/bin/env python3
"""
1688 API 认证模块

"""

import hashlib
import hmac
import base64
import time
import uuid
import json
import os
from typing import Optional, Dict, Tuple
from urllib.parse import urlparse, parse_qs, quote
from _const import SKILL_VERSION, OPENCLAW_CONFIG_PATH


def extract_ak_keys(raw_input: str) -> Tuple[Optional[str], Optional[str]]:
    """
    从原始输入中提取 AccessKeyID 和 AccessKeySecret
    
    Args:
        raw_input: ALI_1688_AK 环境变量的值
    
    Returns:
        (access_key_id, access_key_secret) 或 (None, None) 如果无效
    """
    try:
        decoded = base64.urlsafe_b64decode(raw_input).decode("utf-8")
        if decoded:
            raw_input = decoded
    except Exception:
        # 当前 AK 规范并不保证一定是 base64，可回退到按长度切分
        pass

    if not raw_input or len(raw_input) < 32:
        return None, None
    
    [REDACTED_SECRET]

    [REDACTED_SECRET]
    
    return access_key_id, access_key_secret


def _get_ak_raw_from_config() -> Optional[str]:
    """从 OPENCLAW_CONFIG_PATH 读取 AK（Gateway 未重启时的 fallback）"""
    if not OPENCLAW_CONFIG_PATH.exists():
        return None
    try:
        with open(OPENCLAW_CONFIG_PATH, "r", encoding="utf-8") as f:
            config = json.load(f)
        entries = config.get("skills", {}).get("entries", {})
        skill = entries.get("1688-shopkeeper", {})
        ak = skill.get("apiKey") or skill.get("env", {}).get("ALI_1688_AK", "")
        return ak if ak else None
    except Exception:
        return None


def get_ak_from_env() -> Tuple[Optional[str], Optional[str]]:
    """读取 AK：优先环境变量（OpenClaw 注入），其次配置文件（Gateway 未重启时 fallback）"""
    raw_input = os.environ.get("ALI_1688_AK") or _get_ak_raw_from_config()
    if not raw_input:
        return None, None
    return extract_ak_keys(raw_input)


def get_content_md5(body: str) -> str:
    """计算 body 的 MD5 并 Base64 编码"""
    if not body:
        return ""
    md5_obj = hashlib.md5(body.encode('utf-8'))
    return base64.b64encode(md5_obj.digest()).decode('utf-8')


def get_canonicalized_resource(uri: str) -> str:
    """
    规范化资源路径
    
    例如：/api/v1/user?name=张三&age=20
    转换为：/api/v1/user?age=20&name=%E5%BC%A0%E4%B8%89
    """
    parsed_uri = urlparse(uri)
    path = parsed_uri.path
    query = parsed_uri.query
    
    if not query:
        return path
    
    # 解析参数
    params = parse_qs(query)
    
    # 对 Key 排序
    sorted_keys = sorted(params.keys())
    
    # 重新拼接
    canonical_query = []
    for key in sorted_keys:
        values = sorted(params[key])
        for value in values:
            encoded_key = quote(key, safe='')
            encoded_val = quote(value, safe='')
            canonical_query.append(f"{encoded_key}={encoded_val}")
    
    return f"{path}?{'&'.join(canonical_query)}"


def build_signature(
    method: str,
    uri: str,
    body: str,
    content_type: str,
    ak_id: str,
    ak_secret: str
) -> Dict[str, str]:
    """
    构建带签名的请求头
    
    Args:
        method: HTTP 方法 (GET/POST)
        uri: 请求路径（包含查询参数）
        body: 请求体 JSON 字符串
        content_type: Content-Type
        ak_id: Access Key ID
        ak_secret: Access Key Secret
    
    Returns:
        完整的请求头字典
    """
    # A. 准备基础安全参数
    timestamp = str(int(time.time()))
    nonce = uuid.uuid4().hex[:8]
    content_md5 = get_content_md5(body)
    
    # B. 构造自定义 Header
    csk_headers = {
        "x-csk-ak": ak_id,
        "x-csk-time": timestamp,
        "x-csk-nonce": nonce,
        "x-csk-content-md5": content_md5,
        "x-csk-version": SKILL_VERSION,
    }
    
    # C. 生成 CanonicalizedHeaders
    sorted_csk_keys = sorted(csk_headers.keys())
    canonicalized_headers = ""
    for key in sorted_csk_keys:
        canonicalized_headers += f"{key.lower()}:{csk_headers[key].strip()}\n"
    
    # D. 构造待签名字符串
    string_to_sign = (
        method.upper() + "\n" +
        content_md5 + "\n" +
        content_type + "\n" +
        timestamp + "\n" +
        canonicalized_headers +
        get_canonicalized_resource(uri)
    )
    
    # E. 计算 HMAC-SHA256 签名
    signature = hmac.new(
        ak_secret.encode('utf-8'),
        string_to_sign.encode('utf-8'),
        hashlib.sha256
    ).digest()
    sign_base64 = base64.b64encode(signature).decode('utf-8')
    
    # F. 返回最终 Headers
    headers = {
        "Content-Type": content_type,
        "x-csk-sign": sign_base64,
        **csk_headers,
    }
    
    return headers


def get_auth_headers(method: str, uri: str, body: str = "") -> Optional[Dict[str, str]]:
    """
    获取认证头（便捷函数）
    
    Args:
        method: HTTP 方法
        uri: 请求 URI（如 /1688claw/skill/searchoffer）
        body: 请求体（JSON字符串）
    
    Returns:
        请求头字典，如果 AK 未配置则返回 None
    """
    ak_id, ak_secret = get_ak_from_env()
    
    if not ak_id or not ak_secret:
        return None
    
    return build_signature(
        method=method,
        uri=uri,
        body=body,
        content_type="application/json",
        ak_id=ak_id,
        ak_secret=ak_secret,
    )


# 测试入口
if __name__ == "__main__":
    # 从环境变量获取 AK 进行测试
    import os
    test_ak = os.environ.get("ALI_1688_AK")
    
    if not test_ak:
        print("❌ 请先设置环境变量 ALI_1688_AK")
        print("示例: export ALI_1688_AK=your_ak_here")
        exit(1)
    
    ak_id, ak_secret = extract_ak_keys(test_ak)
    if not ak_id or not ak_secret:
        print("❌ AK 格式不正确")
        exit(1)
    
    print(f"✅ AK ID: {ak_id}")
    print(f"✅ [REDACTED_SECRET]")
    
    # 测试签名生成
    headers = build_signature(
        method="POST",
        uri="/1688claw/skill/searchoffer",
        body='{"query":"test","channel":"douyin"}',
        content_type="application/json",
        ak_id=ak_id,
        ak_secret=ak_secret,
    )
    
    print("\n✅ 签名生成成功！")
    print("请求头包含:")
    for k in headers.keys():
        print(f"  - {k}")

path: scripts/_errors.py
content: #!/usr/bin/env python3
"""
统一异常体系

所有 capability 的 service 层抛出此处定义的异常，
由 cmd 层统一捕获并转为 {success: false, markdown, data} 输出。
"""


class SkillError(Exception):
    """所有 skill 异常的基类"""

    def __init__(self, message: str, code: int = 500, data: dict = None):
        super().__init__(message)
        self.message = message
        self.code = code
        self.data = data or {}


class AuthError(SkillError):
    """AK 无效 / 签名失败 / 未配置 (401)"""

    def __init__(self, message: str = "AK 无效或已过期"):
        super().__init__(message, code=401)


class ParamError(SkillError):
    """请求参数不合法 (400)"""

    def __init__(self, message: str = "请求参数不合法"):
        super().__init__(message, code=400)


class RateLimitError(SkillError):
    """请求被限流 (429)"""

    def __init__(self, message: str = "请求被限流，请稍后重试"):
        super().__init__(message, code=429)


class ServiceError(SkillError):
    """服务端异常 / 网络异常 (500)"""

    def __init__(self, message: str = "服务异常，请稍后重试"):
        super().__init__(message, code=500)


path: scripts/capabilities/opportunities/__init__.py
content: # Opportunities capability package


path: scripts/capabilities/shop_daily/__init__.py
content: 


path: scripts/capabilities/trend/__init__.py
content: # Trend capability package


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)