AI

RAG vs Fine-Tuning for Business Data

A practical framework for choosing RAG, fine-tuning, SQL, or a hybrid architecture when building AI features around business data.

Rizky Romadon profile photoRizky Romadon··18 min read

Sources

Article details

Context for reading and verifying this note.

Updated Jul 20, 202618 min readAI8 sourcesAI-assisted, human-reviewed

Creation context: AI assisted with research, structure, or drafting. Rizky Romadon reviewed the sources, technical claims, examples, and final publishing decision.

Introduction

I have not implemented a Retrieval-Augmented Generation system in production yet. My starting point is a business question: if I have purchase data, how should an AI application answer questions about it? Should I use RAG, fine-tune a model, or use something else?

This article is a design exercise based on that scenario. It combines my backend engineering perspective with current Spring AI documentation and primary research. The examples are representative, not results from a deployed system.

The most useful conclusion arrived early: RAG and fine-tuning are not two interchangeable ways to load business data into a model. RAG supplies relevant external knowledge when a request is made. Fine-tuning changes how a model behaves by training it on examples. Neither should replace a transactional database when the answer requires exact, current facts.

For purchase data, the practical architecture is often a combination:

  • SQL or a controlled tool call for exact orders, totals, dates, and customer facts.
  • RAG for product documentation, policies, support notes, reviews, and other unstructured context.
  • Fine-tuning only when a stable behavior, format, or classification task remains difficult after prompting and evaluation.

That distinction prevents an expensive architecture from being built around the wrong problem.

TL;DR

NeedBest starting pointWhy
Exact and current purchase totalsSQL through a controlled toolDatabases are designed for filters, joins, aggregation, and consistency
Answers grounded in policies or product documentsRAGRetrieves relevant source material at request time
A consistent classification or response behaviorPrompting first, then consider fine-tuningFine-tuning changes behavior rather than acting as a live database
Questions combining transactions and documentsTool calling plus RAGEach data source is handled by the system best suited to it

My default choice would be a hybrid design. I would keep the system of record authoritative, retrieve unstructured context only when needed, and delay fine-tuning until a measured evaluation shows that it solves a repeatable behavior problem.

The Fundamental Difference: Knowledge and Behavior

RAG gives a model selected information during inference. A retriever searches an external collection, the application adds the relevant passages to the model context, and the model uses that context to produce an answer. The model's parameters do not need to change.

Fine-tuning trains a model on examples so that its parameters—or a smaller set of adapter parameters—better reflect a desired task or response pattern. Techniques such as LoRA can make adaptation more parameter-efficient, but the conceptual goal remains different from retrieval.

This leads to a simple mental model:

QuestionRAGFine-tuning
Where does new knowledge live?External documents or recordsModel or adapter parameters
Can information be updated without retraining?Yes, by updating the retrieval sourceUsually no; another training cycle is needed
Can an answer point back to retrieved evidence?Yes, if the application preserves source metadataNot naturally
Is it good for exact aggregation?Usually notNo
Is it good for repeated style or task behavior?Sometimes, through promptingPotentially, when supported by quality examples
Main operational workIngestion, retrieval, access control, evaluationDataset creation, training, versioning, and evaluation

The original RAG research described a combination of parametric memory and external non-parametric memory for knowledge-intensive tasks. That external memory is useful because facts can be inspected and updated. It does not make retrieval automatically correct, secure, or appropriate for every kind of data.

Fine-tuning is also not a reliable way to make a model remember every purchase. Even if training examples contain transaction data, there is no database-style guarantee that the model will return every matching record, calculate an exact total, respect a late refund, or forget one customer on demand.

Start by Classifying the Business Question

Before selecting an AI technique, I would classify the questions the application must answer. “Purchase data” can mean several very different things.

Consider these representative questions:

  1. How much did customer 184 spend in the last 90 days?
  2. Which customers bought product A but not product B?
  3. What is our refund policy for a damaged item?
  4. Why might customers be returning this product?
  5. Classify this support request into one of our internal queues.

The first two require exact structured operations. SQL is a natural fit because the answer depends on filters, joins, negation, dates, and aggregation. The model may translate intent into safe application parameters, but it should not invent the result.

The third question is document retrieval. A policy may live in a knowledge base, handbook, or versioned document. RAG can retrieve the applicable passage and let the answer include its source.

The fourth may need both. Return records can provide counts and trends, while reviews and support notes provide qualitative context. A combined answer should distinguish measured facts from model-generated interpretation.

The fifth is a behavior task. A well-written prompt and structured output may be sufficient. Fine-tuning becomes worth testing when the categories are stable, enough reviewed examples exist, and the baseline still misses the target.

The architecture follows the question, not the popularity of a technique.

