Skip to content

词汇与构词领域知识

最后更新:2026-06-15 本文档沉淀 Lampio 涉及的语言学/构词学领域概念——不是规划,也不是实现说明, 而是产品功能背后的业务知识:每个概念是什么、彼此的边界、以及它落在 app 的哪张表 / 哪个界面。

用途:做词汇相关功能(词源卡、近义辨析、消歧、cloze、词形还原)时,先在这里对齐术语, 避免把「词根」当「词目」、把「词族」当「词形」之类的概念混淆带进代码和文案。


1. 构词学四概念:词源 / 词根 / 词族 / 词形

这是最容易混淆的一组。一句话先框住关系:

词根嵌在词源里,词族是词源的兄弟,词形是同一个词的语法外衣。

transfer 为例:

                       transfer(一个词)

   ┌────────────────────────┼────────────────────────┐
   │(往后看历史)           │(往外长:别的词)       │(往内看:同一个词的语法变化)
   │                        │                         │
  词源                     词族                       词形
  源自拉丁语 transferre    transferable(形)          transfers(三单)
  「搬过去」               transference(名)           transferring(现分)
   └─ 词根(词源的零件)    transferee/transferor(名)  transferred(过去式/过去分词)
      trans 跨越           transferability(名)
      ferre 携带           …                          (词义不变,只换语法外衣)
