isEligible = true refundAmount = 1240 reason = "Supply was interrupted for 14 hours, which exceeds the 12-hour guarantee." Now, there is absolutely nothing left for the LLM to guess or infer.
The Concept: Verdicts, Not Evidence
When you expose an invocable method to an AI agent, you must strictly control the narrative. If you return raw data, the model acts as the judge, jury, and executioner. This leads to drift and hallucinations. To prevent this, follow these core rules:
- Return the conclusion: Do the math and logic in Apex. Give the AI the final state (e.g., eligible vs. ineligible).
- Provide a reason string: This is a deliberate design choice. It gives the model the exact, correct words to use when explaining the decision to the user.
- Stop AI justification: Without a provided reason string, the model will compose its own justification for a decision it didn't actually make. The AI's explanation can be wildly wrong even when the final verdict is technically right.
- Respect bulkification: Invocable methods receive and return lists. They are bulkified by design, even if the AI typically calls them one at a time.
- Enforce security: Always use
with sharingandUSER_MODEqueries. This ensures the action perfectly mirrors the running user's field-level security and sharing rules.
// ❌ BAD: Returning RAW RECORDS
// The model must compare dates, read picklists, and reach a verdict.
public List<Case> getRefundEligibility(List<Id> caseIds) { ... }
// ✅ GOOD: Returning a DECISION
// The model receives exact instructions and strings to output.
public class RefundDecision {
@InvocableVariable public Boolean isEligible;
@InvocableVariable public String coverageType;
@InvocableVariable public String reason;
}
- Rule: Every Apex action meant for an LLM should return a decided value and a plain-text reason string.
- Gain: The verdict cannot drift, and the AI uses accurate, pre-approved wording instead of inventing its own.
- Price: You have to design specific wrapper classes for your return variables, and business logic is locked in code (requiring a release to change).
- Limits: Standard Apex governor limits still apply, and the AI's ReAct loop might call the action repeatedly if it gets confused.
- Mirror — Returning the record: It feels more flexible, but it moves business-critical decision making into a probabilistic model where you cannot write unit tests for it.
- At Volume: Bulkify properly. Invocables receive lists, and per-record calls will quickly exhaust limits if not handled correctly.
Core Q&A
A: The verdict and the explanation carry two separate risks. Returning a boolean fixes the verdict, but it leaves the model completely free to compose its own justification. That explanation can be totally wrong even when the verdict is right—and customers will remember the explanation.
By returning the decided value, the supporting figures, and a plain-language reason sentence, you restrict the LLM's creativity. You can then add a prompt instruction telling the agent to "state the provided reason exactly."
A: LLMs are highly obedient—to a fault. They will happily read and surface any data you feed them. If your Apex action runs in system context (without with sharing or WITH USER_MODE in your SOQL), you bypass the entire Salesforce security model. The AI might read a hidden field (like a private margin calculation or internal HR note) and confidently display it to a user who has no rights to see it. Always let the platform's security handle visibility.
A: AI agents (like Copilot) typically invoke actions for a single conversational turn, leading developers to assume they only need to process one record at a time. However, Salesforce requires @InvocableMethod to take a List<Request> and return a List<Response>.
You must loop through the request list just like you would in a standard Flow or trigger. If you just grab requests[0], your code will immediately break if the action is ever reused in a bulk Flow or a future batch-agent scenario. Write for lists, query outside the loop, and return a matching list of verdicts.
A: Try a simple experiment: temporarily alter your code to return the raw record instead of the decision wrapper. Then, ask the AI the exact same eligibility question five times in five separate conversational sessions. You will quickly notice the phrasing, logic, and sometimes even the final verdict drifting. This is the ultimate proof that business rules belong in deterministic code, not probabilistic prompts.