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

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

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

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

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

null

在这里插入图片描述

🤖 AI Agent工作流程

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

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

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

🔍 任务分解与执行

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

关键决策点

    1. 模糊描述处理
    • • "请了团队喝咖啡" → 自动拆分为多人消费
    • • "买了办公用品" → 匹配预设的办公类别
    1. 异常检测
    • • 识别金额异常(如10000元的午餐)
    • • 检测时间冲突(未来日期消费)
    1. 上下文关联
    • • "续费了年度会员" → 关联去年同期的记账
    • • "报销差旅费" → 匹配对应的报销账户

🚀 核心功能亮点

    1. 自然语言解析
    • • 智能识别消费描述中的金额、类别和时间

    • • 支持批量处理多日消费记录

    • • 示例输入:

      diff 复制代码
      7.6
      - 66 午餐 12:00
      - 900 物业费(最近一季度)
      7.7
      - 150 购物
    1. Fireflyiii深度集成
    • • 通过OpenAPI自动创建交易记录
    • • 保持与Fireflyiii数据模型完全兼容
    1. 多场景部署
    • • 本地开发环境
    • • Docker容器化部署
    • • NAS设备部署(如极空间)

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

Langchain核心组件

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

完整代码实现

python 复制代码
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. 模型初始化
    ini 复制代码
    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: 模型提供商
    1. 处理链构建
    lua 复制代码
    self.chain = self.prompt | self.llm | self.parser
    • | 运算符连接组件
    • • 数据流:模板 → 模型 → 解析器
    1. 链式调用
    arduino 复制代码
    result = self.chain.invoke({
        "input_text": text,
        "categories": [...],
        "tags": [...]
    })
    • • 动态注入变量到模板
    • • 自动处理模型调用和输出解析

实际调用示例

ini 复制代码
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通过多步推理处理复杂场景:

    makefile 复制代码
    用户输入: "支付了上个月的电费500元"
    Agent思考:
      1. 这是水电费支出
      2. 时间应为上个月最后一天
      3. 需要关联电力公司账户
      4. 分类到"家庭开支/水电煤"
    1. 自我修正机制
    • • 当Fireflyiii返回错误时,Agent自动:
        1. 分析错误原因
        1. 调整数据格式
        1. 重新提交请求
    1. 记忆上下文

    使用ConversationBufferMemory保存对话历史:

    ini 复制代码
    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 如果搜不到的话,就需要手动拉取源码打包镜像再导入到极空间了。

主要配置的环境变量如下:

null

在这里插入图片描述

如果不想手动配置的,也可以在极空间中新建一个.env文件,将文件挂载到/app/.env目录下

ini 复制代码
# 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端口
    1. 配置环境变量
    1. 启动容器

💡体验案例

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

✅ 总结

Fireflyiii-AI记账系统通过:

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

项目地址:github.com/your-repo/f...

遇到问题?在GitHub提交Issue或通过公众号一颗程序树联系作者!

相关推荐
Livingbody1 小时前
ubuntu25.04完美安装typora免费版教程
后端
阿华的代码王国1 小时前
【Android】RecyclerView实现新闻列表布局(1)适配器使用相关问题
android·xml·java·前端·后端
码农BookSea1 小时前
自研 DSL 神器:万字拆解 ANTLR 4 核心原理与高级应用
java·后端
lovebugs1 小时前
Java并发编程:深入理解volatile与指令重排
java·后端·面试
海奥华21 小时前
操作系统到 Go 运行时的内存管理演进与实现
开发语言·后端·golang
codervibe1 小时前
Spring Boot 服务层泛型抽象与代码复用实战
后端
_風箏2 小时前
Shell【脚本 04】传递参数的4种方式(位置参数、特殊变量、环境变量和命名参数)实例说明
后端
斜月2 小时前
Python Asyncio以及Futures并发编程实践
后端·python
CRUD被占用了2 小时前
coze-studio学习笔记(一)
后端