CtrlK
BlogDocsLog inGet started
Tessl Logo

miloco-miot-pet-register

宠物成员注册主流程。**用户表达「登记/记住/让系统认识我家的猫/狗等宠物」意图就触发本 SKILL,不要求出现"注册/登记"字面词**——两条通路:①**描述它的样子**(纯文字,如"胖胖是我家橘猫,尾部有白毛、体型偏胖")→ 建花名册 + 写外观;②**发照片/视频** → 观察出多姿态候选参考图 + 共性外观 → 确认 → 落库(花名册 + 识别参照 + 外观)。也覆盖给存量宠物"补充素材"。**只用用户主动提供的信息**(文字或素材):宠物没有"陌生宠物池",不从摄像头挑、不模拟。纯改名 / 删宠物走 miloco-cli pet CRUD。

76

Quality

96%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Low

Low-risk findings worth noting

SKILL.md
Quality
Evals
Security

miloco-miot-pet-register

何时激活

用户意图 / 触发源用户说了类似…→ 通路
文字描述登记"登记下胖胖,我家橘猫,尾部白毛、偏胖"(无附件,但描述了样子)B 文字通路(第二步 2.1)
附素材登记"这是我家猫小黑"(附图/视频)/ "记住这只狗"(附图/视频)A 素材通路(第二步 2.2)
给存量宠物补充素材"给小黑再传几张"(附图/视频)A 素材通路 → 落库走 append(第五步 5.3)
只说登记、无描述无素材"帮我登记我家猫"(既没描述样子也没附素材)引导(第二步 2.4):给个描述 或 发素材
纯改名 / 删宠物"把小黑改名" / "删掉小黑"→ miloco-cli pet update/delete(非本 SKILL)

判断规则:用户想让系统记住/认识某只宠物(建身份 + 记外观) → 本 SKILL。只改花名册行(改名/删) → CRUD 命令。

总原则 · 只用用户主动提供的信息,不从摄像头挑

本 SKILL 靠用户主动给的文字描述或上传的素材建档。宠物没有"陌生宠物池"(系统不对宠物做 ReID/聚类,认不出的宠物只在实时描述里泛称"一只黑猫",不攒成"待认领候选")。所以:

  • ❌ 不实现、也不要用其他工具"模拟""从摄像头看到的宠物里挑一只建档"——这条通路不存在。
  • 用户若要"从画面里挑没登记的宠物" → 一句话告知暂不支持,引导改为"描述一下它的样子,或发张清晰照片/视频"。

这与人注册不同:人有"陌生人池"(摄像头累积未识别人可挑出建档),宠物没有对应基建。别把人的 pool fetch / 从摄像头挑那套套到宠物上。

前置 · 功能门(关闭时整个注册不可用)

宠物识别是实验性功能,总开关 pet_recognition 控制。关闭时,注册所有端点(建花名册 / 头像 / 参考图 / observe)一律返 404 → A 素材通路与 B 文字通路都走不了:

  • 用户想登记宠物却功能没开 → 引导去设置打开:"宠物识别功能没开,现在还没法给它建档——去设置里打开「宠物识别」,打开后我就能帮它建档、在画面里认出它。"
  • 别在关闭时假装建档 / 承诺"已记下";纯"家里有只狗"这类家庭事实由 miloco-home-profile skill 记录(与识别无关、不受此门控)。
  • 怎么判开关:miloco-cli config get features.pet_recognition --value-only(输出 True / False,与 miloco-home-profile 同口径)。注意 pet list 不受门控(关闭时也正常返回存量花名册),不能拿它的成功/失败反推开关状态。

核心工作流

5 步流水线(仿人注册;两条通路 A 素材 / B 文字,无陌生池):

  1. 解析触发源 — 宠物名 / 物种 / 外观描述 + 有无附件;是否"补充素材"
  2. 通路判定 — B 文字通路(有描述无素材)/ A 素材通路(有素材且功能开);都无 → 引导
  3. 首轮准备 — A:pet observe --save-crops 出候选参考图 + 共性外观;B:回显解析出的 名/物种/外观 请用户确认
  4. 等待用户回复 — 本轮不发中间消息
  5. 次轮落库 — 确认 → pet add(若新) + (A 才有)reference-crops + 写外观 + commit;取消 → 不落库

推荐路径

  • 首选发素材(推荐一段短视频,或 1~3 张、最好 3 张覆盖不同姿态/角度的照片):姿态越全,识别越准——不仅记外观,还能建识别参照让系统在画面里认出它。纯文字描述也能完成注册,只是没有识别参照(画面里认不出)——落库后提示用户"想让画面里认得出,再发张照片/视频"。