A Hypothetical Purchase-Data Architecture

For this design exercise, imagine a business with four relevant data groups:

DataShapeExamplesAccess path
TransactionsStructured and frequently changingOrders, items, prices, refundsRepository or analytics service
Customer profileStructured and sensitiveAccount, segment, consentAuthorized customer service
Business knowledgeUnstructured and versionedPolicies, product guides, FAQsRAG retrieval
Customer feedbackMostly unstructuredReviews and support notesRAG or an analytical pipeline

The model would not receive direct database credentials. The application would expose narrow tools with explicit parameters and authorization rules. A tool could return an approved summary such as total spend and order count, rather than arbitrary rows or arbitrary SQL.

The retrieval path would index approved documents in a vector store. Each document chunk would carry metadata such as tenant, document type, product, locale, policy version, and visibility. Retrieval would apply authorization-aware filters before any text entered the model context.

An orchestration layer would decide which capability a request needs:

  • Transaction question: call the purchase-summary tool.
  • Policy question: retrieve approved policy passages.
  • Mixed question: call the tool and retrieve documents, then ask the model to synthesize a clearly attributed answer.
  • Unsupported or ambiguous question: ask for clarification or decline.

This resembles the separation I prefer in small-product system design: keep responsibilities clear, keep the source of truth explicit, and introduce another component only when it owns a real job.

Why Exact Purchase Facts Belong Behind a Tool

Embedding every transaction as text may look like a shortcut. A record could become a sentence such as “Customer 184 purchased two items on July 10.” The application could then run similarity search over those sentences.

That design breaks down quickly.

Vector search ranks semantic similarity; it is not an exact relational query engine. It does not naturally guarantee that all relevant orders were returned before a total was calculated. Refunds and status changes require re-indexing. Date ranges, joins, distinct counts, and “bought A but not B” logic are better expressed as database operations.

A narrow Spring service could expose a representative tool like this:

JAVA
public record PurchaseSummary(
    BigDecimal totalPaid,
    long completedOrders,
    LocalDate from,
    LocalDate to
) {}
 
@Service
class PurchaseTools {
    private final PurchaseAnalyticsService analytics;
    private final CustomerAccessPolicy accessPolicy;
 
    PurchaseTools(
        PurchaseAnalyticsService analytics,
        CustomerAccessPolicy accessPolicy
    ) {
        this.analytics = analytics;
        this.accessPolicy = accessPolicy;
    }
 
    @Tool(description = "Return an authorized customer's completed purchase summary")
    PurchaseSummary getPurchaseSummary(
        @ToolParam(description = "Internal customer identifier") UUID customerId,
        @ToolParam(description = "Inclusive start date") LocalDate from,
        @ToolParam(description = "Inclusive end date") LocalDate to
    ) {
        accessPolicy.requireCanView(customerId);
        return analytics.summarizeCompletedPurchases(customerId, from, to);
    }
}

This is representative code, not a complete security implementation. In a real application, identity should come from trusted request context where possible, date ranges should be bounded, returned fields should be minimized, calls should be audited, and the service must enforce tenant isolation independently of the model.

Spring AI's tool-calling API provides the connection between a chat model and application methods. The important design decision is not the annotation. It is making the callable boundary narrow, deterministic, authorized, and observable.

Where RAG Adds Value

RAG becomes useful when the answer depends on unstructured material that would otherwise exceed the prompt or be difficult to locate manually. In the purchase scenario, that might include:

  • the refund policy that applied on the purchase date;
  • product compatibility documentation;
  • warranty conditions for a region;
  • support notes associated with a recurring issue;
  • product reviews that explain a quantitative return trend.

A basic RAG flow has two parts. The offline or event-driven ingestion path reads documents, splits them into useful chunks, creates embeddings, and writes them to a vector store. The request path searches the vector store, adds selected chunks to the prompt, and generates an answer.

Spring AI provides interfaces for both parts. Its ETL pipeline uses document readers, transformers such as TokenTextSplitter, and writers such as a VectorStore. A simplified representative ingestion service could look like this:

JAVA
@Service
class KnowledgeIngestionService {
    private final VectorStore vectorStore;
    private final TokenTextSplitter splitter = new TokenTextSplitter();
 
    KnowledgeIngestionService(VectorStore vectorStore) {
        this.vectorStore = vectorStore;
    }
 
    void ingest(List<Document> approvedDocuments) {
        List<Document> chunks = splitter.apply(approvedDocuments);
        vectorStore.add(chunks);
    }
}

The real work sits around this small amount of plumbing: parsing quality, chunk boundaries, metadata, document lifecycle, duplicate handling, deletion, access control, and evaluation.

For retrieval, Spring AI's QuestionAnswerAdvisor offers a direct starting point:

