下载地址
https://www.zhengdianxue.com/wp-content/uploads/skills/cyinfo--datang-voice-hub.zip将提示词发送给你的 AI 安装该 skills
请根据 https://skillhub.cn/install/skillhub.md,安装 @cyinfo/datang-voice-hub。电商(淘宝/天猫店铺)评价一键同步到本地,按岗位(运营/客服/店主/产品供应链)与形态(简报/详报/专项)出分析报告:好评率、差评率、DSR、VOC 痛点与飙升词、时段与 SKU 归因,可导出 HTML/PDF/Excel,并跟踪差评改进闭环。
阅读全文 (展开查看完整说明)
概述
帮你同步淘宝/天猫评价 → 生成分析报告 → 跟踪差评改进闭环的本地工具。
前置:连接器自愈(第2步无条件执行 · 不需要你判断任何东西)
⛔ 绝不要让 agent 自己判断「工具在不在」 —— 那是不可观测条件。
新会话的工具列表里本来就没有
mcp__rephub__*,agent 不会去"发现缺失",只会顺着流程往下走。2026-09-17 实测:全新环境(删连接器 + 删 Token)全程没提示安装 —— 因为第2步的
onboard是纯 CLI、压根不需要 MCP,agent 一路走到"请填 Token",从没意识到连接器没装。
✅ 正确做法 —— 无条件幂等自愈:第2步开头每次都跑一次
install.py --ensure(纯本地、不联网、毫秒级)。装没装、有没有信任,全由脚本判断,不劳 agent 判断。
退出码是唯一判据,四个值都要有分支,缺一个就会在最需要指引的场景里失去指引:
- 退出码 0 → 已就绪 且 已信任 → 静默继续,不向用户汇报本节;
- 退出码 2 → 本次刚装上、但已信任 → 禁止让用户去点「信任」
(已信任时连接器页根本不渲染该按钮,让用户去找只会扑空);
只转告一句「重开一次对话」,同时本次请求照常用 CLI 兜底跑完,不要中断;
- 退出码 3 → 未受信任(从未信任,或入口 command/args 变更致旧信任作废)→
转告「到连接器设置点信任 + 重开一次对话」,同时本次请求走 CLI 兜底;
- 退出码 1 → 安装失败(写
mcp.json出错 / 权限不足 / JSON 损坏)→这是唯一需要停下来报障的码:把 stderr 原样转给用户,不要引导点信任、
不要让用户重开对话(配置都没写进去,重开也没用),本次请求继续走 CLI 兜底。
⚠️ 旧版文档只覆盖 0/2/3,漏了
1—— agent 遇到安装失败时没有任何分支可走,容易把它当成「已就绪」继续往下,或错误地引导用户点信任。
⛔ 红线:不要把「配置缺失」当成「未信任」。二者是互不相干的两份数据
(前者
mcp.json,后者mcp-approvals.json),没有因果关系。2026-09-17 实测事故:对早已信任的用户,旧流程因为退出码 2 就一律让他去点「信任」,
而按钮压根不存在 —— 根因正是用「配置条目缺不缺」这一个信号,打包了「要不要点信任」
和「要不要重开」这两个本该独立的结论。修复已进入
cmd_ensure的退出码契约。
以下三件事构成完整的首次配置(下表步骤1由 --ensure 自动驱动; 下表步骤2要不要做,由 --ensure 的退出码唯一决定 —— 只有返回 3 才需要,返回 0/2 说明已信任,没有按钮可点)。
⚠️ 注意:这里的「步骤1/2/3」是首次配置视角;下方「使用流程」的「第1/2/3/4步」
是每次请求的执行视角。两套编号互不相干(首次配置只做一次,使用流程每次都走),别混。
| # | 步骤 | 谁做 | 动作 |
|---|---|---|---|
| 1 | 生成宿主 MCP 配置 | agent 执行 | python bootstrap/install.py --ensure(幂等自愈,已装则跳过) |
| 2 | 点「信任」(条件步) | 用户(只能用户点) | 仅当 --ensure 退出码 = 3:连接器设置 → rephub → 信任。退出码 0/2 = 已信任,跳过本步 |
| 3 | 提供平台 Token | 用户发给 agent | 见「订购引导」,由 agent 用 onboard --set-token 写入 |
--ensure 幂等:未装就自动装上;已装且已信任则一行「已就绪」直接通过(退出码 0);已装但未信任则返回 3 并给出 [WARN](此时才需要用户点信任)。写入时只合并mcpServers.rephub、保留其它已有 server、写入前备份 .bak。它写入的是本机绝对路径——宿主拉起 MCP server 时 PATH/cwd 不可控,手抄或用相对路径会拉不起 bridge。
⛔ 红线:只写
mcp.json,绝不程序化写mcp-approvals.json—— 信任是用户本人的安全授权,代写等于绕过安全机制。入口(command/args)变更后旧信任会作废,须让用户重新点一次「信任」。
⛔ 不要让用户手工复制
config/mcp/rephub.host.json.example(内含<...>占位符,照抄会配到废弃入口)。
工具异常时的环境自检:python bootstrap/install.py --doctor(10 项:Python 版本 / 目录结构 /凭证 / service / 端口文件 / jusico / 代理 / MCP 配置 / 工具清单 / 数据库;不依赖业务内核,损坏时也能跑)。
使用流程(固定顺序 · 禁止跳步 / 先分析)
⛔ 行为铁律(最高优先级)
- 收到请求即进入流程:禁止介绍、复述、架构说明、"好的我来帮你…"等铺垫;第一句必须是第1步的产物。
- 全程只与用户交互两次(第1步选「平台+时间段」、第3步选「岗位/形态/格式」),两次面板之间与之后均静默执行,不逐步汇报、不回卷。
唯一例外:第2步发现凭证未配置时必须停下等用户发 API Token —— 这是异常分支,不算违反本条(见第2步第1点)。
- 内部细节(查库 / 判新鲜度 / 同步 / 降级 / 去重)不对用户复述,只在结果里带必要说明。
- 禁止预扫描:收到请求即按四步执行,禁止先通读/扫描 skill 目录下其他文件(
ARCHITECTURE.md、glossary.md、*.py源码等);四步流程只依赖本skill.md正文即可完成,参考文档按需定向 read,绝不预先全读;执行时直接调命令/工具(python -m interfaces.cli ...、render_ui面板),不先读源码。
第1步 选平台 + 时间段(第一个交互点 · 弹面板)
- 平台:当前只接入了淘宝/天猫(淘系) —— 面板里只有这一个选项且已预选,用户点「拉取数据」即等于选定
taobao。
⛔ 绝不要列出京东 / 拼多多 / 抖音 / 美团 / 去哪儿 / Amazon / Temu —— 一个都没实现适配器,
选中必抛
PlatformNotAvailable(registry 里没有它、也没有适配器),整轮流程白跑。2026-09-18 已把
config/platforms.json与infrastructure/sync/registry.py同步收敛为只有taobao,面板模板也只剩一项 —— 未接入的平台不登记、不展示,避免"选项里有、实际拉不到"的假承诺。
用户点名未接入平台时:直接说明「该平台暂未接入」,并请他改看淘宝 ——
不要报错终止,也不要假装支持往下走。
- 时间段:即拉取数据的起止周期,与平台在同一面板一次收齐;不选则走默认 15 天。
⚠️ 面板里的 7/15/30/90/180 只是快捷选项,
window_days实际支持 1–365 任意整数。用户说「2 天」「3 天」「45 天」等非选项值照传,不要因面板没有就拒绝、或擅自改成相近选项
(2026-09-18 实例:用户要 2 天,面板无此选项,直接传
window_days=2完全正常)。⚠️
render_ui面板没有「自定义天数」入口(只有这 5 个快捷值);但AskUserQuestion路径自带 Other 自由输入框,用户可直接填任意天数(如 2 / 45)。
别把「面板没有这个选项」当成「用户不能填」—— 旧版把两条路混为一谈,白限制了兜底路径。
因此用户已在对话里说出具体天数时,直接采用该值,不要再拿面板选项去覆盖或回问一遍;
面板此时的作用只是让用户确认 / 改选,不是唯一的取值来源。
- 淘宝天猫同属淘系,归一为
taobao(天猫是别名,不单列为一个选项;platforms命令会显示taobao (含:tmall/天猫))。
| 维度 | 选项 | 默认 |
|---|---|---|
| 平台 | 淘宝/天猫(淘系)(taobao)唯一可选项,已预选 | taobao(必须选) |
| 时间 | 7 / 15 / 30 / 90 / 180 天(仅快捷选项;实际支持 1–365 任意整数) | 15 天 |
想确认当前接了哪些平台 —— 动态查,不要背死表:
python -m interfaces.cli --db data/rephub.db platforms # 输出 code / label / status / 订购链接 / 凭证;只有 status=available 才拉得到数该命令读的是
config/platforms.json(与面板选项同源)。⚠️ 接入新平台时四处必须一起改,漏一处就会出现「选项里有、同步报错」:
①
config/platforms.json加条目 → ②infrastructure/sync/registry.py追加register_platform(...)→ ③
infrastructure/sync/{平台}_adapter.py实现SyncPort→ ④assets/choice-panel-platform.jsonl加选项(面板模板是静态文件,不会自动读 platforms.json)。
交互方式(必守):每次收到查看评价类请求,第一件事就是弹出面板 A 让用户选/确认「平台+时间段」(即使平台已点名也要弹),禁止纯文字罗列让用户手动打字,禁止跳过面板直接执行。
- 首选
render_ui工具:把面板 A 模板 [assets/choice-panel-platform.jsonl](assets/choice-panel-platform.jsonl)(相对本 skill 根目录)的完整内容作为jsonl参数传入。模板已预选"/platform": ["taobao"],照原样传即可,不要改它、也不要往里加平台。提交后返回dataModel,形如{"/platform":["taobao"], "/window":["30"]}。- 兜底(必读 · 本环境实际走这条):本环境无
render_ui工具,改用选择题面板(AskUserQuestion)。⛔
AskUserQuestion每题的选项必须 2–4 个(工具 schema 硬约束minItems=2 / maxItems=4),给 1 个或 5 个都会直接调用失败。因此:
- 平台只剩 1 个可选项时,不要为它单独开一题 —— 把「当前仅支持淘宝/天猫(淘系)」写进
时间段的题干,只问时间段 1 题(
questions允许 1–4 题)。旧版教「平台项只给一个选项并预选」,照做必报错 —— 平台收敛到只剩淘宝后才暴露。
- 时间段 5 个快捷值超限,只取 4 个(如
7 / 15 / 30 / 90),并在题干注明「要其它天数(如 2 天、45 天)请在自由输入框里直接填」。
- 它自带 Other 自由输入,所以自定义天数完全可行,不必被快捷值绑死。
- 平台未选 → 停在此步;时间段未选 → 走默认 15 天。
第2步 拉数据(静默 · 不向用户逐步汇报)
按第1步选定的「平台 + 时间段」拉取数据:
- 连接器自愈(无条件跑,一次都不能省):
python bootstrap/install.py --ensure- 退出码 0 → 已就绪且已信任 → 静默继续,不向用户汇报;
- 退出码 2 → 本次刚装上、但已信任 → 不要让用户点「信任」(按钮不会渲染),
只转告「重开一次对话」;同时本次请求照常用 CLI 兜底跑完,不要中断;
- 退出码 3 → 未受信任 → 转告「点信任 + 重开对话」,同样走 CLI 兜底;
- 退出码 1 → 安装失败 → 转报 stderr 原文,不引导点信任、不叫用户重开,走 CLI 兜底。
(契约原理与这起事故的根因见「前置:连接器自愈」)
- 查凭证:运行
onboard --platform {code}(命令见下方速查)检查凭证是否就绪。- 未接入平台(未登记在
config/platforms.json)→ 打印[未接入平台] …于 stderr 且退出码 1;
- 未接入平台(未登记在
回到第1步请用户改选 taobao,不要继续、也不要引导订购。(平台名支持 taobao / tmall / 淘宝 / 天猫 四种写法,内部都归一为 taobao。)
- 未配 → 输出订购引导(见下),停在此步,等用户在对话里把 API Token 发过来。
- 用户在对话中发来 Token 后(注意:这是对话期发生的,不是安装时):
“bash python -m interfaces.cli --db data/rephub.db onboard --platform taobao --set-token "<用户发来的Token>" “ > 必须走命令写入,不要手改 JSON —— CLI 会保留其他平台已有的键值,并做「临时文件 + 原子替换」,> 避免常驻 service 正在读时拿到写了一半的文件。> 写完后无需重启 service:凭证是逐次懒加载的,下一次调用立即生效。> 这也是「一处录入、所有 AI 工具共享」的实现方式 —— Token 只存在 service 侧,不散落到各工具配置里。
- 已配 → 继续同步。
- 同步(首选 MCP 工具):走宿主已配好的
rephubMCP Server,宿主启动时已自动完成tools/list,工具 schema 已注入上下文 —— 不再盲猜参数。- 先
ToolSearch加载mcp__rephub__rephub_sync的 schema,再DeferExecuteTool调用:platform= 第1步选定的平台 code(如taobao)window_days= 第1步选定的时间段(如15)shop= 店铺 ID(留空 = 默认店)。
- 先
> ⚠️ 参数名用 shop,但它要填的值恰恰就是** jusico 的 session_info_id** > (taobao_adapter 内部执行的正是 kw["session_info_id"] = shop)。两件事别搞反:> 参数名不能写成 session_info_id=;值不能换成店铺名或店铺链接(必然拉空)。> 拿不准店铺 ID 时留空走默认店最稳 —— 旧文档只写「不要写成 session_info_id」,> 与 CLI help(「如淘宝 session_info_id」)和 MCP schema 说法冲突,已订正。
limit/max_rows:MCP 与 CLI 的max_rows默认都是 5000(taobao_adapter.MAX_ROWS),
超过会在 notice 里提示 truncated;要控体积显式传 limit(如 limit=100 用于测试), 要拉更多显式上调 max_rows(如 20000)> ⚠️ 旧文档/旧 schema 描述曾写「MCP 默认 100000」,那是 MAX_ROWS 从 100000 下调到 5000 之前的值,已失效。
- ⚠️ 返回的是
{task_id, status:"running"},不是入库结果 ——rephub_sync是异步的:
调用秒级返回,拉取在后台线程继续。返回体里没有 synced。
- 等它跑完(必做 · 不许跳过):反复调
mcp__rephub__rephub_sync_status(task_id=上一步的 task_id),
间隔 ~15 秒,直到 status ∈ {done, error}。
⛔
status实际有 5 个值,不是 3 个 —— 旧版只写了running|done|error:
running/done/error/not_found/no_task。后两个永远不会变成
done,只判done|error会一直轮询下去 = 死循环:
not_found→ task_id 失效或写错(任务表在 service 内存里,service 重启即清空)→ 停止轮询,重新触发一次
rephub_sync;
no_task→ 本机还没有任何同步任务(通常是漏了触发)→ 同样重新触发。救场:
task_id可留空,留空返回最近一次任务 —— 丢了 task_id 时用这个,不必重跑。
返回体两个计数含义不同,别混用:synced = 已抓取条数(领先于落库),committed = 真实入库行数。⛔ 看进度、判样本量一律用 committed —— 批量提交会让 synced 领先成百上千条,2026-09-17 曾出现「synced 涨了 400、库里 3 分钟零写入」,据 synced 汇报会误判成拉取失败。
✅ 这是多次短调用,不违反红线 2 —— 红线禁的是「单次工具调用阻塞等待全量完成」。
⛔ 不许跳过这步直接出报告:第4步是
auto_sync=false纯读本地库,同步没跑完就去读会拿到残缺数据甚至出空报告。宁可多轮询几次。
- 判样本量:用轮询终止时的
committed(真实入库行数),不要用synced。committed = 0→ 不要立刻换窗口重跑一次同步(已实测浪费 ~45s)。改为调mcp__rephub__rephub_aggregates
看本地是否有任何历史数据;
- 探底全空 → 提示「该账号下从未采集到评价:请确认已在服务市场订购、
已配置有效 API Token,且该窗口内数据源侧确实产生了评价」,停(不弹面板 B)。
- 探底有历史、当前窗口为 0 → 说明是「本窗口内无数据(非从未采集)」:
提示用户该窗口内无评价,可建议扩大窗口(如改 7 / 15 天)再看;同样不弹面板 B(本窗口零数据,出空报告无意义,别硬凑)。> ⛔ 探底时必须放大 window_days(如 window_days=365),不要照抄默认的 15 —— > 用刚刚拉空的同一个窗口再查一次,返回必然还是 0,根本区分不出「从未采集」和「本窗口无数据」,> 等于把红线 5 的意图架空。探的是本地库里有没有任何历史,窗口就该开到最大。> platform 传第1步的平台(精确)或不传(跨平台,更宽)都行,都能起探底作用。> ⛔ 不要提名不存在的后台(旧版此处写「去 ratetool 后台触发采集」,代码与配置里根本没有> ratetool、全仓仅此一处提及)—— 数据源侧只有 jusico。要交叉验证就调一次> mcp__rephub__rephub_search_reviews,直查原文确认真是「没有」还是「拉不到」。
committed > 0→ 继续第3步(弹面板 B)。
> ⚠️ 本条两条分支同样只能用 committed:同步跑完后二者会相等,但出错/中断时 synced 可能> 远大于 0 而 committed 仍为 0(未提交批次),据 synced > 0 放行会拿着空库去出报告。
CLI 兜底(仅以下场景):① MCP 工具不可用 / 报错;② 需调
--max-workers(并发分页线程数,MCP 未暴露此参数);③ 开发期改完代码需绕过 MCP Server 直接验证同步链路。兜底命令:
python run_sync_once.py --platform {code} --days {window}(注意此入口--max-rows默认 5000)。
第3步 选报告参数(第二个交互点 · 弹面板)
岗位 / 报告形态 / 文件格式三维,在同一面板一次收齐;不选则走默认。
| 维度 | 选项 | 默认 |
|---|---|---|
| 格式 | pdf / html / md / xlsx / card(卡片) | html |
| 形态 | 详报 / 简报 / 专项 | 详报 |
| 岗位 | 运营 / 客服 / 店主 / 产品供应链 | 运营 |
交互方式(必守):第2步确认有数据后,弹出面板 B(岗位+形态+格式),禁止纯文字罗列,禁止跳过面板。
- 首选
render_ui工具:读取 [assets/choice-panel-report.jsonl](assets/choice-panel-report.jsonl),把其完整内容作为render_ui的jsonl参数传入(一次收齐「岗位+形态+格式」3 项)。提交后返回dataModel,形如{"/format":["html"], "/form":["full"], "/role":["ops"]}。- 兜底:本环境无
render_ui时,改用选择题面板(AskUserQuestion)一次收齐 3 项。⛔ 同样受每题 2–4 个选项约束:格式有 5 个值,兜底时只放 4 个(
html/md/xlsx),需要
card(卡片)走自由输入;形态 3 个、岗位 4 个,均不超限。
- 岗位 code → 中文映射(必用):面板
/role返回英文 code,传工具前必须转成中文:ops→运营、service→客服、owner→店主、supply→产品供应链。- ⛔ 格式值照抄、不要自作翻译:
/format的原值是html/md/xlsx/card(与导出参数同名)。用AskUserQuestion兜底时选项值也必须给这几个原值 —— 写成excel会导致导出失败(正确是xlsx),写成「卡片」也会失败(正确是card)。- 三项未选 → 走默认(格式 html / 形态 详报 / 岗位 运营)。
第4步 生成报告(静默)
走 MCP 工具 mcp__rephub__rephub_report,复用第1步的 window_days,不再重复同步(auto_sync=false,纯本地读库):
- 先
ToolSearch加载mcp__rephub__rephub_report的 schema。 DeferExecuteTool调用,参数映射:role= 第3步岗位中文(运营 / 客服 / 店主 / 产品供应链)form= 第3步形态(brief/full/deep)window_days= 第1步的时间段export_formats= 第3步格式(md/xlsx/html/pdf/card,逗号分隔)
> ⚠️ 不要依赖 schema 默认值 —— 该参数在工具 schema 里 default 是 pdf,而流程约定的> 默认是 html。用户未选格式时必须显式传 export_formats="html",省略会静默导出 PDF。
platform= 第1步平台 codeauto_sync=false(报告前不补同步,数据已在第2步落库)
- 工具返回 Markdown 全文(末尾附
报告ID与生成文件:路径清单),按需present_files展示给用户。
报告默认存到 agent 工作空间目录下的
rephub_reports/(如~/rephub_reports/淘宝运营评论详报…html);路径就在返回体末尾的 meta 里,
present_files直接传那个路径即可,无需自己拼。
本地无数据(样本量 0)时不生成报告,改为提示(不硬凑空报告)。
CLI 兜底:
python -m interfaces.cli --db data/rephub.db report --tenant T1 --project P1 --platform {code} --role {岗位中文} --form {形态} --window {window} --export {格式} --no-sync(MCP 不可用时)。
订购引导(无凭证时)
⛔ 先判平台是否已接入,再决定要不要引导订购(第二道防线):
onboard对未登记平台会在 stderr 打印「[未接入平台] …已登记平台:taobao」并退出码 1(2026-09-18 修:此前是 stdout 打印「[未知平台]…」+ 退出码 0,agent 会误以为可以继续、
停在等 Token 上,用户只能干等)。但别依赖它兜底 —— 平台可用性必须在第1步就判定,
面板里没有的平台一律不进第2步;走到这里的应该只有
taobao。简言之:只有淘宝值得走订购流程。
无凭证需引导订购时,输出清晰提示 + 可点击跳转链接,不要只给裸链接或纯文字:
🔔 首次使用「淘宝」,需先在服务市场订购以获取 API Token。
👉 **点击前往淘宝服务市场订购**:[立即订购]({ordering_url})
订购完成后,把 API Token 发给我,即可完成配置。链接取
config/platforms.json的ordering_url;subscribe_note一并融入提示。当前只有
taobao一条且其ordering_url已登记;将来某平台ordering_url为空时提示「订购链接待补充」,不编造链接。
结果呈现
直接给报告/结论 + 一句数据口径(如「数据截至 X」)。不解释查库、降级、去重等机制。
护栏与红线
数据护栏(一句话)
数据不足自动降级;数据源未提供的字段标注「数据源未提供」不估算;禁编造量化;同事件同天只出一份。
两条口径(用户拍板 · 2026-09-18 · 必守)
| # | 口径 | 说明 |
|---|---|---|
| 1 | 时间窗口以用户给出的为准 | 说 2 天就是 2 天、说 3 天就是 3 天,不做自适应放大。内部按自然日对齐切分(与平台 days 同口径:days=2 = 今天 + 昨天)。库是增量累积的,不会因残留更早数据而把「近 2 天」算成 3 天(曾因此 1365 条变 4448 条) |
| 2 | 差评以评论实际内容判定 | 不看平台 rating_label(该店铺实测全为 good,无信息量),按评价文本判定情感 |
⚠️ 由口径 2 派生:报告里的「好评率」是文本判定值,与平台标签的 100% 好评并存是正常的,
不是 bug —— 前者从文本里挖出了平台标签掩盖的隐性负面(如「物流差死了 就不能费点心思包装一下吗」,
平台标
good但内容明确是负面)。不要拿平台 rating 去"纠正"报告,也不要反过来。⛔ 判定「数据缺失」前必须先确认同步
done且truncated=false——2026-09-17 曾据一份没跑完的数据断言「只拉到好评、中差评丢失」,结论完全错误。
MCP / 调用红线(必守)
这组红线源于 2026-09-15 一次 17 分钟事故归因(详见
docs/开发文档/MCP集成链路专项-17分钟事故归因与标准流程调整方案.md)。
initialize≠tools/list—— MCP 握手(initialize)只返回serverInfo/capabilities,不含工具定义。工具 schema 必须再单独调tools/list才能拿到。本项目jusico_client.py历史上只做了握手就直奔tools/call,导致参数只能盲猜 —— 已是事故根因之一。走宿主 MCP 集成时,宿主会自动完成tools/list,schema 零成本注入上下文;手写客户端场景必须显式补tools/list。- jusico 单次调用 ~1–7 秒;「30–65 秒」是并发 10 造成的排队假象 —— 2026-09-18 实测:
并发降为 3 后 search_reviews / get_review_stats 单次 1–7 秒,1365 条(14 页)33 秒跑完。旧文档记载的 30–65s 源于 DEFAULT_MAX_WORKERS=10 把请求堵在服务端排队 + 超时重试,不是接口本身慢 —— 那时错误地据此开更高并发,反而更慢。⛔ 并发不是越大越快:10 并发实测 1.51 页/分,3 并发 25 页/分(约 17 倍差距),且 10 并发曾直接把同步打到 error(read timed out)。不要为提速而调大并发。
探查 / 诊断脚本仍建议
run_in_background=true—— 单次虽快,全量分页累计仍可能超 120s。已知限制:MCP 工具调用(
DeferExecuteTool)无法显式后台化,由宿主管理超时。缓解手段是用limit/window_days控体积,而不是退回 Bash 手写脚本。
- 本环境无
render_ui工具 —— 面板 A / 面板 B 改用选择题面板(AskUserQuestion)一次收齐同一批参数。render_ui仅在环境中可用时优先使用。
⛔
AskUserQuestion每题必须 2–4 个选项(schemaminItems=2 / maxItems=4),给 1 个或 5 个直接调用失败。落地规则:平台只剩 1 个 → 不为它单开一题(写进题干);
时间段 5 个快捷值 → 只放 4 个;报告格式 5 个值 → 只放 4 个(
card走自由输入)。另:它自带 Other 自由输入,用户可填任意天数 / 格式,不必受快捷值限制。
max_rows默认 5000(MCP 与 CLI 一致) —— 单次同步最多 5000 条,超出会truncated(在notice里提示),
不会静默拉爆。要控体积传 limit(如 limit=100 测试用);要拉更多显式上调 max_rows。
⚠️ 别再引用「MCP 默认 100000」—— 那是
MAX_ROWS下调前的旧值,2026-09-18 已订正。
- 同步结果为 0 条时不要立刻换窗口重跑(事故中浪费 ~45s)—— 先调
rephub_aggregates
看本地有无任何历史数据,一次确认「从未采集」还是「该窗口内无数据」。⚠️ 该调用必须显式放大 window_days(如 365)才能起到探底作用 —— 沿用刚拉空的窗口只会再得到一个 0,白跑一次(探底探的是本地全库,不是当前窗口)。
- 组件间 localhost 通信必须绕过系统代理 —— 本机存在 HTTP 代理时,
urllib会拿它去连127.0.0.1,导致 service 明明没运行却返回代理的502,降级判断被静默绕过。mcp_bridge.py已用ProxyHandler({})处理;新写任何 localhost 调用代码时都必须显式禁用代理。
MCP 链路架构(排障前必读 · 完整论证见专项文档)
排障、
Not connected、工具"凭空消失"、改代码后不生效时才读本节。完整设计见
docs/开发文档/MCP集成架构专项-rephub服务化跨工具零配置直连根治方案.md。
宿主 AI 工具(WorkBuddy / qoder / qclaw / …)
└─ interfaces/mcp_bridge.py ← 工具沙箱内 · **零外网需求** · 薄桥(只做协议转发)
│ http://127.0.0.1:8731 ← 必须绕过系统代理(见红线 6)
▼
interfaces/rephub_service.py ← 沙箱外常驻进程 · **唯一外网出口**
│ HTTPS + Bearer Token
▼
jusico.com为什么这么拆:原先 stdio MCP server 由各工具以子进程拉起,会继承工具沙箱 → 没有外网出口 → 连 jusico 必然超时。把需要外网的业务逻辑挪到沙箱外的常驻 service 后,工具侧薄桥完全不需要外网权限,因此任何工具的沙箱策略都不影响链路。
业务逻辑单一真源 = interfaces/mcp_core.py(bridge 与 service 共用同一份 dispatch())。原 mcp_server.py(deprecated 兼容壳)已于 2026-09-17 移除,对外入口统一为 mcp_bridge.py(薄桥) + rephub_service.py(常驻服务);不要再配置或引用 mcp_server.py,它指向的是会踩「子进程无外网」坑的旧路径。
改完代码要做什么(照表执行,别一律重启整个应用):
| 改了什么 | 需要的操作 |
|---|---|
mcp_core.py / application / domain / infrastructure 等业务层 | 重启 service(见下「重启 service」) |
rephub_service.py | 重启 service |
mcp_bridge.py | 宿主重连 bridge(重开会话;必要时重启宿主) |
mcp.json 的 command / args / env | 必须让用户重新点「信任」 —— 见下方 F11 |
故障降级三级(service 未运行时):① bridge 后台线程自动拉起 service;② 若拉起后仍不通(常见原因:桥带起来的 service 继承桥所在沙箱 → 同样无外网,本地查询可用、jusico 仍失败);③ 返回人类可读错误 + 一条可复制的自愈命令。
排障口诀 · 工具"凭空消失":先查宿主主日志里的 [MCP Security] 行。
日志位置按宿主版本不同:新版是平铺的
~/.workbuddy/logs/main.log/daemon.log(2026-09-17 实测即为此形态);部分版本为
~/.workbuddy/logs/<日期>/workbuddyMainThread__*.log。别只认一个路径就断言"日志不存在"。
- 看到
skipping untrusted server→ 信任失效(改了mcp.json的 command/args → 配置 hash 变
→ 旧信任作废 → 宿主直接跳过该 server,一个工具都不注册),处置:让用户去连接器设置重新信任。
- 没有任何
[MCP Security]行 → 宿主并未把它当未信任跳过,不是信任问题。
典型成因:配置是会话中途才写入的,而工具清单是启动时快照 → 处置是让用户重开一次对话;绝不要让用户去找「信任」按钮(已信任时它根本不渲染)—— 这正是 2026-09-17 那次误判的根因。
两种症状表现一样,但处置完全相反,先看日志再动手。
⚠️ 不要程序化写
~/.workbuddy/mcp-approvals.json—— 那是用户本人的安全授权,只能由用户点「信任」,代写等于绕过安全机制。
排障口诀 · 用户在连接器页删掉了 rephub:宿主只会把 mcp.json 的 mcpServers.rephub 抹掉(mcp-approvals.json 里的信任记录会完整残留 —— 条目没了它无从作用,但条目写回后立即重新生效),不会有任何提示告诉用户哪个 skill 依赖它 —— 这是宿主通用行为,skill 侧拦不住。症状是 5 个工具全消失 + service 无人拉起(:8731 无响应)。
处置(第②步是条件步,只看退出码): ① 跑 python bootstrap/install.py --ensure(自动写回条目); ② 仅当退出码为 3 时才让用户去点信任 —— 退出码 2 表示信任记录仍在、已受信任, 此时连接器页根本不会渲染「信任」按钮,让用户去找只会扑空(2026-09-17 实测); 退出码 1 = 安装失败(条目没写回),此时应转报 stderr 而不是让用户点信任;③ 重开一次对话(工具清单是会话级快照)。在此期间本次请求用 CLI 兜底跑完,不要干等 —— 见「兜底路径:CLI」。
注:正常流程里第2步每次都会跑
--ensure,所以这条一般不会漏;此条目用于人工排障。自查信任状态(纯本地、不联网):看
~/.workbuddy/mcp-approvals.json里有没有以
::rephub结尾的键 —— 有即已信任。--ensure内部_trust_state()判的正是这个。
jusico 原始 API 踩坑备忘(直连 / 联调时必读)
| 坑 | 说明 |
|---|---|
result 传 "all" | 等同省略,返回全量(2026-09-18 实测:all 与省略均 total=1365)。旧文档称「会匹配为空」已证伪 |
result 三档真值 | 仅接受 good/neutral/bad,参数确实生效。实测该店铺 2/7/30 天三档恒为 good=total、neutral=0、bad=0(官方 get_review_stats 交叉验证一致)→ 中差评真实为 0,不是拉取不全。判定「漏拉数据」前必须先确认同步 done 且 truncated=false |
session_info_id 传 0 | 会被当成「店铺 0」导致空结果;仅给定真实 shop 时才传 |
has_reply 默认 false | 意为「只含未回复」;schema 描述与 default 存在矛盾,用前实测 |
越界 offset | 服务端返回 404 表示无更多数据,客户端已视为空结果(非异常) |
SSE 不可 read() 到 EOF | 服务端 keep-alive 不关连接,须逐行增量读,取到首个完整 message 即返回 |
命令速查(agent 内部使用,不对用户展示)
以下命令直接照抄执行,无需读
cli.py源码。收到「查看评价」类请求 → 按四步走:第1步弹面板 A(平台+时间段)→ 第2步拉数据 → 第3步弹面板 B(岗位/形态/格式) → 第4步出报告。
禁止先读
ARCHITECTURE.md/glossary.md/ 源码。主路径 = MCP 工具(
mcp__rephub__*),CLI 仅作兜底。⚠️ 流程的唯一真源是上方「使用流程」 —— 本节只放命令;两处若有分歧,以正文为准。
主路径:MCP 工具(默认走这条)
宿主启动 server 时自动 tools/list → schema 已注入上下文,无需盲猜参数。
⛔ 本节不要写「工具不存在就去装」这类条件分支 —— 「工具存不存在」是不可观测条件
(论证见「前置:连接器自愈」),写了也白写。连接器装没装由第2步的
--ensure无条件自愈,本节概不负责。本节唯一职责:调不通就立刻改用下方 CLI 把活干完,不要停下来诊断。
⛔ 也不要让用户手工抄
config/mcp/rephub.host.json.example(含占位符,照抄会配到废弃入口)。
⛔ 兜底路径(缺 MCP 时必走,不是可选项):MCP 工具不可用时,本次请求一律改用 CLI 完成,不要中断。
CLI 与 MCP 共用同一套内核与同一个本地库,读库 / 出报告 / 同步全都能独立跑(2026-09-17 实测:
删掉连接器后
capabilities、report均正常)。所以缺工具时的正确动作是「一边补装、一边把活干完」,而不是回报"环境未就绪"就结束。
等价替换:MCP
rephub_sync(触发+轮询)→run_sync_once.py(一条命令跑完,含等待);MCP
rephub_report→cli ... report --no-sync;MCPrephub_search_reviews无 CLI 等价物,需要原文时用
cli ... report或提示用户稍后重试。见下方「兜底路径:CLI」。
链路形态:宿主 →
mcp_bridge.py(沙箱内薄桥)→127.0.0.1:8731→rephub_service.py(沙箱外常驻出口)→ jusico。五个工具:
rephub_sync/rephub_sync_status/rephub_aggregates/rephub_report/rephub_search_reviews。⚠️
rephub_sync是异步的:调用秒级返回{task_id, status:"running"},后台线程继续拉取;用
rephub_sync_status查进度(看committed,不是synced—— 后者是已抓取数,会领先落库成百上千条)。禁止阻塞等待全量完成 —— 宿主对单次工具调用有超时上限,而全量同步远超该上限,等待必然被判超时(2026-09-16 曾因此误报「服务忙」,实际数据在后台正常入库)。
另:新增工具后宿主工具目录是会话级快照,重信任/重启 service 都不会刷新,需重开一次对话才会出现。
第2步对应命令(流程见上方「使用流程 · 第2步」,本节只放命令):
# ① 连接器自愈:无条件执行(幂等,纯本地毫秒级)。退出码 0=就绪且已信任→静默;
# 2=刚装上但已信任→**别让用户点信任**,只让其重开对话;3=未信任→才引导点信任;
# 1=**安装失败**→转报 stderr 原文(不引导点信任、不叫重开),本次走 CLI 兜底
python bootstrap/install.py --ensure
# ② 查凭证(未配→订购引导;已配→继续同步)。onboard 仍走 CLI(MCP 未暴露此能力)
python -m interfaces.cli --db data/rephub.db onboard --platform taobao# ② 同步(两步:触发 → 轮询结果。别指望一次调用拿到入库条数)
# 2.1 ToolSearch 加载 mcp__rephub__rephub_sync → DeferExecuteTool 调用
# platform="taobao" window_days=15 shop=""(默认店) limit=None(全量,受 max_rows 默认 5000 封顶)
# 返回:{"task_id":"...", "status":"running"} ← **没有 synced**,这是异步触发凭证
#
# 2.2 ToolSearch 加载 mcp__rephub__rephub_sync_status → 每 ~15s 查一次
# rephub_sync_status(task_id=上一步的 task_id)
# 返回:{"task_id":"...", "status":"running|done|error|not_found|no_task", "synced":N, "committed":M, ...}
# ↑ 终止条件必须包含 not_found / no_task —— 只等 done|error 会死循环(这俩永远不会变成 done)
# ↑ task_id 可留空:留空返回最近一次任务(丢了 task_id 时的救场手段,不必重跑同步)
# ↑ synced=已抓取条数(领先于落库);committed=**真实入库行数**(判断进度以它为准)
# ↑ 轮询到 done/error 为止;出报告前判样本量用 committed,不要用 synced⚠️ MCP 不可用(用户尚未点信任 / 工具没注册)时,同步立刻改用 CLI 兜底,不许停在这里干等:
python run_sync_once.py --platform taobao --days 15(等价能力,见下方「兜底路径:CLI」)。读库出报告同理:
python -m interfaces.cli --db data/rephub.db report ... --no-sync。
第4步对应命令(流程见上方「使用流程 · 第4步」,本节只放命令;auto_sync=false 不重复同步):
# 1. ToolSearch 加载 mcp__rephub__rephub_report
# 2. DeferExecuteTool 调用,关键参数:
# role="运营" form="full" window_days=15 export_formats="html" platform="taobao" auto_sync=false
# 返回:Markdown 全文 + 生成文件路径 → present_files 展示给用户可选聚合查询(不拉数,只读本地库):
# mcp__rephub__rephub_aggregates(window_days=15, platform="taobao")
# 返回结论型聚合 JSON:总量/差评率/追评率/DSR/痛点词/事件
# 探底用法(第2步 committed=0 时):window_days 放大到 365 再查,判断「本地有没有任何历史」即时直查原始评价(不落库,按条件查少量原文):
# mcp__rephub__rephub_search_reviews —— 四维度 AND 组合查询
# platform(必填) / days(默认15) / start_date+end_date(优先于days) /
# title_keyword(按商品标题包含匹配,Python层后置过滤) / item_id(直传jusico) /
# shop / limit(默认20,上限50) / offset
# 返回:原始评价明细(review_id/item_title/content/append_content/reply/rating_label/...)
# 红线:仅用于「按条件看几条评价原文」;大批量分析走 rephub_sync + rephub_report
# 示例:
# 按产品ID查: rephub_search_reviews(platform="taobao", item_id="123456", days=30)
# 按时间段查: rephub_search_reviews(platform="taobao", start_date="2026-09-01", end_date="2026-09-15")
# 按标题关键词查: rephub_search_reviews(platform="taobao", title_keyword="电动牙刷", days=30)
# 组合查询: rephub_search_reviews(platform="taobao", item_id="123456",
# title_keyword="电池", start_date="2026-09-01",
# end_date="2026-09-15", limit=20)
# 注意:title_keyword 是 Python 层后置过滤(在 jusico 返回窗口内匹配 item_title),
# 若 jusico 一次返回的 N 条里没匹配项,会提示「无匹配,建议加大 limit 或缩小 days」。兜底路径:CLI(仅以下场景使用)
- MCP 工具不可用 / 报错
- 需调
--max-workers(并发分页线程数,MCP 未暴露) - 开发期改完代码需绕过 MCP Server 直接验证同步链路
# 同步(MCP 与 CLI 的 --max-rows 默认都是 5000,无需区分;要更多显式上调)
python run_sync_once.py --platform taobao --days 15
python run_sync_once.py --platform taobao --days 15 --limit 100 # 控体积测试
python run_sync_once.py --platform taobao --shop <id> --max-rows 20000 # 指定店铺/上调上限
# 出报告
python -m interfaces.cli --db data/rephub.db report --tenant T1 --project P1
--platform taobao --role 运营 --form full --window 15 --export html --no-sync
# 旧一条龙入口(保留作「快速出报告」兜底,默认流程不优先)
python -m interfaces.cli --db data/rephub.db run --tenant T1 --project P1
--platform taobao --role 运营 --form full --window 15 --export html
# 常用开关:--no-sync(跳过同步直接用本地数据)、--force-sync(强制重拉)、
# --max-workers N(并发分页线程数,默认 3,与 MCP 路径一致;1=串行)代码更新后的重启 / 验证(开发期 · 默认用户手动触发)
改动生效方式按层不同——别一律重启整个应用(对照上方「改完代码要做什么」表):
# 1 绕过 MCP 直接验证业务逻辑(最优先:无需重启任何东西,直接驱动 UseCase)
python run_sync_once.py --platform taobao # 默认 15 天、上限 5000
python run_sync_once.py --platform taobao --days 15 --limit 100 # 控体积测试
python run_sync_once.py --platform taobao --shop <id> --max-rows 20000 # 指定店铺/上调上限# 2 一键重启 rephub-service(改了业务层 / mcp_core / rephub_service 时推荐)
powershell -ExecutionPolicy Bypass -File restart_mcp.ps1 -ServiceOnly
# 脚本会:结束旧进程 → 用原解释器重新拉起 → 轮询 /health 直到就绪 → 打印结果。
# 想连同 MCP 入口一起重启:
powershell -ExecutionPolicy Bypass -File restart_mcp.ps1 -Service⚠️ 在 Bash 里嵌套调用
powershell -File …可能被安全策略拒绝(表现为 exit 1 且无输出、service 其实没重启 —— 2026-09-18 实测)。此时改用 PowerShell 工具直接执行脚本
(
Set-Location到 skill 根 →& .restart_mcp.ps1 -ServiceOnly),脚本本身没问题。判断有没有真重启:看
/health的pid是否变化。
service 重启后
/health的credential若为missing属正常的待录入状态,不是故障。
# 手动方式(脚本不可用时):查 PID → 结束 → 重新拉起
curl -s --noproxy '*' http://127.0.0.1:8731/health # 先看状态:jusico / credential / tools
# ↑ --noproxy 不可省(红线 6):本机有代理时不加会拿到代理的 502,把"服务没运行"误判成别的故障
cat data/rephub_service.pid # 查 PID(文件缺失时看 8731 端口占用)
python interfaces/rephub_service.py --port 8731 # (后台常驻)启动后会重写 pid/port 文件⚠️ service 不是宿主拉起的:杀掉后宿主不会自动重开,必须手动重新拉起。
bridge 的②级自愈可以临时补位,但那样拉起的 service 继承桥所在沙箱 → 同样无外网
(本地查询可用、jusico 仍失败),不能当正式手段,仅限救急。
# 3 让宿主重新加载 bridge(改了 mcp_bridge.py 时)
powershell -ExecutionPolicy Bypass -File restart_mcp.ps1 -List # 预览进程(不杀)
powershell -ExecutionPolicy Bypass -File restart_mcp.ps1 # 结束 bridge,宿主自动重拉当前会话不会刷新 MCP 工具索引 —— 重拉后工具仍不出现是正常现象,重开一次会话即可;
仍不行才让用户重启宿主应用。
⛔ 改了
mcp.json的 command / args / env 后工具会全部消失,这不是链路故障 ——配置 hash 变了导致旧信任作废,宿主直接跳过该 server。让用户去连接器设置里重新信任即可,
不要去改
mcp-approvals.json。
进阶命令(非默认流程,cli --help 共 21 个子命令):init / schedule / trigger-check / trigger-run / report-history / report-wizard / export / suggestion-* / capabilities / role-views / platforms 数据导入(从外部文件补数据,不经 jusico):sync-csv / sync-json
sync-json读 RepHub 后端导出的sync_pullJSON(见infrastructure/sync/mcp_adapter.py,兼容信封 / 顶层表名 / 裸数组三种形态);
sync-csv读 CSV。两者与 jusico 同步实现同一SyncPort。
完整命令 / 架构 / 红线
按需查阅(默认不读):以下文件仅在命中对应场景时才定向
read,绝不预读或全目录扫描。
| 场景 | 才读的文件 |
|---|---|
| 报错排障 / 查完整命令参数 | ARCHITECTURE.md |
| MCP 链路架构 / 工具消失 / 跨工具部署 | docs/开发文档/MCP集成架构专项-rephub服务化跨工具零配置直连根治方案.md(含实测记录 F1–F11) |
| 接新平台(加适配器+凭证) | infrastructure/sync/registry.py(四处同改:①config/platforms.json ②registry 的 register_platform ③infrastructure/sync/{平台}_adapter.py ④assets/choice-panel-platform.jsonl) |
| 联调 jusico 原始接口 | infrastructure/sync/jusico_client.py |
| 术语口径 | glossary.md |