Skip to main content
New tool CRON Expression Builder — preview next run times before you schedule Apex. Open the builder →
A 3D holographic file folder representing an Agentforce Prompt Template accessing external file resources.
Agentforce & AI

Agentforce Prompt Template: Accessing Notes and Attachments

Struggling to include Notes and Attachments in your Agentforce Prompt Templates? We explain why the standard resource selector misses these objects and how to fix it with Data Cloud or Apex.

The short answer

Prompt Builder cannot natively query Notes, Attachments, or Files because polymorphic junction objects like ContentDocumentLink are not exposed in the template resource picker. Developers can resolve this by using an Apex-defined invocable resource to extract file text or by ingesting ContentVersion records into Data Cloud for vector search.

Key takeaways Create an Apex class with an @InvocableMethod to query ContentDocumentLink and feed extracted file text into Prompt Builder. Ingest ContentVersion records into Data Cloud and enable vector search to ground Agentforce prompts across high volumes of files. Add conditional fallback instructions in prompt templates to prevent model hallucinations when records have no attachments. Grant the Agentforce user profile appropriate permissions to access ContentDocument records to ensure background queries return data.

The Prompt Template Dilemma

As we integrate Agentforce into our enterprise workflows, one of the most common friction points developers face is retrieving unstructured data. When you build a apex-lwc-guide/" class="auto-link">Prompt Template in Salesforce, you naturally expect to select the main Input Object and pull in associated records. However, when you try to reference ContentDocument, ContentVersion, or the legacy Note and Attachment objects, you often find that the Prompt Builder resource picker does not expose these directly.

This happens because Prompt Builder is optimized for querying relational data through the standard Data Graph layer. Because Notes and Attachments (and the newer Files/ContentDocument structure) are stored via polymorphic relationships and system-level joins, they aren't automatically presented as "Related Lists" in the template editor. In this guide, we’ll explore how to overcome this limitation and feed that critical unstructured data into your LLM.

The Architecture Limitation: Why Prompt Builder Misses Files

Prompt Builder relies on the Einstein Trust Layer to fetch context. When you use the "Template" feature, the system generates a SOQL query behind the scenes to fetch the fields defined in your template. The ContentDocumentLink object, which connects an Account or Case to a file, is a junction object. Unlike a standard lookup field (e.g., Contact.AccountId), Prompt Builder’s UI does not support traversing these complex junction structures natively in the prompt preview tool.

If your goal is to summarize a Case using the latest PDF attached to it, you cannot simply click "Insert Resource" and expect to see "Related Notes." You must intervene at the data retrieval layer.

Strategy 1: Using Apex-Defined Resources

The most robust way to solve this is by creating an Apex-defined Prompt Resource. This allows us to write a custom class that handles the ContentDocumentLink query, extracts the text content, and passes it to the prompt.

First, we create an Invocable method to fetch the content:

public class PromptContentRetriever {
    @InvocableMethod(label='Get Latest Attachment Text' description='Fetches text from latest file')
    public static List<String> getAttachmentContent(List<Id> recordIds) {
        List<String> results = new List<String>();
        for (Id recordId : recordIds) {
            // Fetch the most recent document link
            ContentDocumentLink link = [SELECT ContentDocument.LatestPublishedVersion.VersionData 
                                       FROM ContentDocumentLink 
                                       WHERE LinkedEntityId = :recordId 
                                       ORDER BY SystemModStamp DESC LIMIT 1];
            
            if (link != null) {
                results.add(link.ContentDocument.LatestPublishedVersion.VersionData.toString());
            } else {
                results.add('No attachments found.');
            }
        }
        return results;
    }
}

Once deployed, go to Prompt Builder and select Add Resource. Choose Apex and select your PromptContentRetriever. You can now drag this resource into your template body. The LLM will now receive the raw string of the attachment content directly in its context window.

Strategy 2: Data Cloud and Unstructured Data

For enterprise-scale Agentforce implementations, relying on Apex for every file can create maintenance overhead. This is where Data Cloud shines. Instead of querying local Salesforce objects, we ingest the ContentVersion records into Data Cloud.

  1. Data Stream: Create a Data Stream for the ContentVersion object.
  2. Data Model Mapping: Map the VersionData to a text-based attribute in the Data Model.
  3. Search Index: Enable the Data Cloud Vector Database (if using RAG) or a standard lookup.
  4. Prompt Builder Integration: Use the Data Cloud resource type in your prompt template.

By indexing these files as unstructured text in Data Cloud, the Agentforce prompt can perform a vector search to find relevant information across thousands of files, rather than being restricted to the "latest" attachment.

Implementing a "Safe" Fallback

When dealing with AI, context is everything. You should never assume an attachment exists. When building your prompt template, always use a fallback condition to prevent the LLM from hallucinating when no attachment is found.

In your prompt template configuration, structure your instruction as follows:

"Review the following context provided from the Case record.

Case Details: {{Case.Subject}} / {{Case.Description}}

{IF: {!AttachmentResource} != 'No attachments found.'} Additional File Context: {!AttachmentResource} {ELSE} No file attachments were available for analysis. Proceed using only Case Details. {ENDIF}"

Key Takeaways

  • Don't search for native support: Prompt Builder does not natively "see" Files or Notes via the UI because of the complex polymorphic nature of ContentDocumentLink.
  • Use Apex-Defined Resources: For simple, direct-access needs, write an @InvocableMethod to query ContentVersion and return the string content to your template.
  • Scale with Data Cloud: If your agents need to parse large volumes of historical documents, migrate your file ingestion to Data Cloud and use it as a vector-ready resource.
  • Handle Nulls: Always implement logic in your template instructions to handle scenarios where the attachment retrieval returns empty data; this reduces AI hallucination significantly.
  • Permissions Check: Ensure your Agentforce user profile has 'View All' or appropriate access to ContentDocument records, otherwise the background query will return an empty set.

Frequently asked questions

Why can't Prompt Builder access Files and Attachments directly?

Prompt Builder relies on standard relational queries and cannot natively traverse polymorphic junction objects like ContentDocumentLink in its resource picker. Because Files and Attachments rely on system-level joins, they do not appear automatically as related lists.

How do you pass file content to a prompt template in Agentforce?

Write an Apex class with an @InvocableMethod that queries ContentDocumentLink for the target record and converts the LatestPublishedVersion.VersionData to a string. Add this Apex resource in Prompt Builder to insert the raw text directly into the prompt context.

How do you use Data Cloud to access unstructured file data in Prompt Builder?

Create a Data Stream on ContentVersion, map VersionData to a text attribute in your Data Model, and index the data in Data Cloud. You can then select the Data Cloud resource type in Prompt Builder to perform vector search across files.

How do you handle missing attachments in Agentforce prompt templates?

Implement conditional IF/ELSE logic in your prompt instructions to check if the attachment resource returned content. If no attachment exists, instruct the model to proceed using only the standard record fields to prevent hallucinations.

Newsletter

One email every Tuesday

New guides, tool updates, and the release-note changes that break things.

No spam. Unsubscribe in one click.

Comments

Loading comments...

Leave a Comment