JAVA
ChatResponse response = ChatClient.builder(chatModel)
    .build()
    .prompt()
    .advisors(QuestionAnswerAdvisor.builder(vectorStore).build())
    .user(question)
    .call()
    .chatResponse();

For more control, its RetrievalAugmentationAdvisor supports a modular flow, while VectorStoreDocumentRetriever supports settings such as top-K results, similarity thresholds, and metadata filters. Those APIs make an initial implementation approachable. They do not choose the correct documents or prove answer quality automatically.

That is why I would treat Spring AI as application infrastructure, not as a guarantee that an application is “doing RAG correctly.” The quality of retrieval still depends on the data and the decisions around it.

When Fine-Tuning Is the Better Experiment

Fine-tuning becomes a reasonable experiment when the missing capability is stable behavior rather than changing knowledge.

Examples could include:

  • mapping support messages into a stable internal taxonomy;
  • producing a strictly defined response style that prompting cannot deliver reliably;
  • extracting domain fields from recurring document formats;
  • following organization-specific response patterns across many requests.

I would not begin there. I would first build a baseline with a clear prompt, representative few-shot examples, and structured output. Modern application code can validate the model's response and retry or reject invalid results. That baseline is faster to change and gives the fine-tuning experiment something concrete to beat.

Fine-tuning requires more than a collection of historical conversations. Training examples need correct labels, consistent policies, removal or protection of sensitive data, separation into training and evaluation sets, and a plan for versioning. If the examples contain conflicting behavior, the model learns the conflict.

It also does not eliminate RAG. A fine-tuned classifier may route a request well while RAG supplies the latest policy. A fine-tuned response model may use a tool to obtain current purchase totals. Behavior and knowledge can be improved independently.

Spring AI is useful here as the application integration layer around models, prompts, tools, and evaluation. I would not treat it as the fine-tuning training platform itself. Training capabilities, supported data formats, and model lifecycle depend on the selected model provider.

Decision Record: My Starting Architecture

For the hypothetical purchase-data application, my decision would be:

Start with controlled SQL-backed tools for transaction facts and add RAG only for approved unstructured knowledge. Do not fine-tune until an evaluated prompting baseline exposes a stable behavior gap.

The reasons are practical:

  1. Purchase records already have an authoritative home.
  2. Exact questions need deterministic queries and calculations.
  3. Policies and product documents change independently from model versions.
  4. Retrieved passages can preserve evidence and version metadata.
  5. Fine-tuning adds a dataset and model lifecycle before its value is proven.

The request flow would remain explicit:

Request typeData operationModel responsibility
“How much did this customer spend?”Authorized database aggregationExplain the returned result
“Can this item be refunded?”Retrieve applicable policyAnswer from cited passages
“Why did returns increase?”Aggregate return data and retrieve feedbackSeparate facts from possible explanations
“Route this support ticket”No knowledge retrieval unless neededProduce a validated classification

This is also a hedge against provider change. Keeping business facts and retrieval logic outside the model reduces coupling, an idea I discuss further in designing backends that survive model deprecations.

Security and Privacy Are Part of Retrieval Design

Business data makes RAG security more than a prompt-engineering concern. A semantically relevant chunk may still be forbidden for the current user.

The OWASP GenAI guidance on vector and embedding weaknesses highlights risks including unauthorized access, leakage, and poisoning. In a multi-tenant application, a missing or incorrect filter could place another tenant's text in the model context. Once that happens, a polite system prompt is not an adequate access-control boundary.

I would require several controls:

  • Authorize at the source service and retrieval boundary, not only in the prompt.
  • Attach trusted metadata during ingestion; do not accept tenant identifiers from document text.
  • Apply tenant and visibility constraints before retrieving candidate chunks.
  • Separate highly sensitive data when the vector store's isolation model is insufficient.
  • Validate ingestion sources and protect them from unauthorized modification.
  • Record document IDs and versions used for an answer without logging unnecessary customer content.
  • Define deletion and re-indexing behavior for corrected or expired documents.
  • Treat retrieved text as untrusted input that may contain prompt-injection instructions.

Spring AI supports portable metadata filter expressions in its vector store API. Those filters are helpful, but they are one mechanism inside a larger authorization design. Application tests should attempt cross-tenant retrieval and verify that forbidden documents never reach the model.

The same principle applies to tool calls. The model can propose a tool and parameters, but the application must decide whether the authenticated actor may perform the operation. This is consistent with the safety boundaries in my backend workflow for AI coding agents: AI output can request an action; trusted code must enforce the rules.

Evaluation Before Architecture Expansion

A convincing demo question is not enough to validate RAG. I would create an evaluation set before tuning chunk sizes, switching vector databases, or adding a reranker.

