Read-Only LLM Assistant for Bank Account Q&A: A Technical Implementation Guide
This article explains how to build an LLM assistant that answers questions about a user's bank accounts and transactions while staying read-only. It covers the shift from dashboard-driven finance apps to question-driven analysis, how to enforce capability boundaries at the authorization, interface, tool, and output layers, and the bank account authorization and token lifecycle. It also covers the normalized transaction data model, a natural-language-to-controlled-query pipeline that validates a restricted query specification against whitelists and limits before a deterministic engine computes the numbers, and the guardrails that keep model-written amounts traceable and verifiable. You will also find guidance on anomaly detection, privacy and data governance, compliance limits, enterprise reuse, and a pre-launch checklist.
1. Requirements Evolution: From Information Retrieval to Financial Understanding
Traditional personal finance tools follow a dashboard-driven interaction model: users open the app, browse preset pie charts and lists, and can only filter within a fixed set of dimensions. The limitation is that financial questions are open-ended, time-based, and conditional: “How much did that restaurant charge cost last Wednesday?” or “If my rent goes up 5%, how much will I have left this month?” Dashboards can hardly answer them.
An LLM assistant changes the entry point from a chart to a question, and the analysis logic from a preset report to an on-demand query. It also introduces a new risk: an LLM’s natural language ability and its numeric computation ability are two different things. Once you let the model “do the math” on statement amounts, hallucination turns into financial misinformation. The core design question can therefore be summarized in one sentence: let the model handle language understanding, and let deterministic systems handle fact retrieval and numeric computation.
2. Capability Boundaries: Read-Only Semantics as the Foundation of the Whole Design
In terms of product form, the feature is explicitly positioned as an information and analysis tool with no transfer, rebalancing, payment, or card-linking capability. This boundary is not a patch added by the compliance team after the fact; it should be reflected at every layer of the technical architecture:
- Authorization layer: the access scope requested from the data provider covers read access only; no write or payment-initiation scopes are requested.
- Interface layer: no call channel with fund-operation capability is exposed or wrapped; no code path exists that could reach a transfer API.
- Tool layer: the tool set the model can invoke is constrained by a whitelist, and the tool descriptions contain no “initiate / change / submit” actions.
- Output layer: answers must not contain action promises or investment advice such as “I have transferred the money for you” or “I recommend buying”; the assistant only describes and explains.
This “capability unreachable” design is far more reliable than “telling the model in the prompt not to transfer money.” The latter is a probabilistic constraint; the former is a structural one. A security review should verify code paths and permission declarations, not prompt wording.
3. Account Connection and the Authorization Flow
Connecting an account usually does not connect directly to each bank; it goes through an account aggregation provider. A typical flow:
- The user initiates “connect account” in the frontend, and the backend issues a one-time session identifier and a short-lived authorization request;
- The user is redirected to the aggregator’s hosted page and logs in to the bank themselves, completing multi-factor authentication;
- What the bank side returns is an access token, not the account password; the application never touches or stores the user’s bank credentials;
- The application uses the token to pull the account list and transaction data; the token is stored encrypted and can be revoked at any time.
Three engineering points are easy to overlook:
- Token lifecycle management: access tokens are usually short-lived, so you need a refresh mechanism and failure degradation (when a pull fails, explicitly state “data has not been updated” instead of presenting cached data as live data).
- Data freshness labeling: bank data has synchronization delays, so the answer must indicate “data as of a certain time.” Otherwise, users will treat stale data as a live balance.
- Revocation takes effect immediately: after unlinking, the local cached copies must be deleted and token validity must be checked before the next request, so that access is technically impossible going forward.
4. Data Model: First Turn Statements into Queryable Facts
Once transaction records enter the system, they must be normalized first; otherwise neither querying nor aggregation downstream is feasible. A minimal viable normalized structure roughly includes:
- Account identifier (only masked fields such as the last four digits)
- Account type
- Balance and credit limit
- Transaction timestamp
- Original amount and currency
- Raw merchant description
- Normalized merchant name and spending category
- Transaction status (posted / pending / voided)
- Billing cycle attribution
Two quality-critical pieces are categorization and merchant normalization:
- Categorization: a two-tier “rules first, model fallback” strategy is recommended. The rules layer uses keyword mapping to handle high-frequency, unambiguous cases (rent, utilities, well-known chains). The model layer handles the long tail of vaguely described transactions, and human feedback flows back continuously to refine the rule base.
- Recurring charge detection: cluster equal or near-equal charges from the same merchant over time to identify subscription-style spending, and estimate the next charge date. This kind of judgment is better done with statistical methods than generated directly by the model, because it is easier to explain and reproduce.
5. Core Q&A Pipeline: NL → Controlled Query → Deterministic Computation
The recommended pipeline is: the model only translates; it does not calculate.
# 1) Express the query intent with a restricted DSL instead of generating SQL directlyQUERY_SPEC = {"time_range": {"start": "2026-08-01", "end": "2026-08-31"}, # mandatory time window"group_by": ["category"], # whitelisted dimensions"metrics": ["sum_amount"], # whitelisted metrics"filters": [{"field": "status", "op": "=", "value": "posted"}],"limit": 500, # row limit}ALLOWED_DIMENSIONS = {"category", "merchant", "account", "day", "week", "month"}ALLOWED_METRICS = {"sum_amount", "count", "avg_amount", "max_amount"}def validate(spec: dict) -> dict:assert set(spec["group_by"]) <= ALLOWED_DIMENSIONS, "illegal aggregation dimension"assert set(spec["metrics"]) <= ALLOWED_METRICS, "illegal metric"assert spec.get("limit", 10**9) <= 500, "result set too large"# Validate the upper bound of the time window to avoid full-table scansdays = (date.fromisoformat(spec["time_range"]["end"])- date.fromisoformat(spec["time_range"]["start"])).daysassert 0 < days <= 366, "time range out of allowed bounds"return spec
The benefit is that what the model outputs is not a directly executable statement, but an intermediate representation that must pass whitelist and boundary validation. If validation fails, the system should ask the model to clarify (for example, ask for the time range) instead of guessing to fill the gap.
Numeric computation is performed by the computation engine, which returns a structured result:
{"period": "2026-08","total_spend": 4309.37,"currency": "USD","by_category": [{"category": "housing & utilities", "amount": 2210.44, "share": 0.51},{"category": "dining", "amount": 1024.51, "share": 0.24}],"committed_upcoming": [{"label": "Subscription A", "amount": 15.99, "due": "2026-09-03"},{"label": "Subscription B", "amount": 42.00, "due": "2026-09-07"}],"available_before_payday": 1393.22,"data_as_of": "2026-09-18T10:22:00Z"}
Once the model has this result, its job is only three things: organize the narrative, explain terms, and generate chart descriptions on demand. The system prompt should state the constraints explicitly:
Rules:1. All amounts must be quoted verbatim from the values returned by the computation engine; do not add, subtract, convert, or estimate them.2. If the data required is not returned in the result, answer "the current data is not sufficient to calculate this" and do not speculate.3. Do not provide investment advice, do not recommend any financial product, and do not promise returns.4. When a term is involved (such as the annual percentage rate, APR), first explain its meaning, then give the calculated result based on the returned data.5. Remind users that key figures are authoritative only through the financial institution's official channels.
6. Numeric Trust: Hallucination Guardrails Belong in the Architecture, Not the Prompt
Even with the constraints above, several layers of fallback are needed:
- Consistency checks: every amount in the answer should be traceable to a field in the result set; post-processing can compare the values, and if they do not match, rewrite the answer or downgrade it to table output.
- Table first: when multiple line items are involved, prefer a structured table, which reduces the space for the model to freely generate numbers.
- Confidence degradation: when data is missing, an account has not been synced, or the time span is too large, state the limitation explicitly instead of producing an answer that looks complete.
- Explainability: explain the basis for “how this category was assigned” and “why this was counted as a subscription,” so the user can verify it themselves.
7. Anomaly Detection: From Aggregation to Insight
Aggregation is only the starting point; the real value lies in surfacing problems the user would not notice themselves:
- Duplicate charges: multiple charges from the same merchant with the same amount within a very short interval;
- Unexpected fees: cross-border fees, currency conversion fees, late fees, annual fees, and other non-consumption expenses;
- Bill increases: recurring charges rising month over month, or an abnormal increase in the number of subscriptions;
- Pending transaction risk: authorized but not yet settled transactions may lead to an inaccurate balance.
In implementation, the recommended division of labor is: a rules engine handles deterministic anomalies, a statistical model handles trend anomalies, and the LLM translates the findings into human language. The three are clearly separated, so the model is not made responsible for factual judgments it is not good at.
8. Privacy and Data Governance
Once sensitive financial data is connected, governance measures should be verifiable:
- Data minimization: request only the fields required to deliver the feature and the minimum necessary time span (the common practice is up to two years of transaction history); do not request beyond that scope.
- Masking and no echo: accounts are displayed only as irreversible fragments such as the last four digits, and full account numbers are not output in answers by default.
- Partitioned processing strategy: conversations inside the dedicated finance workspace are excluded from model training, while interactions outside it follow the user’s regular privacy settings. This distinction must be implemented as data-flow routing isolation in engineering, not just declared in documentation.
- Encryption and key management: encryption throughout transmission, encryption at rest for tokens and caches, and key custody and rotation folded into the standard security process.
- Audit and retention: record data access logs (who accessed which data category and when), and define retention periods and automatic cleanup policies for caches and logs.
- Revocability: unbinding via one click takes effect immediately and cleans up the derived data.
9. Compliance Red Lines
This type of feature sits close to the boundary of financial regulation, so the engineering implementation needs to move in lockstep with compliance:
- No investment advice and no personalized wealth management recommendations
- No promised returns
- No embedded advertising or paid ranking
- No selling financial products to users
The feature interface should carry a clear disclaimer and data definition note, and every number in the answers should be labeled with its data source and as-of time.
10. Extending to the Enterprise: The Same Pattern Can Be Reused
The “constrained natural language query + deterministic computation engine” pattern is not limited to personal scenarios; it also applies to expense report analysis, cash flow Q&A, and business metric queries. For production use, general-purpose cloud capabilities are enough to support the whole chain:
- Object storage holds the raw statement files and query result snapshots
- A message queue smooths traffic peaks and decouples the bank data synchronization jobs
- A container platform hosts the query and computation services and provides elastic scaling
- A logging service provides a full audit trail
- Monitoring and alerting track key metrics such as sync failure rate and token invalidation rate
On Baidu AI Cloud, these capabilities belong to general-purpose categories, so they can be used directly to build the technical foundation for this kind of data-sensitive Q&A system.
11. Implementation Checklist
- Is there any code path that can reach a fund-operation API? (It should be zero.)
- Is the model output a constrained intermediate representation that passes whitelist and boundary validation?
- Are all amounts computed by the deterministic engine and checked back for consistency?
- Is the data synchronization delay explicitly stated in the answers?
- Is the training data routing actually isolated in the dedicated workspace?
- Do the local cache and tokens completely expire after unbinding?
- Is there any advertising, recommendation ranking, or referral to financial products?
- Are user-facing disclaimers and data definition notes in place?
The conclusion is straightforward: when an AI assistant enters the personal finance space, competitiveness comes not from how well the model chats, but from how tightly the boundaries are drawn, how accurately the numbers are computed, and how strictly privacy is managed. Treating language understanding as the interaction layer, fact computation as the trusted layer, and replacing probabilistic constraints with structural ones is what allows this kind of feature to hold up over the long term on real financial data.
