基于Fireflyiii开源记账系统,结合Langchain和DeepSeek实现AI Agent记账智能体

该文章已生成可运行项目,

基于Langchain和DeepSeek的AI Agent记账系统:Fireflyiii-AI-Recorder深度解析

随着AI的爆火,以及MCP的出现,越来越多的AI agent应用也逐渐开始爆火。这里我们通过一个案例,聊一聊如何通过Langchain构建AI智能体应用。

许多人都有记账的习惯,但往往会因为过于繁琐而中途放弃。大多数记账软件需要填写消费时间、地点、收入或支出账户、分类等信息,非常麻烦。不过,有了AI之后,这些意图识别的工作都可以交给AI完成。我使用的记账工具是名为FireflyIII的开源软件,它不仅支持私有化部署,还能够提供一些商业化的财务功能。

因此为了方便我的使用,我便基于FireflyIII的api的功能,结合Langchain和deepseek api实现了这样一个AI记账的功能。

在这里插入图片描述

🤖 AI Agent工作流程

记账AI Agent是一个智能代理系统,它能够:

  • 理解人类自然语言描述的消费行为
  • 自主决策如何分类和记录财务数据
  • 与Fireflyiii系统交互完成记账操作
  • 从错误中学习并优化决策流程

与传统记账软件不同,AI Agent具备语义理解逻辑推理能力,能处理模糊、不完整的消费描述。

🔍 任务分解与执行

用户输入文本
语义解析
AI决策引擎
金额识别
消费分类
时间推断
数据验证
Fireflyiii记账
结果反馈

关键决策点

  1. 模糊描述处理

    • “请了团队喝咖啡” → 自动拆分为多人消费
    • “买了办公用品” → 匹配预设的办公类别
  2. 异常检测

    • 识别金额异常(如10000元的午餐)
    • 检测时间冲突(未来日期消费)
  3. 上下文关联

    • “续费了年度会员” → 关联去年同期的记账
    • “报销差旅费” → 匹配对应的报销账户

🚀 核心功能亮点

  1. 自然语言解析

    • 智能识别消费描述中的金额、类别和时间
    • 支持批量处理多日消费记录
    • 示例输入:
      7.6
      - 66 午餐 12:00
      - 900 物业费(最近一季度)
      7.7
      - 150 购物
      
  2. Fireflyiii深度集成

    • 通过OpenAPI自动创建交易记录
    • 保持与Fireflyiii数据模型完全兼容
  3. 多场景部署

    • 本地开发环境
    • Docker容器化部署
    • NAS设备部署(如极空间)

🚀 核心代码:Langchain+DeepSeek实现原理

Langchain核心组件

用户输入
Prompt模板
DeepSeek大模型
JSON输出解析器
结构化数据
准备工作
  1. 安装Python 3.10+
  2. 获取DeepSeek API Key
  3. 准备Fireflyiii实例和API密钥
1. Prompt模板
  • 定义输入输出规范
  • 包含示例和指令
  • 动态插入变量
2. DeepSeek大模型
  • 使用init_chat_model初始化
  • 支持多模型提供商
  • 处理自然语言理解任务
3. JSON输出解析器
  • 确保输出为规范JSON格式
  • 自动转换模型原始输出
  • 提供错误处理机制
4. 处理链(Chain)
  • 连接各组件:prompt | llm | parser
  • 实现端到端数据处理
  • 支持异步调用

完整代码实现

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import JsonOutputParser
from langchain.chat_models import init_chat_model

class FireflyTransactionAgent:
    def __init__(self):
        # 初始化DeepSeek模型
        self.llm = init_chat_model(
            "deepseek-chat",
            api_key=settings.openai_api_key,
            base_url=settings.openai_api_base,
            model_provider="deepseek",
        )
        
        # 创建JSON解析器
        self.parser = JsonOutputParser()
        
        # 构建Prompt模板
        self.prompt = ChatPromptTemplate.from_template("""
            请将以下交易记录解析为JSON数组,包含字段:
            - date: 交易日期(YYYY-MM-DDTHH:mm)
            - description: 描述
            - amount: 金额
            - category: 分类
            - tags: 标签列表
            - think_result: AI思考过程
            
            示例输入:
            07.06
            - 12.00 午餐 66
            
            示例输出:
            {{
                "transactions": [{{
                    "date": "2025-07-06T12:00",
                    "description": "午餐",
                    "amount": 66,
                    "category": "餐饮",
                    "tags": ["餐饮-午餐"]
                }}],
                "think_result": "识别为午餐消费,归类到餐饮"
            }}
            
            实际输入:
            {input_text}
        """)
        
        # 创建处理链
        self.chain = self.prompt | self.llm | self.parser
    
    def parse(self, text: str) -> Dict:
        # 获取分类和标签数据
        tags_and_categories = self.get_tags_and_categories()
        
        # 执行处理链
        result = self.chain.invoke({
            "input_text": text,
            "categories": tags_and_categories["categories"],
            "tags": tags_and_categories["tags"]
        })
        
        return {
            "transactions": result.get("transactions", []),
            "think_result": result.get("think_result", "")
        }

