当AI不work:我如何最终实现自动化财务决算

持续了十年的手动流程

在过去的十年里,我每个月都会进行一次个人财务决算。这个过程完全是手动的:登录多个银行和券商网站,把每一个股票、债券、基金、定期的名称、当前价值和日期,一个个手动录入一个草台班子Excel里。这个表格最终会生成一个汇总视图,展示我的总资产、总负债、以及各类资产的分布占比,为我提供一个财务概览。

这个流程虽然有用,但执行起来非常痛苦。它不仅耗时,重复,而且充满了琐碎的输入和计算,一不小心就弄错了。但意外的是,这么多年我从来没有想过自动化。可能因为我的潜意识里面就觉得这种东西就不可能自动化——要访问多个封闭的金融系统,这在技术上就是不可行的。但是,最近我用AI做了很多之前想都不敢想的事情,就不由自主开始重新思考这个问题:到底能不能能把这个繁琐的任务完全交给机器,从而实现又更省心,又更准确,甚至更高频的财务决算?

首次尝试:Plaid的合规高墙

我的第一反应当然就是问大哥怎么办。大哥说,这个简单啊,你可以用一个标准的、程序化的解决方案——一个叫做Plaid的工具。Plaid是一个专业的金融服务API,它可以让我们的app安全地连接到用户的银行账户,然后用统一的格式获取账户信息。比如TurboTax用的就是Plaid来一站拿到用户的各种税表。聊完以后,我感觉,卧槽大哥牛逼。我下面就可以通过一个统一的API,一把拿到所有账户的持仓和价格。问题就搞定了。

我立即申请了一个开发者账号。但是很快就遇到了一个大问题:合规审查。Plaid对申请生产环境(Production)API密钥的用户有着很多变态要求。它给了我一大堆问卷。里面问:“公司是否有专门的信息安全团队?”、“系统补丁的更新频率是多久?”、“是否有内部网络漏洞扫描机制?”以及“客户信息泄露的应急预案是什么?”把我问懵了。我只是个小虾米想要连自己的账户看看余额而已。你吼那么大声干什么?

我瞎几把填了以后,生产密钥申请很快就被驳回了。这里也不能用开发(Development)密钥,因为许多大型银行(如Wells Fargo或Chase)强制要求使用OAuth进行认证,而OAuth认证又必须使用生产密钥。这条路被彻底堵死了。

思路转变:GUI作为最后的API

标准的数据接口走不通,我就开始想邪招了。如果全自动不行,那么半自动行不行?这里我的核心痛点在于手动输入数据,如果能解决这个瓶颈,效率仍然可以大幅提高。

这时,我想到了Vision LLM和类似Computer Use的用法。我的新思路是:既然没办法用API直接拿到数据,那么我就从GUI (图形用户界面)上抓。具体流程是,我手动登录银行网站,然后对持仓信息的页面截图。这些截图中包含了所有我需要的信息:股票代码、价格、总价值等。接着,我将这些图片交给一个视觉大模型进行识别和解析,让它把图片中的非结构化信息,转换为结构化的 JSON/CSV 格式。最后,再用一个简单的Python脚本处理这些结构化数据。

我很快用这个想法做了一个实验。我选择了在本地部署的Ollama环境,使用Qwen2.5-VL:32b模型来处理截图。结果非常理想。对于我提供的20多个持仓条目,模型的识别准确率几乎是100%。唯一的错误发生在一个持仓的股数上——我的微软股票的股数非常诡异的带个小数,模型识别不了。这是一个非常小的问题,大不了我把这零点几股卖掉就好。这个probing experiment解决了最大的不确定性,证明了这条路是可能走通的。

构建与验证:你信不信任AI处理的财务数据?

方案可行,接下来就是工程实现。但另一个问题成了拦路虎:金融数据极其敏感,我们如何确保AI的处理过程是准确的?换言之,我们怎么对AI的结果建立信任?为了解决这个问题,我设计了一套人机协作的工作流,建立了一个双重验证框架。

AI辅助的开发流程

首先,我利用AI完成了大部分繁重的工作。

  1. 数据结构设计:我让AI分析我过去十年的Excel表格,并基于此设计出一个更规范、更健壮的数据库表结构(最终以简单的CSV文件形式存储,方便我再给其它AI分析)。
  2. Prompt设计:我让AI根据这个新的数据结构,为视觉大模型设计了一个专门的Prompt。这个Prompt会指导视觉大模型输出格式高度统一、可直接被下游程序解析的JSON。(这个prompt在文末会贴)
  3. 代码生成:我让AI编写了后续处理的Python脚本。这个脚本负责解析视觉大模型输出的JSON文件,与历史数据进行合并,并生成一个可视化的HTML报告供我审查。

