LISTING-AI-IMPLEMENTATION-REPORT-2026-08-21.md 12 KB

Listing AI 评分工作台实施与验收报告

日期:2026-08-21
范围:Saas-voc Angular 前端、Saas-voc-server 后端、目标 Parse 首轮全量数据
结论:规则评分基线已完成;固定 Rubric 的真实 AI 评分已初步落地并仅对受控样本验证,未对全量商品调用模型。

0. 当前初步发布状态(优先于下文历史说明)

  • listing-jd-v2 继续作为 824 个商品的确定性规则基线;当前最新结果分布为 823 个规则评分 + 1 个真实 AI 评分。
  • listing-jd-ai-v1 不是自由打分:模型只返回固定原子标准的等级、证据、理由和置信度,服务端按冻结权重合成分数。
  • 真实成功样本 10020401158454:规则基线 100,AI 综合分 62,模型 deepseek-v4-flash,Prompt listing-ai-score-p1。
  • 相同 sourceHash + rubricVersion + model + promptVersion 再次评分复用同一结果,不重复调用模型;实测缓存任务约 3.5 秒完成。
  • 前后端均限制单个 AI 任务最多 10 个商品;11 个商品请求在创建任务前返回 HTTP 429 listing_ai_budget_exceeded。
  • AI 失败不会覆盖既有规则分;源数据不足时结果为 partial,不会把 unknown 伪装成 0 分或通过。
  • 当前已知 UX 限制:创建任务后会进入任务详情;partial 页面的“重试失败项”文案可能造成误解,后续应改为“部分完成/缺少输入证据”。

1. 最终结果

本轮 JD 列表接口返回的动态商品总数为 824。全量同步与冻结评分任务结果如下:

指标 结果
源快照(去重 productId) 824
同步成功 / 失败 824 / 0
任务冻结总数 / terminal 824 / 824
有效数值评分 765
部分结果 59
blocked / failed 0 / 0
平均分(仅统计有数值结果) 97.0
missing / orphan / stale result 0 / 0 / 0
五维结构异常 0

最新规则任务:985b4dd5-f4c2-4d0c-9764-56652e496ed3,rubric 为 listing-jd-v2,状态为 partial。824 个 item 全部完成,其中 59 个商品因上游缺少必需字段而保留部分结果;维度不可评分数为卖点 4、详情 22、规格 40,各维度有重叠。系统没有把缺失字段伪装成 0 分。

listing-jd-v1 曾错误地把 JD features 中大量值为 0/1 的传输控制标记当成营销卖点,导致多数商品误中“合并重复卖点”扣分。按“rubric 不原地修改”的承重墙发布 v2:内部标记不再参与卖点评分;上游没有独立营销卖点字段时,重复性规则为 unknown 且不扣分。v1 结果仍保留用于审计。

任务时间为 2026-08-21 05:35:22.517Z 至 05:41:21.010Z,约 5 分 58 秒。该数据只作为当前环境基线,不承诺固定 SLA。

2. 已落地调用链

