← 返回博客

在微信小程序里做离线的自然语言记账

拾光账本最受欢迎的功能是“一句话记账”:输入“昨天打车 35”,自动识别成日期、分类、金额。很多人以为背后是大模型,其实它是一个 200 行左右的规则解析器,跑在小程序端,完全离线。

为什么不用大模型

记账是高频、低价值的动作。一次调用慢半秒、贵一分钱、需要网络,用户都会觉得烦。而且账目内容敏感,能不出手机就不出手机。

解析器的三层

  1. 金额。 找出最像金额的数字,处理“28.5”“二十八”“两百块”这类写法。
  2. 时间。 把“昨天”“上周五”“前天晚上”换算成具体日期,默认今天。
  3. 分类。 一份只有 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,对我来说这就是最大的优点。