整个流程是:我自己手动截图,然后本地的Qwen2.5-VL模型处理这些图片并生成JSON文件。接着,另一个脚本会解析这些JSON,进行数据整合和可视化。如果我审查HTML报告后认为没有问题,只需在命令行输入“yes”,新的数据就会被追加到我的主数据库中。

结果驱动与交叉验证

对于AI系统的准确性,我的核心思想是:结果驱动,而非过程驱动。我不关心AI内部的思考过程或者程序是不是完美,我只关心它的最终结果是否准确。如果比如20个结果上面AI都是对的,而且没有明显的pattern,那我就假设这个正确性是可以信任可以推广的。

而在结果验证方面,我采用了交叉验证(Cross-Check)的方法。在过去的手动记账中,我会花费很多精力去核对每个月的总资产。所以它可以看作是一个相对可靠的Ground Truth。我的验证方法是,(用确定性的程序)把AI从Excel里面解析出的所有分项资产的价值加起来,然后与我当月记录的总资产进行比对,看看差了多少。如果这两个数相差超过5%,程序就会报警。

在AI对过去十年的Excel记录转换以后,程序发现大部分月份的误差都在5%以内,但有6个月份的数据差异显著高于这个阈值。我一个个过了这6条记录,发现问题几乎全部出在我当年的手动录入上——有的是金额数字输入错误,有的是日期写错导致无法对齐。这个发现很有意思,这说明这套自动化流程不仅没有犯错,反而帮助我找出了过去十年手动记账中隐藏的错误。进一步说明了自动化的好。

结论与思考

这个项目最终花费了我大约两个小时的时间,把一个困扰我十年的手动任务实现了自动化。现在,我可以在几分钟内完成过去需要半个多小时才能完成的工作。更重要的是,数据的准确性和分析的频率都得到了极大的提升。

这次经历也引发了我的一些思考:

  1. GUI和API的界限没有我们想得明晰:当API因为合规、商业或者任何原因无法访问时,视觉大模型提供了一种全新的自动化方式。任何软件的GUI,都可以被当作一个非官方的API来用。这为自动化那些封闭的、传统的系统开辟了巨大的可能性。
  2. 本地模型的价值:对于处理个人隐私数据(尤其是金融数据)的场景,使用Ollama在本地运行模型对我的心理安全感很重要。这样所有敏感信息都在我自己的设备上。
  3. 全自动搞不定不妨半自动:很多时候AI看起来不work的时候,不妨回头想一想初心——我为什么想做这件事,我可以接受怎样的trade off,这个问题怎么绕过去。可以自己想,也可以和AI讨论。这种和AI积极共创的心态往往可以大幅提升用AI完成任务的成功率。

另外,这是我用的VLLM的prompt:


我正在处理财务决算工作,需要将金融账户的屏幕截图转换为标准化的JSON格式。

重要说明:

  • 请保持金额的原始数值,不要进行任何单位转换
  • 只输出JSON,不需要其他解释文字
  • 如果无法确定某个字段,使用null值

输出格式要求:

根据截图类型,输出以下JSON结构之一:

1. 账户列表截图

{
  "data_type": "accounts",
  "currency": "USD",
  "items": [
    {
      "name": "[完整账户名称]",
      "balance": [余额数字,保持原始数值],
      "account_type": "[账户类型: checking, savings, brokerage, ira, investment]",
      "account_number_suffix": "[账户号后几位]",
      "full_account_name": "[截图中显示的完整账户名]"
    }
  ]
}

2. 股票列表截图

{
  "data_type": "stocks", 
  "currency": "USD",
  "items": [
    {
      "ticker": "[股票代码]",
      "amount": [持股数量,整数],
      "balance": [总价值,保持原始数值],
      "price_per_share": [每股价格,如果可见],
      "account_context": "[所属账户信息,如果可见]"
    }
  ]
}

账户类型识别规则:

  • 包含"checking"字样 → "checking"
  • 包含"savings"字样 → "savings"
  • 包含"brokerage"字样 → "brokerage"
  • 包含"IRA"字样 → "ira"
  • Betterment账户类型 → "investment"
  • 其他投资账户 → "investment"

请严格按照上述格式处理截图内容。


Comments