An agent that can only talk is half a product. Give it a typed, validated, confirmed write action — so it can act without ever writing junk to your records. A hands-on AI Projects Lab build.
Falcon Appliances wants its support agent to do more than answer questions — it should be able to log a warranty claim when a customer reports a defect. That's a write to your data, driven by an LLM, so the bar is high: the agent must pass exactly the right fields, we must validate them, and a human (or the customer) should confirm before anything is committed. We'll build that as a custom Agentforce action.
For beginners: an agent action is a capability you give an agent — something it can do, not just say. You can build one from a Flow, a prompt template, or Apex. Apex actions use the @InvocableMethod annotation, the same mechanism Flow uses, so a single well-written action is reusable by both the agent and any Flow.
The action's labels and descriptions matter as much as the code. The Atlas Reasoning Engine reads them to decide when and how to call the action, so write them for the model, not just for yourself. Keep inputs typed and minimal, and bulkify — an invocable action can be reused in a Flow that processes many records.
public with sharing class LogWarrantyClaimAction {
public class Request {
@InvocableVariable(required=true label='Case Id'
description='The case the warranty claim relates to.')
public Id caseId;
@InvocableVariable(required=true label='Reported Issue'
description='Short description of the defect the customer reported.')
public String issue;
}
public class Result {
@InvocableVariable(label='Claim Number')
public String claimNumber;
}
@InvocableMethod(label='Log Warranty Claim'
description='Creates a warranty claim for a case and returns the claim number.')
public static List<Result> run(List<Request> requests) {
List<Warranty_Claim__c> claims = new List<Warranty_Claim__c>();
for (Request r : requests) {
// Validate before touching the database
if (String.isBlank(r.issue)) {
throw new AuraHandledException('A reported issue is required.');
}
claims.add(new Warranty_Claim__c(
Case__c = r.caseId,
Issue__c = r.issue,
Status__c = 'Submitted'));
}
insert claims; // one DML for the whole batch
List<Result> out = new List<Result>();
for (Warranty_Claim__c c : claims) {
Result res = new Result();
res.claimNumber = c.Name;
out.add(res);
}
return out;
}
}
with sharing: the action runs as the agent user. Enforce that user's permissions and record access on purpose — an agent should never be able to write records a real user in its role couldn't.Good instruction: "Only log a warranty claim after you have confirmed the product, the defect, and that the customer wants to proceed. Read the claim number back to them."
Deterministic guardrails belong outside the LLM's discretion. Two layers keep a write action safe:
Sources: Create Custom Actions Using Apex InvocableMethod (Agentforce Developer Guide) · Build and Enhance Agentforce Actions · Call an Agent from a Flow or Apex Class (Salesforce Help)