奇记 QiNote:把记账变成一句聊天
一款 AI 驱动的聊天式记账 App:自然语言一句话成账、小票拍照识别、Bento 统计看板与本地优先的数据设计。本文聊产品定位、功能全景与 MVVM + Clean Architecture 分层。

本文是「奇记 QiNote」项目系列的第一篇:先聊清楚这款 App 是什么、为什么做,以及整体架构长什么样。技术细节会在后续两篇里展开。

项目背景
记账这件事,难的不是算,而是记。市面上的记账 App 大多要求用户在多个输入框之间跳转——选分类、填金额、挑日期,一套流程下来至少七八次点击。真实生活里,一笔「打车 28 块」的消费发生在关上车门的那一秒,等用户打开 App 找到入口,这笔账大概率就丢了。
奇记 QiNote 的出发点非常直接:把记账压缩成一句话。用户在聊天框里输入「昨天打车 28.5」,App 自动解析出类型、分类、金额、日期并落库;拿到一张小票,直接拍照发过去,AI 读图提取金额和时间。整个交互模式向"和助手对话"靠拢,而不是"填表单"。
项目以个人独立开发完成,从产品定义、UI 设计到编码实现全部一手操办,代码开源于 GitHub。
功能特性
- 对话式记账:自然语言一句话成账,支持文字描述与聊天上下文补全("也是 35 块"也能算对);
- 小票识别:拍照或选图后走多模态模型,自动提取金额、消费时间(精确到秒)并按图片内容拆分日期;
- 手动模式:聊不清楚的时候切回传统表单,双入口互为兜底;
- 统计看板:首页 Bento 风格统计卡(月支出 / 月收入 / 账单数 / 结余),统计页提供环形分类占比图与趋势折线图,均带入场动画;
- 账单管理:按日期分组、详情编辑、重复记录检测提示、分类自定义(含图标);
- 实时通知:记账过程与结果通过系统通知实时呈现,HyperOS 机型上直接进"超级岛"(下一篇专门讲);
- 本地优先:数据全部存在 Room 里,不依赖任何账号体系。
技术栈与架构
| 分类 | 选型 |
|---|---|
| 语言 / UI | Kotlin + Jetpack Compose + Material 3 |
| 架构 | MVVM + Clean Architecture 分层 |
| 依赖注入 | Hilt(@Singleton 用例层、@ViewModelScope 注入) |
| 数据 | Room(账单 / 分类 / 聊天记录三实体)+ DataStore |
| 网络 | OkHttp + kotlinx.serialization,自带指数退避重试 |
| 图片 | Coil |
| 特系能力 | HyperNotification(超级岛)、Shizuku(特权通道) |
整体分层如下,用例层(UseCase)是整个 App 的"业务中枢",UI 层不直接碰仓库与网络:
flowchart TB
subgraph UI["UI 层(Compose)"]
Home["首页 HomeScreen"]
Entry["记账入口 EntrySheet"]
Stats["统计 StatsScreen"]
Settings["设置 SettingsScreen"]
end
subgraph Domain["用例层"]
UC["AiBookkeepingUseCase"]
end
subgraph Data["数据层"]
Repo["BillRepository / CategoryRepository / ChatMessageRepository"]
DB[("Room 数据库")]
AI["AiApiService(OkHttp)"]
Local["LocalBillParser(本地正则)"]
end
Entry --> UC
Home --> Repo
Stats --> Repo
UC --> AI
UC --> Local
UC --> Repo
Repo --> DB
几个值得展开的架构决定:
金额全程用分(Long)存储。 ParsedBill.amount 是以分为单位的 Long,解析层统一 Math.round(yuan * 100),展示层再除回去。浮点金额在累加时产生的精度误差是记账类应用的经典 bug 源,这个决定从第一行代码就规避掉了。
聊天记录也入库。 ChatMessageEntity 让记账历史天然成为一份"对话流水",同时为 AI 补全提供上下文——发送请求时会带上最近 10 条有效消息,用户接着说一句"也是 35 块",模型能理解指的是上一笔的同类别消费。
分类是 ID 体系而非字符串。 内置 13 个支出分类 + 3 个收入分类(food=餐饮美食 这类 ID=名称 映射),用户自定义分类会合并进 System Prompt,模型只能从合法 ID 集合里选,选了未知 ID 一律回退 daily,从校验层面杜绝了"AI 自创分类"。
工程细节
minSdk 24,覆盖面广;同时为老设备开启了 core library desugaring,直接使用java.time;- release 构建开启
minifyEnabled + shrinkResources,配合 ProGuard 规则裁剪; - 主题层面自建了
QiTheme设计系统(色彩 / 间距 / 圆角 / 缓动曲线 / 字体五个 token 组),深浅色模式全覆盖; - 首页 Bento 卡片用
HeroEntrance做延迟入场,环形图与趋势图全部用 ComposeCanvas手绘,不引图表库——省掉一个 200KB+ 的依赖,动画节奏也更可控。
小结
奇记目前是 v1.0.1:定位清晰(聊天式 AI 记账)、架构标准(MVVM + Clean Architecture)、数据本地化。系列后续两篇会深入两条最有意思的技术线:AI 记账链路的双通道设计,以及 HyperOS 超级岛通知的四级降级策略。

