FreelanceFlow:自由工作者的 AI 簿記工具
FreelanceFlow: The AI Book-keeper
FreelanceFlow 是供自由工作者使用的本機 AI 簿記工具,以 Gemma 3 4B 經 Ollama 讀取收據,並提供資料校驗及 CSV 匯出。在 7 張真實收據測試中,金額辨識正確 6/7;有日期的收據日期辨識為 4/4,有店名的收據店名辨識為 3/3,每張平均需時 179.5 秒(手提電腦 CPU)。文件在用戶電腦處理,不會傳到伺服器,亦沒有逐份文件的 API 費用。
This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle
What I Built
FreelanceFlow is an AI bookkeeper for freelancers that runs entirely on their own computer.
Freelancers, creators and tiny agencies handle their own money but have no finance team. Receipts are photos, invoices are PDFs, and everything piles up. Many pay an accountant mainly to organize paperwork. A cloud AI tool could do it, but uploading client invoices and bank data to a server you don't control is exactly what a careful freelancer avoids.
With FreelanceFlow, a freelancer drops in receipt images or PDFs. A local open-weight model reads them. My own validation rules flag anything doubtful. The freelancer fixes the table, downloads a clean CSV for their accountant, and sees a monthly forecast and unusual-spending alerts.
Who would pay: solo freelancers (designers, developers, writers, tutors) who want privacy and a low price. The target is a small monthly fee of about $5 to $10, far less than an accountant's hourly rate.
Demo
Project page: https://karishma-das.github.io/freelanceflow/
The app itself runs on the user's laptop (that is the privacy point), so the demo is a video plus a static project page.
Code
FreelanceFlow
A privacy-first AI bookkeeper for freelancers. A local open-source vision model (Gemma 3 4B via Ollama) reads receipts, my own validation rules flag bad records, and the app exports a clean CSV, shows a forecast and flags unusual spending. Documents are read on your own computer.
What it does
- Upload receipt images (PNG/JPG) or PDFs.
- Gemma extracts amount, date, store name and category.
- Validation rules flag records for human review.
- Edit the table, then download a CSV.
- Forecast next month's income and expenses.
- Alerts for unusual spending.
Results (measured)
Test set: 7 real receipts of mixed quality (kept private, not in this repo).
| Field | Correct |
|---|---|
| Amount | 6/7 |
| Date | 4/4 (receipts where the answer key has a date) |
| Store name | 3/3 (receipts where the answer key has a store name) |
- Average time per receipt: 179.5 seconds on a laptop CPU (no API cost)
- Flagged for review: 6 of 7
- 6…
How I Built It
Open pieces: Gemma 3 (4B, open-weight) running locally through Ollama, with Python, Pydantic, PyMuPDF, pandas, Streamlit and pytest.
Pipeline:
- Upload PNG, JPG or PDF. PDF pages are converted to images with PyMuPDF.
- Read. Gemma returns structured fields (amount, category, store, date), forced into a Pydantic schema.
- Check. Rules I wrote myself flag missing dates and store names, zero or negative amounts, future or very old dates, unknown categories, and tax larger than the total.
- Export. The user edits the table in Streamlit and downloads a CSV.
- Plan. A forecast tab and an alert for any expense more than 3x its category median.
Measured results on 7 real receipts of mixed quality (clear, wrinkled, faded, blurry, and a photo of a hand holding a pile of receipts). The receipts are private and not in the repo.
| Field | Correct |
|---|---|
| Amount | 6/7 |
| Date | 4/4 (receipts where the answer key has a date) |
| Store name | 3/3 (receipts where the answer key has a store name) |
| Flagged for review | 6 of 7 |
| Time per receipt | about 180 seconds on a laptop CPU |
The most useful lesson. My first version asked the model for the date directly and got 0 out of 4, because the small model kept answering "null". So I split the job: the model reads the text on the receipt, and plain Python code finds and converts the date. Dates went to 4 out of 4. With a small local model, let the model read and let normal code parse and check.
What failed:
- One amount was read as -354.83 instead of 54.83. My "amount must be positive" rule flagged it.
- An unreadable receipt still got an amount and a made-up store name. Validation flagged it only for a missing date, so it does not catch a confidently wrong store name yet.
- Store names were missed on three receipts.
- My first answer key was wrong: I had typed a store's slogan as its name. The model was right, so I fixed the key.
- It is slow, about 3 minutes per receipt on a CPU. The app can load saved results for demos.
Forecast, honestly. The forecast tab uses a 3-month average as its baseline, with TabPFN wired in as the model to try first. I did not get TabPFN's local license login working in time, so every forecast in my demo used the average fallback, tested on a synthetic 18-month history, not real data. The code reports which method actually ran.
Why Does Open Innovation Matter?
- Privacy. Gemma reads each document on the user's machine, so receipts never reach a server. For a bookkeeping tool, that is the main selling point.
- Cost. There is no per-document API fee, so a cheap subscription can still work as a side hustle. Cost per document in my tests was zero.
- No lock-in. The model name is a single line in the code. If a better open model appears, I swap it, and I am not tied to someone else's pricing.
- Works offline. The sensitive step, extraction, needs no internet.
I did not benchmark against a closed API, so I won't claim it is more accurate. My claim is narrower: for this job, privacy and cost matter as much as accuracy, and open models let me keep both.
Prize Categories
-
Best Use of Gemma: Gemma 3 4B runs locally through Ollama and does all the document reading.
來源:DEV Community · dev.to