Agentforce
Grounding an Agentforce agent on data you can't ingest: External Objects and live calls
Your agent has to answer from data that lives in another system and changes by the minute: live stock, an order's status, today's price. The grounding tutorials assume that data is already in Data 360. Here's the decision they skip: when to ingest, when to virtualize with External Objects, and when to just call the API live, plus the one constraint that rules most of it out.
A customer asks an agent whether a part is in stock. The true answer lives in a warehouse system that updates every few seconds, and none of it is in Salesforce.
Most grounding tutorials skip straight past this. They assume the data is already sitting in Data 360, indexed and waiting. Yours isn’t, and copying a table that changes by the second into a platform on a batch schedule is how an agent ends up quoting stock that sold twenty minutes ago.
So the real question is not how to ground an agent. It’s how to get an agent to read external data that is too fresh, too large, or too governed to ingest. There are four answers, and they are not interchangeable.
One constraint decides most of it, so take it up front. A retriever, the thing that does semantic search for grounding, can only point at a search index built on a Data 360 data model object. It cannot point at an External Object.
So if the agent needs to search across a body of external knowledge, that knowledge has to come into Data 360 and be indexed. If it needs one specific live fact instead, you have better options that never touch Data 360. Everything below follows from that split.
Grounding and actions are two different jobs
Before the four options, separate two words that get used as if they mean the same thing.
Grounding is retrieval into the prompt. Before the model generates, the platform fetches context, merge fields and retriever results, and injects it into the prompt so the answer rests on your data instead of the model’s memory. Grounding is a read, and it runs every time that prompt runs.
An action is a tool the agent decides to call. It can read or write, it fires when the agent’s reasoning selects it, and it can reach any system you expose. Trailhead’s own grounding module draws this line. It matters because “read a live external fact” can be solved either way, and the right choice depends on whether the agent should reason about that data or just relay it.
Option 1: pull the record you already have
If the data is a field on a record, ground on it directly. Salesforce Prompt Builder supports record merge fields, related-list merge fields, and DMO merge fields, and a Flex template can carry up to five grounding resources. Merge fields are live at execution time and cost nothing.
Teams skip this because it feels too simple. If the fact already lives in the CRM or a unified profile, don’t build a pipeline to fetch what a merge field returns for free.
Option 2: virtualize it with External Objects
When the data lives outside Salesforce and has to be current, the underused option is Salesforce Connect. You register the external system as a data source using an OData 2.0 or 4.0 adapter, or a custom Apex adapter, and its tables surface as External Objects. Nothing is stored in Salesforce. Every query is a live callout, so the data is as fresh as the source.
The catch is the one from the top: a retriever cannot index an External Object. You ground on it through a Flow or Apex data provider instead of RAG. Salesforce documented this path directly, noting that grounding a template with Flow or Apex lets you reference data from anywhere, including external sources. The Apex class runs a SOQL query against the External Object, or makes its own callout, and returns text into the template.
External Objects earn their place for volatile, structured data: an order status, a live balance, a shipment location, read for one specific record. They fall down on scale and analysis. You can’t run an aggregate or a roll-up on an External Object, reporting fetches only a slice of the rows, and every query inherits the latency and rate limits of the external API. A slow source means a slow agent.
Option 3: bring it into Data 360 when the agent has to search it
The moment the requirement is “search across a lot of external content and find the relevant piece”, you’re back to Data 360, because that’s the only place a retriever can look. Two routes get the data there.
Ingestion copies it in, by connector, the Ingestion API, or MuleSoft, on a batch or streaming schedule. Streaming ingestion processes roughly every three minutes; batch is minutes to hours. Either way the agent reads a copy, only as fresh as the last refresh.
Zero-copy federation queries the data in place in Snowflake, BigQuery, Databricks, or Redshift without duplicating it. That sounds like it solves freshness for free, and for analytics it largely does.
There’s a wrinkle for grounding, though. To feed semantic search, federated content still has to be chunked and embedded into Data 360, with the chunks and vectors stored in index DMOs. The source rows stay put; the embeddings the retriever searches are a derived copy. “Zero copy” describes where the source lives, not the freshness of what the agent searches.
Whichever route, the retriever rules shape your data model. A retriever fetches from one search index, and a search index is built on a single DMO. Model the data so the thing you want searched is one indexable object, not scattered across five.
Option 4: skip grounding and let the agent call the API
The fourth option abandons grounding. Instead of pre-loading data into the prompt, you give the agent an action that fetches the data when it decides it needs it: invocable Apex making a callout, a Flow HTTP Callout, or an External Services action imported from an OpenAPI spec. The last is fastest to stand up: import the spec, pick the operations, and each becomes an action the agent can call with no code.
Reach for this when the agent needs to read and act, check inventory then reserve it, or when the data is so specific that searching for it makes no sense. An action also keeps volatile data out of your data model entirely.
The price is latency, paid inside the conversation. A live callout blocks the agent’s turn while it waits. Apex callouts default to a 10-second timeout and cap at 120 seconds, and External Services sync operations also time out at 120 seconds. A slow API becomes an agent that appears to hang.
You’re also spending against callout governor limits, so an action that fans out to several endpoints can run out of budget mid-turn.
The trade-offs on one page
| Approach | Freshness | Runtime latency | Cost | Retriever can search it? |
|---|---|---|---|---|
| Merge fields (CRM / DMO) | Live at execution | Negligible | None | N/A, direct read |
| External Objects (Salesforce Connect) | Real-time, live callout | One callout per query | No Data 360 credits; bounded by the source | No, ground via Flow/Apex |
| Data 360 ingestion | Stale by refresh: streaming ~3 min, batch minutes to hours | Fast, data is local | Ingestion credits by volume | Yes |
| Zero-copy federation | Source is live; searchable embeddings are a scheduled copy | Depends on the warehouse | Fewer storage credits; external compute billed separately | Yes, once chunked and indexed |
| Live action (Apex / Flow / External Services) | Real-time, on demand | Full callout latency, up to 120s | No credits; spends callout budget | It’s an action, not grounding |
How I choose
Start from what the agent has to do with the data, not from what looks modern.
For one current fact about a specific record that lives outside Salesforce, use an External Object grounded through Apex, or a live action if the agent should also write back. You get real-time data with nothing copied and no credits burned.
To search a body of external knowledge, manuals, a product catalog, past tickets, accept that it belongs in Data 360, and pick ingestion or federation on how fresh the searchable copy must be. Don’t fight the retriever constraint; design the DMO around it.
If the data is already a field on a record, ground on the merge field and move on.
The failure I see most is a team ingesting fast-moving transactional data into Data 360 because a tutorial said grounding means Data 360, then wondering why the agent quotes stale numbers. Ingestion is for what the agent searches. External Objects and live actions are for what the agent must read fresh. Get that division right and the rest of the integration is ordinary engineering.
Understanding the basics
Can an Agentforce retriever use External Objects or Salesforce Connect?
No. A retriever performs semantic search against a Data 360 search index, and a search index is built on a data model object. External Objects can’t be indexed this way. To ground on an External Object, use a Flow or Apex data provider in the prompt template instead of a retriever.
What’s the difference between grounding and an action?
Grounding retrieves data into the prompt before the model generates, so the answer rests on your data. An action is a tool the agent chooses to call during its reasoning, and it can read or write to any system you expose. Reading a live external fact can be done either way; use an action when the agent should also act on the data.
Does zero-copy federation keep grounding data live?
For analytics, it queries the source in place. For grounding through a retriever, the federated content is chunked and embedded into Data 360 index objects on a refresh schedule, so the vectors the agent searches are a derived copy. The source stays put; the searchable representation is not live.
How do I add external data as an Agentforce action?
The no-code path is External Services: create a named credential for the endpoint, import the OpenAPI specification under Setup, and select the operations to expose. Each becomes an invocable action available to Flow and to the agent. Apex actions and Flow HTTP Callout are the coded alternatives when you need more control.
Choosing where external data should live sets an agent’s reliability and its bill. If you want a second read on ingest-versus-virtualize-versus-call-live for a specific source, talk to us.