Salesforce shipped a new language this year: Agent Script (often called aScript). It's the DSL you use to define Agentforce agents — conversational flows, LLM prompts, deterministic branching, action calls, the whole thing in one file.
The language is fine. Clean syntax, readable, Python/YAML-ish. Docs here if you want to browse.
You still probably don't want to write it by hand.
What Agent Script actually looks like
Every line is either logic (prefixed with ->) or a prompt (prefixed with |). Logic lines run deterministically. Prompt lines go to the LLM.
name: case_triage
description: |
Classify an inbound case and route it.
steps:
- |
Read the case subject and body. Classify as one of:
"self_serve", "human", or "unknown".
-> set category = llm_output
-> if @variables.category == "self_serve"
-> run @actions.send_kb_reply
with case_id = @variables.case_id
set reply_id
You reference things with @: @actions.<name>, @variables.<name>, @outputs.<name>, @subagent.<name>. You embed a variable inside a prompt with {!@variables.<name>}. You run an action with run ... with ... set. Comparisons are the usual ==, !=, is None. Whitespace matters — mixing spaces and tabs breaks the parse.
Why typing this by hand is a tax
None of it is hard. All of it is annoying.
- You have to remember which prefix is which (
->vs|), and get the indentation exactly right. - You have to remember the
@namespaces (actions,variables,outputs,subagent) and which one applies where. - You have to know the action's input schema before you can write
with .... - You have to context-switch between what the agent should do and how aScript wants you to spell it.
That last one is the real cost. Every minute you spend translating intent into syntax is a minute you're not thinking about whether the agent actually solves the customer's problem.
The Claude Code move
You describe the agent in plain English. Claude reads the aScript reference, your org's action metadata, and your variable definitions. It writes the .ascript file. It deploys via SF CLI. You review the diff.
Here's the prompt:
Build an Agentforce agent called "case_triage".
When a case comes in, it should:
1. Read the subject and description.
2. Classify as self_serve, human, or unknown.
3. If self_serve, run the send_kb_reply action with the case_id.
4. If human, escalate to the Tier2_Support queue.
5. If unknown, ask the customer one clarifying question.
Store the classification in a variable called category.
Deploy to dev-org when done.
That's the whole input. No syntax. No ->. No @variables.. You describe what the agent does; Claude handles the spelling.
What it does next
Claude Code will typically:
- Inspect your org.
retrieve_metadataonAiAgentand related types. If your org has a customsend_kb_replyaction, Claude reads its input schema so thewithblock is right. - Draft the file. Writes
force-app/main/default/aiAgents/case_triage.ascriptwith the correct indentation and namespace prefixes. - Show you the diff. Before anything deploys, you see the generated aScript. Read it.
- Deploy. On your approval,
deploy_metadatapushes to your dev-org alias. - Offer a smoke test. Claude can run the agent against a sample input and show you the trace, so you catch classification mistakes before real cases hit it.
What to actually verify
Don't rubber-stamp it. The LLM is writing code; your job is to check intent.
- Branch conditions. If you said "classify as X, Y, or unknown," make sure the else-branch is actually
"unknown"and not a silent fallthrough. - Action inputs.
with case_id = @variables.case_idis right;with case = @variables.case_idisn't. Small, easy to miss. - Prompt wording. The
|blocks are the LLM's instructions at runtime. Read them the way you'd read a prompt you were going to ship to users. Because they are. - Variables you didn't ask for. If Claude introduced a new
@variables.retry_countto handle an edge case, decide whether you want it.
Why this changes the workflow
Agentforce agents aren't Flows. They aren't Apex. They're a new thing with new syntax, and most admins aren't going to memorize a new DSL just to ship one agent a quarter.
Claude Code flips the default. Instead of "first, learn aScript," it's "first, describe the behavior, then read the generated aScript to check the work." The language becomes something you read rather than something you write.
That's a much smaller tax.
The point isn't to avoid understanding the language. It's to avoid paying the typing cost every time you ship an agent.
In the next post we'll build a multi-step agent with a subagent handoff — the kind of pattern that's genuinely annoying to hand-write because of how the @subagent references nest. Same workflow, bigger payoff.
Related: Still deciding between Claude Code and Agentforce? Here's the decision framework →
Want the step-by-step on using Claude Code for daily Salesforce work (Flows, fields, Apex, validation rules)? That's what the course covers.