关键代码解析

  1. 模型初始化

    self.llm = init_chat_model(
        "deepseek-chat",
        api_key=settings.openai_api_key,
        base_url=settings.openai_api_base,
        model_provider="deepseek",
    )
    
    • deepseek-chat: 指定模型类型
    • api_key: DeepSeek API密钥
    • base_url: API基础地址
    • model_provider: 模型提供商
  2. 处理链构建

    self.chain = self.prompt | self.llm | self.parser
    
    • | 运算符连接组件
    • 数据流:模板 → 模型 → 解析器
  3. 链式调用

    result = self.chain.invoke({
        "input_text": text,
        "categories": [...],
        "tags": [...]
    })
    
    • 动态注入变量到模板
    • 自动处理模型调用和输出解析

实际调用示例

agent = FireflyTransactionAgent()
input_text = """
07.15
- 12:00 团队午餐 450
- 15:30 办公用品 280
"""

result = agent.parse(input_text)
print(result["think_result"])
# 输出:识别到2笔消费:团队午餐归类为餐饮-团建,办公用品归类为办公-耗材
print(result["transactions"])
# 输出:[{...}, {...}] 结构化数据

关键技术突破

  1. 思维链(CoT)推理
    Agent通过多步推理处理复杂场景:

    用户输入: "支付了上个月的电费500元"
    Agent思考:
      1. 这是水电费支出
      2. 时间应为上个月最后一天
      3. 需要关联电力公司账户
      4. 分类到"家庭开支/水电煤"
    
  2. 自我修正机制

    • 当Fireflyiii返回错误时,Agent自动:
      1. 分析错误原因
      2. 调整数据格式
      3. 重新提交请求
  3. 记忆上下文
    使用ConversationBufferMemory保存对话历史:

    memory = ConversationBufferMemory(memory_key="chat_history")
    agent_executor = AgentExecutor(
        agent=agent,
        tools=tools,
        memory=memory,
        verbose=True
    )
    

📦 部署方案

github主页有部署流程,代码量不多,运行很容易。
docker 镜像下载docker pull zl3n22/fireflyiii-ai-recorder:latest

NAS部署指南(极空间为例)

搜索镜像zl3n22/fireflyiii-ai-recorder 如果搜不到的话,就需要手动拉取源码打包镜像再导入到极空间了。
主要配置的环境变量如下:
在这里插入图片描述
如果不想手动配置的,也可以在极空间中新建一个.env文件,将文件挂载到/app/.env目录下

# Firefly III 配置
FIREFLY_III_URL=你的Firefly III实例地址
FIREFLY_III_API_KEY=你的Firefly III API密钥

# OpenAI兼容API配置
OPENAI_API_BASE=你的OpenAI兼容API地址
OPENAI_API_KEY=你的OpenAI API密钥
OPENAI_MODEL_NAME=使用的模型名称

  1. 创建容器时映射5001端口
  2. 配置环境变量
  3. 启动容器

💡体验案例

这里我输入了两个日期的三条不同的记录,通过点击AI解析记录后,能看到AI把这段话分解成了三个不同的交易记录,同时附上了对应的分析过程。

✅ 总结

Fireflyiii-AI记账系统通过:

  • 降低记账门槛(自然语言输入)
  • 提升数据准确性(AI智能解析)
  • 简化部署流程(多平台支持)

项目地址:https://github.com/your-repo/fireflyiii-ai-recorder
遇到问题?在GitHub提交Issue或通过公众号一颗程序树联系作者!

