---
cuppy_hub: salesforce
cuppy_path: patterns/golden-record-rag-pipeline-for-revenue.md
cuppy_section: docs
cuppy_doc: CW9B-D581
cuppy_doc_uuid: caefa46e-730a-4aa0-95f8-cdd372664eb2
cuppy_permalink: https://cuppy.io/salesforce/d/CW9B-D581
cuppy_version: 1
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/salesforce/docs/patterns/golden-record-rag-pipeline-for-revenue
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: e70e7b4d8c28e9b298342acddd4cf988a34865cb9d03ee075dc4930ccab12e61
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Golden-record RAG pipeline for revenue

**Goal:** a seller asks "brief me on Acme", "who buys like Acme but has gone quiet?" or "what should I offer them?". The agent answers from **one reconciled view** of each customer: every duplicate account and contact merged, with all their orders counted once.

## Architecture

```mermaid
flowchart LR
  CRM[CRM: Account, Contact, Order, OrderItem, Product2] --> S[Data streams → DLOs]
  S --> M[Mappings → Account, Individual, Contact Points, Sales Order, Sales Order Product]
  M --> IR[Identity resolution → golden people + accounts]
  IR --> CI[Calculated insight: revenue rollup per golden record]
  CI --> DG[Data graph: golden record + orders + rollup]
  CI --> N[Transform: account narrative DMO]
  N --> IX[Hybrid search index] --> R[Retriever] --> L[Data Library]
  DG --> F[Flow: Get_Account_Revenue_Context]
  F --> A[Revenue Assistant agent]
  L --> A
  P[Prompt: Next_Best_Offer] --> A
```

## Stages

| # | Stage | Built with | Output | Verify (`query-sql`) |
|---|---|---|---|---|
| 1 | Ingest | `POST /ssot/data-streams` × 5 (`reference/data360/streams-and-mapping.md`) | Five DLOs | Rows in each DLO |
| 2 | Map | Standard Account and Contact mappings; **your own** Order → Sales Order and OrderItem → Sales Order Product | Revenue DMOs | `COUNT(*)` on `ssot__SalesOrder__dlm` matches the Order DLO |
| 3 | Unify | Two rulesets, people and accounts (`reference/data360/identity-resolution.md`) | Unified and link DMOs | Consolidation rate within the expected band |
| 4 | Roll up | `Revenue_Rollup__cio` (`reference/data360/insights-and-data-graphs.md`) | Lifetime revenue, order count, last order date and average order value per golden record | `SUM` of revenue equals `SUM(ssot__GrandTotalAmount__c)` |
| 5a | Real-time context | Data graph rooted on the unified account, with orders and rollup | One JSON document per golden record | A known account returns its orders |
| 5b | Semantic context | Batch transform writing `Account_Narrative__dlm` (one text row per golden account) → hybrid index → retriever | Searchable narratives with the account name prepended to every chunk | Chunk count > 0; the index is Ready |
| 6 | Agent | Data Library (RETRIEVER), flow, prompt template, Revenue Assistant (`guides/data360/ground-a-revenue-agent.md`) | Published, active agent | Agent tests pass the gate |

Stages 1 to 5 are scripted by `guides/data360/automate-the-golden-record-pipeline.md`. Stage 6 uses `sf agent` commands. Moving to another org uses data kits for the Data 360 parts (`reference/data360/automation-and-data-kits.md`) and `sf project deploy` for the flow, prompt and agent.

## The narrative row (stage 5b)

One row per golden account, built from the unified account and the rollup. The hub's reading: indexing a generated narrative is how to make structured golden records searchable, because a search index embeds text fields.

```text
Acme Corporation (golden record of 3 CRM accounts). 14 orders, lifetime revenue 120,400 USD,
average order 8,600, last order 2026-09-12 (41 days ago). Top products: Pro Licence, Support Plus.
Segment: high value, recently active.
```

- Put the account name first, **and** prepend it to every chunk, so citations name the right account.
- Write numbers as words the seller would use; keyword search in a hybrid index matches them.
- Never include contact points (email, phone) in the narrative: the agent doesn't need them to sell, and the index would expose them to every agent user.

## Known-good

- Unify **before** you roll up, and roll up **before** you index. Re-run stages 3 to 5 in that order after each ingest cycle.
- One golden ID flows through everything: the data graph root, the narrative row key, and the flow's lookup.
- Stage gates in CI: `apply` → `run --allow-billable` → `wait` → `run` → `verify`, then the agent tests.

## Known-bad

| Design | What happens |
|---|---|
| Indexing the CRM Account object directly | Duplicates surface as separate accounts, and revenue is split across them |
| Rolling up Sales Order Product and Sales Order in one aggregate | Revenue is multiplied by the line count |
| Joining orders straight to `UnifiedIndividual__dlm` without the link DMO and key qualifier | Few or no matches |
| Putting the data graph JSON into the search index | Large chunks of IDs embed badly. Index the narrative, look the graph up by ID |
| A service agent with no Data 360 access for the agent user | Empty knowledge summaries; the agent refuses every search |
| Running identity resolution on every CI build | The daily on-demand quota runs out and credits are wasted. Run only after data or rule changes |


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 376 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/salesforce/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
