尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

AI理财App如何识别外卖消费?从账单解析到大模型吐槽全拆解

AI理财App如何识别外卖消费?从账单解析到大模型吐槽全拆解 最近不少开发者群里都在聊一个现象明明只是点了一份外卖月底一看账单却发现这块支出占了大头。更让人上头的是那种图片看起来精致、到手却“货不对板”的踩雷外卖网上有人把它叫“假外卖”。不少团队把这个当成段子但有一款 AI 理财 App 却把它做成了产品功能自动识别你的外卖消费用带点吐槽语气的方式提醒你“又在乱花钱”。有公开信息显示这款产品年收入已经超过 1 亿美元。单看这个数据确实会让做技术的人好奇这种“会吐槽用户”的 AI 产品到底是怎么实现的这篇文章不讨论它的商业模式而是从技术侧做一次系统拆解。如果你想做一个同样具备账单识别、外卖消费分析和 AI 提醒能力的理财类 App需要掌握哪些核心能力从后端接口设计到大模型 Prompt 工程再到简单的前端演示我会给出一个可以照着搭建的最小闭环方案。无论你是刚接触 AI 应用开发还是已经在做 App 开发都可以从这篇文章里拿到一套可执行的思路。1. 背景与核心概念1.1 “假外卖”消费现象与 AI 理财的结合点“假外卖”并不是一个严谨的电商分类它更像是用户对外卖体验的一种吐槽图片看着很有食欲实际分量少、口味差价格还不便宜或者某家店根本没有实体厨房菜品只是料理包加热。站在消费者角度这是一种“不值得”的消费。但站在理财类产品角度“不值得的消费”恰恰是刚需场景。很多人月底看账单时都会感慨“我什么时候点了这么多外卖”传统记账 App 的做法是自动同步账单生成分类报表然后告诉你“本月餐饮支出占比过高”。这种提醒虽然正确但用户已经麻木了很难产生行为改变。AI 理财 App 的做法更聪明它不仅仅记账还会结合大模型理解每一笔消费的上下文。当你连续三天点了高客单价外卖或者一周内多次出现“图片精美但实际一般”的外卖订单时它会用一句略带调侃的话提醒你比如“这家的精修图你已经信了三次下次换一家吧”。这种表达方式比冷冰冰的“您已超支”更容易让用户记住也更愿意分享截图产品因此获得了自然传播。1.2 这类产品的技术本质是什么去掉“会吐槽”这个表面卖点这款产品的技术本质是一个典型的 AI Agent 应用外部账单数据经过解析后进入规则引擎做初步分类再通过大模型进行语义分析和话术生成最后输出带人格化的提醒建议。整个链路包含四个关键模块账单数据接入从支付账单、短信、电商订单中抽取结构化数据。消费分类与风险判断判断一笔消费属于“外卖/堂食/日用/娱乐”并评估是否属于非理性消费。大模型对话生成根据用户消费特征生成个性化、有风格的提醒文案。用户反馈闭环用户是否接受提醒、是否产生行为改变反哺模型优化。所以这款产品能够成功不是因为“会吐槽”这个点子本身值多少钱而是因为它把大模型能力嵌入到了用户最频繁的消费场景中同时用文案风格降低了用户的防御心理。1.3 开发者可以从中学到什么从这个案例中技术开发者至少可以得到三个启发第一AI 应用不一定要做大而全的“智能助理”。只做“账单分析 提醒文案”这一个点也能形成完整的商业闭环。第二大模型并不需要参与所有决策。账单分类完全可以用规则和轻量模型完成大模型只需要负责“最后一公里”的文案生成这样成本更低、响应更快。第三产品人格化是差异化的关键。同样调用一个通用大模型提示词写得好不好直接决定了用户是觉得“有趣”还是“烦人”。接下来我会围绕上述链路带你搭建一个简化版“会吐槽的外卖检测 AI 理财助手”。2. 环境准备与版本说明2.1 开发环境搭建为了降低上手门槛本文示例采用 Python 后端 大模型 HTTP 接口 一个 HTML 测试页面的方案。你可以不用写一行 Android 或 iOS 代码就能跑通核心逻辑后续再把它迁移到 Flutter 或原生 App 中。推荐环境如下组件推荐方案说明操作系统Windows 10/11、macOS 12、Linux均可Python3.9 及以上示例代码使用 3.9 语法Web 框架FastAPI轻量、自带接口文档适合快速演示大模型 APIOpenAI 兼容的 Chat Completions 接口本示例只通过 HTTP 调用可适配多种服务前端演示HTML JavaScript仅做效果验证可替换为任意移动端方案版本需要根据你的项目实际情况调整本文示例以常见环境为例重点演示配置思路。如果你本机没有 Python 环境建议先安装 Python 3.9 以上版本再安装 FastAPI 和 uvicorn。2.2 项目整体架构为了便于理解我们先把流程拆成几步用户粘贴账单文本 | v [账单解析服务] -- 按行拆分提取金额/商户/时间 | v [消费分类服务] -- 规则匹配识别外卖类订单 | v [风险判断模块] -- 统计总额、外卖次数、频率 | v [大模型吐槽生成] -- 调用 LLM API 生成文案 | v [返回结果] -- JSON 数据前端展示这里有一个设计原则前两步尽量用规则引擎完成避免每次处理都调用大模型。大模型只在最后一步生成文案时参与成本可控。2.3 依赖清单在项目根目录创建requirements.txtfastapi0.110.0 uvicorn[standard]0.29.0 pydantic2.6.4 requests2.31.0这里我固定了示例中使用的版本但实际安装时请以你本机环境为准。如果你的 Python 版本较低可以适当下调 FastAPI 的版本。3. 核心原理拆解3.1 账单数据的接入与清洗真实 App 获取账单的方式有很多比如用户授权后通过支付宝、微信支付、银联等开放接口同步账单用户手动复制支付短信或账单截图通过手机系统无障碍服务读取短信验证码和数据。为了快速演示我们采用最直接的方式让用户粘贴一段模拟账单文本程序按行解析。账单文本可能长这样2025-01-06 12:31 美团外卖 煲仔饭 支付 39.90 元 2025-01-06 18:02 某某咖啡 拿铁 支付 28.00 元 2025-01-07 13:10 饿了么 炸鸡套餐 支付 45.50 元 2025-01-08 09:20 地铁充值 支付 50.00 元 2025-01-08 20:40 美团外卖 深夜烧烤 支付 86.00 元每一行包含四个关键字段时间、商户名称、商品描述、金额。在真实项目中数据格式会更复杂因此需要先做一次清洗——去掉无效字符、统一金额单位、补全缺失字段。3.2 外卖消费识别模型设计外卖订单的识别不需要一上来就用深度学习。最常见的做法是“关键词规则 平台名称命中”商户名称或支付渠道中带有“美团外卖”“饿了么”“外卖”等词时直接标记为外卖。商品描述中包含“配送费”“打包费”等特征词时作为辅助判断。部分第三方支付账单不会写平台名只写商户名。这时可以维护一个“高频外卖商户关键词表”比如“汉堡”“奶茶”“炸鸡”“麻辣烫”等。规则设计得好90% 以上的常见外卖消费都能识别出来。剩余无法判断的订单再交给大模型做兜底分析。这种“规则 模型”的分级结构在实际工程中非常实用既能保证速度也能控制 API 成本。在我给出的示例中我会用一个restaurant_keywords列表来做判断。你可以根据自己的业务场景扩展这个列表。3.3 吐槽话术生成大模型 Prompt 工程让 AI“会吐槽”本质上是一个 Prompt 工程问题。同样的模型不同的提示词会带来完全不同的输出风格。设计这个 Prompt 时要注意三点第一要定义好人设。不能让它变成一个无脑骂用户的角色而是一个“懂理财、嘴有点贫但出发点是为你好”的朋友。第二要给出结构化输入。把用户的外卖次数、总金额、消费频率作为变量传入模型才有依据去吐槽。第三要限定输出格式和长度。最好控制在 50 字以内避免生成一大段空洞说教。下面是我在示例中使用的提示词模板SYSTEM_PROMPT 你是一个说话幽默但一针见血的个人理财助手。 用户会把最近的外卖消费数据发给你你需要用简短、略带吐槽但又不刻薄的话提醒用户注意消费。 要求 1. 语气轻松像朋友聊天不要用官方客服腔 2. 结合具体数据比如消费次数、金额、频率 3. 字数控制在 50 字以内 4. 不要编造用户没有提供的数据。 这个 Prompt 之所以有效是因为它明确了语气、字数、数据来源边界。在实际产品中你还可以对不同用户配置不同风格比如“毒舌版”“温和版”“搞笑版”用 A/B 测试来观察用户接受度。3.4 消费评分与用户画像除了文案产品还需要一个可量化的“乱花钱指数”。这个指数不一定要特别复杂可以先用几个规则叠加过去 7 天外卖订单数超过 5 次得分 20单笔外卖金额超过 80 元每笔加 5 分存在深夜21 点后下单行为每次加 5 分周末外卖次数明显高于工作日加 10 分。这是一个典型的启发式评分模型。它不一定准确但足以支持 MVP 阶段的“风险等级”提示。后续如果要做精细化可以引入用户历史消费分布计算 Z-Score 或百分位排名。下面我会在实战代码里实现一个简化版返回high / normal / low三个风险等级配合 AI 文案一起展示。4. 完整实战案例从零构建 AI 理财助手4.1 创建项目结构先创建以下目录结构ai-finance-assistant/ ├── requirements.txt ├── main.py ├── services/ │ ├── __init__.py │ ├── bill_parser.py │ └── ai_comment.py └── static/ └── index.html在终端中执行mkdir ai-finance-assistant cd ai-finance-assistant mkdir services static然后创建requirements.txt并安装依赖pip install -r requirements.txt4.2 编写账单解析服务创建services/bill_parser.py。它的职责是从原始文本中解析出账单条目并做外卖分类。# 文件路径services/bill_parser.py import re from typing import List, Dict # 常见外卖平台关键词 PLATFORM_KEYWORDS [美团外卖, 饿了么, 大众点评, 外卖] # 常见餐饮品类关键词用于辅助判断 FOOD_KEYWORDS [ 汉堡, 奶茶, 咖啡, 炸鸡, 麻辣烫, 烧烤, 煲仔饭, 披萨, 寿司, 面, 饭, 套餐, 小龙虾, 甜品, 夜宵, 便当 ] class BillItem: def __init__(self, date: str, merchant: str, description: str, amount: float, category: str): self.date date self.merchant merchant self.description description self.amount amount self.category category def to_dict(self) - Dict: return { date: self.date, merchant: self.merchant, description: self.description, amount: self.amount, category: self.category, } def _parse_amount(value: str) - float: 从字符串中提取金额例如 39.90 元 - 39.90 match re.search(r(\d\.?\d*), value) if match: return float(match.group(1)) return 0.0 def _classify(merchant: str, description: str) - str: 判断一笔消费是否为外卖 text f{merchant} {description} for kw in PLATFORM_KEYWORDS: if kw in text: return takeout for kw in FOOD_KEYWORDS: if kw in text: return takeout return other def parse_bill(raw_text: str) - List[BillItem]: 解析账单文本返回 BillItem 列表 items [] lines [line.strip() for line in raw_text.splitlines() if line.strip()] for line in lines: parts line.split() if len(parts) 5: continue date parts[0] # 合并商户与商品描述具体列数量以实际文本为准 merchant parts[1] description .join(parts[2:-2]) amount _parse_amount(parts[-2]) category _classify(merchant, description) items.append(BillItem(date, merchant, description, amount, category)) return items这段代码有几个要点_parse_amount使用正则从字符串中提取数字避免账单里出现“¥19.9”“19.9元”“19.90 元”等不同格式时解析失败。_classify优先用平台名识别再用品类关键词兜底。parse_bill按行拆分并假设账单格式为“日期 商户 描述 金额单位”。如果真实数据格式不同你需要调整字段位置。4.3 实现风险评分与统计服务我在main.py里直接写统计逻辑方便你查看完整流程。# 文件路径main.py from typing import List from services.bill_parser import BillItem, parse_bill from services.ai_comment import generate_comment def compute_risk(items: List[BillItem]) - dict: 基于账单条目计算风险和统计信息 takeout_items [item for item in items if item.category takeout] total_spent round(sum(item.amount for item in items), 2) takeout_count len(takeout_items) takeout_spent round(sum(item.amount for item in takeout_items), 2) # 简单的风险评分规则 score 0 if takeout_count 5: score 20 for item in takeout_items: if item.amount 80: score 5 if 深夜 in item.description or 夜宵 in item.description: score 5 if item.date.endswith(06) or item.date.endswith(07): score 3 if score 30: risk_level high elif score 15: risk_level normal else: risk_level low return { total_spent: total_spent, takeout_count: takeout_count, takeout_spent: takeout_spent, risk_score: score, risk_level: risk_level, }这段代码里我故意保留了一个很朴素的日期判断逻辑如果日期以06或07结尾就认为可能是周末。真实场景中你应该用datetime来判断这里只是演示思路。4.4 对接大模型实现 AI 吐槽引擎创建services/ai_comment.py通过 HTTP 调用 OpenAI 兼容的 Chat Completions 接口。# 文件路径services/ai_comment.py import os import requests SYSTEM_PROMPT 你是一个说话幽默但一针见血的个人理财助手。 用户会把最近的外卖消费数据发给你你需要用简短、略带吐槽但又不刻薄的话提醒用户注意消费。 要求 1. 语气轻松像朋友聊天不要用官方客服腔 2. 结合具体数据比如消费次数、金额、频率 3. 字数控制在 50 字以内 4. 不要编造用户没有提供的数据。 def _build_user_message(stats: dict) - str: return ( f我最近一共花了 {stats[total_spent]} 元 f其中外卖 {stats[takeout_count]} 次 f外卖花了 {stats[takeout_spent]} 元 f风险评分 {stats[risk_score]}风险等级 {stats[risk_level]}。 ) def generate_comment(stats: dict) - str: 调用大模型生成吐槽文案。 需要设置环境变量 LLM_API_KEY、LLM_BASE_URL、LLM_MODEL。 api_key os.getenv(LLM_API_KEY) base_url os.getenv(LLM_BASE_URL, https://api.openai.com/v1) model os.getenv(LLM_MODEL, gpt-3.5-turbo) if not api_key: return 你还没配置大模型 API Key先不吐槽了注意省着点花。 url f{base_url.rstrip(/)}/chat/completions headers { Authorization: fBearer {api_key}, Content-Type: application/json, } payload { model: model, messages: [ {role: system, content: SYSTEM_PROMPT}, {role: user, content: _build_user_message(stats)}, ], temperature: 0.9, max_tokens: 100, } try: resp requests.post(url, headersheaders, jsonpayload, timeout15) resp.raise_for_status() data resp.json() return data[choices][0][message][content].strip() except Exception as exc: return fAI 暂时开小差了{exc}但账单数据显示你真的该控制一下外卖了。这段代码有两点需要重点说明我没有把LLM_API_KEY写死在代码里而是通过环境变量注入避免密钥泄露到代码仓库。base_url支持自定义意味着你可以通过兼容网关接入国内大模型服务也可以对接 OpenAI。不同服务商的接口地址不同请根据实际情况修改。4.5 编写 FastAPI 接口回到main.py把上面的逻辑串起来# 文件路径main.py from fastapi import FastAPI, HTTPException from fastapi.staticfiles import StaticFiles from pydantic import BaseModel, Field from typing import List from services.bill_parser import BillItem, parse_bill from services.ai_comment import generate_comment from compute_risk import compute_risk app FastAPI(titleAI 理财助手 Demo) class BillRequest(BaseModel): text: str Field(..., min_length10, description账单原文) class BillResponse(BaseModel): items: List[dict] stats: dict comment: str app.post(/api/v1/analyze, response_modelBillResponse) def analyze_bill(req: BillRequest): items parse_bill(req.text) if not items: raise HTTPException(status_code400, detail未能从账单文本中解析出有效条目) stats compute_risk(items) comment generate_comment(stats) return BillResponse( items[item.to_dict() for item in items], statsstats, commentcomment, ) app.mount(/, StaticFiles(directorystatic, htmlTrue), namestatic)注意我在示例中把compute_risk单独导入。你可以把compute_risk函数放到main.py中也可以单独建一个compute_risk.py。为了结构清晰建议单独拆文件。这里以“示例思路如下需按实际结构调整”为原则你在本地实现时保持模块分层即可。4.6 编写前端测试页面创建static/index.html做一个极简页面用户粘贴账单文本点击按钮后调用后端接口展示解析结果和 AI 吐槽。!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleAI 外卖吐槽助手/title style body { font-family: sans-serif; max-width: 720px; margin: 40px auto; padding: 0 16px; } textarea { width: 100%; height: 180px; margin-bottom: 12px; padding: 12px; font-size: 14px; } button { padding: 10px 20px; font-size: 16px; cursor: pointer; } .card { border: 1px solid #eee; border-radius: 8px; padding: 16px; margin-top: 16px; } .risk-high { color: #d33; } .risk-normal { color: #e6a23c; } .risk-low { color: #67c23a; } pre { background: #f7f7f7; padding: 12px; border-radius: 8px; overflow-x: auto; } /style /head body h2AI 外卖吐槽助手/h2 p粘贴你的账单文本每行一条点击分析看看 AI 怎么吐槽你。/p textarea idbillInput placeholder示例#10;2025-01-06 12:31 美团外卖 煲仔饭 支付 39.90 元#10;2025-01-08 20:40 美团外卖 深夜烧烤 支付 86.00 元/textarea br button onclickanalyze()开始分析/button div idresult/div script async function analyze() { const text document.getElementById(billInput).value; if (!text.trim()) { alert(请先粘贴账单文本); return; } const resp await fetch(/api/v1/analyze, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ text }) }); const data await resp.json(); if (!resp.ok) { alert(data.detail || 请求失败); return; } const stats data.stats; const riskClass risk- stats.risk_level; let html div classcard; html h3分析结果/h3; html p总消费b${stats.total_spent}/b 元/p; html p外卖次数b${stats.takeout_count}/b 次/p; html p外卖金额b${stats.takeout_spent}/b 元/p; html p风险评分b${stats.risk_score}/b/p; html p class${riskClass}风险等级${stats.risk_level}/p; html p stylemargin-top:8px;font-size:18px; ${data.comment}/p; html h4识别明细/h4; html pre JSON.stringify(data.items, null, 2) /pre; html /div; document.getElementById(result).innerHTML html; } /script /body /html这里我在页面上用了一个 emoji 作为引用图标如果你所在团队要求统一风格可以删掉或者换成普通文字。4.7 运行与验证启动后端服务export LLM_API_KEY你的大模型API Key export LLM_BASE_URLhttps://api.openai.com/v1 export LLM_MODELgpt-3.5-turbo uvicorn main:app --reload --port 8000如果你在 Windows 命令行环境export需要换成setset LLM_API_KEY你的大模型API Key set LLM_BASE_URLhttps://api.openai.com/v1 set LLM_MODELgpt-3.5-turbo启动后打开浏览器访问http://127.0.0.1:8000粘贴示例账单点击“开始分析”。如果你不想打开页面也可以用 curl 测试接口curl -X POST http://127.0.0.1:8000/api/v1/analyze \ -H Content-Type: application/json \ -d {text: 2025-01-06 12:31 美团外卖 煲仔饭 支付 39.90 元\n2025-01-08 20:40 美团外卖 深夜烧烤 支付 86.00 元}预期返回一个 JSON 对象包含items、stats和comment三个字段。如果大模型 API 没有配置comment会返回兜底文案其他统计功能仍然正常可用。5. 常见问题与排查思路在实际动手过程中你可能会遇到下面这些问题。问题现象常见原因解决思路接口返回“未能解析出有效条目”输入的账单文本格式与代码假设不一致检查文本列数调整parse_bill中的字段位置金额解析为 0.0金额中没有匹配到数字检查_parse_amount正则确认支持“19.9元”“¥19.9”等格式外卖分类不准确关键词表覆盖不全扩展FOOD_KEYWORDS列表或用大模型兜底判断启动后页面 404static目录不存在或index.html路径不对确认static文件夹和index.html已创建AI 返回超时网络不稳定或超时设置太短增大timeout或切换为流式输出AI 回复内容偏长、语气生硬Prompt 约束不足在SYSTEM_PROMPT中强化字数限制和语气要求除了表格中的问题有一个高频问题值得单独说明如果你调用的是国内大模型服务它们的接口不一定叫chat/completions字段也可能不同。建议先阅读服务商的官方文档再调整generate_comment中的 URL 和 payload。另外开发阶段不要把密钥写进代码里。一旦提交到 Git 仓库哪怕再删掉密钥也可能已经泄露。正确的做法是用环境变量或配置中心管理密钥并在.gitignore中忽略.env文件。6. 最佳实践与工程建议6.1 成本控制让大模型只做“最后一公里”如果你每个账单都调用一次大模型API 费用会非常惊人。合理的做法是用规则和正则完成 80% 的账单分类只有遇到低置信度样本时才调用大模型判断文案生成单独设计一套 Prompt同一批次统计数据只调用一次。如果产品用户量大还可以引入缓存机制相同或相近的统计结果在短时间内直接复用上次生成的文案或者提前准备一批模板文案做冷启动。6.2 产品文案的双刃剑“会吐槽”是这个产品最大的亮点也是最容易翻车的地方。AI 生成的文案如果失控可能变成冒犯用户。我建议在生成侧做好三层保护第一层Prompt 中明确禁止攻击性语言强调“友善调侃”。第二层在代码逻辑中过滤敏感词。如果 AI 输出中包含辱骂、歧视、政治等敏感词汇直接走兜底文案。第三层在 UI 层提供用户反馈入口。用户觉得文案不舒服时可以标记“不喜欢”产品侧用这些数据反向优化 Prompt。6.3 数据隐私与合规边界处理用户账单数据属于明确的敏感行为。即使只是做个人项目也应该注意只获取实现功能所必需的数据不碰与消费无关的通讯录、相册权限账单文本尽量在服务端或端侧处理不存原始数据如果涉及银行卡、支付信息必须在生产环境中启用 HTTPS并遵循最小权限原则上线前参考相关隐私合规要求公示数据用途并提供“删除我的数据”入口。不要因为功能好玩就忽视了数据安全边界。尤其在与支付通道对接时任何越权访问都是严重事故。6.4 从 Demo 到生产环境的差距上面的例子能帮你跑通一个最小闭环但距离生产还差几件事接入真实账单需要与支付平台或银行开放平台签约通过授权接口获取账单而不是让用户粘贴文本。用户体系登录、会话管理、用户画像存储。任务调度每天定时分析前一天消费生成日报推送。多端适配把 HTML 原型迁移到 Flutter、Android、iOS。监控告警大模型调用失败率、接口延迟、异常文案出现次数都要纳入监控。如果你是个人开发者我建议先用“粘贴文本”的方式验证产品需求等确认用户真的喜欢这种提醒方式后再投入成本接入真实账单数据。这样开发效率最高风险也最低。7. 总结与学习路线基于“会吐槽用户乱点外卖”的 AI 理财 App 案例我从技术侧拆解了一个 AI 消费提醒产品的完整链路账单解析、外卖分类、风险评分、大模型文案生成、前后端联调。你跟着示例代码跑通后已经掌握了一个具备基本人格化表达能力的 AI 助手后端模型。如果想继续深入建议按下面几个方向扩展学习学习大模型应用开发框架例如 LangChain 或 Spring AI把 Prompt、记忆和工具调用做得更规范学习 Flutter 或 Android 开发把 HTML 原型变成真正的 App学习数据仓库和数据同步为接入支付宝、微信账单做准备学习 A/B 测试与用户反馈体系用数据判断哪种吐槽风格更好。产品侧可以优化的方向也很多比如对不同用户群体设置不同人格增加“月光预警”“周报复盘”“好友消费排行”等功能。第一步先把账单解析和一条 AI 吐槽跑通再去加更多装饰能力。你会发现真正难的不是调用大模型而是如何在每一次提醒里既让用户觉得有趣又能提供真实的价值。希望这篇文章对你做 AI 应用开发、App 开发或理财类产品设计有帮助有问题可以在评论区一起交流。
返回列表