本文章已经生成可运行项目
背景 最开始记账的时候使用的某著名记账应用,软件本身也算中规中矩,后来一方面因为卖用户信息的传闻闹得沸沸扬扬,一方面觉得输入太慢,也远不如 Excel 灵活,于是改用 Excel。 Excel 的好处就比较多了,输入快捷,统计方便,扩展灵活。但因为当时记得是简单的流水账,虽然可以分类统计开销之类,但各种账户之间的情况一团乱麻,最近接触到复式记账法,打算尝试下,而支持复式记账的软件可供选择的就不多了。 GnuCash 免费开源、支持 Windows、支持复式记账,相比 Excel,麻烦的就是需要记录的东西比较多(其实 Excel 也可以复式记账,不过功能实现上相对麻烦,不如专业软件省心) ,好处是你可以精确知道自己有多少钱了(或者,钱在哪了?或者,有没有钱了?或者,欠多少钱了?) 目前使用的是 GnuCash 2.6.18 版本(中文界面)。 复式记账概念 对于普通用户来说,GnuCash 涉及到大量财务方面的专业词汇,本身的汉化也不全,上手可能略有麻烦,建议使用之前简单了解一下复式记账法。 (以下说法仅供参考)因为复式记账是以公司为主体的,所以有些概念套到个人、家庭账目上会很别扭,像借记、贷记的说法也比较绕,开始可以略过,基本上了解「一切皆科目,数字在科目中流动」即可。具体来说,任何一笔账目,都会至少对应两个科目——点个外卖,「支出」会变化,如果信用卡付账,「负债」会变化,如果现金付账,「资产」会变化。至于左列、右列、加还是减这些也可以等具体记账时实践。此外的两大科目,「收入」很好理解,发工资了,「收入」「资产」都会变化;「权益」这个概念因为也是主要针对公司的(谁出了多少本钱?),个人使用的时候,可以简单理解为最开始记账的时刻各个账户(科目)有多少钱(「所有者权益」-「期初余额」) 软件的使用 科目设置 装好软件后会首先要求设置科目层次(不清楚设置的话一路前进即可),因为后面要提到的快速补全不支持中文的问题,可以先选择「通用科目」,之后根据实际情况修改成英文或拼音,不同科目大类的设定多有不同,不熟悉复式记账的最好直接修改「通用科目」中特定或类似的科目。科目大类一般为默认的「权益」、「资产」、「负债」、「收入」、「支出」。 账目不对的时候系统会自动生成「不平衡的」科目,这是因为复式记账任何账目至少涉及两大科目而实际录入的账目不平的关系,改好账目后「不平衡的」科目金额会归零(「孤立的」科目情况类似) 存储格式 GnuCash 提供了四种存储格式,xml 格式有定期的数据备份(sqlite3 似乎没有),数据库放在云同步软件(Dropbox 或者坚果云)中就可以轻松实现多终端同步使用了。 快速录入 科目快速补全(Quickfill) 对中文用户来说有点尴尬,中文版默认创建中文科目,而该功能仅支持英文(不包括数字),所以为了使用该功能,建议使用英文(或拼音)命名所有科目。例如 Assets:Cash(ZiChan:XianJin) 可以在任意科目类单元格里使用 A:C (Z:X)快速补全(中间的冒号可以在设置「编辑-首选项-科目-分隔字符」中修改为其他符号,如填入 slash 可修改为 /) 注意,「自动提升列表」(功能编辑-首选项-账簿-动作)科目快速补全功能有点冲突,可以关闭该功能(或者使用每次打冒号之前按下 Esc 键关闭提示列表,再用子科目的首字母补全)。 日期快速切换 在日期类单元格,可以使用 - = 切换至前一天后一天 _ + 切换至前一周后一周 m h 切换至本月的第一天最后一天 y r 切换至本年的第一天最后一天 t 切换至今天 金额简单计算 作为一款记账软件,GnuCash 在金额类单元格里提供了简单的计算功能,例如可以直接输入 30*2 这类表达式(不需要输入 = 号) 交易记忆补全 在描述单元格输入之前输入过的内容时,会出现自动补全提示,TAB 执行补全会根据匹配历史交易自动补全整个交易(包括相关科目金额),这个功能极大的减轻了频繁发生的日常开支记账的工作量。 账簿模式 GnuCash 提供了「基本分类账」、「自动拆分分类账」「交易日记账」三种账簿模式(「查看」菜单),新手建议一般情况下使用「基本分类账」模式方便账目录入,需要拆分交易的时候切换到「交易日记账」模式方便分割交易。另外可以通过 工具-总分类账 菜单调出「总分类账」页面,熟练的话直接在该页面记账更方便(不需要打开或者选择科目页面)。 拆分交易 因为关系到交易涉及各科目的准确记录,拆分交易这种操作就很有必要了(购买记录根据物品拆分,支出记录根据付款方式拆分等)。Gnucash 的拆分交易操作刚接触有点绕,新手建议切换至「交易日记账」模式中操作。 具体操作(根据物品拆分的情况),(「交易日记账」下),每笔交易在选中状态时至少包括四行内容: 第一行为交易描述,可以在描述单元格中填入交易梗概(因为在其他模式中无法直接看到具体分割条目的备注,所以梗概建议有一定信息量方便查阅) (之后 TAB 转入)第二行开始记录具体分割条目,首先记录资金去向,依次填入(可通过 TAB 切换)备注(物品名)、科目(消费类别)、资金收入(物品价格)、资金支出(应为空)。(之后 TAB 转入)第三行重复,直至分项物品记录完毕。 (之后 TAB 转入)最后一行记录资金来源,依次填入备注(可为空)、科目(支出账户)、资金收入(应为空)、资金支出(支出总金额),其中资金支出一栏已由系统自动计算,可与实际支出金额对照校验。 对账 对于个人用户来说,涉及存在清晰账单(银行卡、支付宝之类)的科目,对账功能比较好用。下面以具体操作说明: 选择特定科目,右键 - 对账,选择日期(如信用卡的账单日期),期末余额(信用卡的账单金额)- 确定,对账窗口会列出所有对账期间的收入支出明细,分别全选(Crtl + A,空格),账目无误的话右下角的差额会为 0,否则表示账目与实际不符,需要手动修正(补充)具体账目或者通过「面板菜单栏-余额」自动添加条目修正,修正无误后点击「选中项对账」即可。(对账操作后,对过账的条目的第五列内容会由「未」变为「对」) 修改界面语言 在 \\gnucash\\etc\\gnucash\\environment 任意位置中添加 链接:https://www.jianshu.com/p/d04231e2c76f
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Demonslzh6

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值