Run Large Language Model (GPT) agents in Salesforce apex.
Watch Full Demo Here
An “Agent” is a technique for instilling the ability for an LLM to “Reason” and take “Action”. This approach is introduced by the ReAct Paper (Reason → Act) and used in popular libraries like langchain and auto-gpt.
Model
: LLM/GTP model. Currently only OpenAI GPT Completion & Chat models are supported.Prompt
: The communication "protocol" between the model & system. Currently only ReAct style prompts are supported.Agent
: A instance formed to solve a given objective.Tools
: The commands at the agents disposalAction
: The act of invoking a toolforce:source:push
) or to a developer edition (force:mdapi:deploy
)Warning Scratch & developer orgs have a limit of 5 chained queueable jobs, which will limit how much work the agent can do.
Assign yourself to the Apex Agent
permission set. sfdx force:user:permset:assign -n Apex_Agents
Open Setup -> Named Credential -> External Credential -> OpenAI
. Edit the "Permission Set Mapping" to add a "Authentication Parameters" with name of API_KEY
and your OpenAI API Key as the value
(Optional) Open Setup -> Custom Settings -> Apex Agent Settings -> manage
and add your SERP API key & ExtactorAPI key. This is required to enable the internet search capabilities. Both have free tiers.
Navigate to the "Apex Agents" app (from app launcher) and run a task. Or start the agent using example code below.
This library is not production ready and may never be:
Warning Salesforce seems to have a bug with
aborting
queueable jobs with long running HTTP callouts. If you abort a job, it will still run to completion, and continue to schedule the following jobs!
OpenAIChatModel chatLLM = new OpenAIChatModel();
// chatLLM.model = 'gpt-3.5-turbo';
chatLLM.model = 'gpt-4';
SerpAPIKey__c mc = SerpAPIKey__c.getInstance(UserInfo.getUserId());
Map<String, IAgentTool> tools = new Map<String, IAgentTool>{
'search_internet' => new InternetSearchAgentTool(mc.API_Key__c),
'find_records' => new SOSLSearchAgentTool(),
'send_notification' => new SentNotificationAgentTool(),
'create_records' => new CreateRecordAgentTool(),
'get_fields' => new GetSObjectFieldsAgentTool(),
'list_custom_objects' => new ListSObjectAgentTool(),
'execute_soql' => new RunSQLAgentTool()
};
ReActZeroShotChatPrompt prompt = new ReActZeroShotChatPrompt(tools);
ReActChatAgent agent = new ReActChatAgent('Find 3 accounts with missing phone numbers and try to populate them from the internet', prompt, chatLLM);
agent.maxInvocations = 15;
AgentQueueable manager = new AgentQueueable(agent);
manager.startAgent();
Note For best results, it's recommended that you use
OpenAIChatModel
withgpt-4
&ReActZeroShotChatPromptManager
and only include the minimum number of tools you need.
Creating a custom tool is easy. Just create a class that implements the IAgentTool interface and add it to the map of tools when you create the prompt.
public class GreetingAgentTool implements IAgentTool {
public string getDescription() {
return 'Get a greeting';
}
public Map<string, string> getParameters() {
return new Map<string, string>({
'name' => 'The name to greet'
});
}
public string execute(Map<string, string> args) {
if(String.isEmpty(args.get('name')){
// throw an error with instructions so the agent can self correct
throw new Agent.ActionRuntimeException('missing required parameter: name');
}
return 'hello ' + args.get('name');
}
Tips:
JSON.serialize
You can write your own ReAct style prompts by implementing Prompt.IReAct
.
Currently there is some primitive logging place to an Object call Agent_Log__c
. Agent steps fire Agent_Event__e immediate platform events, which result in the log being updated in realtime.
{thought/reasoning} {action_result}
Tested Prompts:
Search for accounts containing the word "sample" and send a notification to the user with name = "charlie jonas", notifying them that they should remove the account.
write a SOQL query that returns all billing related fields for an account. Send me a notification with the results of the query
Get the weather tomorrow in Lander, wyoming. Send a notification to Charlie Jonas letting him know how to dress
Research 3 companies that offer leading edge solutions for building API. Insert the new account with basic information about the business, but only if the account does not already exist.
Find out how many employees work at amazon and update the account
query 3 accounts that do not have Number of Employees set. Update the account with the number of employees from the internet.
See if you can fill in any missing information on the amazon account. Send me a notification with the summary
Search for accounts containing the word "sample". Create a task assigned to me with the subject "Remove Sample Account
write a SOQL query to group invoice total by project name. Send me the results in a notification
The easiest way to contribute at this stage is to create new "AgentTools" (PR's welcome!) and experiment to see what this thing can do.