源 Parse EcomAuth(服务端取最新 token)
  -> JdTokenProvider
  -> JdSpClient(path/query/header 签名、超时、重试)
  -> JdProductClient(多页列表 + 商品详情)
  -> sync-jd-listings(去重、并发、checkpoint、幂等)
  -> ListingSourceSnapshot(Parse 或 PostgreSQL)
  -> ListingAiService + listing-jd-v2 rule engine
  -> Job / Item / Result / Version(可恢复、可审计)
  -> /api/listing-ai/*(认证、workspace RBAC、Zod、cursor)
  -> Angular ListingAiApiService / Store
  -> 工作台 / 商品详情 / 任务 / 版本页面

规则基线由版本化确定性规则产生;AI 评分只对固定语义标准作结构化判定,数值权重和总分仍由服务端计算。AI 不覆盖 JD 源快照,也不调用 JD 写接口。

3. 后端落地

3.1 核心能力

  • JD productId 作为 path 签名字段参与 MD5,但不重复出现在 query;itemStatus 兼容对象/字符串返回。
  • 列表全分页、多轮防抖去重、详情并发 3、超时/有限重试、checkpoint 原子串行写入和 --resume。
  • JD 图片相对路径归一化到受控 HTTPS CDN;HTML 服务端 allowlist 清洗。
  • listing-jd-v2 五维评分:标题、核心卖点、主图、详情、规格;每维保存 coverage、ruleId、fieldPath、证据和建议。
  • sourceHash + rubricVersion 保证确定性和结果幂等;源变化后旧分不作为当前分返回,旧版本标记 stale。
  • 批任务冻结 productId + sourceHash,支持幂等键、进度、取消、失败/部分重试,以及进程启动时恢复 queued/running 任务。
  • AI 输出通过严格 Zod schema;上游失败时不写入 AI 分并保留既有规则分。LISTING_AI_CONCURRENCY 和 LISTING_AI_MAX_ITEMS_PER_JOB 对并发与单任务费用上限做 fail-closed 控制。
  • 工作台真实 AI 入口只接受已选商品,前端和后端共同限制每任务最多 10 个商品。API 使用 scoringMode=ai|rules 区分 listing-jd-ai-v1 和 listing-jd-v2;后端拒绝超限请求时不会创建任务。
  • 版本只在内部创建/采纳;采纳前再次校验 sourceHash,并写 audit log。
  • Parse REST 与 PostgreSQL 两种持久化驱动均已实现;新增 PostgreSQL migration 007_listing_ai.sql 和 Parse schema。

3.2 API

Method Path 用途
GET /api/listing-ai/products 当前页商品 + 动态 summary/filter/sort/cursor
GET /api/listing-ai/products/:productId 清洗后的源详情、当前分、版本摘要
GET /api/listing-ai/products/:productId/scores/latest 当前 sourceHash 的最新评分
POST /api/listing-ai/score-jobs 以选中 ID 或筛选快照创建冻结任务
GET /api/listing-ai/score-jobs 任务列表
GET /api/listing-ai/score-jobs/:jobId 任务进度
GET /api/listing-ai/score-jobs/:jobId/items terminal/item/error 明细
POST /api/listing-ai/score-jobs/:jobId/retry 合法状态下重试
POST /api/listing-ai/score-jobs/:jobId/cancel 合法状态下取消
GET /api/listing-ai/versions workspace 版本列表
GET/POST /api/listing-ai/products/:productId/versions 商品版本列表/创建草稿
GET /api/listing-ai/versions/:versionId 版本详情
POST /api/listing-ai/versions/:versionId/adopt 内部采纳,不发布 JD

所有 endpoint 位于现有 /api 认证中间件之后,并使用 WorkspaceAccessService。写操作要求 analysis:run 或 action:write,且发起、重试、取消、创建版本、采纳都会写审计。

3.3 运维命令

真实凭据只通过服务端环境变量加载,不进入命令参数、Angular、日志或文档。

# 建表/建 Parse class 后,全量同步;中断后使用同一 checkpoint 恢复
npm run sync:jd-listings -- --workspace <workspace-id> --checkpoint logs/jd-listing-sync.json --resume

# 默认只执行确定性规则评分,不产生 AI 费用
npm run score:jd-listings -- --workspace <workspace-id>

# 校验 sources/results/job/items/orphan/stale/维度完整性
npm run verify:listing-rollout -- --workspace <workspace-id>

4. Angular 落地

新增 lazy route /listing-ai,包含:

  • /listing-ai/workbench:动态汇总、筛选/排序 URL 持久化、cursor 分页、选中/筛选批量评分;
  • /listing-ai/workbench/:productId:移动端预览、五维规则/AI证据、模型、Prompt、置信度和改进建议;
  • /listing-ai/tasks、/listing-ai/tasks/:jobId:任务列表、2–5 秒 polling、进度、item 错误、重试/取消;
  • /listing-ai/versions:版本、源 hash、状态、内容差异和内部采纳。

京东 tab 可用,天猫/抖音/拼多多明确禁用并显示“即将支持”。前端代码没有写死 614、821 或 824,首屏仅请求 summary 和当前页。证据展示合并在 listing-dimension-panel,版本 diff 合并在版本页面,没有增加无业务逻辑的包装组件。

5. 主要文件变动

后端新增

  • src/modules/listing-ai/domain.ts
  • src/modules/listing-ai/listing-ai.service.ts
  • src/modules/listing-ai/routes.ts、schemas.ts
  • src/modules/listing-ai/clients/*
  • src/modules/listing-ai/normalization/*
  • src/modules/listing-ai/scoring/rule-engine.ts
  • src/modules/listing-ai/repositories/*
  • migrations/007_listing_ai.sql
  • scripts/sync-jd-listings.ts
  • scripts/score-listings.ts
  • scripts/verify-listing-rollout.ts
  • test/listing-ai.*.test.ts、test/jd-sp-client.signature.test.ts

后端同时修改 src/app.ts、src/server.ts、src/local-app.ts、src/local-server.ts、src/config/env.ts、src/db/parse-rest.schema.ts、.env.example 和 package.json,只做依赖注入、路由、配置、readiness 和脚本接线。

前端新增

  • src/modules/listing-ai/models/*
  • src/modules/listing-ai/services/*
  • src/modules/listing-ai/components/*
  • src/modules/listing-ai/pages/*
  • src/modules/listing-ai/listing-ai.routes.ts
  • src/modules/listing-ai/listing-ai.shared.scss

前端同时修改 src/app/app.routes.ts、src/app/core/config/runtime-config.ts 和现有导航配置。未删除旧 route、旧页面、旧表或旧 Parse class。

6. 验证证据

验证 结果
后端 npm run typecheck 通过
后端 npm test 80/80 通过
Angular production build 通过,hash a89262792de71d81
Angular Listing AI 定向测试 2/2 ChromeHeadless 通过
本地 API smoke 目录分页、任务创建/执行、partial 语义通过
真实 JD shadow 20、100、824 逐级执行;最终同步 824/824
真实规则评分 824/824 terminal;765 scored、59 partial、0 blocked、0 failed
rollout verifier missing/orphan/stale/invalidDimensions 均为 0

7. 承重墙验证

  • 没有让 Angular 直连 JD 或 Parse;真实密钥只存在于被 .gitignore 命中的本地配置/服务端环境变量。
  • 没有修改现有 VOC 的 analysis_run 状态机,也没有改写 insight -> decision -> action -> validation 链路。
  • productId 全程按字符串处理;不从库存推导销量,不把 Listing 当 VOC。
  • 源快照、评分、建议版本分层;采纳不覆盖源,不调用 JD 写接口。
  • Parse 健康检查使用 class 资源;挂载根 404 不再被误判,HTTP 403/code119 只做有限重试。

8. 尚未解除的发布门禁

  1. AI 成本与质量批准:当前硬限制为每任务最多 10 个商品,并且只完成受控样本验证;在人工 golden set、一致性回归、总预算和日预算冻结前,不开放 824 商品全量 AI 评分。
  2. rubric 业务冻结:工程规则已升级为 listing-jd-v2 并保留 v1 审计记录;标题阈值、核心卖点口径仍需产品/运营对 20 个样本人工复核。后续口径变化继续发布新版本,不覆盖既有结果。
  3. 多实例强租约:当前启动恢复、幂等键和数据库唯一约束满足单 worker/受控部署恢复;若部署多个并发 worker 实例,需在领取任务前增加数据库级 lease/SKIP LOCKED。在此之前,同 workspace 只启一个 Listing score worker。

以上门禁不影响已经完成的 824 商品确定性评分和工作台联调,但会阻止“全量 AI 优化建议”和多实例 worker 直接开放生产。

8.1 任务状态语义

  • 创建成功后前端当前会导航到任务详情,用于观察异步执行进度;这是现有交互,不是服务端重定向。
  • failed 表示模型、网络、schema 或存储失败;此时不覆盖规则分。
  • partial 表示模型调用可能已经成功,但至少一个固定维度因源数据不足被判为 unknown,因此不生成伪造总分。
  • 例如商品 10020422869649 的真实 AI 请求已完成,但京东输入没有独立卖点文本,卖点维度为 unknown,任务因此为 partial 而不是调用失败。