mirror of
https://github.com/qingjian-team/qingjian.git
synced 2026-11-06 08:13:51 +00:00
- 勾上的应用里横屏打字时换成半透明悬浮小键盘,键盘外的点击透给游戏(onComputeInsets 只收键盘那一块,内容区不顶起),也不进横屏全屏编辑 - 顶栏拖动、透明度一键换档、换回普通键盘、收起;位置按应用记住(存成可挪范围里的比例,换屏幕尺寸也落在屏内) - 设置 › 键盘 › 游戏键盘:总开关、透明度、大小、译词(缺省关,关时不记生词)与应用列表;列表只列横屏打过字的应用 - 功能面板「常用功能」加「游戏键盘」一格,在应用里直接给它开关,不用退出去设置 - manifest 声明查桌面应用,设置页才取得到应用名与图标
31 KiB
31 KiB
Roadmap
各阶段有依赖关系:先把 Core 和 CLI 打通再碰平台 API,否则会在没有可测试内核的情况下调试 IMK。
Phase 1 — Core
- 基础 Composition 状态机
- Candidate 数据模型(含词性 + 译文的 annotation 结构)
- 拼音解析(全拼、
'分隔、末尾残缺音节) - ü 韵母规范化:全拼
lue/nue与词库lve/nve等价,生成与导入统一使用v - 中文候选生成(词级)
- 基础词库(TSV 内存词库,
assets/sample/为手写样例) - 候选排序(词级规则排序)
- CLI 测试工具(
apps/cli:候选 + 词性译文 + 各阶段耗时,序号上屏记入用户词频) - 音节表查找改为 trie
- 简拼(声母缩写
kf→ 开发,与全拼混用,marked text 自动补') - 开发测试词库:曾用雾凇拼音(GPL,不可发布);2026-09-05 起换成自建词库,见 Phase 2 末尾「产品词库」
- 中→英释义:
tools/dict-convert从 CC-CEDICT 生成 11.5 万条(CC BY-SA 4.0,可发布) - 带词性的中英 / 中日释义表:
tools/gloss-gen用 LLM 批量生成(2026-09-05 起覆盖整个自建词库 23.9 万词,词性 + 英文译词 + 日文译词与假名,assets/glossary/),Sense.reading+ 汉字注平假名(candidate::furigana);取代 CC-CEDICT 表做随包数据 - Option+数字上屏候选的译文(
Engine::commit_translation,控制器在handleEvent:client:里按键码认,其余交父类) - 整段切不动时取能切分的最长前缀出候选,剩余字母作为未切分尾部保留(
kaifv→kai'f'v) - 整句转换(bigram + Viterbi),含简拼整句(
wxqcf→ 我想去蹭饭 /jttqhh→ 今天天气很好) - 模糊音(Core
fuzzy,配置[fuzzy]):z/zh、c/ch、s/sh、n/l、f/h、l/r、an/ang、en/eng、in/ing, 词库按「每个位置多种写法」一次查出,模糊命中词频减半排序,整句转换同样生效 - 偏好设置「关于」页(2026-09-05):版本 + 构建号、测试版许可(仓库
LICENSE由 MIT 改为测试版保留所有权利,开源时再定)、数据署名、隐私说明、 「打开日志目录」「复制诊断信息」;日志缺省 info、[general] log_level热切换 - 双拼(2026-09-05,Core
shuangpin):小鹤 / 自然码 / 微软 / 搜狗四套方案,键 → 全拼解码后复用全拼的切分与整句,配置[general] shuangpin, 偏好设置「通用」页弹出菜单,CLI--shuangpin - 查词性能:
lookup_pattern/lookup_exact逐级前缀二分收窄(简拼位置按音节块跳扫,小区间线性), 同一次查询内前缀模式记忆化,排序键预计算 + 只选前 500 条。长输入 20 ms → 0.2 ms,全简拼zhgdoima70 ms → 1 到 3 ms,单字母 30 ms → 3 到 4 ms - 逐键性能(2026-09-05,
qingjian-cli --typing按前缀逐键计时):纠错变体先用无分配的「能否完整切分」过滤 (zhzhzh…16 键 parse 39 ms → 0.2 ms);整句格子候选跨按键缓存(sentence::SpanCache,上屏 / 学习时清,sss…15 键 rank 12 ms → 1 ms);bigram 表改成按前词分组的 CSR 布局;词频 / 语言模型 / 个人 n-gram 的哈希表换 foldhash; 预选键打包成 u128;没开模糊音不逐条对模糊命中。结果:全拼、简拼长句每键 0.3 到 3 ms,单字母首键 5 ms(模糊音全开 8 ms), 英文模式每键 0.3 ms 以内;启动 0.9 s(词库 0.24 s + LM 表 0.62 s) - 数据二进制化(2026-09-05,
crates/qingjian-format):.qj容器 = 头 + 分节表 +META(名称 / 许可证 / 署名)+ 原样落盘的内存数组, mmap 零拷贝打开;词库与语言模型都进了容器(dict-convert pack dict|lm),启动 0.93 s → 0.05 s(词库 12 ms + LM 9 ms) - 产品词库(2026-09-05,见 Phase 2 末尾)
以上「已完成」指 2026-09-06 的状态:自用能用,词库已是自建的产品数据(基础 + 11 本随包领域词库),学习数据原子写、坏文件容忍(见 Phase 2「崩溃不丢」)。
Phase 2 — macOS
- IMK 空壳(打包、安装、注册、按键到达链路)
- Input Method Kit 接入 Core(
apps/macos/src/host.rs进程级单例 Engine) - 输入事件处理(字母 /
'/ 数字选词 / 空格 / 回车 / 退格 / Delete / Esc / 上下键选词 / 左右键与 Cmd+左右移动拼音光标) - Composition 显示(marked text 显示原始拼音)
- 自定义竖排候选窗口(
candidate_window.rs+candidate_view.rs自绘,theme.rs集中可视参数) - 中文输入
- 候选选择与上屏(上屏后剩余拼音继续组句)
- 候选翻页(PageUp、PageDown / Tab、Shift+Tab /
[](缺省)或,.(配置)翻页,上下键到页边自动翻页,右下角页码;组句期间未识别的编辑动作一律吞掉) - 拼音光标编辑:左右键移动光标,插入 / 退格 / Delete 相对光标;marked text 里显示真实光标
- 光标作用域:光标停在中间时候选、云端词校验、联想请求都只看光标前的拼音(
Composition::scope),上屏吃掉作用域后光标落到末尾 - 整句转换(Core
sentence):词图 + Viterbi + 束搜索,Dictionary::lookup_exact精确长度查词图格子;整句排第一,CandidateKind::Sentence - 简拼整句:简拼位置按前缀取词进格子(格子多留到 20 个),语言模型在路径上挑读音;
jttqhh→ 今天天气很好、wjdzjsg→ 我觉得自己是个; 两字母简拼仍是词优先(sj时间 /zg这个,Viterbi 单词路径分高就不出句子);有音节没转成字的不算句子;英文词 / 英文补全留在句子前面 - bigram 语言模型(
qingjian-lm,LanguageModeltrait 注入):dict-convert bigram从中文维基 + LCCC 统计,pack lm打成lm.qj随 bundle 打包,没有时退化为一元 - 个人 n-gram(Core
sentence::UserNgram,Learner::user_ngram()):上屏词序列在线计数,与静态模型插值进 Viterbi;user-ngram.tsv落盘; 2026-09-06 加三元(绝对折扣回退到二元,Viterbi 前二词取前驱回指,CommitChain记两个词) - 自动造词:连着选出的两个词合起来词库没有、记够次数就成用户词(同段拼音两次 / 分段三次)
- 快捷候选(Core
shortcut):rq/sj/xq出日期 / 时间 / 星期,v开头表达式模式出四则运算结果与中文数字(见 candidate-ui.md) - 中文标点(Core
punctuation:全角映射、引号配对、数字后的点保持半角;组句期间,.把高亮候选上屏再补标点;配成翻页键时只翻页) - 候选框顶部自绘 preedit 行与光标(不依赖应用画插入点)
- bundle id 改为
app.qingjian.inputmethod(2026-09-06,域名 qingjian.app 注册后;TISInputSourceID与连接名同步,旧 idcom.yenharvey.qingjian的输入源要在系统设置里删掉重加) - 中英切换:Caps Lock 亮着 = 英文模式(默认小写、Shift 大写、标点半角);按住 Shift 的大写字母直接透传;切换输入源时强制收窗
- 单击 Shift 切中英(2026-10-12):复用
[shortcut] switch_mode的 shift,偏好设置「快捷键」页勾选;勾上后单击 Shift 切中英、Caps Lock 退化成只管大小写。 IMK 拿不到修饰键的按下 / 抬起,用 30 ms 定时器轮询NSEvent::modifierFlags_class()做边沿检测(host/mode/switch.rs);缺省不勾,Caps Lock 行为不变 - 英文模式候选(Core
english,Engine::set_english_mode):词表精确词 / 前缀补全 / 一处编辑纠正,Tab 与上下键选词(上下键动过之后空格也选),空格回车标点原样上屏;[general] english_candidates可关;CLI--english-mode - 按应用关英文候选(2026-09-05):
[apps] english_candidates_off,按bundleIdentifier认,缺省终端 / 编辑器 / IDE 名单,*前缀匹配; 偏好设置「通用」页勾选框;[apps]分节留给以后的按应用 preedit 模式。2026-10-10 改成白名单english_candidates_on(缺省浏览器 / 聊天 / 办公), Photoshop 这类靠单键快捷键的软件列不完 - 个人英文词表(2026-09-05,
user-english.tsv):回车 / 英文模式直通原样上屏的英文词(切不成完整拼音的字母串)与选过的英文候选都记, 与随包词表一起出英文候选且在前;修的是gist这类随包词表里没有的词永远出不了候选、回车多少次也学不会的问题 - 中英混输:整段输入在英文词表里即出英文候选,作为拼音「不像话」时排第一,否则排第二(词表 2026-09-05 起来自
assets/lexicon/05_english,ESDB / CSpell,MIT) - 英文补全:拼音不像话且 ≥ 3 个字母时出该前缀下最常用的 3 个英文词(词频 wordfreq),第一个字母就切不动的输入也出
- 英文直输段:组句中敲
-后整段原样上屏(no-way),-不再翻页 - emoji 候选(Core
emoji,Unicode CLDR 中文 annotations,assets/emoji/):紧跟对应词,右侧标注词 - 密钥:输入法进程读配置同目录的
.env(launchd 看不到 shell 环境变量) - 学习语言、每页候选数、翻页键、外观、模式键从配置文件读取(
[general]/[shortcut]),保存后自动热加载 - 应用图标与输入法菜单图标(
assets/icon/logo.png→ bundle.sh 生成 icns;菜单图标assets/icon/menu.pdf模板图随深浅色反色) - 菜单栏「中 / 英」状态项(NSStatusItem,激活时显示,定时轮询 Caps Lock)
- 输入法菜单(状态项 + 系统输入源菜单共用一份 NSMenu:云联想 / 模糊音勾选、偏好设置、日志目录、版本)
- 退格撤销学习:上屏后整个退格删掉再重打同一段拼音换选,上一次的学习退回去
- 输入日志(2026-09-05):
input-log.jsonl每次上屏一行(键 / 切分 / 前 5 候选 / 选了第几个 / 来源 / 纠错 / 撤销 / 时间),只写本机,[general] input_log缺省开,「高级」页开关 + 清空;CoreInputLoggertrait,学习 crateInputLog落盘;离线回放评测与个人模型的数据来源 - 回放评测(2026-09-05):CLI
--replay input-log.jsonl,按来源算首选 / 前五命中率、平均名次,打印没命中的例子;内存学习不写文件 - 输入日志 v1(2026-09-12,
docs/plan/model-eval.md):日志当评测基础设施,每个模型假设先有尺子再立项。新增事件session/retype(组句内退格重打、 跨上屏相近重打)/passthrough/prediction/break,上屏行加rescored/app/pages/ms、候选记一页 9 条;空的原样上屏不再记 (旧日志一半是它);回放报告加重打、联想接受率、隐式信号(命中 / 未命中两组的翻页与耗时)、重排 / 未重排两组命中 - 整句评测集(2026-09-08):CLI
--eval-text <中文文本>...,用户自己的文本切句、按词库读音转全拼、冷启动还原,--eval-save冻结句子集; 基线(本仓库 docs + 个人技术笔记 8322 句):首选 37.6%、字准确率 76.9%,技术文本里的行话(候选 / 词库 / 释义表)是主要丢分处 - 删除候选(2026-09-05):⇧ + 数字(
[shortcut] delete_candidate),用户词整个删、词库词清全部学习(Learner::forget,个人 n-gramforget_word),拼音行右侧显示结果 - 拼写纠错:一处编辑(换位 / 换字母 / 多一个 / 少一个)凑出完整音节,拼音行画删除线,回车原样上屏,接受与拒绝都进学习; 2026-09-05 挑选改成噪声信道(纠正后整句得分扣编辑代价仍高于原样才纠,末尾单字母只试换位),修掉 你后妈 / 我峡谷区 这类选错
- 词图内敲错边 + 个人敲错表(2026-09-06):整句词图里每个完整音节按一处敲错变体(相邻键换位 / 相邻键 / 多键 / 少键)查词并扣代价,
meiganxi→ 没关系;接受的 (敲的, 要的) 音节对记user-typos.tsv,代价按次数打折。回放:带数据 词 91.2% → 91.5%、整句持平, 冷引擎整句 89.3% → 87.5%(两条歧义句改读:fayibanben 法语版本、shishao 是啥),每键最慢 3.5 ms → 4.7 ms - README 安装 / 隐私 / 数据许可(2026-09-06):pkg 安装与「仍要打开」、卸载;不上传数据、云联想发什么发到哪怎么关、 输入日志缺省开只写本机怎么关怎么清;测试版许可与随包数据署名表(与「关于」页一致)
- 领域词拆成随包的
.qj(2026-09-06):dict-convert lexicon把 THUOCL 领域词按来源文件拆成 11 本(语料 ≥ 50 次的留在基础词库), 基础词库 22 万 → 8.7 万条、dict.qj10 MB → 3 MB、加载 79 → 25 ms;领域词库合计 13 万条 7 MB 放Resources/dicts/,[dictionaries] domains缺省只开成语,偏好设置「词库」页可勾选。回放(614 条冷引擎):词 前五 96.5% → 96.1%(少一个词),整句持平 87.5% - pkg 安装器(2026-09-06):
bundle.sh --pkg出Qingjian-<版本>.pkg(装/Library/Input Methods/,关重定位,postinstall 以登录用户身份qingjian-macos --register注册并启用输入源,欢迎页 / 许可证 / 结束页),版本号与构建号打包时注入,uninstall.sh随包; 签名 / 公证做成环境变量开关,等 Developer ID 证书到位就能签。未签名的 pkg 测试者要在「隐私与安全性」里点「仍要打开」 - 崩溃不丢(2026-09-06):学习数据六张表、
config.toml、.env原子写(临时文件 + fsync + 改名);学习数据坏行跳过、 编码坏了按替换字符读、真读不了退回内存学习不覆盖文件,输入法照常启动;IMK 回调与定时器边界catch_unwind,panic 后缓冲区字母原样上屏; 激活期间每 60 秒落一次盘。设计见architecture.md「崩溃不丢」 - 候选窗口收尾:竖排 / 横排(
[general] layout)、拼音行分段样式(CoreMarkedSegment,纠错删除线的位置已留好)、 拼音显示位置 行内 / 窗口 / 两处([general] preedit)、按光标所在屏幕定位并处理屏幕边缘 - 日志按天分文件、只留 7 天;文件被删后下一条日志重建(
app/logging/,自己的LogFile写入端按 nlink 判断) - 偏好设置窗口(原生 AppKit,改完即写回
config.toml;密钥写.env) - 偏好设置重做(2026-09-05):六页标签视图(通用 / 候选窗口 / 快捷键 / 模糊音 / 词库 / 云服务 / 高级),用户视角措辞, 快捷键录制按钮 + 「恢复默认快捷键」,「词库」页导入 / 开关 / 移除,编辑菜单让 ⌘V 能粘贴
- 产品词库(2026-09-05):
assets/lexicon/自建源(规范字 8105 + 常用词 5.6 万 + THUOCL 领域词 15.7 万),dict-convert lexicon建dict.tsv, 读音 Unihan + LLM 多音字标注(gloss-gen pinyin,6.8 万词,含常用词表自带拼音的 288 处纠错),词频用自己的语料统计;成品 20.5 万条,dict.qj10 MB、lm.qj27 MB,启动 70 ms;英文词表换成 ESDB / CSpell 9.5 万词。雾凇拼音与其英文词表已全部移除 - 短语层(2026-09-12):常用词表是词典词头,不收 我的 / 好的 / 不知道 / 有没有 这类人整块打的组合;
dict-convert phrases从语料相邻两三词里挖 (对话语料 ≥ 2000 次 + 边界规则,读音由成分词拼出)5400 条进基础词库,品牌词 青简 也进(brand.tsv);起因与验收见docs/notes/phrase-layer.md - 领域词(2026-09-12):输入日志里选过、公开语料里出现过、词库与短语层都没有的词人工挑 48 条进基础词库(
assets/lexicon/domain_words.tsv:对齐 / 后端 / 词库 / 候选框 / 看看 / 再也), 语言模型里与短语一样走合成计数(低频词当 token 统计会吸走成分词的二元证据);回放词级 +34、整句 +6、整句评测集持平,见docs/notes/domain-words.md
2026-09-06 状态:自用日常在用;bundle.sh 从 assets/(词库源、释义表)与 data/generated/(生成物、.qj、领域词库)打产品数据,没有生成物时打样例;
--pkg 出分发包。给测试者发第一版前只剩特殊应用验证;签名等 Developer ID 证书。
Phase 3 — Translation
- Candidate Translation API(
Translatortrait,Engine::annotate候选生成后异步补译文;Sense词性 + 译文 + 读音) - 中文 → English、中文 → 日本語:
tools/gloss-genLLM 批量生成 6.4 万常用词(词性、译词、日文假名),随包表;日文按汉字段注平假名 - 本地词典:
Glossary内存查表,格式词\t词性. 译词[|假名];CC-CEDICT 表保留为备用来源 - 翻译语言设置:
[general] learning_language,菜单与偏好设置只列打进包里有释义表的语言 - Option+数字上屏候选的译文
- 释义表随仓库发布(
assets/glossary/,2026-09-05):中→英 / 日覆盖整个自建词库 24.9 万词,多字词 91.6% 有英文释义、98% 日文; 英→中 4.5 万词(wordfreq ≥ 2500 + 技术词),英文候选右侧显示中文(Engine 按候选种类查表);三张表都进.qj - 上屏译词:⌥ + 数字第一条、⇧⌥ + 数字第二条,修饰键可录制;⌃⌥T 翻译应用里选中的文字(云服务)
- 释义兜底(2026-09-06):Core
GlossFillertrait(与Predictor分开:独立线程、攒批、不丢请求),随包表查不到的词库词 / 云端词上屏后入队,qingjian-predict::CloudGlossFiller攒 1.5 秒或 8 个词发一次(提示词与 gloss-gen 同源,只要当前学习语言),结果经Translator::learn进qingjian-translate::PersonalGlossary(user-glossary-<语言>.tsv,格式同随包表,可手改,LayeredTranslator个人表优先),随 flush 落盘; 壳每秒Engine::poll_glosses;随云联想开关一起开,发出去的只有那个词 - JMdict 校对假名与日文词性(等级标签已做,见 Phase 4)
Phase 4 — Learning
- 用户词频(
user.tsv)、用户词(user-words.tsv) - 词级排序接语言模型:上一个上屏的词做上下文,同输入串下选过的词优先(
user-choices.tsv),非末尾简拼少的切分优先 - 输入习惯学习:个人 n-gram + 自动造词;用户点选的转移记双份、整句路径顺带的记一份,选择次数加分取对数并封顶(否则 的 的 173 次会把 号的 抬过 好的)
- 个人敲错表(2026-09-06,
user-typos.tsv):接受过的 (敲的, 要的) 音节对,词图敲错边与整段纠错按次数打折;退格撤销一并撤销 - 学习数据落盘可靠(2026-09-06):六张表原子写、坏行跳过、读不了退回内存学习、激活期间每 60 秒落一次盘(Phase 2「崩溃不丢」)
- 输入统计(2026-09-06):Core
UsageMetertrait,每次上屏折成汉字 / 中文词(整句按切词数)/ 英文词 / 次数;qingjian-learning::UsageStats按天记usage.tsv,与输入日志无关(日志关掉或清空统计还在),随学习数据每 60 秒落盘; 偏好设置「统计」页:今天 / 最近 7 天 / 累计 三行四列 + 「累计 xx 字,约等于 n 本《某书》」(book_scale,书目从《道德经》到《平凡的世界》) - 生词识别(2026-09-06):Core
VocabularyTrackertrait +Sense::fresh;一条译词在用户上屏时出现在候选窗口里的轮次不到 3(FRESH_UNTIL)算生词, 候选里橙色画译词,看熟了变回灰。「看到」按上屏那一刻屏幕上那一页算(壳Engine::note_displayed),上屏带译词的候选记「上屏过」,⌥+数字 打出译词记「用过」;qingjian-learning::VocabularyBook一个译词一行user-vocab.tsv(语言 / 译词 / 看到轮次 / 上屏 / 用过 / 首见 / 末见),只记译词与次数 - 学习词汇统计(2026-09-06):偏好设置「统计」页词汇块:见过 / 看熟 / 上屏过 / 打出过 / 本周新见的译词数(
VocabularySummary), 再按等级分行(词表总数 / 见过 / 看熟 / 上屏过):英文 CEFR A1–C2(CEFR-J 1.5 + Octanove,8,845 词)、日文 JLPT N5–N1(Tanos 经 elzup,7,757 词),qingjian-translate::LevelTable读assets/levels/levels-{en,ja}.tsv(tools/corpus/levels.py生成),VocabularyBook::with_levels;等级不进候选窗口 - 可选复习功能
Phase 5 — Cross-platform
- [~] Windows TSF(
apps/windows/{server,tsf},真机自用中;细节见docs/design/architecture.md「Windows:TSF」)- Server 进程 + TSF DLL 骨架、命名管道 IPC、多会话分派、端到端上屏
- preedit 内联下划线、候选窗(词性 + 译文 + 分页 + 阴影)、云联想、失焦上屏、中英切换、设置界面、Inno 安装器
- 候选窗渲染搬进 Server 进程 +
uiAccess+ 自签,覆盖微软商店 / 任务栏搜索等高 z-band 宿主 - 中英切换可配置(2026-09-15,issue #81):
[shortcut] switch_mode选单击 Shift / 单击 Ctrl / 不切换,[general] english_mode关掉则内置英文模式整体停用(固定中文、不再登记语言栏按钮、状态条也不切); 四项都在「设置 → 通用」,DLL 激活时读一次配置 - 发版:Certum 开源代码签名证书、
windows-v<版本>标签与 CI
- Linux Fcitx5 第一阶段:Rust Server、默认候选面板、用户目录安装与手动启动(2026-09-18);未改系统 Fcitx5 的 GTK4 / Qt6 X11 输入已验证
- Linux 后续:Server 自绘 X11 窗口、Server 向 GNOME 扩展发送位图、神经重排、自动启动与 Debian 包;各自独立 PR,IBus 暂缓
- [~] Android(
apps/android,feat/android分支):输入核心、学习与统计、词库与繁体、高级、云联想已与 PC 对齐,外观(主题)进行中; 实现要点见docs/notes/android.md - 移动端与平板:iOS、iPadOS、HarmonyOS
- 分工:候选条(显示面)由
qingjian-render出位图,Android 现在的键盘与面板(输入面)由 Kotlin 自绘。 只有 Android 一个移动端时这种分法可以接受;做第二个移动平台时,键盘与面板统一移到 Rust,各平台只接输入框连接、触摸转发、震动与无障碍 - 统一之前先做:主题推导只留渲染器一份(键盘配色也从主题算出,壳只读);键位表与尺寸计算挪进共享 crate、按宽度出布局; 渲染器补彩色 emoji(Android COLRv1、Apple sbix)与只重画变化区域;在 Android 上验证 Rust 画九宫格的按键延迟与手感
- Android 壳里还写在 Kotlin、统一时要搬进 Rust 的规则:
- 键位表与角标:
keyboard/layout/KeyboardLayout.kt(全键盘、九宫格、注音大千、日语、数字键盘、符号页) - 尺寸与排版:
keyboard/layout/KeyboardMetrics.kt(行高、按宽度分键、九宫格列宽) - 游戏键盘(横屏悬浮)的尺寸档与拖动:
settings/GameKeyboard.kt的Size(占屏宽比例、行高)、service/GameFrame.kt(位置按可挪范围的比例记) - 滑行起判阈值:
keyboard/SwipeTrail.kt的START_KEYS;上滑判定:keyboard/KeyboardView.kt的FLICK_DP(往上多远、不偏出本列);Shift 双击锁定的间隔:service/input/Composer.kt的DOUBLE_TAP_MS - 键位排法:
settings/Settings.kt的Arrangement(左手便捷:符号面板分类列在左、返回在左下) - 写死的颜色并进主题推导:
ClipboardPanel代码高亮的数字色、AppColors的生词标签色与危险操作红、TranslateBar/ProcessTextActivity的失败红
- 键位表与角标:
- 平板与 iPad 有两种形态:接实体键盘时只剩候选窗,按 PC 方式工作(翻页键、Shift 切换等手机上不搬的项要用上); 不接时是屏幕键盘,要适配全宽、浮动与分屏等宽度,面板在大屏上排多列
- 分工:候选条(显示面)由
- 配置同步
- 跨平台词库
Phase 6 — 云联想
Core 定义 Predictor trait(与 Translator / Learner 同一模式),网络实现放独立 crate qingjian-predict,
Core 永远不联网。第一个实现接 DeepSeek(OpenAI 兼容接口),接口做成 provider 无关。
- 本地输入历史:
InputHistory(内存环形 4096 字符,可清除;落盘与查看界面待做) Predictortrait:submit/poll非阻塞,请求带序号,Engine 只认最新序号;NoPredictor缺省qingjian-predict:CloudPredictor,async-openai 走 OpenAI 兼容接口,后台线程防抖 300 ms、缓存 64 条、超时 5 s- 云端词:模型给「拼音对应的词 + 全拼」,Core 逐音节校验;词库没有的选中后记成用户词(
user-words.tsv) - 云端词位置(2026-09-05):到了只补进第一页末尾
[predict] slots格(缺省 2),前面的本地候选一格不挪,不预留不画占位; CoreCandidateLayout出排布,壳Session只管高亮与页码;偏好设置「云服务」页可选 0–4 格 - 触发:只在组句中,停键后同一次请求要云端词和整句补全(preedit 右侧,Tab 接受);上屏后不联想
- 整句补全进学习(2026-09-05):Tab 接受的句子按语言模型切词(
sentence::segment_text)记进个人 n-gram,可随退格退回 - 纠错:云端词按容错编辑距离校验(简拼不算错),模型可纠正错字 / 漏字 / 多字;本地历史不进请求
- 提示策略(2026-09-05):本地候选与本地整句在提示词里标成「可能全错的本地猜测」,模型独立判断、只给本地给不出的词,没有就空;不再照抄本地候选
- 上下文来源:IMK
attributedSubstringFromRange:读 marked text 前后,应用不支持时退回本地输入历史 - 展示:云朵图标(SF Symbols
cloud)区分,不重排已有候选、不阻塞输入 - 隐私:默认关闭;开启时菜单栏「中 / 英」带 ☁︎;Secure Input 绝不发送;观察长度在 Core 裁剪
- 配置:
~/Library/Application Support/Qingjian/config.toml的[predict],首次运行写模板;密钥可填配置或环境变量 - 问字模式:
?+ 问题拼音,PredictionKind::Question走同一条 Predictor 通道、单独的提示词,答案带声调读音、不校验拼音(见 candidate-ui.md) - 问字只答字不复述(2026-09-05):请求带本地整句转换出的问题汉字(
guess),提示词只答被问的字,restates_question剔掉把问题写回来的「答案」 - 菜单开关、偏好设置窗口里的开关 / 接口 / 模型 / 密钥
- 释义表进
.qj(2026-09-05):Glossary双存法(TSV 哈希表 / 映射的 arena + 词条表 + 释义表 + 哈希索引),pack glossary --language,启动回到 50 ms - 翻译选中文字读不到选区时候选窗口提示 2.5 秒(
host/presenting/notice.rs) - 语料挖新词(
dict-convert mine):分词落成连续单字的段按子串计数,虚词规则 + 相邻字对 PMI≥3 过滤(2026-09-07 从会话脚本进工具,oov_filter.rs),lexicon --extra-words并入词库 - 多词库与词库管理(2026-09-05):Engine 附加词库列表;用户目录
dicts/+[dictionaries] disabled;偏好设置「词库」页导入(TSV / Rime yaml / .qj → .qj)、开关、移除 - 翻译选中的文字(2026-09-05):⌃⌥T 把应用里的选区交给云端翻译,译文在候选窗口里回车替换、Esc 保留;快捷键可改;
双向:中文选区译成学习语言,外文(拉丁字母 / 假名)选区译回中文,方向按字符统计定(
translation_target) - 输入历史落盘与清除(2026-09-05):
input-log.jsonl+ 偏好设置「高级」页开关 / 清空(查看界面没做,文件是 jsonl 直接看) - 密钥进钥匙串(等签名定了再做);云联想按应用禁用
- 请求量控制:按分钟限流、统计本月请求数并显示
Phase 7 — 个人模型
目标是「输入法越用越像自己」。分两步,第二步有评测门槛。
- 个人 n-gram:bigram 计数 + 与静态模型按证据量插值,随上屏在线更新,直接进整句转换的 Viterbi 打分(见 Phase 2)。 个人数据量级(一年几百 KB 到几 MB)上,这一步拿到绝大部分个性化收益,成本接近零
- 个人 trigram(2026-09-06):与二元一起在线计数,绝对折扣(D = 0.75)回退到二元,不训练;
--replay在 423 条日志上与二元持平 (冷 词 77.7% / 整句 87.0%,带数据 90.2% / 97.1%),三元要数据攒起来才见效,--typing每键最慢 2.7 ms 不变 - 小 Transformer 实验分支(2026-09-08):
qingjian-neural(candle,Metal / Accelerate / CPU),用途「重排整句转换的前 6 条路径」; CLI--neural接,壳未接。回放上词 +0.5、整句 −1.1(静态替换 λ 0.25、前文 64),没过门槛,且尺子有偏,见docs/notes/neural-rescoring.md - 整句评测集上过门槛(2026-09-08 晚):冻结集 8322 句,基线整句首选 37.6%,small λ 0.75 前文 64 到 41.9%(+4.3),
不给前文也有 +2.2;翻好 382 句、翻坏 54 句,见
docs/notes/neural-rescoring.md - 进壳(2026-09-08 晚):前文 KV 缓存(64 字前文 × 8 条 133 → 28 ms)、Core
engine/rescoring异步重排(后台线程 + 文本分数缓存,壳停键 80 ms 请求)、 应用光标前文当前文、λ 缺省 0.5、[model] enabled开关与「云服务」页勾选、知微模型现随包放Resources/models/hanzhang-zhiwei/;TextEdit 端到端 候选声称 → 候选生成 - 模型单文件
.qjm(2026-09-12):.qj容器新种类Kind::Model,三节原样装三件套;find_model先.qjm再目录;pack model/tools/release/pack-model.sh; data Release 上传model.qjm,macResources/models/hanzhang-zhiwei/与 Windowsdata\models\hanzhang-zhiwei只带这一个文件 - 本地模型后续:个人微调(闲时训练);权重许可已定与代码一致 GPL-3.0-or-later(2026-09-12,写在
pack-model.sh) - 闲时训练:门禁包括接电源、温度、空闲时长;训练数据来自本地输入历史;模型与数据都可一键清除
- 评测门槛:留出用户文本上比 n-gram 的困惑度与 top-1 命中率,赢了才默认启用;每次按键推理延迟有上限
- 模型文件的版本与迁移
规模参考
| 项目 | 量级 |
|---|---|
| librime(C++) | 约 5 万行 |
| Phase 1 + 2 到 macOS 自用级别 | 全职约 2 到 3 个月 |