词汇表¶
一个共享列表,列出 Hex 应该知道的人名、项目名和产品名;每个名称可附带可选的“听起来像”拼写,这些拼写是转录中可能出现的替代写法。空列表(默认情况)不会改变任何内容。窗口可在 macOS、Linux 和 Windows 上编辑该列表;hex vocabulary 命令目前仅限 macOS。
General › Vocabulary // vocabulary.settings; after Language
├── Row value -> "None", "1 term", "N terms" -> opens the Vocabulary sheet
├── Selected model takes no vocabulary (ModelDefinition::vocabulary_use)
│ -> muted note on the row and under the sheet's description: "SenseVoice
│ Small doesn't use these terms; rewriting and search still do"; Parakeet,
│ Underdog Bark, Whisper, and Qwen3-ASR (QwenCleo too) show none
├── Parakeet-based model with Labs › Vocabulary biasing off -> the sheet says
│ transcription uses the terms only with it on
├── Selected model reads fewer terms than the list holds -> muted line under
│ the sheet's description: "This model reads the first 38 of 52 terms"
│ (dictation::vocabulary::terms_read: Parakeet's 64-term cap or the
│ prompt's character budget, the same count transcription takes; scene
│ vocabulary-budget)
├── Sheet description -> what the list does, then "Terms with spaces match
│ only when said in full" (a term is matched whole; "Dax Rad" doesn't help
│ "Dax" said alone, so a name also said alone gets its own row)
├── Sheet rows -> Term | Sounds like (comma-separated) | ×; scroll past 8
├── Empty list -> Opens with one blank row focused; opening never animates rows
├── Add term -> New empty row, focused; the list glides to its end and the row
│ rises 8 pt as it fades in (SETTLE, bounce 0; Reduce Motion: fade only);
│ saved once the term has text
├── Edits -> Debounced drafts, like Modes' corrections -> settings.json `vocabulary`
├── × -> Removes that row at any click speed or focus; rows keep an identity,
│ so a late edit, focus change, or second × for a removed row touches nothing
├── Done, Escape, or a press outside -> Saves, drops blank rows, closes
├── Past the limits -> Keep the term (cut to 64 characters) and the spellings
│ that fit; inline danger note // never drops the term
└── Boost -> no control in the window: Normal (default) unless changed with
`hex settings set vocabulary_boost off|light|normal|strong`
(settings.json `vocabulary_boost`) // vocabulary.boost
Transcription (Parakeet: RNN-T and TDT, Underdog Bark and Nemotron 3.5 ASR too) // vocabulary.transcription; transcription::gguf_session::with_vocabulary
├── Only with Labs › Vocabulary biasing on (`labs.vocabulary_biasing`, off by
│ default; labs.md) -> off: no run takes the list; the sheet says so, and
│ rewriting and search still use it
├── Every run and live stream reads the list and the boost at its start:
│ dictation, meetings, captures, the local API
├── First 64 terms (the engine's cap) and their spellings; empty or Off -> unchanged
├── Whole-clip run on an RNN-T model (Parakeet unified): meetings, captures,
│ the local API, dictation that falls back to the whole clip
│ └── The greedy words stand; where the audio could also spell a term, the
│ decoder follows the term alongside them, and the term replaces them
│ only when its score plus the boost per term piece beats theirs at the
│ word boundary (0.6 × the boost when the words don't sound like it)
├── Live stream or TDT model -> after the greedy decode, spans of up to 4 words
│ that look or sound like a term (or match a "sounds like" spelling) are
│ rescored on the same audio frames from the same decoder state: the term
│ replaces the span only when its score plus the boost per term piece beats
│ the heard words'
├── Left alone: case-only differences, inflections ("Cappuccinos"), and addresses
│ and paths ("opencode.ai"); rescoring also skips terms under 5 letters
│ without a spelling, which the RNN-T decoder can still write ("Kip" -> Kit)
└── SenseVoice, Cohere, GigaAM, Granite, Apple Speech -> no vocabulary in transcription
Context prompt (Whisper incl. ivrit.ai and NB-Whisper, Qwen3-ASR, QwenCleo) // vocabulary.prompt-transcription; transcription::gguf_session::with_vocabulary
├── Always on (not Labs): replaced the per-model Recognition hints box (#129)
├── Every whole-clip run reads the list at its start: dictation, meetings,
│ captures, the local API; live streams run without it
├── "Term, Term, …": the first terms in list order, as many as fit 500
│ characters (Whisper: its prompt slot holds 223 tokens and trims an
│ overlong one from the front) or 1,000 (Qwen3-ASR's system message); the
│ 64-term cap is Parakeet's bias array only (#1246)
├── The sheet says how many terms the selected model reads when that is
│ fewer than the list; the 64-term vs full-budget hit rate is unmeasured
├── Whisper: transcribe.cpp's generic context prompt in the <|startofprev|>
│ slot; Qwen3-ASR: the system message
├── Output that only repeats the prompt (two or more terms) is dropped, as
│ both models return it on silence or noise (README.md#get-ready)
└── "Sounds like" spellings are not sent; rewriting and search use them
Recognition hints, folded in // vocabulary.hints
├── Loading settings.json -> `recognition_hints` of the selected model and the
│ recent models (newest first), split on commas, semicolons, and line
│ breaks, become terms; names already listed (any case) are skipped, and
│ the rewritten file drops the field
└── `hex settings get|set transcription.recognition_hints` -> deprecated alias:
reads the terms comma-separated; set adds names (cli.md)
hex vocabulary // vocabulary.cli
├── list [--json]
├── add <term> [--sounds-like a,b] -> New term, or new spellings merged into it
│ └── Already there, nothing new -> changed: false
├── remove <term> -> Any case
└── Running Hex saves and reloads settings; an open window adopts the change
A mode's own vocabulary // vocabulary.modes; DictationMode::vocabulary
├── settings.json `dictation_processing.modes[].vocabulary`, same entries; no
│ window editor yet (Output lists it as the mode's first step; Edit with
│ agent's prompt explains it)
├── Its terms come first, then the shared list's, each term once (any case),
│ so the 64-term cap keeps them
├── OpenCode rewriting -> every OS, the mode chosen for the dictation
└── Transcription -> macOS dictation only: the mode of the app and page last
seen by the context monitor (≤ 0.5 s old) when the stream or whole-clip run
starts; meetings, captures, the local API, Linux, and Windows hear with
the shared list
OpenCode rewriting (Modes) // vocabulary.prompt
└── Prompt gains "Vocabulary (spell these exactly when the speaker means them):
term (may be transcribed as a, b); …" before the foreground application
Live meeting chapters (experiment live-chapters) // vocabulary.chapters
└── Chapter passes and the boundary pass start with "Names and terms that may
appear: a, b, …" (first 30 terms, no spellings), read on each call
Meeting notes (Labs › Vocabulary in meeting notes) // vocabulary.notes
├── Off (default) -> notes prompts are unchanged
└── On -> the final title and summary prompt (automatic notes and Regenerate
summary) starts with the same line, read at each generation, ahead of the
calendar event; it shares the transcript's excerpt budget (#1154)
Search // vocabulary.search
├── hex meetings search, MCP search_transcripts, hex history --search
├── Query word = a one-word term, fuzzy on
│ ├── Its "sounds like" spellings, or the term as two words -> 0.5 (like a prefix)
│ └── A word that sounds like it (≥2 consonant sounds, ≤ half the letters changed,
│ not a stopword or common word) -> 0.3
└── Aliases never count as exact; exact hits always rank first
该列表位于 settings.json 中,字段名为 vocabulary,每个条目可以是一个纯术语("Rune")或 {term, sounds_like} 形式;两者均可加载,而 Hex 在写入没有拼写的术语时会将其保存为纯字符串。hex vocabulary list --json 保持对象形式。该字段仅在非空时写入,因此旧文件可以原样加载且不会被重写。术语忽略大小写后必须唯一;最多 500 个术语,每个最多 64 个字符,每个术语最多 16 个拼写。只读命令(hex history、hex meetings、hex mcp)直接从文件中读取该字段,从不加载或迁移设置。
辅音很少的短名称(如 Rune、Dax)听起来会和太多词相似,因此搜索只能通过“sounds like”拼写来找到它们的错误转写,而重新评分也只在拼写匹配时才进行修改。转写绝不会盲目替换文本:只有当模型对同一段音频的评分接近所听内容时,术语才会被加入。这两者都位于 Hex 的 transcribe.cpp 分支中(分支 hex/parakeet-vocabulary-tree:decode_rnnt_tree 位于 src/arch/parakeet/decoder.cpp,重新评分位于 vocabulary.cpp);相关测量数据见 vocabulary-boost-results.md。
临时默认值,每一项都在单一位置修改:
hex vocabulary listed in --help // control/cli.rs: add #[command(hide = true)] to hide it
Prompt wording // dictation/processor.rs: vocabulary_lines
Chapter prompt wording // meeting/chapters.rs: vocabulary_line
Short-name rule // meeting/query.rs: SOUND_ALIKE_MIN_CONSONANTS
Suggested terms // dictation/vocabulary.rs: SUGGESTED
Boost strengths (nats per term piece) // dictation/vocabulary.rs: VocabularyBoost::nats
来源:dictation/vocabulary.rs、rune_ui/vocabulary.rs、meeting/query.rs(vocabulary_aliases、sounds_alike)、dictation/processor.rs(vocabulary_lines)以及 control.rs(edit_vocabulary)。
检查项:dictation::vocabulary::tests(去重与合并、限幅、忽略大小写的移除、逗号拆分、在无设置情况下读取已保存列表、前 64 个术语及其拼写进入转写、仅凭字符数限制提示词(the_prompt_keeps_the_first_terms_that_fit)、表格数量与两者均匹配(terms_read_counts_exactly_what_transcription_takes)、提示合并、增强名称);loading_folds_saved_recognition_hints_into_the_vocabulary_once 位于 app_settings.rs;recognition_hints_alias_the_vocabulary 位于 control/settings.rs;whisper_and_qwen3_asr_read_the_vocabulary_as_a_prompt_and_parakeet_biases 位于 transcription/models.rs;vocabulary_round_trips_and_stays_out_of_files_without_one 位于 app_settings.rs;a_vocabulary_term_finds_its_mis_transcriptions_below_exact_hits、sounds_like_spellings_and_split_words_alias_a_term、vocabulary_never_pulls_in_common_words 以及 sound_alikes_need_two_consonant_sounds_and_few_changes 位于 meeting/query_tests.rs;prompt_names_vocabulary_terms_and_their_mistranscriptions;vocabulary_edits_report_whether_they_changed_the_list 以及请求往返位于 control.rs;vocabulary_lists_terms_with_their_spellings 位于 control/cli.rs;rows_project_to_cleaned_merged_entries、rows_past_the_limits_keep_their_term_and_what_fits、the_sheet_starts_empty_lists_with_a_row_and_saves_on_close、removing_a_focused_row_leaves_the_others_and_late_edits_touch_nothing、removing_the_last_row_then_editing_it_is_harmless、rapid_removals_from_one_frame_remove_only_their_own_rows 以及 a_reload_retires_the_old_rows 位于 rune_ui/vocabulary.rs;the_vocabulary_row_opens_its_sheet、add_term_scrolls_the_new_row_into_view 以及 the_vocabulary_row_says_when_the_model_ignores_the_list 位于 rune_ui/tests.rs;only_parakeet_based_models_use_the_vocabulary 位于 transcription/models.rs。
场景:mac-settings-vocabulary、mac-settings-vocabulary-empty、vocabulary-unused(Whisper,无黄金场景)。已于 2026-10-23 在 macOS 上通过;未观察到“未使用模型”提示中的检查被执行。尚未观察到:在运行中的 Hex 中编辑表格、针对正在运行的 Hex 执行 CLI 编辑,或在使用实时提供程序时进行重写。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 hex19/hex