Agentforce
Agentforce DX: building and previewing agents from the CLI instead of clicking through Studio
Every agent you build in the browser is a config you cannot diff, review, or roll back. Agentforce DX turns an agent into source: a YAML spec, generate and preview commands, and metadata that moves through your pipeline like any other. Here is the pro-code loop, the metadata under the hood, and the deployment dependencies that trip up the first migration.
Here is the moment every team hits eventually. You built an agent in Agentforce Studio, it works, and now you need to get it from your sandbox into production, or from one developer’s scratch org into a teammate’s. You go looking for the “export” button and discover the agent is a web of clicks: topics defined in a builder, actions wired in a panel, instructions typed into text boxes, all of it living as config you cannot see in one place, cannot diff, cannot code-review, and cannot cleanly roll back when a change makes the agent worse.
This is the problem Agentforce DX exists to solve. It is the pro-code toolchain, a sf agent CLI plugin and a VS Code extension, that treats an agent the way you already treat Apex and Lightning components: as source. You author from a YAML spec, generate the agent into an org, preview its behavior in the terminal, and move the whole thing through your pipeline as metadata. If you have read our take on testing agents in CI/CD, this is the other half of that story: the authoring and deployment loop that testing plugs into. This post is the loop itself, the metadata underneath it, and the specific things that break the first time you move an agent between orgs.
Why “agent as source” is the point, not a preference
The case for pro-code agents is the same case that made source-driven development win everywhere else on the platform, and it is worth being explicit about because clicking in Studio feels faster right up until it doesn’t:
- You can diff a change. “What did this agent look like before someone edited the instructions?” is answerable when the agent is a file in git and unanswerable when it is state in an org.
- You can review a change. An agent’s topics and actions are exactly the kind of thing that benefits from a second pair of eyes before it reaches customers, and a YAML pull request is reviewable in a way a Studio session is not.
- You can promote a change. The same artifact moves scratch org → sandbox → production, instead of being rebuilt by hand at each stop with the transcription errors that implies.
- You can roll a change back. Because the previous version is a commit, not a memory.
None of that is exotic. It is the ordinary discipline that keeps a platform healthy, applied to a new kind of object. The reason it needs saying is that agents arrived through a point-and-click builder first, and a lot of teams are running production agents today with no version history at all, the agent equivalent of editing Apex directly in production.
The loop: spec, create, preview
Agentforce DX ships as a plugin to the Salesforce CLI. Install it into an existing DX project and you get a sf agent command group. The core authoring loop is three commands.
Generate a spec. You start from an agent spec, a YAML description of what the agent is for, which the platform uses to draft the agent’s subagents (formerly called topics; more on that naming below):
sf agent generate agent-spec \
--type customer \
--role "Answer billing and subscription questions and escalate anything that touches a refund" \
--company-name "Northwind Utilities" \
--company-desc "A regional energy provider serving residential customers" \
--max-topics 5 \
--output-file specs/agentSpec.yaml
That writes agentSpec.yaml into the specs/ directory of your project. The top of the file carries the agent’s properties (agentType, role, companyName, companyDescription, maxNumOfTopics, tone) and the bottom carries an LLM-drafted list of subagents, each with a description and sample utterances. This is a starting point, not a finished agent: you are expected to open the YAML and edit it: tighten a subagent’s scope, rewrite a fuzzy description, delete one the model invented that you do not want. The whole value is that this is now a text file you can shape by hand and check in.
Create the agent in an org. Once the spec reads the way you want, you materialize it:
sf agent create --spec specs/agentSpec.yaml --name "Billing Assistant" \
--target-org my-scratch
This builds the actual agent metadata in the target org from your spec. Now it exists as something Studio can open and something your project can track.
Preview before you commit to an org round-trip. The command that changes the day-to-day feel is sf agent preview, now generally available. It opens an interactive session in your terminal. You type utterances, the agent responds, and you watch which subagent it routed to and which actions it fired, without leaving VS Code and without clicking through the Studio conversation panel:
sf agent preview --api-name Billing_Assistant --target-org my-scratch
You can also script a preview end to end (start a session, send a sequence of messages, inspect, and end it) which is the seam where interactive iteration turns into the repeatable evaluation runs that belong in CI. That handoff from agent preview to agent test is deliberate, and it is where the testing-in-CI/CD discipline picks up: the same YAML-defined test specs (sf agent generate test-spec, sf agent test run) gate your deploys once the agent behaves.
What an agent is, in metadata
To move agents between orgs with confidence you have to know what they decompose into, because the CLI’s friendly YAML sits on top of a set of metadata types that have their own rules, and their own migration history.
The pieces:
BotandBotVersion: the agent itself and its versioned definition. Yes, the metadata still says “Bot”; agents inherited the plumbing that Einstein Bots ran on.GenAiPlannerBundle: the reasoning configuration: the container that ties the agent’s subagents and actions together for the planner. This type has a wrinkle that will bite you if you learned agents a year ago: the originalGenAiPlannertype existed in API versions 60 through 63, and from API 64.0 onward it is deprecated and replaced byGenAiPlannerBundle. Deploying against the wrong one is a common first-migration failure.GenAiPlugin, a subagent (topic): a category of related actions the agent can carry out. An agent has several.GenAiFunction, an action the agent can take.GenAiPromptTemplate, prompt templates the agent grounds on, where you use them.
All of these arrived starting in API version 60, so pin your project’s sourceApiVersion high enough to see them. And note the naming shift the ecosystem is still absorbing: as of April 2026 Salesforce renamed agent topics to subagents in the product surface, while the underlying metadata type stayed GenAiPlugin. So you will read “subagent” in current docs and the newer CLI output, “topic” in older material, and GenAiPlugin in the actual XML, three names, one concept. We wrote the design-level treatment of that layer in designing subagents and topics; here the point is just to recognize all three names refer to the same metadata.
Once you know the parts, deployment is ordinary source movement:
sf project deploy start \
--metadata Bot GenAiPlannerBundle GenAiPlugin GenAiFunction \
--target-org staging
The deployment dependency that trips the first migration
Here is the failure that shows up on nearly every first attempt to promote an agent, and it is worth internalizing before you burn an afternoon on it.
A subagent references actions, and those actions must exist in the destination org, or deploy in the same transaction. A GenAiPlugin (subagent) points at the GenAiFunction actions it can call. If you deploy the subagent to an org where those actions do not yet exist, the deploy fails on a dangling reference. The fix is to include the whole dependency set in one deployment, or to have deployed the actions first.
It goes deeper than the GenAI types, because agent actions are usually thin wrappers over real automation. An action that runs a Flow needs that Flow in the target org. An action backed by an Apex invocable needs the Apex class. An action that calls out through an API or MuleSoft needs the named credential and external service registered. The agent metadata is the top of a dependency tree, and a migration that ships only the top of the tree produces an agent that deploys and then does nothing, every action a dead reference.
Two practical guards:
- Deploy the substrate first, or together. Flows, Apex, prompt templates, named credentials, the things actions wrap, go before or alongside the agent, never after.
- Preview in the destination, not just the source. An agent that previews perfectly in your scratch org and fails in staging is almost always missing a dependency that happened to exist where you built it. Run
sf agent previewagainst the target after deploying, and route a few utterances through the actions specifically, before you call the migration done.
If you have wrestled with getting an agent from sandbox to production through the UI, this is the same dependency problem. Agentforce DX does not remove it, it just makes it a reviewable, repeatable, source-controlled version of it instead of a manual scavenger hunt.
Where the CLI does and does not replace the browser
Be clear-eyed about the boundary, because Agentforce DX is not a total replacement for Studio and pretending otherwise leads to frustration.
The CLI is where you want to be for the things code is good at: authoring and refining the spec, scripting previews, running evaluations, and, above all, moving agents through environments as reviewable metadata. Studio is still where the next-gen builder gives you a visual view of the reasoning, where business users can inspect an agent without reading YAML, and where some of the newest configuration surfaces land first. Real teams run both: build and iterate in whichever fits the task, but let the source of truth be the files in the repo, and treat any change made directly in a browser as something to pull back down into the project before it becomes the version nobody can reproduce.
There are rough edges. The sf agent generate agent-spec command has had reported cases of producing an empty subagents list depending on how the org and flags are set up, a reminder that the spec is a draft to inspect, not an oracle to trust blindly. And because this tooling is young and moving fast, pin your CLI plugin version in a project where a reproducible build matters.
The takeaways:
- Agentforce DX makes an agent source, a YAML spec plus metadata, so you can diff, review, promote, and roll it back like any other platform artifact.
- The core loop is
agent generate agent-spec→ edit the YAML →agent create→agent preview, withagent testgating deploys downstream. - Under the hood an agent is
Bot/BotVersion,GenAiPlannerBundle(which replacedGenAiPlannerat API 64),GenAiPluginsubagents, andGenAiFunctionactions: three names (“topic,” “subagent,”GenAiPlugin) for the same layer. - The first-migration killer is dependencies: a subagent’s actions, and the Flows/Apex/credentials those actions wrap, must exist in the destination or deploy with it. Preview against the target org, not just where you built it.
- Keep the repo as the source of truth even when you build in Studio, an agent with no version history is production debt waiting to happen. If you are standing up agents for the first time, our setup checklist covers the org-side groundwork this pipeline assumes.