← Engineering private financial AI

Part 1 of 12 · 7 min read

Private financial AI: from a question to a verified answer

The complete local architecture: adviser workflows, permissioned evidence, deterministic calculations, model decisions and reviewable results.

Arunank Sharan · Kuzushi Labs ·

In this article

A relationship manager asks a simple question: “How much of this household’s eligible wealth is in equity?” Answering it usually means finding the right account, checking the valuation date, deciding which assets belong in the denominator, performing the calculation and preparing an explanation. The assistant brings those steps into one workflow. The useful output is a number with a source and a date, ready for someone to review.

That is the starting point for this series: a private financial assistant that interprets requests in English, Hindi and Hinglish, uses permissioned data, calls deterministic financial tools and runs within the organisation’s infrastructure. The small language model handles language and task selection. The surrounding system establishes what it can read, calculate and return.

The articles explain that architecture from data preparation through deployment and evaluation. The accompanying public reference kit contains authored portfolio scenarios, selected public financial data and executable components. It is the concrete build used throughout the walkthroughs; client records and operational identifiers stay outside it.

A private financial request passes through identity, approved evidence, deterministic tools and a reviewable answer.

Start with the work being completed

There are three useful entry points. An adviser can ask for an explanation grounded in an approved document; request a calculation with explicit assumptions; or summarise an authorised portfolio snapshot. These requests look similar in a chat window but require different evidence.

RequestWork brought into the assistantRequired evidenceCompleted output
“What is the equity share?”Locate holdings, check scope, calculate concentrationDated eligible-assets snapshotPercentage, numerator, denominator and citation
“Project ₹25 lakh for five years at 6%”Translate a scenario into calculator inputsConfirmed horizon and compounding conventionA labelled scenario value
“Explain this product’s exit conditions”Locate and interpret the relevant passageApproved document version and applicability dateExplanation linked to its evidence
“Use the June figures for today”Identify a stale valuationRequested date and snapshot dateA request for current evidence
“Sell the equity allocation now”Recognise a transaction requestSeparate transaction authorityA handoff to an independent approval process

The workflow is read-only. A completed explanation and an executed trade are different products with different controls. Keeping that distinction visible makes the assistant useful without pretending that generating a sentence authorises a transaction.

Follow one request through the system

Take an authored household, H-A, with ₹48,000,000 of equity inside ₹80,000,000 of eligible assets. The requested snapshot date is 1 September 2026. The concentration is 60%.

The gateway first resolves the authenticated user’s access to H-A. The request does not acquire new permissions because the user types a different household identifier. Next, the orchestrator presents a small tool catalogue to the model. The model proposes a portfolio read; the runtime checks household access and date; the portfolio service returns the snapshot. A concentration tool computes the ratio. Finally, a result assembler attaches the source identifier and the assumptions used.

{
  "household": "H-A",
  "as_of": "2026-09-01",
  "equity_inr": "48000000",
  "eligible_inr": "80000000",
  "source": "snapshot-A"
}

Notice the denominator’s name. “Eligible assets” is a business definition. It may exclude liabilities, non-investible property or positions that the organisation does not value in this workflow. That definition belongs in the snapshot contract. The model must not silently substitute total net worth because it sounds more familiar.

from decimal import Decimal, ROUND_HALF_UP

def equity_share(equity_inr, eligible_inr):
    equity = Decimal(equity_inr)
    eligible = Decimal(eligible_inr)
    if not equity.is_finite() or not eligible.is_finite():
        raise ValueError("finite amounts required")
    if not Decimal("0") <= equity <= eligible or eligible <= 0:
        raise ValueError("invalid eligible-assets snapshot")
    return (equity / eligible * 100).quantize(
        Decimal("0.01"), rounding=ROUND_HALF_UP
    )

assert equity_share("48000000", "80000000") == Decimal("60.00")

The final result contains value, unit, subject, as_of and source. “60” alone is insufficient. Sixty rupees, sixty percent and sixty percent of a different household’s assets are different answers.

Separate four sources of authority

Identity establishes access. Evidence establishes facts. Calculators establish numerical results under stated assumptions. The model establishes a proposed interpretation and a readable explanation. Each component has a narrow job, and the runtime joins them.

ComponentOwnsDoes not decide
Identity and policy serviceHousehold and role permissionsFinancial answer wording
Retrieval and portfolio servicesVersioned documents and snapshotsWhether to execute a model instruction
Deterministic toolsFormula, precision and input validationSuitability or guaranteed returns
Language modelIntent, arguments, clarification and wordingIts own access rights
OrchestratorTool admission, time budgets and trusted traceFacts absent from tools
Result assemblerClaim-to-evidence linksNew unsupported claims

This separation also makes failure easier to explain. Missing inputs produce clarification. A denied household stays denied. A timeout produces an unavailable result. A document with instructions to export data remains a document; it never becomes an instruction to the runtime.

The alternation between model decisions and external observations follows the broad interaction pattern described in ReAct. The additional engineering here is the typed boundary around every action and every final claim.

Local deployment is an end-to-end property

The inference process is only one part of private execution. A prompt can also pass through retrieval, an embedding service, logs, tracing, crash collection and a support workflow. The complete deployment keeps those dependencies inside the approved environment.

I separate public-material preparation from household execution. The first environment acquires permitted public documents, prepares training material and builds versioned artifacts. The restricted environment imports approved artifacts and owns private indexes, authentication, inference, calculations and operational records. A model timeout does not trigger a silent fallback to an external provider.

An import package carries model and tokenizer revisions, dataset hashes, adapter identity, runtime configuration and a compatibility report. An operational event carries a request ID, tool name, duration and policy outcome. Routine metrics do not need to contain a full account statement. Detailed traces have a narrower retention and access policy.

A local deployment still needs update and rollback paths. Importing a new model must not replace the approved index or change the calculator version incidentally. Treat the release as a set of independently identified artifacts, then approve the combination that was actually evaluated.

The model learns behaviour; tools retain changing facts

Fine-tuning is useful for extracting amounts, handling financial language, choosing an appropriate tool and returning a consistent response shape. Current holdings, product terms and date-sensitive rules belong in external evidence. This keeps corrections local: update a snapshot or document rather than retrain the assistant to forget an obsolete figure.

The reference adaptation path uses Gemma 4 E4B Instruct. Model choice is one replaceable component. The same workflow contracts can compare an unadapted local model, an adapted model and its serving export without changing the business task.

The practical design question is whether adaptation improves accepted answers per unit of time and cost. A fluent answer that needs an adviser to reconstruct every number has not completed the work.

Design the result for a person, too

The UI should expose four things together: the direct answer, the source snapshot or passage, the assumptions and the available next action. For our concentration example, that means “60% of eligible assets”, the two underlying amounts, the date and a link to the permitted snapshot view.

A denied request should explain how access is obtained. A missing horizon should ask a single precise question. An unavailable portfolio service should preserve the request so it can be retried, without displaying yesterday’s value as today’s answer. These are ordinary product behaviours, not decorations around the model.

Measure completion at that level. Track accepted answers, requests needing correction, time to a reviewable result and the proportion that resolve through clarification. Track access failures separately: averaging them into a general accuracy score hides an important dimension of system behaviour.

The rest of the series builds each layer. Part 2 creates source-linked data; Part 7 implements the runtime; Part 11 connects a local model to the executable benchmark.