第一步 · 解析触发源

从用户话里抽:宠物名 name物种 species(猫/狗/其它)、外观描述(若有);并看有无图/视频附件。

  • "登记胖胖,橘猫,尾部白毛、偏胖" → name=胖胖, species=猫, 外观="橘猫,尾部有白毛,体型偏胖"(无附件 → B)
  • "这是我家金毛 Max"(附视频) → name=Max, species=狗(金毛=品种,归外观), 有素材 → A
  • "我家那条狗"(无名) → 追问真名("这只狗叫什么名字?我用它作标识")
  • 完整规则见 references/species-name-parsing.md

🚨 重名前置查重(拿到 name 后、observe / 落库之前必做):先 miloco-cli pet list 看该 name 是否已在花名册(后端按精确名判重,pet add 撞名直接 409)。按结果分流:

  • 名不存在 → 正常往下(A observe / B 回显)。
  • 名已存在 + 用户明确是"补充素材"("给小黑再传几张") → A 素材通路 + 落库走 append(第五步 5.3),复用已有 pet_id,无需再问。
  • 名已存在 + 用户是"注册/登记"意图(非明确补充)不要 observe、不要落库,本轮停下问用户三选一(第五步 5.5),按回复再走;严禁自作主张直接 append / 覆盖。

第二步 · 通路判定

收到用户消息:
  if pet_recognition 关(`config get features.pet_recognition --value-only` → `False`):
                                             → 引导去设置打开(见异常表),本轮结束;纯家庭事实交 miloco-home-profile
  elif 含图/视频附件:                         → 2.2 A 素材通路
  elif 有文字外观描述(无附件):               → 2.1 B 文字通路
  else:  # 既没描述也没素材                   → 2.4 引导:给描述 或 发素材,本轮结束等回复

2.1 B 文字通路(描述建档)

把第一步解析出的 名/物种/外观回显给用户确认(不擅自落库,分阶段):

用户: 登记下胖胖,我家橘猫,尾部有白毛、体型偏胖

Agent: 好的,登记这只:
       - 名字:胖胖  · 物种:猫
       - 外观:橘猫,尾部有白毛,体型偏胖
       确认入库?(想让系统在画面里也认出它,回头发张照片或短视频,我再建识别参照)

发完本轮终止等待;用户确认 → 第五步 5.2 落库。外观描述不足(只有名/物种)也可先建档,外观可空或提示补。

2.2 A 素材通路(素材建识别参照)

见第三步 observe;拿候选参考图 + 共性外观发用户确认。

2.4 无描述无素材 → 引导(复述已知信息、只补问缺的)

接住第一步已解析到的信息(物种 / 名字),只追问缺失项,别重复问用户已经说了的;两条方式都给出,但素材优先(效果最好),文字兜底。

已知物种(如已说"猫")、缺名字 + 外观:

用户: 我想登记下我家的猫

Agent: 好嘞,这只猫要登记(顺便告诉我它叫什么),两种方式(效果从好到省事):
       - **发一段短视频,或 1~3 张、最好 3 张照片**,尽量拍全不同姿态/角度——认得最准,还能建识别参照让画面里也认出它;
       - 或**只用文字描述它长什么样**(毛色花纹/体型/显著标记),我先建档,回头再补素材加识别参照。

啥都没说(如"帮我登记个宠物"):把物种也一起问("是猫、狗还是别的宠物,叫什么,什么样")。 发完本轮终止等待,用户补描述/素材后重进第一步。

第三步 · A 素材通路首轮(observe)

对上传的素材调 一次 pet observe,拿候选参考 crop + 共性外观描述。

🚨 <MediaPath> 用消息给的真实路径:即用户消息里 [media attached: <绝对路径>] / MediaPath(s) 提供的那个(通常形如 ~/.openclaw/workspace/media/inbound/openclaw-staged-…/….mp4)。绝不message_id(如 om_x100…)拼文件名、绝不/tmp/openclaw/media/inbound/… 之类路径。

单图 / 多图(≤3,单次批量)/ 视频(原文件,禁抽帧):

miloco-cli pet observe --image <MediaPath> --save-crops /tmp/<uuid>_pet --pretty
miloco-cli pet observe --images <p1> --images <p2> --images <p3> --save-crops /tmp/<uuid>_pet --pretty
miloco-cli pet observe --video <MediaPath.mp4> --save-crops /tmp/<uuid>_pet --pretty