概念本质transfer 的例子app 里数据/界面落点
词源 etymology词的来历叙述源自拉丁语 transferre「搬过去」✅ 词源卡 1–2 行vocabulary.etymology(JSON {summary_en,summary_zh,roots?}
词根 root来历里的语素零件(词源的子集,非独立词trans 跨越 · ferre 携带✅ 词源卡「词根」行etymology.roots
词族 word family同家族的派生整词(构词网络,各有词性/各有其义)transferable · transference · transferee…✅ 词源卡「同族词」chipsvocabulary.word_family
词形 word forms同一个词的屈折语法变化(时态/单复数,词义不变transfers · transferring · transferred❌ 不展示vocabulary.word_forms(cloze 挖空内部用,见 §3)

关键边界(写代码 / 写文案时反复用到)

  • 词根 vs 词族 = 语素 vs 整词ferre/trans 不能单独当词用(零件);transferable 是成品词。 → 词根永远出现在词源叙述内部,词族永远是可点击的独立词 chips。

  • 词族 vs 词形 = 不同的词 vs 同一个词transfer → transferable新词(形容词,新义,进自己的词条); transfer → transferred 只是 transfer 的过去式(还是 transfer,只换了语法外衣,不单独成词条)。 → 这条决定了 app 为什么把词族做成 chips、却把词形藏起来:词族有学习价值(拓展词汇量),词形对学习者噪声大、价值低。

  • 方向不同 词源 / 词根 朝后看历史(这个词怎么来的); 词族 / 词形 看横向 / 纵向的构词关系(这个词长出了什么 / 变形成什么)。

反 folk etymology 纪律

词源数据预装时严守真实性:拿不准来历的词宁可留 NULL,不编「民间词源」。 典型如 posh/golf/tip 这类有流行 acronym 传说但语源学上证伪的词,etymology 全数 NULL。 (详见 docs/cross-end/12-etymology-handoff.md / 预装库 reseed v20)


2. 词目(lemma / 归一形)vs 词根

这两个不是一回事,schema 里的注释曾把 lemma 简写成「词根」,是不精确的。

概念是什么例子是不是独立词
词目 / 归一形 lemma一个词的词典基本形(去掉屈折后的标准查询形)transferredtransfermicemousebettergood✅ 是整词
词根 root词源里的语素零件(构词最小单位,见 §1)transfer 的根是 ferre/trans❌ 不是词
  • lemma = 词形还原(lemmatization)的结果,仍然是一个能查字典的完整单词,只是脱掉了「词形」那层语法外衣(§1 第四列的逆操作)。
  • app 里 vocabulary.word 主键存的就是归一形:写入前必经 lemmatizer::normalize()(lemmatize + NFC)。 用户在文中双击 transferred,存进生词本的是 transfer——这样跨端 PK 一致、复习时不会 transfer/transferred 重复入账。
  • word_page_links.lemma 列记录的是「这条语境里那个词的归一形」,不是形态学词根。

红线提示:写入 vocabulary / learning_entries / known_words 等表的 word 字段前必经归一, 否则破坏跨端主键一致性(CLAUDE.md 技术红线 #9)。这是「词目」概念在工程上的硬约束。

数据落点(2026-06-15 cross-end/13 lemmatizer 折叠):归一所需的 surface→base 映射(140,277 条)+ base 形集合(101,713 条;两个数经 2026-08-18 cross-end/24 从 140,370 / 101,646 变到 140,281 / 101,709, 再经 2026-08-25 cross-end/28 的 v27 残留修正变到现值) 此前是两个 include_str! 的 JSON 资产,现已折叠进预装库 lampio_dict.dblemma_surface_to_base / lemma_base_forms,运行时由 commands/lemmatizer.rs 只读直载进内存 (查词仍 O(1))。打包/加载的 byte-equal 资产由 3 → 1。归一算法(4 层管线)仍是两端各一份的代码,对齐义务不变。


3. 为什么词形(word forms)只在 cloze 内部用、不展示

复习卡 cloze(填空)正面要把生词从真实例句里挖空,让用户回忆。 但用户存词时读到的句子里,那个词可能是任意词形:存的是 transfer,句子里却是 transferred

→ 挖空匹配需要知道 transfer所有词形transfers/transferring/transferred), 才能在句子里定位并扣掉正确的那一个。这就是 word_forms 的唯一用途:匹配,不是展示

对学习者而言「transfer 的过去式是 transferred」信息量低、噪声大,所以不进任何卡面 / chips。 (对比 §1:词族进 chips 是因为它扩词汇量,词形不进是因为它没有新词义。)


4. 词义 / 义项(polysemy / sense)——消歧的根基

一个词条下往往有多个义项(sense):同一个 word、不同的释义,按词性和语义分裂。 存在 pos_definitions JSON 里(每个义项一条 gloss + examples + synonyms…)。

核心业务问题:一词多义时,用户此刻读到的是哪一个义项?

  • 例:bank 在「river bank」和「open a bank account」里是两个完全不同的义项。
  • 直接把所有义项堆给用户 = 噪声;标错义项 = 自信地误导(比堆所有义项更糟)。

app 的处理(roadmap ⑥ 系列):

  1. 双击查词时,把当前句子 + 候选义项交给 Edge Function disambiguate-sense 选「贴合义项」。
  2. 存的是义项的 gloss 文本(不是 sense_index)——规避预装库 reseed 后义项顺序漂移导致「自信标错」。
  3. 复习翻面时按 gloss 文本重新定位,给贴合语境的那条释义打绿底高亮。

设计教训(已写进 project memory project_word_sense_disambiguation): Phase 0 本地 Lesk 算法实测放弃——例句噪声 + 字面匹配会产出自信的错误徽标(反例 number)。 消歧宁可不标,不可标错。义项选择交给 LLM 而非本地启发式。


5. 搭配 / 近义 / 辨析——三种不同的词间关系

近义辨析功能(roadmap ⑤)背后是三个不同的关系,容易混为一谈。三者都挂在 pos_definitions 每个义项内部:

关系是什么例子(以 big 义项为例)数据键
近义词 synonym义近、可能可替换的词large · huge · enormoussynonyms
辨析 differentiation近义词之间怎么区分用(细微差别)hugebig 程度更强、更主观differentiation[{synonym,distinction_en,distinction_zh}]
搭配 collocation这个词习惯和谁一起出现(固定组合)big decision · big mistake(不说 large decisioncollocations[{pattern,note_zh}]

边界

  • 近义 vs 搭配 = 能换的词 vs 能连的词 近义关注「这个词≈哪个词」;搭配关注「这个词常接哪个词」。 largebig 的近义;big dealbig 的搭配——搭配里换成近义 large deal 反而不地道。

  • 近义 vs 辨析 = 列出来 vs 讲清楚 光给近义词列表(big ≈ huge ≈ enormous)学习者还是不知道何时用哪个; 辨析就是补上「huge 强调体量惊人、enormous 更书面」这层可操作的区分

这三键随 pos_definitions 整体由 RVH 预装库 pipeline 单点产出(reseed v19 起), RB 侧不就地修改(技术红线 #10)。


6. 这些概念在 vocabulary 表的落点速查

概念列 / 键性质
词目(归一形)word(PK COLLATE NOCASE)写入必经 lemmatizer::normalize
词源etymology(JSON {summary_en,summary_zh,roots?}独立列;merge 时单独 DO UPDATE SET
词根etymology.roots(词源 JSON 内部)语素,非独立词
词族word_family派生整词网络
词形word_forms仅 cloze 匹配用,不展示
义项pos_definitions[].gloss消歧选「贴合义项」存 gloss 文本
近义 / 辨析 / 搭配pos_definitions[].{synonyms,differentiation,collocations}三关系,义项内部
插图emoji(OpenMoji hexcode)不进同步矩阵
难度primary_cefr_level(A1–C2)+ cefr_inferred/cefr_sourceCEFR;inferred 标识来源可信度

所有这些列由 RVH 预装库 pipeline 单点产出,RB / RVH 两端 byte-equal 共享 lampio_dict.db(技术红线 #10)。 运行时只 ATTACH 只读读取,绝不就地 ALTER / UPDATE。 列的完整 schema + 同步矩阵见 docs/database-schema.md,跨端交接细节见 docs/cross-end/


7. 预装词库的数据源(RVH pipeline)

⚠️ 这段话过期过两轮,现已订正:流水线 2026-07-19 就迁进了 RB,物理位置是 tools/vocabulary_builder_v3/(README + config.yaml 是权威说明),RVH 降级为纯消费方; 2026-08-28 合仓后 RVH 也不再是独立仓(= 本仓 rvh/)。改 pipeline 就在 RB 会话做, 不需要换会话(会话隔离的判据是工具链,见 CLAUDE.md §9 —— 而这个 pipeline 虽然是 Dart, 跑的是 dart run、不碰 Flutter)。预装库单点见技术红线 #10 / /vocab-reseed skill。

预装库不是单一来源,而是多源融合 + LLM 增强:不同来源各补不同字段。一句话概括分工—— 词表来源决定「收哪些词、什么难度」,Kaikki 提供「词条主体内容」,LLM 补「Kaikki 缺的 + 教学增值的」。

7.1 字段 → 来源 映射(核心)

字段主来源性质
收词范围 + CEFR 难度Oxford 5000 / CEFR-J / Google 词频词表三源(见 §7.2)
英文释义 glossKaikki (Wiktionary)词条主源抽取
例句 examplesKaikki 优先 + LLM 补全平行数组 example_source 逐句标 corpus/llm(见 §7.4)
IPA 音标Kaikki抽取
词性 POS / 近义 synonyms / 反义 antonymsKaikki抽取
词形 word_formsKaikki(屈折数据)抽取(§3 cloze 匹配用)
词族 word_familyKaikki(derived 正向 + etymology_templates 反向扫描)+ Google 词频过滤抽取+过滤,非 LLM
中文释义(sense 级)LLM(默认 DeepSeek)翻译,强制相邻义项译文相异
近义辨析 differentiation + 搭配 collocationsLLM生成(roadmap ⑤,§5)
词源 etymology(summary + roots)LLM生成,反 folk etymology(roadmap ⑦,§1)
插图 emoji人工复核的 word→OpenMoji hexcode 映射表静态映射
音频 audio下载 MP3(A1/A2/B1)/ URL(B2-C2);Free Dictionary API 兜底 URL见 §7.5

易错点:词族是 Kaikki 抽取的、词源是 LLM 生成的——虽然 §1 里它俩是「兄弟」概念, 但数据来路完全不同。词族有 Wiktionary 的派生关系可挖,词源叙述则需要 LLM 写(且严守真实性宁缺毋造)。

7.2 词表三源(决定收哪些词 + 难度)— Step 1

按优先级合并、按小写 headword 去重:

  1. Oxford 5000 — 骨架,自带官方 A1–C2 CEFR 分级。
  2. CEFR-J Vocabulary Profile(7799 词)— 补 A1–B2 覆盖。
  3. Google Web Trillion 词频(333k 词)— 取 top 20k,按词频 rank 推断 C1/C2(rank<10000→C1,≥10000→C2,伪 CEFR)。

过滤:停用词 / 单字母 / 纯数字。 ⚠️ 专有名词并没有被收词阶段过滤掉 —— config.yamlexclude_proper_nouns: true 是个 死开关wordlist_builder.dart::_shouldExclude 从没读过它),专名照常进 vocabulary。 此处曾写作「专有名词移去 reference_words,不进 vocabulary」,那是从未存在过的行为 (2026-08-31 订正)。今天专名在运行时由 src-tauri/src/db/vocab_scope.rs 的谓词挡在 「可学 / 计难度」之外(vocabulary 里仍有它们,因为「可查」角色需要); 收词阶段真正落实这道闸是 L-C 的活,见 docs/plans/proper-noun-governance-plan.md。 → 这就是 cefr_inferred / cefr_source 两列的由来:Oxford/CEFR-J 给的是权威 CEFR,Google rank 推断的标 inferred

7.3 词条主源:Kaikki (Wiktionary) — Step 2/3

Kaikki 是 Wiktionary 的结构化 JSONL dump,单词内容的主数据源。按 master wordlist 匹配抽取, 跳过对学习者无关的 POS(name/symbol/affix/prefix/suffix/particle/numeral/article)。 中文释义由 CC-CEDICT 选配补充,音频 URL 由 Free Dictionary API 兜底。

7.4 例句的双来源(重要细节)

例句不是单一来源:Kaikki 真实语料优先,LLM 只补 Kaikki 缺例句的义项

  • examples 数组与 example_source 数组平行,逐句标 corpus(来自 Kaikki/Wiktionary 真实语料)或 llm(生成)。
  • LLM 补全是确定性缓存data/generated_examples.json 提交进 RVH 仓库),不是每次构建重新请求——保证可复现。
  • 同理 differentiation / etymology 也是提交进仓库的确定性缓存(differentiation.json / etymology.json)。

这解释了运行时另一条线 lookup-or-fetch-word Edge Function:用户查到预装库外的词时, 走同样的 Kaikki+清洗逻辑实时兜底(例句清洗规则三端严格对齐,见 §7.3 kaikki_parser 注释)。

7.5 质量门槛(quality governor)

pipeline 末尾按阈值卡关,达不到不出库:CEFR 覆盖 100%、英文释义 >98%、IPA >90%、 例句 >80%、中文翻译 >85%、义项区分率 >90%(抽样 200 词人工复核)。 → 这是预装库「12,291 词、字段高覆盖」质量保证的来源。

7.6 LLM provider 纪律

中文翻译 + 例句/辨析/词源生成默认用 DeepSeek(成本低),可切 Claude(质量高 ~10×)/ OpenAI。 换 LLM provider = pipeline 大版本号 bump(RVH 红线)——因为生成内容会变,影响 byte-equal 与跨端一致性。