The set should contain representative questions and expected evidence, including:

  • answerable questions with one clear source;
  • questions that require multiple passages;
  • questions whose answer changed between document versions;
  • questions with no authorized answer;
  • ambiguous questions that should trigger clarification;
  • attempted cross-tenant access;
  • exact transaction questions that should route to a tool instead of RAG;
  • mixed questions that require both paths.

I would measure the pipeline in layers:

LayerExample checks
RoutingWas the correct tool, retriever, or refusal path selected?
RetrievalDid the expected source appear in the candidates?
AuthorizationWere forbidden sources absent?
Grounded answerIs each factual claim supported by returned data or passages?
Task resultIs the final answer useful, complete, and correctly qualified?
OperationsWhat were the latency, token use, retrieval count, and failure mode?

Spring AI includes a RelevancyEvaluator that can help test whether an answer is relevant to the user question and retrieved context. I would combine automated evaluation with reviewed examples. Model-based evaluators are useful signals, not final truth, especially for calculations and authorization.

Fine-tuning needs the same discipline. The comparison should use a held-out evaluation set and a baseline. The tuned model should improve the target metric without reducing safety, factual grounding, or valid structured output. Otherwise the additional lifecycle is not justified.

Cost, Latency, and Operational Trade-Offs

RAG adds work to each relevant request: embedding the query, searching, perhaps reranking, and sending retrieved context to the model. It also adds an ingestion system. The costs are visible and can often be controlled with caching, smaller candidate sets, selective routing, and document lifecycle policies.

Fine-tuning shifts some cost toward dataset preparation, training, deployment, and repeated evaluation. It may reduce prompt length for a task, but that benefit should be measured against provider pricing and operational complexity rather than assumed.

Tool calling adds application round trips but keeps calculations deterministic and data current. For exact business facts, that is usually a good trade. A small result object can also consume less model context than many retrieved transaction chunks.

I would optimize only after tracing the complete request. A “fast” vector search can still produce a slow response if it supplies excessive context. A smaller tuned prompt can still be expensive if the model requires a separate deployment and retraining process. Calm operations come from measured bottlenecks, not architecture labels.

Common Mistakes I Would Avoid

Treating a vector store as the system of record

Vector stores are designed for retrieval by similarity. They should not quietly become the authoritative location for mutable transaction facts.

Using fine-tuning to memorize changing data

Orders, stock, prices, customer permissions, and policies can change after training. They need a current source and an access-controlled read path.

Adding RAG to every request

Retrieval can add irrelevant context and latency. Route only the questions that need external knowledge.

Trusting similarity as authorization

Metadata filters improve retrieval scope, but authorization must be enforced as a security property and tested at boundaries.

Evaluating only the final prose

A fluent answer can hide a routing error, missing source, stale document, or incorrect total. Evaluate retrieval and tool results separately from language quality.

Building a training dataset before defining success

Without a baseline and metric, fine-tuning becomes an expensive activity rather than a testable engineering decision.

A Practical Starting Checklist

If I were turning this design exercise into a proof of concept, I would proceed in this order:

  1. List real user questions and classify each as exact data, unstructured knowledge, behavior, or a combination.
  2. Build one narrow, authorized tool for an exact business question.
  3. Select a small approved document collection with clear ownership and versions.
  4. Add document metadata for tenant, visibility, product, locale, and validity period where applicable.
  5. Implement a basic Spring AI retrieval flow without premature reranking or tuning.
  6. Preserve source IDs in the answer so a reviewer can inspect the evidence.
  7. Create evaluation cases for routing, retrieval, groundedness, refusal, and tenant isolation.
  8. Measure latency and token use on the full request path.
  9. Improve the weakest measured layer.
  10. Consider fine-tuning only if a stable behavior problem remains and enough reviewed examples exist.

That sequence keeps the first experiment small while preserving the boundaries a production system would need. It also makes it easier to stop if retrieval does not add enough value.

Conclusion

RAG and fine-tuning answer different questions. RAG asks, “What external information should this model see now?” Fine-tuning asks, “What behavior should this model learn from examples?” Exact business data introduces a third question: “Which trusted system should calculate the current fact?”

For a purchase-data application, my starting answer is a hybrid architecture. SQL-backed tools should own exact transactions and aggregations. RAG should add approved unstructured context such as policies, product documents, and support knowledge. Fine-tuning should remain a later, evidence-based option for stable classification or response behavior.

My next practical step would be to choose ten representative business questions and classify them before writing any RAG code. That small exercise would reveal whether the project actually needs retrieval, tool calling, fine-tuning, or all three—and prevent the model from becoming a complicated substitute for a database.

The Spring AI examples, security boundaries, and any claims adapted to a real business system should still be reviewed against the target environment and provider versions.

Related posts