返回字段:

  • detected — 是否检出猫/狗
  • description — 共性外观描述(物种 / 体型 / 毛色花纹 / 显著标记 / summary),即待落库的外观
  • crops_saved[{index, path, score, species_guess}]:每张候选参考 crop 的本地路径 + 绝对质量分(第五步喂 reference-crops --scores)。注意:这些是发给系统落库用的单张,不逐张发用户
  • montage_saved_to多姿态参考图横向拼成的一张图(后端统一高 384 等比缩放拼接);发用户看候选就发这一张,别把 crops_saved 逐张刷屏
  • avatar_saved_to — 默认头像本地路径(observe 已按头部框裁好;第五步喂 pet avatar 作注册默认头像)
  • candidates — 候选元数据(已清 base64)
  • warnings数组 [{type, level, message}](type 见下表,level 多为 warn,message 是人话);逐条转述给用户
  • refs_inconsistent顶层布尔字段:多图时 omni 疑似"不是同一只";同一件事也会在 warnings 里出现一条 type = refs_inconsistent——两处是同一个信号,跟住户只说一遍

本步硬约束:

  • ❌ 每轮 pet observe 恰调一次,不"再试 / 刷新一下"。结果不理想(检不到 / 大众脸)直接按结果发话让用户决定。
  • ❌ 视频禁客户端抽帧--image(丢多帧姿态,识别参照差);原文件交 --video,后端选帧。
  • ❌ 不给 CLI 加 | jq / | grep 管道(丢字段)。
  • 🚨 拼图用 message 工具发、只发图:候选图必须用 message(action=send, media=montage_saved_to) 显式上传(飞书 DM MEDIA: 内联标记不渲染);发 montage_saved_to 这一张(多姿态已横向拼好),不逐张发 crops_saved(刷屏),无 montage 才退单张。这条 messagetext 留空、不写话术——话术改用普通文字回复(见下条)。
  • 🚨 发完拼图后,必须再用一句普通文字回复(assistant content)把确认话术说出来——像平时聊天直接回文字、不经任何工具,内容用下方"首轮文字模板"。别只调 message 发张图就收尾。(即:图走 message 工具、话术走你的文字回复,两者分开。)
  • 🚨 发完(拼图 + 文字确认),本轮到此为止:进第四步纯等待——严禁本轮落库(pet add / reference-crops)。observe 与落库是两轮,落库须等用户下轮回"确认"。
  • 🚨 别把用户的"注册/登记"当成对 observe 结果的认可:那是意图;而这次具体记成什么样(外观、选哪几张图)得用户看过、回"确认"才算数。所以本轮只把结果给他看,落库是他点头后下一轮的事。

处理提示(发用户时用自然语言转述;前五条是 warnings[].type 的取值;末条的顶层 refs_inconsistentwarnings 里的同名条目是同一件事,合并成一句说、别转述两遍):

信号含义首轮话术处理
warnings[].type = species_mismatch检出物种与用户说的不符"我看着更像{检出物种},你确认是{用户物种}吗?"
warnings[].type = generic_look大众花色/脸,难独一区分照常注册,但提示"这只花色比较常见,后续多补不同姿态识别更稳"
warnings[].type = multiple_pets画面里不止一只"画面里不止一只,本次先注册主体那只;其它的分别再各传一次"
warnings[].type = partial_decode_failed有图没解出来(截断/损坏/不是图片),已跳过"其中有张我没打开(文件像是损坏了),这次用剩下的看的;想把那张也算上就重新发一次"
warnings[].type = low_sharpness素材偏糊(不硬拒,只是参照会打折)照常注册,但提示"这几张有点糊,识别参照效果会差些;有更清晰的可以再补"
顶层 refs_inconsistent = true多图疑似不是同一只"这几张看着可能不是同一只?确认都是{name}我再入库,或只留同一只的"

首轮文字模板(作为你这轮的普通文字回复(assistant content) 直接说出来,不放进 message):

观察好了:{summary}。我挑了 N 张不同姿态作识别参照(图),确认给「{name}」入库?回"确认"。

{summary} 是 observe 出的完整外观描述、已含物种,外观只说这一次,别再在句首另起"这是一只…"重复一遍。)

无名时句尾追问:"这只{物种}叫什么名字?"

第四步 · 等待用户回复

发完(候选图 / 回显)后纯等待:不发中间消息、不主动重跑 observe,直到用户下一轮回复。

  • "确认"/"好"/"对" → 第五步落库
  • "取消"/"不对" → 第五步 5.4
  • 改名字/物种/外观/删某张候选 → 按回复调整后落库(如用户说"第 2 张不要",落库时 --crops 去掉该张;改外观则用新外观写 member_persona)

