> 作者 @zzzzzzzp(立意 · 判据 · 取舍) · 协作 多多 · AI 助手(检索 · 编码 · 核查)
> 版权 著作权归 @zzzzzzzp 所有(All Rights Reserved) · 版本 v1.4.0
万象-图片精修去水印
对已有图片做五件事:去文字水印、增强清晰、人像美化、老照修复、抠图去背。
- 做什么:先判该走哪一操作,再按输入纪律处理,输出干净可用图。
- 何时用:手上有一张已有图片要加工,而不是要重新生成一张时。
- 不做什么:不做整图重绘;不处理来源不明的版权素材。
数据边界与外部连接(必读)
- 文档处理全在本机:所有读写只发生在你显式指定的文件上。
- 不采集、不上传用户的任何内容;不扫描目录、不常驻后台、不联网轮询。
- 唯一的外部连接:技能自带的按量付费组件(
a2m/)会与支付宝发生支付校验与履约回执,
该链路只传订单号与金额,不含你的文件内容;本地服务仅监听127.0.0.1。 - 凭据:作服务端使用时,商户私钥从你的本机环境变量读取,不落盘、不进包。
- 回流组件默认未启用:包内不含任何收件地址,也不自动注册任何钩子;是否启用完全由你决定。
何时用
- 用户给了一张已有图片,要在它上面做加工(不是重新生成一张)。
- 五类诉求之一:去文字/水印、增强、人像、修复、抠图。
不适用:让模型凭空生成一张图(→ 图像生成);做视频(→ 视频工具);3D 模型或模板特效(→ 万象-3D模型生成与特效)。
§0 三条铁律
- 一次只选一个操作。 五个操作各对应固定的服务模型,不得改写映射,也不要一次串两个(「先抠图再美化」= 两次独立任务,分步做)。
- 绝不自动重试。 提交失败不重跑;拿到任务号之后只查原任务。一个任务被提交两次就是两个任务,可能双倍计费、也可能拿到两份不一致的结果。
- 不许伪造。 失败就返回真实错误;不得编造结果地址、不得用旧图顶替。产物必须落到本地再展示。
§1 五操作选型(先判走哪个)
| 诉求 | 操作 | 典型场景 |
|---|---|---|
| 去水印 / 去台标 / 去字幕 / 去印章 / 去旧文字 | erase |
素材清理、去渠道标记 |
| 提分辨率 / 去噪 / 去模糊 / 锐化 / 暗光提亮 | enhance |
低位图救急、翻拍优化 |
| 磨皮 / 祛瑕疵 / 匀肤 / 瘦脸 / 五官微调 | beauty |
证件照、商务形象、写真 |
| 老照片 / 划痕 / 折痕 / 霉斑 / 褪色 / 破损补全 | restore |
家族老照片、档案照 |
| 前景提取 / 透明底 / 抠人抠物 | matting |
合成素材、商品图 |
> 🔴 matting 只给「前景 + 透明底」。 要白底、彩色底、或换背景,必须再做一步合成。把 matting 说成「换背景已完成」是内容错 —— 用户拿到的是透明底,不是他要的底。
§2 输入纪律
- 输入三选一:本地文件 / 可访问的 HTTP(S) 地址 / 已是小体积的 base64。本地图优先用文件方式。
- 不要把本地图转成 base64 塞进对话或命令行 —— 会撑爆上下文与命令行长度;也不要写包装脚本绕开长度限制。
- base64 只用于本来就小的值;大体积 base64 不得打印到对话或日志。
- 体积门槛:本地文件或解码后的图必须非空且小于 4 MB。超了先压缩或换文件方式(这一步要问用户,不要擅自压掉画质)。
- 不要替用户扩写指令:用户给的加工要求原样透传;想补细节先问。
§3 执行流程(顺序固定)
- 每次任务前取一次凭证(连接类工具)→ 只取本次任务需要的那个临时令牌字段;字段缺失就停,不要退化成别的凭证。
- 跑一次图像编辑(脚本内部默认轮询:每 5 秒一次、最长 600 秒)。
- 超时且已返回任务号 → 只用「查询」动作查该任务。
- 读结果的本地路径字段(脚本已把产物存到本地)。
- 用展示动作把每份产物显示出来,并把完整路径回报给用户。
凭证纪律:不展示、不解释、不缓存、不复用;不得退回到长期密钥等其他凭证形态。
§4 超时与重试(照抄这张表,别自创)
| 情形 | 正确动作 |
|---|---|
| 提交后脚本仍在轮询 | 等着,不要在外面加等待循环 |
| 命令超时且已拿到任务号 | 只查原任务;必要时重新取凭证,但不重新提交 |
| 命令超时且没拿到任务号 | 报 SUBMISSION_STATUS_UNKNOWN,如实告知用户状态未知 |
| 查询显示还在处理 | 继续查该任务 |
| 真的失败了 | 把清洗过的真实错误给用户,不编造结果或路径 |
⚠️ 禁止用外部「等待 N 秒再跑一次」的循环去重跑提交 —— 每次调用都会新建任务。
§5 越界分流(这类请求不归本技能)
| 用户其实想要 | 正确去处 |
|---|---|
| 文生图、图生图创作、风格迁移 | 图像生成 |
| 3D 模型、基于模板的图片转视频特效 | 万象-3D模型生成与特效 |
| 一般文生视频 / 图生视频 | 视频工具 |
| 只是看图(识别内容、读图里的字) | 视觉理解(不是本技能) |
§6 本机实测坑
- 运行环境缺失就停,不要自动装运行时;
python3不可用时试python,都不行就停下问用户。 - 不要猜安装目录、不要手拼安装包内部路径 —— 用技能目录下的脚本路径写法。
- 批量处理要显式说清语义:是逐张独立处理,还是要求风格一致?要求一致时逐张独立跑会得到不一致的结果。
- 抠图结果先看透明通道:拿到图先确认是透明底还是被填了白,别把白底当作透明底交付。
- 产物要落到工作区内并有明确文件名,不要只给一个临时目录路径。
§7 能力边界与反例
能做:五操作选型、输入形态选择与体积把关、执行与轮询纪律、越界分流、失败如实上报。
不做:
| 反例 | 正确去处 |
|---|---|
| 让本技能「生成」一张不存在的图 | 图像生成 |
| 把本地图转 base64 塞进对话 | 用文件方式 |
| 提交失败后自动重跑 | 禁止;只查原任务 |
把 matting 说成完成了换背景 |
需再合成一步 |
| 编造一个产物地址让交付看起来成功 | 禁止;如实报错 |
§8 输入形态纪律(2026-09-21 吸收自平台件的判定条目)
> 来源:平台内置的图片处理件。只取操作判据,不引其正文。
- 本地图片优先走「文件路径」传参,绝不把本地图转成 Base64 再传 —— 对话里贴长串 Base64 既不可读,也容易被截断。
- Base64 传参只用于「输入本来就是一段小 Base64」的场景;不要把大 payload 打进对话或日志。
- 输入必须非空且小于 4 MB(本地文件或解码后的图)。
- 每个操作对应固定的服务模型,不要自己改映射。
- 抠图只给透明底前景。 要白底 / 彩底 / 替换背景,那是另一步合成,不能说抠图本身已经把这件事做完了。
- 失败时返回真实错误,不要编造结果或文件路径。
常见误用与常见问题(FAQ)
常见误用(反模式)
| 误用 | 后果 | 正解 |
|---|---|---|
| 一次串两个操作(「先抠图再美化」) | 映射错乱 | 一次只选一个操作;五个操作各对应固定服务模型,不得改写映射;串两个 = 两次独立任务,分步做 |
| 失败时编造结果或文件路径 | 伪造 | 不许伪造 —— 失败就返回真实错误;不得编造结果地址、不得用旧图顶替;产物必须落到本地再展示 |
| 把本地图转成 base64 塞进对话或命令行 | 撑爆上下文与命令行长度 | 不要 base64;也不要写包装脚本绕开长度限制 |
| 用大体积 base64 传参 | 污染对话与日志 | base64 只用于本来就小的值;大体积 base64 不得打印到对话或日志 |
| 提交失败后自动重跑 | 可能重复生成/重复计费 | 禁止;只查原任务 |
| 自己改「操作 ↔ 服务模型」的映射 | 结果错 | 每个操作对应固定的服务模型,不要自己改映射 |
| 替用户扩写加工指令 | 偏离用户意图 | 原样透传;想补细节先问 |
| 体积超 4 MB 就擅自压缩 | 画质被牺牲 | 本地文件或解码后的图必须非空且 < 4 MB;超了先压缩或换文件方式(这一步要问用户) |
| 结果只给一个临时目录路径 | 用户找不到 | 产物要落到工作区内并有明确文件名 |
| 退回到长期密钥等其他凭证形态 | 违反凭证纪律 | 凭证不展示、不解释、不缓存、不复用;字段缺失就停 |
| 猜安装目录、手拼安装包内部路径 | 路径不存在 | 用技能目录下的脚本路径写法 |
| 运行环境缺失就自动装运行时 | 越界 | 运行环境缺失就停;python3 不可用试 python,都不行就停下问用户 |
常见问题
- Q:五个操作怎么选? A:见「§1 五操作选型(先判走哪个)」—— 去文字与水印/增强锐化去噪去模糊提亮/人像美化/老照与破损修复/抠图去背。
- Q:执行顺序可以调吗? A:顺序固定,见「§3 执行流程(顺序固定)」。
- Q:超时和重试怎么定? A:照抄「§4 超时与重试」这张表,别自创。
- Q:哪些请求不归本技能? A:见「§5 越界分流」。
- Q:输入有什么纪律? A:见「§2 输入纪律」与「§8 输入形态纪律」。
附 · 来源交代
| 项 | 说明 |
|---|---|
| 版本 | 1.0.0 |
| 建立日期 | 2026-09-19 |
| 来源 | 自研(origin: own)。建立动机:平台内置的图片处理系统件覆盖了本域的操作面,但①为版本目录结构、随平台升级整体替换,本机经验无处沉淀;②操作选型与「抠图不等于换背景」这类界内反例没有集中落点。故按功能域自研一部,只吸收操作类别、参数边界与执行纪律,不复制其文本;§6 本机实测坑、§7 反例表为自有增量。 |
| 与系统件的关系 | 并存,不替换。系统件仍负责实际的服务调用;本技能负责选型判据与交付纪律。 |
| 著作权 | 署名 zzzzzzzp,All Rights Reserved |
附 · 付费与授权
§〇 · 本技能定位为付费技能(Pay Skill)
| 项 | 内容 |
|---|---|
| 定位 | 付费版(Pay Skill 通道) |
| 计费形态 | 按次 |
| 已接入的服务 | serviceId API_13DCD6D650224B51 | 服务地址 https://wb-workbase.app.workbuddy.host/demo/a2m/resource(无凭证时返回 402 + Payment-Needed 账单)| 单价 0.25 元/次 |
| 🔴 单价须与注册价一致 | 平台明确警告:实际支付价与注册标价不一致会导致用户无法支付 ⇒ 向导里单价填 0.25,不要凭手感改 |
| 这条服务是复用的 | 服务名称是通用的「万象skill」,属同一作者、同一 appId ⇒ 与「万象-支付宝AI付接入」「万象-SkillHub自动上架」共用同一条已注册服务,不另注册 |
| 标识 | 付费技能加一道金色光圈(GOLD = #C8A02C)—— 判据=该技能被调用时按次收费 |
> 🔴 付费技能一律走完整付费路径 —— 是付费定位,就照着付费通道做完:
> 随包实现 402 链路(见 §〇·2)、接入相应服务、按注册价填单价、走 Pay Skill 向导。
> 不回头讨论「要不要改成免费」。若确实要转免费,改的是 万象标识体系/tools/gen_icons.py 的
> PAY_SKILLS 名单与本段声明(显式改动),不是偷偷少做一步。
§〇·2 · 随包提供的 402 付费链路实现(平台「付费改造」检测就看这个)
🔴 实测判据(平台原话):SkillHub 在提交时会做一次「支付宝付费改造」检测,
判据是技能包内是否存在 402 支付链路的实现,缺失项会被逐条列出:
> 「缺失项:402账单下发 / 携带凭证重试 / 验付调用 / 履约确认 / 订单持久化与幂等」
> 「该检查不阻断提交。提交后平台审核仍会重新做一次完整检测,若不合规将被拒绝。」
⇒ 本包自带该实现(目录 a2m/,零密钥、可直接 npm install && npm start):
| 平台检测项 | 本包对应实现 | 位置 |
|---|---|---|
| 402 账单下发 | 无凭证 ⇒ HTTP 402 + Payment-Needed(Base64URL 账单,商户本地 RSA2 签名) |
a2m/a2m.js buildPaymentRequired();路由在 a2m/server.js |
| 携带凭证重试 | 解析 Payment-Proof 头并重放同一资源请求 |
a2m/a2m.js decodePaymentProof() |
| 验付调用 | 查询交易并逐项严格比对(trade_no / 金额 / 资源 ID / 订单状态与时效) | a2m/a2m.js verifyPayment() |
| 履约确认 | 交付后调履约确认;失败可重试且不重复生成资源 | a2m/a2m.js confirmFulfillment() |
| 订单持久化与幂等 | SQLite 事务 + 唯一约束(非内存订单);重复交付不重复扣费 | a2m/orderRepository.js prepareFulfillment() |
配置边界(有意为之,勿改成「能跑就行」):配置缺失即明确失败(资源路由返回 503),
不构造 SDK、不使用占位密钥、不提供任何跳过验付的路径。密钥只走运行环境变量或本地配置文件,永不入包。
cd a2m && npm install && npm run smoke # 冒烟:账单结构 / RSA2 签名 / 幂等边界
npm start # 默认 http://localhost:3000/demo/a2m/resource