1688 以图搜款同款供应商快速搜索。从产品图片出发,一键完成:以图搜款 → 多条件筛选 → 未确认项自动询盘 → TOP10 表格输出。 轻量版,不带 AlphaShop 查厂、不生成 HTML 报告。筛选条件缺失时自动通过 inquiry-1688 询盘补齐。
---
name: 1688-find-similar-suppliers
version: "1.3.0"
description: |
1688 以图搜款同款供应商快速搜索。从产品图片出发,一键完成:以图搜款 → 多条件筛选 → 未确认项自动询盘 → TOP10 表格输出。
轻量版,不带 AlphaShop 查厂、不生成 HTML 报告。筛选条件缺失时自动通过 inquiry-1688 询盘补齐。
metadata:
openclaw:
emoji: "🔍"
requires:
bins: ["python3"]
---
# 1688-find-similar-suppliers(轻量同款供应商搜索)
**触发词**:找同款供应商、搜同款、以图搜款、找类似款供应商、图片找货源、帮我找同款
## 定位
轻量级以图搜款 → 多条件筛选 → 筛不到的用询盘问供应商 → TOP10 表格。
与 `1688-scout-inquiry-report`(全链路 HTML 报告+AlphaShop 查厂)的区别:
| 对比项 | find-similar-suppliers | scout-inquiry-report |
|--------|----------------------|---------------------|
| 输出 | Markdown TOP10 表格 | HTML 可视化报告 |
| 询盘 | ✅ 仅针对筛选缺失项(代发/发货) | ✅ 批量全量询盘 |
| AlphaShop 查厂 | ❌ 不包含 | ✅ 包含 |
| 适用场景 | 快速找同款+确认关键条件 | 完整供应商尽调 |
## 前置检查
必须有产品图片。无图时明确拒绝,引导用户发图。
## 工作流
### Step 1: 以图搜款
```bash
cd ~/.hermes/skills/1688-product-find
/usr/bin/python3 cli.py image_search --image "{image_path}" --limit 20 --sort sold_desc
```
**⚠️ 用 `/usr/bin/python3`**,不要用 `python3`(可能指向 venv 缺 keyring)。
**设计图/渲染图**:加 `--score-level medium` 提升召回率:
```bash
/usr/bin/python3 cli.py image_search --image "{image_path}" --limit 20 --sort sold_desc --score-level medium
```
**0 结果处理**:
1. 先用 `--score-level medium` 重试
2. 仍 0 结果 → 告知用户换图,不降级关键词搜索
### Step 2: 多条件筛选
从 `data.data.similar_products` 或 `data.similar_products` 中提取商品(兼容两种嵌套深度)。
#### 筛选条件清单
对每条商品逐项检查,标记 ✅ / ❌ / ❓(未知需询盘确认):
| 条件 | 数据来源 | 判断逻辑 |
|------|---------|---------|
| **一件代发** | `service_infos` | 含「一件代发/代发」→ ✅;无此字段 → ❓ |
| **包邮** | `service_infos` | 含「包邮/免邮」→ ✅;无 → ❌ |
| **起批量** | `sku_info.quantity_begin` | ≤2 → ✅(适合小批量试单);>10 → ⚠️ |
| **48h发货** | `service_infos` | 含「48小时发货/24小时发货」→ ✅;无 → ❓ |
| **退货包运费** | `service_infos` | 含「退货包运费」→ ✅;无 → ❌ |
```python
def evaluate_product(product):
services = [s.get('value', '') for s in product.get('service_infos', [])]
def has(kw_list):
return any(kw in s for s in services for kw in kw_list)
return {
'dropship': True if has(['一件代发', '代发']) else ('unknown' if not services else False),
'free_shipping': has(['包邮', '免邮']),
'fast_ship': True if has(['48小时发货', '24小时发货']) else ('unknown' if not services else False),
'return_free': has(['退货包运费']),
'min_qty': product.get('sku_info', {}).get('quantity_begin', '?'),
}
```
**筛选排序规则**:
1. 有「一件代发 ✅」的商品排前面
2. 同等条件下按销量降序
3. 取 TOP 10
### Step 3: 筛不到的条件 → 询盘确认
**当关键条件标记为 ❓(未知)时,自动发起询盘确认。**
对 TOP10 中「一件代发」或「48h发货」状态为 ❓ 的商品,通过 `inquiry-1688` 向供应商提问:
```bash
cd ~/.hermes/skills/inquiry-1688
ALPHASHOP_ACCESS_KEY="xxx" ALPHASHOP_SECRET_KEY="yyy" \
python3 scripts/inquiry.py submit "{detail_url}" "1. 是否支持一件代发?2. 下单后多久可以发货?3. 最小起订量是多少?4. 能否贴牌/定制LOGO?"
```
**⚠️ 凭证必须通过环境变量传入**(inquiry.py 不会自动读取 config):
```python
import json, os, subprocess
with open(os.path.expanduser("~/.openclaw/openclaw.json")) as f:
cfg = json.load(f)["skills"]["entries"]["search-1688-supplier"]["env"]
env = os.environ.copy()
env["ALPHASHOP_ACCESS_KEY"] = cfg["ALPHASHOP_ACCESS_KEY"]
env["ALPHASHOP_SECRET_KEY"] = cfg["ALPHASHOP_SECRET_KEY"]
inquiry_dir = os.path.expanduser("~/.hermes/skills/inquiry-1688")
subprocess.run(
["/usr/bin/python3", "scripts/inquiry.py", "submit", url, question],
env=env, cwd=inquiry_dir
)
```
**询盘触发条件**:
- 仅对 ❓(未知)状态发起,已确认 ✅/❌ 的不重复问
- 优先问「一件代发」和「发货时效」,这两个对跨境代发最关键
- 每个供应商最多询盘一次
**询盘问题模板**(可按需调整):
```
你好,想确认几个问题:
1. 是否支持一件代发?
2. 下单后多久可以发货?
3. 最小起订量(MOQ)是多少?
4. 能否贴牌/定制LOGO?
```
### Step 4: 主动询盘(用户指定供应商)
搜索结果展示后,用户可要求对指定供应商发起**主动询盘**(问价格、认证、定制等)。
**触发条件**:
- 用户说"对TOP N询盘"、"问一下供应商"、"询盘"、"帮我联系供应商"
- 用户指定供应商序号或全部
**执行流程**:
1. **确认询盘对象和问题**:
- 用户指定序号 → 对应 TOP10 中的商品
- 用户说"全部" → 对所有未询盘的供应商执行
- 用户未指定问题 → 使用通用模板
2. **调用 inquiry-1688 发起询盘**:
```python
import json, os, subprocess
def submit_inquiry(url, question):
with open(os.path.expanduser("~/.openclaw/openclaw.json")) as f:
cfg = json.load(f)["skills"]["entries"]["search-1688-supplier"]["env"]
env = os.environ.copy()
env["ALPHASHOP_ACCESS_KEY"] = cfg["ALPHASHOP_ACCESS_KEY"]
env["ALPHASHOP_SECRET_KEY"] = cfg["ALPHASHOP_SECRET_KEY"]
inquiry_dir = os.path.expanduser("~/.hermes/skills/inquiry-1688")
result = subprocess.run(
["/usr/bin/python3", "scripts/inquiry.py", "submit", url, question],
env=env, cwd=inquiry_dir, capture_output=True, text=True
)
if "FAIL_ACCOUNT_POINT_NOT_ENOUGH" in result.stdout:
return {"error": "积分不足", "url": "https://www.alphashop.cn/seller-center/home/api-list"}
if result.returncode == 0:
return {"status": "submitted", "output": result.stdout}
return {"error": result.stderr or result.stdout}
```
3. **询盘结果记录**:
- 成功 → 记录 taskId,标记"已询盘"
- 积分不足 → 立即停止,告知用户充值
- 失败 → 记录原因,继续下一个
**常用主动询盘模板**:
| 场景 | 问题模板 |
|------|---------|
| **跨境代发** | `你好,我们是跨境电商卖家,想咨询:1. 这款产品的批发价是多少?量大有优惠吗?2. 是否支持一件代发?代发包邮吗?3. 最小起订量(MOQ)是多少?4. 能贴我们自己的品牌LOGO吗?` |
| **OEM定制** | `你好,想咨询OEM合作:1. 是否支持ODM/OEM定制?2. 能否按我们的设计图生产?3. 打样费和周期是多少?4. 有没有FCC/CE/MSDS等认证?` |
| **价格谈判** | `你好,对这款产品很感兴趣:1. 目前批发价是多少?100/500/1000件分别什么价?2. 是否含税含运费?3. 付款方式有哪些?4. 交货周期多长?` |
**输出格式**:
```
### 📞 询盘结果
| 序号 | 供应商 | 商品 | 状态 | TaskId |
|------|--------|------|------|--------|
| 1 | 中山市乐发家用电器有限公司 | 超声波电动牙刷 | ✅ 已提交 | kj-xxxxx |
| 2 | 东莞市东城慕尚居服装厂 | 声波充电式牙刷 | ⚠️ 积分不足 | - |
```
### Step 4: 输出 TOP10 表格
直接输出 `markdown` 字段(CLI 命令返回的 Markdown 表格),Agent 分析追加在后面,不混入。
**表格必须包含**:商品名称、价格、供应商、销量、筛选条件(代发/包邮/发货)、商品链接。
**表格后追加筛选总结**:
```markdown
### 📋 筛选总结
- 一件代发确认 ✅:X 家
- 一件代发未知 ❓(已询盘):Y 家
- 包邮 ✅:X 家
- 48h发货确认 ✅:X 家
```
**表格不得省略行数**:返回多少条就展示多少条,不用"..."或"仅展示前 N 条"。
## Step 5: 用户问题驱动询盘(新功能)
**当用户提问中包含搜索结果没有的信息时,自动询盘补齐。**
### 触发条件
用户在提问时同时提到了信息需求,例如:
- "找同款供应商,问一下能不能贴牌"
- "搜同款,确认一下一件代发的价格"
- "帮我找这个产品的供应商,问问有没有CE认证"
### 执行流程
1. **解析用户问题中的信息需求**:
识别关键词,映射到询盘问题:
| 用户提到的关键词 | 询盘问题 |
|----------------|---------|
| 价格/多少钱/批发价 | 这款产品的批发价是多少?量大有优惠吗?100/500/1000件分别什么价? |
| 代发/一件代发 | 是否支持一件代发?代发包邮吗? |
| MOQ/起订量/最小起订 | 最小起订量(MOQ)是多少? |
| 贴牌/定制/LOGO/OEM/ODM | 能否贴牌/定制LOGO?支持OEM/ODM吗? |
| 认证/CE/FCC/MSDS | 产品有哪些认证?能提供CE/FCC/MSDS等证书吗? |
| 发货/交期/多久发货 | 下单后多久可以发货?支持48小时发货吗? |
| 样品/打样 | 可以寄样品吗?打样费和周期是多少? |
| 包邮/运费 | 是否包邮?运费怎么算? |
| 退换/售后 | 支持退换货吗?退换政策是什么? |
2. **自动询盘**:
对 TOP10 中**未确认**对应信息的供应商,自动发起询盘:
```python
# 示例:用户问"找同款,问能不能贴牌"
# 自动拼接询盘问题:
question = "你好,想确认:\n1. 能否贴牌/定制LOGO?支持OEM/ODM吗?"
```
3. **合并已有信息**:
如果搜索结果中已有部分信息(如价格),询盘时只问**缺失**的部分,避免重复提问。
### 询盘问题智能拼接
```python
def build_inquiry_from_user_question(user_question, product_info):
"""
从用户问题中提取信息需求,拼接询盘问题
product_info: 搜索结果中已有的信息
"""
keyword_mapping = {
'价格|多少钱|批发价': '这款产品的批发价是多少?量大有优惠吗?',
'代发|一件代发': '是否支持一件代发?代发包邮吗?',
'MOQ|起订量|最小起订': '最小起订量(MOQ)是多少?',
'贴牌|定制|LOGO|OEM|ODM': '能否贴牌/定制LOGO?支持OEM/ODM吗?',
'认证|CE|FCC|MSDS': '产品有哪些认证?能提供相关证书吗?',
'发货|交期|多久': '下单后多久可以发货?',
'样品|打样': '可以寄样品吗?打样费和周期?',
'包邮|运费': '是否包邮?运费怎么算?',
'退换|售后': '支持退换货吗?退换政策是什么?',
}
questions = []
for pattern, question in keyword_mapping.items():
import re
if re.search(pattern, user_question):
# 检查 product_info 中是否已有该信息
if not has_info_in_result(pattern, product_info):
questions.append(question)
if questions:
return "你好,想确认几个问题:\n" + "\n".join(f"{i+1}. {q}" for i, q in enumerate(questions))
return None
```
### 输出示例
```
### 📞 自动询盘(基于您的问题)
您问了"找同款,问能不能贴牌",已对以下供应商发起询盘:
| 序号 | 供应商 | 询盘问题 | 状态 |
|------|--------|---------|------|
| 1 | 中山市乐发家用电器有限公司 | 能否贴牌/定制LOGO? | ✅ 已提交 |
| 2 | 东莞市东城慕尚居服装厂 | 能否贴牌/定制LOGO? | ✅ 已提交 |
```
---
## 完整执行流程
```bash
# Step 1: 以图搜款(默认 high)
cd ~/.hermes/skills/1688-product-find
/usr/bin/python3 cli.py image_search --image "/path/to/product.jpg" --limit 20 --sort sold_desc
# 如果 0 结果,用 medium 重试
/usr/bin/python3 cli.py image_search --image "/path/to/product.jpg" --limit 20 --sort sold_desc --score-level medium
# Step 3: 对筛选条件为 ❓ 的商品,发起询盘
cd ~/.hermes/skills/inquiry-1688
ALPHASHOP_ACCESS_KEY="xxx" ALPHASHOP_SECRET_KEY="yyy" \
python3 scripts/inquiry.py submit "https://detail.1688.com/offer/xxx.html" "1. 是否支持一件代发?2. 下单后多久发货?3. MOQ多少?"
# Step 4: 用户指定供应商主动询盘(凭证同上)
ALPHASHOP_ACCESS_KEY="xxx" ALPHASHOP_SECRET_KEY="yyy" \
python3 scripts/inquiry.py submit "https://detail.1688.com/offer/xxx.html" "你好,我们是跨境电商卖家,想咨询:1. 批发价多少?量大有优惠吗?2. 支持一件代发吗?3. MOQ多少?4. 能贴牌吗?"
```
**⚠️ 凭证必须从 config 读取后通过环境变量传入**(inquiry.py 不会自动读取 config):
```python
import json, os
with open(os.path.expanduser("~/.openclaw/openclaw.json")) as f:
cfg = json.load(f)["skills"]["entries"]["search-1688-supplier"]["env"]
os.environ["ALPHASHOP_ACCESS_KEY"] = cfg["ALPHASHOP_ACCESS_KEY"]
os.environ["ALPHASHOP_SECRET_KEY"] = cfg["ALPHASHOP_SECRET_KEY"]
```
## 依赖技能
| 技能 | 用途 |
|------|------|
| `1688-product-find` | 以图搜款(image_search) |
| `inquiry-1688` | 筛选条件未知时询盘确认 + 用户指定供应商主动询盘 |
**inquiry-1688 凭证**:AlphaShop (ALPHASHOP_ACCESS_KEY / ALPHASHOP_SECRET_KEY),存储在 `~/.openclaw/openclaw.json` → `skills.entries.search-1688-supplier.env`。**必须通过环境变量传入**,不传会静默失败(stdout 为空)。
## 已知陷阱
- **Python 环境**:始终用 `/usr/bin/python3`,不用 `python3`
- **设计图 0 结果**:先 `high` 再 `medium`,不直接放弃
- **飞书图片缓存**:图片路径可能对应旧图,搜完后检查第一条商品标题是否与产品类型一致
- **1688 全站需登录**:浏览器不可用,所有搜索必须通过 CLI + API 完成
- **trade_seller 不是工厂**:`supplier` 字段多是贸易商,找工厂请用 `1688-scout-inquiry-report`
- **询盘积分限制**:inquiry-1688 API 返回 `FAIL_ACCOUNT_POINT_NOT_ENOUGH` 时停止,告知用户充值
## 常用搜索词示例
### 电动牙刷类
- 核心词:`悬浮声波电动牙刷` `变频声波电动牙刷` `声波电动牙刷 6档模式`
- 属性词:`白色粉色电动牙刷 哑光轻奢` `多模式电动牙刷 护龈美白`
- 场景词:`声波电动牙刷 变频马达 家用敏感牙适配`
- 供应链词:`一件代发 电动牙刷 悬浮声波技术` `工厂直供 变频电动牙刷`
### 宠物用品类
- 猫砂:`猫砂 豆腐猫砂` `豆腐猫砂 OEM` `猫砂 工厂`
- 狗粮:`狗粮 幼犬粮` `成犬粮 天然粮`
- 玩具:`狗玩具 耐咬` `猫玩具 益智`
### 通用供应链关键词
- `一件代发 {产品}` `跨境 {产品}` `{产品} 工厂` `{产品} OEM`
## 更新日志
- v1.3.0 (2026-05-19): 新增用户问题驱动询盘功能——用户提问中包含搜索结果没有的信息时自动询盘补齐
- v1.2.0 (2026-05-19): 新增常用搜索词示例(电动牙刷/宠物用品);补充 image_search medium 重试说明
- v1.1.0 (2026-05-19): 新增多条件筛选(代发/包邮/起批量/发货时效/退货保障)+ 未知条件自动询盘确认
- v1.0.0 (2026-05-19): 初始版本,基于悬浮声波电动牙刷搜索案例
don't have the plugin yet? install it then click "run inline in claude" again.