第五步 · 次轮落库 / 取消

通用:新宠物先建壳(名不存在时——已按第一步"重名前置查重"确认):

miloco-cli pet add --name <name> --species <猫/狗/其它> --pretty   # → 记下返回 id (pet_id)

pet add 返回 409(名已存在):说明前置查重漏了 → 停下走 5.5 问用户(补充 / 覆盖 / 另一只),自动改名硬塞、静默 append / replace。 写外观(两通路都做,用户已确认才写,member_persona,subject_id=pet_id)。含中文用 --ops-file:

# /tmp/<uuid>_persona.json(op=add;entry 必填 type/subject_id/subject_name/content,
#  date 省略即可——后端自动填当日;--user-edit 会把 source/confidence 置 user_told/1.0):
# [{"op":"add","entry":{"type":"member_persona","subject_id":"<pet_id>",
#    "subject_name":"<name>","content":"<外观:A 用 observe 的 summary / B 用用户描述>"}}]
miloco-cli home-profile profile-write --ops-file /tmp/<uuid>_persona.json --user-edit --pretty
miloco-cli home-profile commit --pretty

5.1 A 素材通路 · 存识别参照 + 默认头像

在通用建壳 + 写外观之外,存参考图(注册整组替换,用 observe 存下的 crop + 绝对分):

miloco-cli pet reference-crops <pet_id> \
    --crops /tmp/<uuid>_pet_0.jpg --crops /tmp/<uuid>_pet_1.jpg \
    --scores <crops_saved 各 score 逗号拼接> --mode replace --pretty

再设默认头像(observe 已按头部框自动裁好、存为 <prefix>_avatar.jpg;Agent 注册省的是"用户手动裁剪调整头像"这步,不是不要头像):

miloco-cli pet avatar <pet_id> --image /tmp/<uuid>_pet_avatar.jpg --pretty

回复:"已给「{name}」建好档案:记了 N 张识别参照 + 外观 + 头像。"

5.2 B 文字通路 · 只建壳 + 外观(无识别参照)

只做通用的 pet add + 写外观,不调 reference-crops。回复:

已给「{name}」建好档案(记了外观)。想让系统在画面里认得出它,发张照片或短视频,我再帮它建识别参照。

5.3 补充素材(append,存量宠物 + 素材)

跳过 pet add,直接对已有 pet_id:

miloco-cli pet reference-crops <pet_id> --crops /tmp/<uuid>_pet_0.jpg --scores <score> --mode append --pretty

(append 把新旧参考图按绝对分留 top-3。)外观如有更新同通用第 3 步。回复:"已给「{name}」补充素材,识别参照已更新。"

5.4 用户取消

不调任何落库命令,回复:"好的,没有入库。要重新描述或发素材再看吗?"observe 无副作用,不需清理。

5.5 重名(注册意图撞已有名)· 停下问 + 三分支

第一步"重名前置查重"发现名已存在且是注册意图(或落库时 pet add 撞 409)→ 本轮只发一句问话、不 observe、不落库:

「{name}」已经在花名册里了。你是想:① 给它补充这次的素材,② 覆盖重登(用这次的重新记),还是 ③ 这其实是另一只(那换个名)?回 1 / 2 / 3。

发完本轮终止等待。用户回复后分支:

  • ① 补充(复用已有 pet_id,两轮):本轮 pet observe 出新候选 → 发拼图(message 只发图) + 必须再用普通文字回复(content)一句"这次挑了 N 张,确认加进「{name}」的识别参照?回确认" → 停下等确认(不落库);下一轮确认后走 5.3(reference-crops … --mode append),不重发拼图,回一句"已给「{name}」补充素材,识别参照已更新"。
  • ② 覆盖重登(复用已有 pet_id,两轮):本轮 pet observe 出新候选 → 发拼图(message 只发图) + 必须再用普通文字回复(content)一句"这次挑了 N 张,确认用它们覆盖「{name}」旧档案?回确认" → 停下等确认(不落库);下一轮确认后 reference-crops <pet_id> … --mode replace(整组替换旧参考图)+ 重写 member_persona + 重设默认头像(同 5.1),不重发拼图,回一句"已用新素材覆盖「{name}」的档案"。
  • ③ 另一只 → 请用户给新名字,拿到后按新宠物从第一步重走(pet add 新名)。

