Skip to main content

Agentforce: How the Prompt Gets Built

💬 In plain words: Your instructions are not sent to the model. They are executed to produce a prompt, which is then sent. Everything your logic decided is already fixed by the time the model reads a single word.
📌 Example: By the time the model is asked, the outage status has been fetched, stored in a variable, checked, and turned into the sentence "Tell the customer power is expected back within two hours." The model cannot reopen that decision.

🎬 Real-Life Example: The Restore Time That Was Never Promised

The Old/Bad Way: A team wrote: "If the outage is major, tell the customer a restore estimate, but only if it is confirmed." The agent regularly promised times that were not confirmed.

Why this fails: That is one English sentence asking the model to make a judgement call. The model weighed it against everything else in the prompt and sometimes got it wrong. Nothing was ever fixed before it was asked.

The New/Good Way:

  1. Run an action that returns confirmed true or false, plus the estimate.
  2. Store both in variables.
  3. Branch on the boolean.
  4. The true branch includes a sentence containing the estimate. The false branch includes a sentence saying no estimate is available.

The payoff: The model can no longer promise an unconfirmed time, because the prompt it receives does not contain one.

Concept

  • Prompt building is a sequence, and Salesforce documents it step by step.
  • The prompt starts empty.
  • Each logic line executes in order — increment a counter, run an action, set a variable, evaluate a condition.
  • Each prompt line appends English text to the prompt being built.
  • Conditional lines decide whether the prompt text under them is included at all.
  • Only when the whole list has resolved is the prompt sent to the model.
  • So a decision made at line three cannot be altered by anything the model does at line eleven.
  • This is precisely why Agentforce can be trusted with eligibility and money.
prompt = ""
  ├─ run @actions.get_outage_status
  ├─ set @variables.is_confirmed = @outputs.confirmed
  ├─ append: 'Tell the customer the outage is being worked on.'
  ├─ if is_confirmed == True
  │    └─ append: 'Give the estimate: {[email protected]}'
  └─ if is_confirmed == False
       └─ append: 'Say no estimate is available yet.'
→ send prompt to LLM
🧠 Judge and clerk: Your logic is the judge and reaches the verdict. The model is the clerk and reads it out. The clerk cannot overturn the verdict.

🧭 360 Card — How the Prompt Gets Built

  • Rule: Decide in logic, explain in language. Anything that must be certain is settled before the prompt is sent.
  • Gain: The model cannot contradict a decision it never participated in.
  • Price: More logic lines to write and maintain than a single paragraph of instructions.
  • Limits: Logic lines still obey Apex and action limits, including the 60-second timeout.
  • Mirror — one long instruction paragraph: Faster to write, but fails unpredictably under pressure from a determined user.
  • Later: This is the foundation of every guardrail and test assertion in upcoming posts.
  • At volume: Fewer, sharper prompt lines mean shorter prompts, lower cost, and faster replies.
⚠ INTERVIEW TRAP: Do not describe instructions as "what we tell the model". Half of them never reach the model at all. Saying so shows you understand resolution—and almost nobody does.

Core Q&A

Q: How do you stop an agent from inventing a warranty or eligibility answer?

🎯 Say this first: Run an action, store the result in a variable, and branch on it. The model only phrases an outcome that was already decided.

A: Make the decision before the model is involved.

  • I call an action that returns a decided value — covered true or false, plus a plain-language reason.
  • I store both in variables.
  • Then I branch. Each branch appends different prompt text, but the verdict itself is already fixed.
  • The model receives finished English and its only job is to phrase it kindly.
  • The reason string matters here too. Without it, the model invents its own justification for a decision it did not make.
  • The test is simple: ask the same question ten times and the verdict must be identical every time.

Follow-ups (Scenario-based)

Q1: The same question gives slightly different wording each time. Is that a bug?

A1: Not in itself. Wording variation is expected and both answers can be correct.

  • What must never vary is the decided value — the verdict, the number, the eligibility.
  • If those vary, the decision is still inside the model and needs moving into logic.
  • This is exactly why test frameworks check routing, actions, and decided values rather than exact strings.
  • Common mistake: Trying to force identical wording with more instructions. That fights the tool.

Q2: Where would you put a check that must run no matter what the model says?

A2: after_reasoning, because it runs on every request once reasoning completes.

  • It holds logic only — no prompt text — so it is a genuine control rather than a request.
  • One caveat: If the subagent transitioned away partway through, its after_reasoning never runs.
  • For anything critical, put the guard where it will actually execute, or in the subagent you transition to.