← Back to blog

Offline natural-language bookkeeping in a WeChat mini program

The most loved feature in Shiguang Ledger is one-sentence bookkeeping: type “taxi 35 yesterday” and it figures out the date, category and amount. Plenty of people assume a large language model is behind it. It isn’t. It’s a rule-based parser of about 200 lines that runs on the phone, fully offline.

Why not an LLM

Logging an expense is frequent and low-stakes. If a call takes half a second longer, costs a fraction of a cent, or needs a connection, people get annoyed. Financial notes are also sensitive, so I’d rather they never leave the device.

Three layers

  1. Amount. Find the number that looks most like a price, and cope with forms like “28.5”, “twenty-eight” written out, or “two hundred bucks”.
  2. Date. Turn “yesterday”, “last Friday” or “the night before last” into a real date, defaulting to today.
  3. Category. A word list of just over 300 entries, matched longest-first. Anything unmatched goes under “Other”, and the parser remembers how the user files it later.
export function parse(input: string, now = new Date()) {
  const amount = extractAmount(input);
  const date = extractDate(input, now);
  const category = matchCategory(input) ?? learned.get(input) ?? "Other";
  return { amount, date, category, note: input.trim() };
}

The biggest lesson

Learning matters more than recognizing. Once someone corrects a category, the same phrase is right the next time. After three months accuracy went from 82% to 94%, and the credit goes to users’ own habits rather than a cleverer algorithm.

Mini programs have strict package size limits, and the whole parser minifies to under 8KB. For me that is its best feature.