主题
跨端交接:词汇插图 emoji 列 → RB reseed
日期:2026-06-06 方向:RVH(加 emoji 列 + 复核回填 + 重导出)→ RB(reseed 重导入 + Phase 3 接线) 前序需求:RB docs/cross-end/04-word-illustration-handoff.md(RB 交付 726 候选 + 生成器,委托 RVH 落库) 关联:跨端红线 #10、CHANGELOG [Unreleased]、RB docs/plans/archive/word-illustration-plan.md Phase 3
背景
RB 做「具象名词配 OpenMoji 插图」增强。emoji 是词内禀、语言通用、双端共需的数据,按红线 #10 必须由 RVH pipeline 单点产出进预装库 reading_vocab.db,RB byte-equal 只读消费。本次为 RVH 侧落库 + 回流。
RVH 侧改动
Schema:vocabulary 新增 emoji TEXT(v52→v53)
sql
emoji TEXT -- OpenMoji hexcode 大写(如 '1F436')/ NULL=无图- 存 OpenMoji hexcode 大写(不存 unicode 字符),便于直接映射打包的
openmoji/{hexcode}.svg。 - 词级一词一图(挂
vocabulary.wordPK),正交于 CEFR / word_tags。 - 不进 Supabase 同步矩阵(预装库权威数据,与 vocabulary 表跨端策略一致,无需改 9 表同步引擎)。
回填(严格 / 质量优先档)
RB 交付 726 候选 → RVH 人工复核 505 采用:
| 桶 | 候选 | 采用 | 口径 |
|---|---|---|---|
| tier1(名字=词) | 335 | 326 | 直接采用;同形词主导义弱者弃(bank/bat/fly/key/mouse/watch/rock/seal)+ 动词主导假名词 pick |
| tier2 is_head=1(中心词命中) | 180 | 114 | 剔除图被修饰词主导 / 义项错位(face=monkey face, car=railway car, engine=fire engine, mask=diving mask…)+ 抽象/介词假 head |
| tier2 is_head=0(非中心词) | 211 | 65 | 默认弃(颜色/数字/介词/形容词假阳性);白名单留「emoji 真正描绘该词」者(chocolate→🍫, beach, globe, soccer…) |
| ambiguous=1 | (45) | 仅 14 | 主导义强者留:star/ship/train/drum/pen/ring/bug/hammer/ruler/plate/shell/bowl/bridge/file |
- 去重 hexcode:489(RB 打包 SVG 数)。
- CEFR 分布:A1=195, A2=126, B1=117, B2=64, C1=3。
- 复核固化为脚本
tools/vocabulary_builder_v3/scripts/curate_word_emoji.py(嵌入 DROP/KEEP 覆盖名单,确定性可复现、可审计)+ 提交进仓库的锚点data/word_emoji_mapping.tsv(全 726 行 +keep列,保留复核 provenance)。RB 若要重生成候选,原始 726 候选镜像在data/word-illustrations-mapping.tsv。
严格档落 505(低于 RB 04 文档预估 550–650):按 RVH「低质=负收益」原则,凡 emoji 可能误导(错义 / 图被修饰词主导 / 抽象词)一律弃。可在
curate_word_emoji.py的IS_HEAD0_KEEP/AMBIGUOUS_KEEP名单按需放宽。
pipeline 接入(确定性)
generate_db._applyEmojiMapping 在 Step 6 导出时读 word_emoji_mapping.tsv 的 keep=1 行,按 word(小写 join,COLLATE NOCASE 语义)写 entry.emoji。不调 LLM,确定性。
确定性 / byte-equal 验证(实测)
| 校验 | 结果 |
|---|---|
| pos_definitions 内容 sha(改动前 vs 后) | 完全一致 bb065041… —— 仅 emoji 列新增,pos_definitions 零漂移 |
| 含 emoji 连跑两次内容 sha | 一致 3a13123c…(确定性 OK) |
| 词数 / 非 preinstalled / bad CEFR / 例句>150 | 12291 / 0 / 0 / 0 |
| emoji 覆盖 / 去重 hexcode | 505 / 489 |
| 抽查 | apple→1F34E, dog→1F415, chocolate→1F36B, star→2B50, ship→1F6A2;bank/watch/blue=NULL ✓ |
RB reseed 所需值
| 项 | 值 |
|---|---|
| 新 DB 路径 | assets/databases/reading_vocab.db |
| 文件 SHA256 | a8d7f81b86f09133e5ba938eef4839da1e00c2f40c9da023576391ac2826a41b |
_preinstalledVocabVersion | 16(RVH 侧,15→16) |
RVH _schemaVersion | 53(仅供参考,RB 自管自己的 migration 版本) |
| pos_definitions 内容 sha | bb065041c2728c514366e7d53bea09eef71e262897fc2f35c09357a713221489(与 v15 相同,pos_definitions 未变) |
文件 sha 与 v15 不同属正常(emoji 列 + created_at 时间戳)。RB reseed 比对 pos_definitions 内容 sha 未变,本次纯 additive 加 emoji 列。
RB 侧待办(= RB plan Phase 3)
- migration(
migrations.rs新版本):runtimevocabulary表ALTER TABLE ADD COLUMN emoji TEXT。 - reseed UPSERT(
helpers.rsATTACH + INSERT SELECT):加入emoji列,ON CONFLICT(word) DO UPDATE覆盖emoji(同 pos_definitions 治理语义);bumpVOCABULARY_SEED_VERSION。整包覆盖走scripts/sync-rvh-vocabulary.sh。 - dictionary 读取:
dictionary.rs::extract_pos_groups/lookup_word读入 emoji;src/types/index.tsDictEntry加illustration_hexcode?。 - UI:
WordDetailView.tsx标题区 +ReviewCardFace.tsx正面接已建的WordIllustration组件;scripts/fetch-openmoji-assets.sh拉 489 个 hexcode 的 SVG 到public/openmoji/。 - 署名:Settings/About 放 OpenMoji CC BY-SA 4.0 署名。
RB 走
/vocab-reseedskill 消费本交接(资产 cp + 运行期 UPSERT + bump)。emoji 是 additive 列,RB/Edge 解析忽略未知列即可,不破坏现有 vocabulary 读取。
RVH 侧后续(本会话未做)
RVH 自己的 Flutter 插图 UI(OpenMoji color SVG 打包进 assets + WordIllustration 组件 + 接 WordDetailView/ReviewCardFace + Settings/About 署名)本会话延后——emoji 列已就绪,不阻塞 RB。