--- name: goofish-reply-buyer description: | 闲鱼买家消息回复 skill。何时激活:用户说"看看我有没有未读 / 回复下买家 / 有人问 XX 怎么办 / 他要砍价我怎么办 / 帮我回一下消息 / 处理下催付 / 议价策略"。 功能:拉未读会话 → 逐会话拉历史 → 分类意图(询价/议价/催付/售后/外联风险)→ 按卖家预设策略起草回复 → 用户确认后 `message_send`。核心约束: **不托管发送权**——所有对外消息必须人类点头;调用 `goofish-risk-guard` 做外联词扫描。 metadata: author: goofish-cli version: "0.3.0" tags: [xianyu, im, messaging, buyer] allowed-tools: - mcp__goofish__auth_status - mcp__goofish__message_list_chats - mcp__goofish__message_history - mcp__goofish__message_send - mcp__goofish__item_get --- # 闲鱼回买家消息 ## 工具命名 正文使用 `auth_status` 这类逻辑名。OpenClaw 调 `goofish__<逻辑名>`; Claude Code / Cursor 调 `mcp__goofish__<逻辑名>`。frontmatter 的 `allowed-tools` 保留 Claude 权限预批准格式,OpenClaw 不读取该字段。 ## 触发姿势 用户典型输入: - "看看我未读消息" - "有人问 XXX 怎么回" - "那个议价的我回他多少" - "催付一下下单没付钱的" - "帮我批量处理一下消息" ## 核心原则(反复强调) **永远不自动发消息**。 即使用户说"随便回一下"、"你看着办",也要: 1. 起草一条 2. 展示给用户 3. 等明确的"发 / 嗯发 / ok"后才调 `message_send` 为什么硬要这么做: - 发错话在闲鱼成本高(外联词封号、情绪化引战、误报价) - 买家一旦觉得"卖家不是本人"(AI 味太重),信任归零 - 和 `message_watch` 的长连接事件流不同,单条对话是**对外行为**,不可逆 ## 标准流程 ### Step 1 · 登录态自检 ``` auth_status → valid=false 直接停,提示用户 auth login ``` ### Step 2 · 拉未读会话 ``` message_list_chats(fetch_num=20) ``` 返回按活动时间倒序的会话列表,每项含 session_id / 对方昵称 / 最后一条消息预览 / 未读数。 默认短时 WS 会话发现;先检查 metadata_status 和 metadata_errors。身份缺失或摘要过期的会话先补信息,不猜对方身份。 HTTP 的 has_more 不代表整份会话列表完整,短时同步也不能保证发现全部历史会话。 WS 条目的 unread=null 表示未知,不能按零忽略,也不能直接与数字比较。 **筛选策略**: - 优先未读数 > 0 的 - 按最近活跃倒序 - 一次别处理太多(建议 ≤ 5 个会话一轮),消息太长用户看不过来 ### Step 3 · 逐会话拉上下文 ``` 对每个选中的 cid: message_history(cid=session_id, limit=20) ``` 20 条基本够分类意图了。太长的会话(50+ 条)拉 30 条。 **同时**(如果消息提到具体商品 ID): ``` item_get(item_id=...) # 拿商品的最新状态,价格/标题/是否在售 ``` ### Step 4 · 意图分类 详见 `references/intent-classification.md`。粗分 5 类: | 意图 | 典型 | 处理策略 | |---|---|---| | 询价 / 基本信息 | "多少钱"、"还在吗"、"在哪发货" | 直接回,参考卖家商品描述 | | 议价 | "便宜点"、"XXX 行吗" | 按 `bargain-ladder.md` 阶梯回 | | 催付 | "已付款"、"明天到吗" | 回发货时间 | | 售后 | "坏了"、"不对"、"要退款" | 谨慎回,留证据;严重时建议人工介入 | | 外联 / 风险 | "加个微信"、"走转账" | **block + 合规话术替换** | ### Step 5 · 起草回复 按意图走不同子流程(各有对应 reference)。 起草完**必过 risk-guard 扫描**: - 调用 `goofish-risk-guard` 的 `external-contact-keywords.md` 扫草稿 - 命中 → 换词、重写或标红警告 ### Step 6 · 用户确认 展示格式: ``` 【会话】买家昵称 "xxxxx"(未读 N 条) 【最新来信】 > "原文..." 【意图判定】议价(想砍到 XX 元,距你底线 XX 元) 【草稿回复】 "..." 【风控扫描】通过 ✅ 发送这条吗?(y/改/跳过) ``` 用户回 **"发 / 嗯 / 是 / ok / 1"** 才调 `message_send`。 用户回 "改" → 让他说具体改啥,重新起草。 用户回 "跳过" → 跳到下个会话。 ### Step 7 · 发送 ``` message_send(cid=..., text="...") ``` 成功后: - 给用户确认"已发" - **等一下再处理下一个**(别连发多个 cid,触发频控) ## 卖家人设保持 Agent 要模仿**用户自己的语气**,不要用 AI 常见的书面语: - ❌ "您好,非常感谢您的关注" - ✅ "在的~" - ❌ "经过慎重考虑,我们愿意给您一个优惠" - ✅ "可以少 20,1200 行吗" 具体调教见 `references/tone-guide.md`。 ## 特殊场景 ### 场景:批量催付 用户说"把所有没付款的催一下" - `list_chats` 找"已下单未付款"标签的会话 - 每人起草一条温和催付话术 - **逐条确认**(不要批量群发 — 给发送权等于关掉最后一道保险) ### 场景:买家发差评 **不要**用 AI 写攻击性回评。 - 起草克制的回应(客观 + 解释) - 明确告诉用户"情绪化会扩大损失" - 严重的差评建议走官方申诉,不建议公开回复撕 ### 场景:疑似骗子 / 恶意仅退款 - 提示用户"这看起来像 XX 类型的典型操作,小心" - 让用户判断是否升级到人工客服介入 - Agent 不主动承诺"帮你追责"——界限清晰 ### 场景:买家问外联 - 必须用 risk-guard 的合规话术替换 - 同时提示卖家"对方在问外联,按合规回,不要心软" ## 相关 skill - `goofish-risk-guard` — 每条出门前扫外联词 - `goofish-publish-item` — 发布的商品会回来的消息走本 skill - `goofish-shop-diagnosis` — 发现大量消息都是"还在吗"时,可能是已被限流(消息流入但买家看不到)