头像:A 素材通路已自动落默认头像(observe 的头部裁剪,见 5.1);用户想换/精调去 web 宠物页(Agent 不做手动裁剪)。B 文字通路无素材 → 暂无头像(占位),可后续发张照片/去 web 设。

用户可见输出(硬约束)

术语黑名单

只约束 agent 实际发给用户的 reply 文本;本 SKILL 里的流程/命令描述、agent 自己的推理与日志继续用这些术语没问题。

❌ 用户话术禁用✅ 改用
observe / track / crop / candidate / grounding / tier"观察" / "识别参照(图)" / "候选"
reference-crops / member_persona / commit / profile-write"识别参照" / "外观" / "存档"
任何内部 id(pet_id 内部形态)用宠物名指代,不必展示

多图/视频仍是同一只

A 素材通路多图/视频入库前若 refs_inconsistent,必须先跟用户确认是不是同一只,不擅自把疑似不同只的混入同一档案。

关键约束

约束 1 · 候选/回显与落库分阶段,中间必须用户确认

A 通路 pet observe(出候选)、B 通路(回显解析)→ 等待用户明确回复 → 才 pet add+(A)reference-crops+写外观。observe 无副作用、不落库;绝不在同一轮直接落库。理由:让用户看一眼"准备记成什么样"再入库,避免记错宠物 / 记进大众脸 / 记错外观。

约束 2 · 视频原文件提交,禁抽帧(A 通路)

视频必须 --video <原文件>,不 ffmpeg 抽帧后 --image(丢多帧姿态、识别参照差)。后端 --video 已含选帧。

约束 3 · 同条消息 ≥2 张图单次批量(A 通路)

一条消息多张图是"同一只的多份参照",一次 --images a --images b ...(≤3),不拆 N 次 --image

约束 4 · 功能门 + 无池不模拟

pet_recognition 关 → 整个注册(A 素材 + B 文字通路)均返 404、不可用,引导去设置打开、不建档不假装;宠物无陌生池 → 不实现/不假装"从摄像头挑"。

异常处理

异常处理话术
pet_recognition 关(注册端点返 404)引导去设置打开、不建档"宠物识别功能没开,现在还没法给它建档——去设置里打开「宠物识别」,打开后我就能帮它建档、在画面里认出它。"
detected=false(没检出猫/狗)不入库;先看 warnings——含 partial_decode_failed / low_sharpness 就按第三步表里那条说(是"图没打开 / 偏糊",不是"没看清是猫是狗"),别把住户推去反复换图;都没有才用右侧话术"这张/这段里没看清是猫还是狗,换一张更清楚的,或直接描述它的样子?"
species_mismatch / refs_inconsistent / multiple_pets见第三步处理表同上表
用户没给宠物名追问"这只{物种}叫什么名字?我用它作标识。"
上传非图非视频引导改发或改描述"只能用图片或视频建识别参照;要么重发一张照片/视频,要么直接描述它的样子。"
pet 名已存在(且非补充素材意图)停下走 5.5按 5.5 问三选一(①补充/②覆盖/③另一只),别用旧的两选一
CLI 非零 exit / 服务不可用不抛 stack,人话告知"刚才没登记成功,稍后再试。"
用户要"从摄像头挑没登记的宠物"按总原则引导"宠物暂时只能靠你描述或发照片/视频登记,来一段吧。"

示例与反例

端到端场景 + 反例见 references/examples.md:文字描述注册(B)/ 单只多图注册(A)/ 单只视频注册(A)/ 补充素材(append)/ 无描述无素材引导 + 反例(抽帧、拆调、跳过确认、模拟从摄像头挑、功能关仍强行 observe)。

边界

  • ❌ 不做花名册纯行 CRUD 的改名/删(→ miloco-cli pet update/delete)
  • ❌ 无"陌生宠物池",不从摄像头挑、不模拟
  • ❌ 不接 IdentityEngine/ReID/person 表(红线:宠物走花名册 + 参考图 + member_persona)
  • ✅ 泛档案里顺带提到的宠物事实(作息/习惯/健康)由 miloco-home-profile 处理;本 SKILL 专管"专门登记这只宠物"(建身份 + 外观 ± 识别参照)
  • pet_recognition 关 → 整个注册(A 素材 + B 文字通路)均不可用 → 话术引导去设置打开、不建档
  • ✅ 补充素材走 reference-crops --mode append(绝对分留 top-3)
  • ✅ A 素材通路自动落默认头像(observe 头部裁剪 → pet avatar);精调/更换走 web。B 文字通路无素材 → 占位
Repository
XiaoMi/xiaomi-miloco
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.