Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/halojerry/pounding --skill pounding-ozon-assistant명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SKILL.md 표시 중
| name | pounding-ozon-assistant |
| description | 1688 → Ozon 全链路。跟卖、新上架、变体合并、翻新、选品找货源、制图。 |
每个 Worker 对应不同的云端 webhook,不要混用:
| Worker | 业务 | Webhook 路径 | 说明 |
|---|---|---|---|
| A | 1688→Ozon 新上架 | pl-v3-304140 | 完整 8 阶段管线(类目→属性→制图→上传) |
| B | Ozon 跟卖 | fs-v4-303992 | import-by-sku |
| C | Ozon 翻新 | re-v2-304020 + mx-bp2-377417 | Ozon update + 制图 |
| D | 多SKU变体 | v2-ingest-292201 + pl-v3-304140 + mx-bp2-377417 | 类目匹配 + 管线 + 制图 |
| E | 智能选品 | 无(本地搜索后进入 Worker A) | 1688 搜索 → 用户选品 → Worker A |
接口稳定约定:云端更新工作流内部逻辑时,webhook 路径和信封格式保持不变,Skills 无需修改即可吃到更新。
| 凭据 | 层级 | 来源 | Worker 需要 |
|---|---|---|---|
MXOU_TOKEN | 分发级 | ~/.pounding/config.json → api.key(云端鉴权) | A, B, C, D |
MXOU_IMAGE_TOKEN | 分发级 | ~/.pounding/config.json → api.key(制图,同 key) | A, B, C, D |
ALI_1688_AK | 用户级 | .env 或环境变量 | A, B |
OZON_CLIENT_ID | 用户级 | .env 或环境变量 | A, B, C, D |
OZON_API_KEY | 用户级 | .env 或环境变量 | A, B, C, D |
MXOU_TOKEN、MXOU_IMAGE_TOKEN)都来自 ~/.pounding/config.json 的 api.key——制图和鉴权用同一个 mxou API key,随 Skill 分发给用户,绝不写入 .env。ALI_1688_AK、OZON_CLIENT_ID、OZON_API_KEY)由 AI 助手写入 .env 持久化,下次对话自动加载。.env → 告知"已保存到 .env ✅"。check_config() 列出缺失和已配置项。1688 API 返回文字属性但不返回图片URL、重量、尺寸。用 enrich_product_with_cdp() 补齐——一个函数搞定所有场景(没装 Chrome、没登录、探针失败),绝不崩溃:
from scripts.lib.ak_1688_client import enrich_product_with_cdp
enriched = enrich_product_with_cdp(detail_url=item['detailUrl'], api_data=d)
# 返回 {ok, degraded, degraded_reason, user_action, data: {images, weight_grams, ...}}
# data 永远不为空——degraded 时 images/weight_grams 为空列表/None
# user_action 不为 None 时直接告诉用户那句话即可
必须按返回值类型调用,不要自己猜测嵌套结构!
| 函数 | 模块 | 返回值 | 关键字段 |
|---|---|---|---|
check_config() | config_store | dict | missing: list, present: list, by_tier: dict |
search_products(query, page_size=N) | ak_1688_client | list[dict] ← 直接是列表! | 每个元素: title, price, itemId, detailUrl |
get_product_details(item_ids) | ak_1688_client | dict[str, dict] | {item_id: {title, price, categories, sku_attributes, all_info}} |
search_categories_locally(query, ...) | cloud_client | list[dict] | 每个元素: description_category_id, type_id, category_name, type_name, score |
build_envelope(...) | cloud_client | dict | version, project_id, source, assets, draft, extensions |
submit_envelope(envelope) | cloud_client | dict | task_id, status, category_resolution |
submit_task(envelope) | cloud_client | dict | task_id, status, stages, final_summary |
generate_product_images(token, ...) | cloud_client | dict | {slot: url} |
follow_sell_cloud(sku=..., ...) | cloud_client | dict |
示例 — 用 search_products 正确遍历结果:
items = search_products("保温杯", page_size=5) # 返回 list
for item in items[:3]:
print(f"¥{item.get('price')} {item.get('title')[:50]}")
不要写成 results.get('data', {}).get('result', {}).get('resultList', []) — search_products 返回的已经是列表!
严禁自己拼 webhook URL — 所有云端调用必须通过 cloud_client.py 的函数。URL 路径由 path_registry.json 管理,自己拼的 URL 会错(如旧版 typo mx-bp2-417417 → 正确是 mx-bp2-377417)。制图用 generate_product_images(token),不要自己发 HTTP 请求。
probe_1688_page(url) 一次调用获取全部数据(标题、价格、图片URL、重量、尺寸、SKU、包装信息都在一次页面探针中提取)。
probe_1688_page(),拿到结果直接用generate_product_images(token) 生成的 10 张图 URL 保存在云端任务记录(按 task_id 查询),用户随时可查看。
用户想看之前的图:查任务结果 → result_json.images → 展示给用户。
用户想重新生成某一张(如 main_image 不好看):
# 单张重生 — 直接调 image_gen webhook
token = _get_token()
body = {"slot": "main_image", "prompt": "新的提示词...", "token": token,
"model": "gpt-image-2", "aspect_ratio": "1024x1024"}
resp = requests.post(f"{CLOUD_API_BASE}/webhook/mx-bp2-377417", json=body)
# → {"slot": "main_image", "ok": true, "url": "https://..."}
定价由云端管线计算,计算前必须先获取用户店铺的实际物流渠道——不同用户用不同物流商(RETS/OYX/CEL/...),用错了白算。
完整流程:
# 1. 先获取用户 Ozon 店铺的仓库和物流方式
ozon_client_id = "用户OzonClientID"
ozon_api_key = "用户OzonApiKey"
delivery_methods = requests.post(
"https://api-seller.ozon.ru/v2/delivery-method/list",
headers={"Client-Id": ozon_client_id, "Api-Key": ozon_api_key},
json={"filter": {"status": "ACTIVE"}}
).json()
# 2. 从物流方式中提取 provider(如 RETS、OYX、CEL)
provider = delivery_methods["result"][0]["warehouse_name"] # 或从 provider 字段提取
# 3. 用正确的 provider 计算价格
resp = requests.post(f"{base}/webhook/pricing-v1", json={
"cost_cny": 1688采购价,
"weight_g": 350,
"depth_mm": 70, "width_mm": 70, "height_mm": 240,
"provider": provider, # ← 用户实际的物流商
"service": "Express", # 服务等级
"margin_rate": 0.25,
})
单独请求定价(不上架,只算价):POST /pricing-v1
用户可自定义参数通过请求传入:
{
"cost_cny": 50,
"weight_g": 350,
"provider": "RETS",
"service": "Express",
"margin_rate": 0.25,
"commission_rate": 0.1,
"fx_buffer": 0.05
}
不传 provider → 返回错误提示:必须提供物流商,不能默认。
build_envelope() 需要这两个参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
project_id | "default" | 项目标识,一般用固定值 "default" |
subproject_id | 1688 商品 ID | 子项目标识,用 1688 的 itemId 或 offerId |
envelope = build_envelope(
project_id="default", # 固定用 "default"
subproject_id=item_id, # 1688 商品 ID
source={...}, assets={...}, draft={...}
)
| # | 动作 | 函数 | 对用户说 |
|---|---|---|---|
| 1 | 检查配置 | check_config() | 全部就绪→(静默);有缺失→按 AGENTS.md「首次配置引导」逐个问答填 .env |
| 2 | 获取 1688 详情 | API prod_detail + CDP probe_1688_page() | "正在获取 1688 商品详情..." → "已获取详情({N}张图,{M}个SKU)" |
| 3 | 类目匹配 | 本地主导:先 property/lookup → 云端查缓存;没命中 → 本地 search_categories_locally() → Ozon API 搜索;用户选 → property/confirm → 云端保存。无论命中与否,数据都由本地传给云端。越用越快。 | 命中:"已匹配类目:{类目名}(置信度 {X}%)";未命中:列候选让用户选 → "已确认类目:{类目名},已记录到云端 ✅" |
| 4 | 构建信封 + 提交 | build_envelope() → submit_task(envelope) | "已提交任务 {task_id},云端后台处理中 ⏳ 通常 3-9 分钟完成,我会自动查进度" |
| 5 | 轮询进度 | 每 30 秒查一次 gateway_tasks,直到 terminal=true | 进度更新 → 最终汇报 |
重要:
submit_envelope()走v2-ingest-292201— 只用于类目匹配(property/lookup+confirm)。上架提交必须用submit_task()走pl-v3-304140管线。 异步处理:管线提交后立即返回(~3秒),Agent 通过轮询gateway_tasks查进度,不用傻等。 Ozon API 版本:类目接口用/v1/description-category/tree(不是 v2)。用search_categories_locally()封装好的函数即可(Ozon API 已内联到ozon_api.py,不需要额外 pip 安装)。
Step 4 提交后如果返回
_next_action: "category_matching_required":说明类目还没匹配。自动执行类目匹配(property/lookup → search_categories_locally → 用户选 → property/confirm),匹配完重新提交信封。
| # | 动作 | 函数 | 对用户说 |
|---|---|---|---|
| 1 | 检查配置 | check_config() | (静默,失败时:"缺少配置:{keys}") |
| 2 | 解析 Ozon 商品 | analyze_ozon_product(url) | "正在分析 Ozon 商品..." → "已解析:{product_name}" |
| 3 | CDP 收集原图 | CDP 打开 Ozon 页 | "正在收集商品图片..." |
| 4 | 1688 找同款 | search_products() → 比价 → 问用户 | "找到 {N} 个同款,比价:\n1. ¥{X} ...\n跟卖还是新建?" |
| 5 | 跟卖 | follow_sell_cloud(sku=product_id) | "正在跟卖..." |
| 6 | 制图 → 写入 Ozon | 同 Worker A Step 7-8 | 同 Worker A |
如果复制被拒(fallback_new_product)→ 走 Worker A Step 2-9。
| # | 动作 | 函数 | 对用户说 |
|---|---|---|---|
| 1 | 获取现存产品 | list_product_infos(product_ids=[...]) | "正在获取产品信息..." |
| 2 | 制图 | generate_product_images(token) | "制图中..." |
| 3 | 写入 Ozon | update_followed_product | "正在更新到 Ozon..." |
| # | 动作 | 函数 | 对用户说 |
|---|---|---|---|
| 1 | 构建变体信封 | build_variant_envelope(variants=[...]) | (静默) |
| 2 | 提交 | submit_envelope → submit_task | "已提交变体任务" |
| 3 | 制图 → 更新 | generate_product_images → update | "制图并更新中..." |
触发条件:用户没有指定 1688 商品链接,说"帮我上架蓝海产品/有利润的产品/好卖的产品"
| # | 动作 | 函数 | 对用户说 |
|---|---|---|---|
| 1 | 确认偏好 | 问用户或查店铺 | "好的,帮你找{蓝海/有利润}的产品 ⏳ 先确认——你店铺主要做哪个类目?还是我帮你看看店铺现有品类分布?" |
| 2 | 分析店铺 | ozon_client.list_products() | "正在分析你 Ozon 店铺的品类分布..." |
| 3 | 1688 选品 | 1688-shopkeeper trend/opportunities 或 search_products() | "正在 1688 搜索{类目}热销品..." |
| 4 | 利润/蓝海分析 | 1688 价格 vs Ozon 售价对比 | "正在计算预估利润..." → 过滤低利润/高竞争品 |
| 5 | 呈现候选 | — | "帮你筛选了 {N} 个候选(按利润率排序):\n1. {商品名} — 成本 ¥{X} Ozon 约 ₽{Y} 利润率 ~{Z}% 竞争{低/中/高}\n2. ...\n\n选哪个?或'全上'" |
| 6 | 进入 Worker A | 用户选定后 | "收到,开始上架【{商品名}】⏳" → 进入 Worker A Step 2 |
降级方案:如果 1688-shopkeeper trend/opportunities 不可用 → 让用户指定类目关键词 → 1688 search → 人工筛选 → 呈现候选。
| status | 对用户说 |
|---|---|
accepted | "已提交,云端处理中({task_id})" |
succeeded | "✅ 上架成功!Ozon 任务 ID: {ozon_task_id}" |
blocked | "⛔ 被阻断:{原因}。{建议}" |
failed | "❌ 失败了:{错误}。可以重试或检查配置" |
partial_failed | "⚠️ 部分完成:{详情}" |
跟卖: copy_and_update → "跟卖成功 ✅" | fallback_new_product → "禁止复制,走新建上架"
path, ozon_task_id |
list_product_infos(...) | cloud_client | list[dict] | 每个元素: product_id, name, offer_id, price |
3D Morph PPT — extends morph-ppt with GLB model insertion, cinematographic camera, model-content layout, and enriched visual design system.
Use this skill when the user wants a .pptx with smooth cross-slide animation — PowerPoint Morph transitions, Keynote-style continuous motion, shapes that grow / move / rotate as the slide advances. Trigger on: 'morph', 'morph transition', 'smooth transition', 'continuous animation across slides', 'Keynote-style transition', 'animated slide sequence', 'shape continuity across slides'. Output is a single .pptx. This skill is a scene layer on top of officecli-pptx — inherits every pptx v2 rule (visual floor, grid, palettes, connector canon, Delivery Gate 1–5a). DO NOT invoke for a generic deck, pitch deck, or board review without cross-slide motion — route those to officecli-pptx base or officecli-pitch-deck.
Use this skill to build academic-style .docx output: journal / conference / thesis chapters carrying formal citation style (APA, Chicago, IEEE, MLA), numbered equations, figure & table cross-references, footnotes/endnotes, bibliography, or multi-column journal layout. Trigger on: 'research paper', 'journal paper', 'conference paper', 'manuscript', 'thesis', 'APA', 'MLA', 'Chicago', 'IEEE two-column', 'bibliography', 'hanging indent', 'citation style', 'abstract + keywords', 'equation numbering', 'cross-reference', paper with footnotes/endnotes. Output is a single .docx.
SOC 직업 분류 기준