拾光账本最受欢迎的功能是“一句话记账”:输入“昨天打车 35”,自动识别成日期、分类、金额。很多人以为背后是大模型,其实它是一个 200 行左右的规则解析器,跑在小程序端,完全离线。
为什么不用大模型
记账是高频、低价值的动作。一次调用慢半秒、贵一分钱、需要网络,用户都会觉得烦。而且账目内容敏感,能不出手机就不出手机。
解析器的三层
- 金额。 找出最像金额的数字,处理“28.5”“二十八”“两百块”这类写法。
- 时间。 把“昨天”“上周五”“前天晚上”换算成具体日期,默认今天。
- 分类。 一份只有 300 多个词的词表,按最长匹配归类;匹配不到就放“其他”,并记住用户之后的手动修改。
export function parse(input: string, now = new Date()) {
const amount = extractAmount(input);
const date = extractDate(input, now);
const category = matchCategory(input) ?? learned.get(input) ?? "其他";
return { amount, date, category, note: input.trim() };
}
最大的收获
“能学习”比“能识别”重要。用户改过一次分类,下次同样的说法就自动对了。三个月后,准确率从 82% 涨到了 94%,靠的不是更聪明的算法,而是用户自己的习惯。
小程序的包体积限制很严,这个方案整个解析器压缩后不到 8KB,对我来说这就是最大的优点。