估计很多人都用过类似下面这种记账软件,也就是需要每次手动录入消费金额。用过一段时间后发现不可行,因为很多时候更不想不起来记录,久而久之也就卸载了!
其实个人对记账软件的要求没那么复杂,无需那么多复杂的功能,只要能拍下消费记录,就能够自动识别消费类型,消费时间,消费金额,而且还能实时查询和统计消费情况就行了。一直想自己做一个类似的小助手,最后发现第一关OCR就过不去。不同企业OCR需求,只要标准的发票即可,采用发票样本训练过的OCR模型即可准确识别。
个人消费会涉及到衣食住行方方面面。除了发票、火车票等,还涉及到线下餐饮小票、购物小票、微信淘宝支付记录、数字人民币消费记录等等。从各式各样的消费小票中提前消费时间、金融等等,传统的OCR实现将会是“难上加难”。
正好最近看到了智谱 BigModel 开放平台,Flash 系列免费模型全家桶上线,覆盖语言、图像理解、图像生成、视频生成,均可免费调用 API,多能力多维度应用场景,实现理想效果。
最后灵光一闪,OCR不行,我可以用智谱免费开放的 GLM-4V-Flash 多模态大模型实现以下效果啊:
备注:GLM-4V-Flash 专注于高效的单一图像理解,适用于快速图像解析的场景,例如实时图像分析或批量图像处理。
在设计上,希望尽量简单,英文涉及到消费记录的存储,底层我们采用MySQL进行存储消费数据表。在逻辑上主要包含以下几个方面:
备注:MaxKB开源的RAG系统,其工作流可按照需求进行任务进行编排。
此方案最核心的点在于 GLM-4V-Flash 模型能否正常识别各种消费小票,这需要我们提前验证。GLM-4V-Flash调用提供了API和SDK两种使用方式!在使用前我们需要智谱AI开放平台中获取API KEY:
#智谱AI开放平台地址
https://bigmodel.cn/usercenter
本文我们采用使用SDK调用方式,需要先安装智谱Python库
#安装SDK库
pip install zhipuai
详细的接口,可见智谱官网说明文档:
https://www.bigmodel.cn/dev/api/normal-model/glm-4v
验证脚本如下:
from zhipuai import ZhipuAI
client = ZhipuAI(api_key='b975b3xxxxxxxxxxxxq3y') # 填写您自己的APIKey
response = client.chat.completions.create(
model='glm-4v-flash', # 填写 GLM-4V-Flash 模型名称
messages=[
{
'role': 'user',
'content': [
{
'type': 'text',
'text': '请提取这张消费中消费信息'
},
{
'type': 'image_url',
'image_url': {
'url' : 'https://pic.rmb.bdstatic.com/bjh/events/283bf6b358d25244dd3c22b85f44b2893954.jpeg@h_1280'
}
}
]
}
]
)
print(response.choices[0].message)
经过多次的验证,发现GLM-4V-Flash的识别效果杠杠的,百分百准确!(下图片来源于网上):
在MySQL中创建相关数据库和表(MySQL部署略...)。
#创建finance库
CREATE DATABASE finance /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */ /*!80016 DEFAULT ENCRYPTION='N' */
#创建consumptions表
CREATE TABLE consumptions ( consumption_id int NOT NULL AUTO_INCREMENT, amount decimal(10,2) NOT NULL, consumption_date datetime NOT NULL, category varchar(255) COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (consumption_id)) ENGINE=InnoDB AUTO_INCREMENT=2572 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
为了方便后续测试,我们可以用下列脚本提前在 consumptions 表中生成300条消费记录数据;
INSERT INTO `consumptions` (`amount`, `consumption_date`, `category`)
SELECT
FLOOR(RAND() * 2000 + 1) AS amount,
DATE_ADD('2024-01-01', INTERVAL FLOOR(RAND() * 335) DAY) AS consumption_date,
CASE
WHEN RAND() < 0.25 THEN '餐饮'
WHEN RAND() < 0.5 THEN '购物'
WHEN RAND() < 0.75 THEN '交通'
ELSE '娱乐'
END AS category
FROM
(SELECT a.N + b.N * 10 + c.N * 100 AS N
FROM (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
CROSS JOIN (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
CROSS JOIN (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) c
LIMIT 300) AS nums;
第一步:在MaxKB中接入 GLM-4V-Flash 和 GLM-4-Flash模型,两个都免费不限量
备注:MaxKB是一款基于大语言模型和 RAG 的开源知识库问答系统。
为了实现数据写入和查询,MaxKB的函数库需要两个,一个获取金额数据后,写入数据库,另外一个查询数据库中所有的消费信息。
需要提前在MaxKB的主机中安装MySQL连接库库;
#安装MySQL连接库
docker exec -it maxkb bash
pip install mysql-connector-python -i https://mirrors.aliyun.com/pypi/simple/
#函数库Python脚本
import mysql.connector
from mysql.connector import Error
def execute_sql_query(query):
'''
:param query: 要执行的SQL查询
:return: 查询结果
'''
connection = None
result = None
try:
connection = mysql.connector.connect(
host= '10.1.240.130',
user= 'root',
passwd= 'Password123@mysql',
database= 'finance'
)
if connection.is_connected():
cursor = connection.cursor()
cursor.execute(query)
# 对于SELECT查询,我们使用fetchall()来获取所有结果
# 对于INSERT、UPDATE、DELETE等,你可以通过cursor.rowcount来获取影响的行数
if query.upper().startswith('SELECT'):
result = cursor.fetchall()
else:
connection.commit() # 确保更改被提交到数据库
result = cursor.rowcount # 获取影响的行数
except Error as e:
print(f'Error while connecting to MySQL {e}')
finally:
if connection.is_connected():
cursor.close()
connection.close()
print('MySQL connection is closed')
return result
具体节点如下:
import mysql.connector
from mysql.connector import Error
def execute_sql_query():
'''
:param query: 要执行的SQL查询
:return: 查询结果
'''
connection = None
result = None
query = 'SELECT amount,consumption_date,category FROM finance.consumptions;'#全表查询语句
try:
connection = mysql.connector.connect(
host= 'xxx.xxx.xxx.xxx',
user= 'root',
passwd= 'xxxxxx',
database= 'finance'
)
if connection.is_connected():
cursor = connection.cursor()
cursor.execute(query)
# 对于SELECT查询,我们使用fetchall()来获取所有结果
# 对于INSERT、UPDATE、DELETE等,你可以通过cursor.rowcount来获取影响的行数
if query.upper().startswith('SELECT'):
result = cursor.fetchall()
else:
connection.commit() # 确保更改被提交到数据库
result = cursor.rowcount # 获取影响的行数
except Error as e:
print(f'Error while connecting to MySQL {e}')
finally:
if connection.is_connected():
cursor.close()
connection.close()
print('MySQL connection is closed')
return result
具体节点如下:
至此,所有的验证和准备工作已经完成,剩下的就是利用MaxKB的应用编排能力,将“随手拍”消费管理小助手搭建起来。
第一步:创建高级编排应用
第二步:编排界面中,应用开启上传图片功能
第二步:利用智谱 GLM-4V-Flash 模型理解图片,提取信息,并且生成可执行SQL。具体的提示词如下:
图片:
- {{开始.image}}
第一点要求:
- 理解图片中的信息,请判断图片信息是否属于消费类型,如果不属于消费类型,请直接输出0,无需执行第二点要求。如果是消费类型,执行第二点要求。
第二点要求:
- 理解图片中的信息,判断此消费属于什么类型(从餐饮、出行、住房、服装、娱乐、家庭、工作,这几类中进行选择进行选择);
- 提取图片中消费金额、消费时间(格式为 2024-12-17 12:00:00;
- 依据提取的信息,严格按照此SQL语句 [“INSERT INTO `consumptions` (`amount`, `consumption_date`, `category`) VALUES (100.00, '2024-12-17 12:00:00', '餐饮');”] 生成可执行SQL语句。其中提取到的消费金额字段为amount,消费时间字段为consumption_date,消费类型字段为category;
- 最后只输出完整的SQL语句即可,无需回复任何其他内容
节点配置如下:
当然我们,还需要支持查询功能,可以在工作流中加上查询节点
最后:整体的工作流如下:
比如我们可以拍照,然后通过 GLM-4V-Flash 模型理解,生成SQL后,自动落入库,方便,快捷!
小票类自动识别和录入:
微信支付类自动识别和录入:
支付宝支付类自动识别和录入:
可以看到 GLM-4V-Flash 详细的处理过程和生成的SQL:
如果不录入,可以直接查询,比如提问上图的消费清单内容,”2023-01-01有哪些消费?“和”上个月一共消费了多少金额?“
看到这,你是不是也觉得很6?当然你也可以通过 GLM-4V-Flash 充分验证自己的想法和思路,如果感兴趣的话,赶紧试试吧!