Spaces:
Sleeping
Download CASE_STUDY.md from financeflow/ai: direct link, hf CLI and curl.
- Browser
- Download file 5.07 kB
-
https://huggingface.co/spaces/financeflow/ai/resolve/main/CASE_STUDY.md
- Command line
-
hf download hf://spaces/financeflow/ai/CASE_STUDY.md
-
curl -L -o CASE_STUDY.md https://huggingface.co/spaces/financeflow/ai/resolve/main/CASE_STUDY.md
Case Study β FinanceFlow AI
A concise product case study of why this exists, what was built, and what the results were.
Problem
Finance and operations teams answer the same small questions hundreds of times a week β "What's the total due? When is it overdue? What's the payment term? What's the late-fee clause?" β by opening a PDF and scanning for the number. It's slow, repetitive, and error-prone. Dropping a general chatbot on top makes it worse: an LLM will confidently produce a due date or dollar amount that isn't in the document. In finance, a confidently wrong number is more dangerous than no answer.
User pain
- Time: minutes per lookup, multiplied across invoices/contracts/notes.
- Trust: no way to see where an answer came from, so every AI answer has to be re-verified by hand β which defeats the point.
- Risk: hallucinated figures can flow into payments, reconciliations, or customer comms.
Product hypothesis
If every answer is (a) built only from retrieved passages, (b) shown with the exact source excerpt, and (c) refused when the evidence is weak, then a finance user will trust the tool enough to use it for real lookups β because they can verify each answer in one glance and know the system won't invent facts.
MVP scope
Deliberately small and demoable:
- Upload PDF/TXT β parse β chunk β store.
- Ask a question against one document β retrieve top chunks β answer only from them β return citations (document, page/chunk, excerpt, score).
- Abstain with a fixed message when evidence is weak.
- Dashboard (status, chunk counts, history, delete) + one-click demo mode.
- A golden-dataset evaluation that scores grounding, not just accuracy.
Out of scope (on purpose): auth, multi-tenant storage, vector DB, OCR, cross-document Q&A.
Technical approach
- Backend: FastAPI + SQLite (SQLAlchemy). A single ingestion pipeline (parse β chunk β store) shared by uploads and the eval harness.
- Chunking: overlapping ~120-word windows (25-word overlap), page numbers preserved for PDFs.
- Retrieval: a custom TF-IDF keyword ranker (no ML dependency, fully offline) β rarer shared terms weigh more, normalized by chunk length.
- Answering: extractive by default β return the densest verbatim span,
re-centered on the matched terms so a value next to its label
(
Total Amount Due $2,413.98) is preserved. Optional LLM layer (OpenAI/ Anthropic) behind env vars, with automatic fallback. - Anti-hallucination: two abstention gates (score floor + term coverage),
citations always shown, and
unsupported_answer_counttracked in evaluation.
Tradeoffs
| Decision | Why | Cost |
|---|---|---|
| Keyword TF-IDF over embeddings | Zero deps, offline, transparent, fast to demo | Misses pure paraphrases |
| Extractive over generative default | Cannot invent a number not in the source | Phrasing is less fluent than an LLM |
| Discard raw files after parsing | Privacy + no orphaned-file cleanup | Can't re-process without re-upload |
| SQLite | One-file, zero setup for a reviewer | Not for concurrent production load |
| Abstain aggressively | Trust > coverage in finance | Occasionally refuses a borderline-answerable question |
Evaluation method
A golden dataset (backend/app/golden_dataset.json) pairs each question with
its target document, expected behaviour (answerable / should_abstain), and the
evidence string that should be cited. The harness runs every question through the
real answer pipeline and reports: answered_with_citation, correct_abstentions,
unsupported_answer_count, citation_coverage, and evidence_match_rate.
Runnable from the UI and the CLI (python -m app.eval_cli); CI fails on any
unsupported answer.
Results
- 7/7 golden questions pass,
citation_coverage = 1.0,evidence_match_rate = 1.0,unsupported_answer_count = 0, 2 correct abstentions. - 20 backend tests pass (unit + API via TestClient), green in CI.
- Runs fully offline with no API key; one-click demo seeds three sample documents.
What I would build next
- Swap the keyword ranker for sentence-embedding retrieval (FAISS / sqlite-vec) to handle paraphrased questions, and A/B it against the current ranker using the same golden dataset.
- Exact answer-span highlighting inside the cited excerpt.
- Cross-document Q&A and document collections.
- Auth + per-tenant isolation; background processing + OCR for scanned PDFs.
- Expand the golden set and add precision/recall on citations.
Why this matters for AI workflow automation
This is the core loop behind most useful document AI: ingest β retrieve β answer β cite β evaluate, with guardrails that make it safe to put in front of a real team. The interesting work isn't calling a model β it's the retrieval quality, the abstention policy, and the evaluation that proves the system stays grounded. That's exactly the work of shipping trustworthy AI features in fintech and operations.