食查查 (ShiChaCha) — 买前查一查,避坑黑心商家黑心食品
面向消费者的产品/品牌「负面舆情避坑」Agent。核心命题不是"这个产品好不好吃",而是:
这个牌子背后的人、公司、工厂,有没有坑?
一、触发场景
- 用户上传/提供产品照片(包装、标签、货架图、电商详情截图)。
- 用户手动输入品牌名 / 产品名 / 生产厂家名。
- 用户问:"这个牌子靠谱吗""能买吗""有没有被曝光过""帮我查查代工厂""创始人是谁"。
二、交付物(每次分析必须全部产出)
| 产物 | 文件 | 说明 |
|---|---|---|
| 报告看板(主交付物) | report.html |
分析报告以数据看板形态呈现:结论仪表盘、A–E 等级色带、KPI 卡、扣分构成条形图、严重度堆叠条、时间线、实体图谱、外媒模块、明细表、行动建议清单。单文件 HTML + 内联 SVG,离线可开,可直接打印为 PDF。不输出纯文案报告。 |
| 推荐分 | score.json |
确定性算法计算,可复现;信息不足返回 null |
| 原始数据 | findings.json / queries.json / case.json |
全链路可溯源 |
| 压缩包 | <case-id>.zip |
一键交付 |
> 输出形态铁律:报告即看板。所有结论必须以图表 / 卡片 / 表格 / 清单承载,不允许交付长篇纯文本报告。每一节都对应 report.html 里的一个可视化区块。
二·五、付费门控与计费(PaySkill · 支付宝 AI 按量付费)
本技能是 PaySkill:免费提供「输入解析 + 风险原因清单 + 检索计划」;完整分析(报告 + 看板 + 推荐分 + 打包)为付费资源,走支付宝 AI 按量付费(A2M / HTTP 402 Payment Required)在对话内闭环收款。
计费
| 项 | 值 |
|---|---|
| 渠道 | 支付宝 AI 付(alipay) |
| 产品 | AI按量付费(基于 402 Payment Required 的 A2M 方案) |
| 协议 | x402 |
| 单价 | ¥2.00 / 次(pay_price: "2.00",pay_currency: CNY) |
| 资源标识 | /shichacha/analyze(resource_id,用于防串单) |
| 支付依赖包 | @alipay/alipay-aipay(另有 alipay-sdk 用于服务端验签/回执) |
| 门控实现 | scripts/payskill.js |
四个动作(probe / pay / complete / ack)
| 动作 | 端点 | 作用 | 关键返回 |
|---|---|---|---|
| probe | POST /payskill/probe |
探测资源是否需付费。检查请求头有无 Payment-Proof;无则返回 402 Payment Required,并在 Payment-Needed 头放入 Base64URL 账单 |
402 + Payment-Needed + {error:"Payment Needed", message, resourceId} |
| pay | POST /payskill/pay |
用账单发起支付,把二维码/支付链接交给用户 | {orderId, amount, qrCode, payForm, message} |
| complete | POST /payskill/complete |
用户支付完成后携带 Payment-Proof 重试;服务端调 alipay.aipay.agent.payment.verify 核验凭证,通过则交付资源 |
200 + 资源内容 |
| ack | POST /payskill/ack |
交付后异步调 alipay.aipay.agent.fulfillment.confirm 发履约回执 |
{code:"10000"} |
协议时序
用户/Agent 商家服务端(scripts/payskill.js) 支付宝
│ probe(无凭证) │ │
├─────────────────────────────────────►│ 生成账单+本地RSA2签名 │
│◄──── 402 + Payment-Needed(Base64URL)─┤ │
│ pay(展示二维码/支付链接) │ │
├─────────────────────────────────────►│ 创建订单,写 orders.json │
│◄──── {orderId, qrCode, payForm} ─────┤ │
│ 用户扫码付款 ───────────────────────────────────────────────────────►│
│ complete(带 Payment-Proof) │ │
├─────────────────────────────────────►│ payment.verify ────────────────►│
│ │◄── active/amount/out_trade_no ──┤
│◄──── 200 + 报告/看板/推荐分 ──────────┤ 异步 fulfillment.confirm ──────►│
核验通过判定(缺一不可)
active == true 且 amount == 本次单价 且 out_trade_no == 本地订单号 且 resource_id == /shichacha/analyze 且 trade_no 未被重复履约。任一项不通过 → 重新返回 402 Payment Required 让用户重新支付。
账单(Payment-Needed 解码后)
protocol 层:out_trade_no / amount / currency / resource_id / pay_before / seller_signature / seller_sign_type(RSA2) / seller_unique_id。
method 层:seller_name / seller_id / seller_app_id / goods_name(=「食查查 · 品牌风险分析 1 次」) / seller_unique_id_key / service_id。
加签字段(按 key 字典序拼接后 RSA2 签名,仅本地完成、不请求支付宝):
amount · currency · goods_name · out_trade_no · pay_before · resource_id · seller_id · service_id
支付凭证(Payment-Proof 解码后)
protocol:payment_proof / trade_no;method:client_session。三者即为 payment.verify 的入参。
> 完整字段表、加签串示例、错误码与沙箱测试见 references/payskill.md。
> 启动门控:node scripts/payskill.js(依赖先执行 npx -y @alipay/alipay-aipay@latest install)。
三、工作流(严格按顺序执行)
Step 0 — 建立案件
python scripts/init_case.py --brand "品牌名" --product "产品名" --category "品类" --out cases/<case-id>
--brand必填;--product、--category可空(系统按品牌名启发式推断品类,LLM/检索后可覆盖)。--image <照片路径>可选(仅记录路径,实际识图见 Step 1)。- 产出
case.json(输入与元信息)、findings.json(空骨架)、queries.json(检索计划)。
Step 1 — 输入解析与实体抽取
照片路径:用多模态能力读取图片,从包装标签提取:
- 品牌名 / 产品名
- 委托方(品牌运营主体)
- 受委托生产方 / 生产商 / 分装商 = 代工厂 OEM
- 生产许可证编号(SC 开头)、产地、条码
> 标签术语对照见 references/entity-extraction.md。代工厂是关键——很多品牌出问题根源在代工方。
手动输入路径:直接规范化品牌名,必要时纠正常见别名/错别字。
Step 2 — 实体图谱扩展(这一步决定查得深不深)
围绕品牌构建 4 类实体,写回 findings.json 的 entities:
| 类型 | type 值 |
说明 | 权重系数 |
|---|---|---|---|
| 品牌/产品 | brand |
查询主体本身 | 1.0 |
| 核心关联公司 | company |
品牌运营主体、母公司、股东公司 | 1.0 |
| 创始人/实控人 | founder |
创始人、法定代表人、实控人、高管 | 0.9 |
| 生产厂家 | manufacturer |
自有工厂 | 1.0 |
| 代工厂 OEM | oem |
受委托生产方、分装商 | 1.0 |
| 其他关联方 | related |
关联公司、历史主体 | 0.6 |
扩展手段:检索"XX 品牌 生产厂家""XX 公司 股东""XX 法定代表人""XX 委托生产";优先采信监管通报、企业信用公示、招股书/年报、法院文书。
写入命令:
python scripts/add_finding.py --case cases/<case-id> --entity '{"type":"oem","name":"XX食品有限公司","role":"受委托生产方"}'
Step 3 — 全网舆情检索(多引擎、多信源)
首选:直接用内置的 WebSearch / WebFetch 工具执行 queries.json 里的查询(无需任何 API Key,最稳)。
备选/补充:scripts/search_sources.py(DuckDuckGo / Bing / Google News RSS / Tavily)。
对每个实体 × 每个风险原因生成查询。风险原因完整清单(6 组 42 项 + 定义 + 默认严重度)见 references/risk-causes.md,查询模板见 references/query-templates.md:
| 组 | 风险原因 |
|---|---|
| A 食品安全(直接健康风险) | 抽检不合格 / 微生物超标 / 添加剂违规 / 非法添加 / 污染物超标 / 过期变质 / 篡改生产日期 / 标签标识违规 / 产品召回 / 食品安全事故 / 生产环境不达标 |
| B 经营合规 | 行政处罚 / 无证生产经营 / 虚假宣传 / 价格违法 / 计量作弊 / 环保违法 / 税务违法 / 经营异常 |
| C 信用与司法 | 被执行人 / 失信被执行 / 限制高消费 / 诉讼纠纷 / 股权冻结资产查封 / 破产重整清算 / 吊销注销 |
| D 劳动与供应链 | 欠薪欠款 / 劳动纠纷工伤 / 代工供应商违规连带 / 原料来源不明 |
| E 造假与诚信 | 假冒伪劣 / 检测认证造假 / 虚假产地冒充进口 / 商标侵权不正当竞争 / 瞒报隐瞒 |
| F 创始人/实控人 | 实控人失信被执行 / 实控人行政处罚 / 实控人刑事处罚 / 关联交易利益输送 / 高管动荡团队流失 / 实控人失德言行 |
> 分类铁律:category 只记风险原因。
> - 「外媒报道」是信源属性,不是风险原因 → 用 is_foreign=true,category 填真实原因(如 产品召回)。
> - 「创始人负面」是主体维度,不是风险原因 → 用 entity_type=founder,category 填 实控人失信被执行 等具体原因。
> 写错会被 add_finding.py 直接拒绝。
交叉比对硬要求:同一查询至少覆盖 2 个独立信源;DuckDuckGo 结果偏少时必须补 Bing。把命中的结果数写回 coverage(queries_run、results_total、engines)。
Step 4 — 爆款外媒报道(国际信源)
- 用
Google News RSS(免 Key)与GDELT抓国际报道;查询用品牌英文名/拼音 + 公司英文名。 - 命中 Reuters / AP / BBC / CNN / Bloomberg / FT / NYT / Food Safety News / FDA / EFSA / RASFF 等 → 标记
is_foreign=true且source_tier=1/2,在看板中单独以「🌍 爆款外媒」模块高亮。 - 详见
references/foreign-media.md。
Step 5 — 深度抓取与取证
对每条候选负面,用 WebFetch 抓原文,抽取:时间、主体、事件、处罚/处理结果、来源机构。
信源分级见 references/source-tiers.md(1=监管/司法,5=社媒UGC)。
写入负面舆情(category 必须来自 risk-causes.md,未传 severity 时按该原因的默认严重度自动取值):
# 例1:国内监管通报 → 原因=微生物超标,官方来源
python scripts/add_finding.py --case cases/<case-id> --finding '{
"entity_type":"oem","entity_name":"XX食品有限公司",
"category":"微生物超标","title":"XX批次产品菌落总数超标",
"summary":"2024年市场监管局抽检…","date":"2024-05-11",
"source_tier":1,"source_name":"XX市市场监督管理局",
"url":"https://...","is_official":true,"corroborations":2}'
# 例2:外媒报道 → 原因=产品召回(不是"外媒报道"!),外媒身份用 is_foreign
python scripts/add_finding.py --case cases/<case-id> --finding '{
"entity_type":"brand","entity_name":"XX Brand",
"category":"产品召回","title":"Reuters: XX recalled over contamination",
"summary":"路透社报道…涉及区域为境外市场","date":"2025-03-08",
"source_tier":2,"source_name":"Reuters",
"url":"https://...","is_foreign":true,"corroborations":3}'
只写有 url 可溯源的条目;查不到就诚实留空,绝不编造。 条目会在看板中同时按「风险原因」和「风险分组」两个维度聚合。
Step 6 — 推荐分计算(确定性,可复现)
python scripts/score.py --case cases/<case-id>
规则(详见 references/scoring-rubric.md):满分 100,按 严重度权重 × 置信度系数 × 实体贴近度系数 累加扣分,下限 0。
一次都没检索到任何公开结果 → 推荐分返回 null,显示"信息不足,暂无法评分"。
| 分数 | 等级 | 建议 |
|---|---|---|
| 85–100 | A 推荐 | 未发现实质负面 |
| 70–84 | B 谨慎购买 | 轻微负面 |
| 50–69 | C 警惕 | 中等负面 |
| 30–49 | D 高风险 | 严重负面 |
| 0–29 | E 建议避开 | 重大/系统性负面 |
Step 7 — 生成报告看板与压缩包
python scripts/build_dashboard.py --case cases/<case-id> # → report.html(报告看板)
python scripts/package_case.py --case cases/<case-id> # → <case-id>.zip
唯一交付物是 report.html。 不要把分析结论写成 Markdown 长文——报告以看板形态交付。
用 present_files 把 report.html 呈现给用户(会自动打开实时预览),并在对话里只给极简结论摘要(推荐分 + 等级 + 一句话),细节让用户看板子里看。
四、脚本速查
| 脚本 | 作用 |
|---|---|
scripts/init_case.py |
建案件目录 + 生成 case.json/findings.json/queries.json |
scripts/add_finding.py |
追加实体或负面条目(校验后写入 findings.json) |
scripts/score.py |
确定性推荐分 → score.json |
scripts/build_dashboard.py |
把 score.json + findings.json 渲染成报告看板 report.html |
scripts/search_sources.py |
可选:脚本化多引擎检索(DDG/Bing/News RSS/Tavily) |
scripts/fetch_article.py |
可选:抓取正文用于取证 |
scripts/package_case.py |
打包案件产物为 zip |
scripts/payskill.js |
PaySkill 付费门控:402 / Payment-Needed / Payment-Proof + probe/pay/complete/ack |
五、红线与合规(必须遵守)
- 绝不编造:没有可信来源就不写条目;检索为空就返回"信息不足"。
- 区分事实与推断:推论必须显式标注"(推断)",且不得作为扣分的唯一依据。
- 对事不对人:只陈述公开的客观记录,不作道德审判,不使用侮辱性定性词。
- 避免误伤同名主体:公司名/人名高度重合时,必须核验统一社会信用代码、地址、产品品类,确认不了就标注"主体存疑"且不纳入扣分。
- 每份报告与看板必须带免责声明:
> 本工具所有分析信息来源于网络公开检索结果,由 AI 自动整理与推断,仅供参考,不构成购买、投资或法律建议;真实情况请以官方与权威监管通报为准。 - 演示/示例数据必须显式标注为「演示样例」,不得使用真实主体做示例。
- 付费合规:
Payment-Proof核验必须在服务端完成,不得在客户端放行;out_trade_no全局唯一用于幂等与防重复支付;同一trade_no不得重复履约;未配置商户密钥/私钥时门控必须 fail-closed(返回错误而非默认放行);seller_signature只在本地加签,不请求支付宝。