Prompt engineering
A prompt tells an AI agent who it is, what it needs to accomplish, and how to handle the conversation. The most effective prompts give the model the context only your application can provide, then leave exact data and hard rules to your code.
Start with the smallest prompt that handles the common case. Add instructions when testing reveals a specific gap, and remove instructions that don’t change the agent’s behavior.
Prompt surfaces
SignalWire AI Agents accept instructions in five places. Put each instruction as close as possible to the behavior it controls.
The main prompt, context steps, functions, and conscience affect the live conversation. The post-prompt runs after the conversation and cannot change how the agent responds during the call.
Main prompt
The main prompt provides shared context for the complete conversation. Organize it so the agent can distinguish its objective, facts, process, and speaking style. A useful starting structure is:
- Role and objective: who the agent represents, what it does, and what completes the interaction
- Stable knowledge: terminology, available services, and information required to complete a task
- Task structure: the expected flow, written as outcomes rather than a script for every sentence
- Response guidelines: the tone, response length, and application-specific formatting rules
Keep stage-specific directions in context steps, function selection details in SWAIG function descriptions, global standards in the conscience, and after-call extraction in the post-prompt.
Context steps
Use context steps when a conversation has distinct stages. Each step can define:
text: what the agent should accomplish and how it should behave in that stagestep_criteria: the condition that completes the stagefunctions: the functions available during the stagevalid_steps: the stages the agent may enter next
For example, expose get_quote only in the quote step. This prevents the agent from quoting before
it confirms the trip instead of relying on a sentence that asks it not to.
SWAIG functions
A function definition is also a prompt. Give each function a descriptive name, state when to call it, and describe each parameter precisely.
Prefer get_quote with the description “Price a trip after the caller confirms both addresses” over
function_1 with the description “Check price.” Parameter descriptions should also define the
expected value, such as an address in the caller’s words or one of the supported vehicle types.
Return enough information for the agent to respond without guessing. A quoting function might
return the fare, distance, and a caller-facing explanation when it rejects a trip. A response such
as ok leaves the agent to invent the missing details.
Conscience
Use the conscience for a small set of standards that apply throughout the conversation, including after function calls. Write the behavior you want rather than a long list of prohibitions.
For example: “Say what you know, be clear about what you don’t know, and offer to find help instead of filling gaps. Collect only the information needed to serve the caller.”
Exact outcomes still belong in code. A conscience can tell the agent to respect a pricing policy; only the quoting function can enforce that policy on every call.
Post-prompt
Use the post-prompt to summarize the completed conversation or extract structured data for another system. Name the required fields, allowed values, and output format.
For example, ask for a JSON object containing the final confirmed pickup address, destination, and
an outcome limited to quoted, declined, or unavailable.
Write focused instructions
Use clear, specific language and consistent headings. Tell the agent what a successful interaction looks like, then give it enough flexibility to handle interruptions, corrections, and information provided out of order.
Describe the behavior you want instead of trying to anticipate every failure. “Transfer fare disputes to a dispatcher” gives the agent a clear action. “Don’t mishandle disputes” does not.
Avoid overprompting
Models already understand grammar, common conversational patterns, and how to structure a sentence. Use prompt space for your application’s vocabulary, workflow, boundaries, and required response format.
Don’t embed large catalogs, rate tables, policies, or facts that change. They make the prompt harder to maintain and can still leave the model to calculate or choose an answer. Retrieve that data with a tool call, then have the agent relay the result.
The complete example applies these principles without putting fare data in the prompt.
Complete example
The two implementations below create the same fare-quote agent. The Server SDK example is first and
runs its lookup in Python. The SDK generates a function webhook URL that routes calls to the
get_quote handler. In the SWML example, replace the placeholder web_hook_url with an endpoint
that performs the same lookup.
Both versions include a main prompt, context steps, a get_quote function, a conscience, and a
post-prompt. The small route table stands in for your dispatch system; replace it with your own
current data source in production.
Put guardrails in the right layer
A prompt requests behavior; code enforces it. Use these options in order:
- Define success. A clear objective handles many boundaries without extra prohibitions.
- Enforce exact rules in code. Use functions for prices, discounts, eligibility, permissions, current data, and other outcomes that must be correct.
- Remove unavailable actions. Limit functions and transitions with context steps so the agent cannot take an action at the wrong stage.
- Apply global standards through the conscience. Reserve it for a short set of behavioral, safety, compliance, or brand standards that code cannot express.
- Add a prompt rule when needed. Make it specific and describe the desired response. “Transfer fare disputes to a dispatcher” gives the agent an action; “don’t mishandle disputes” does not.
Test and refine
Treat the first prompt as a draft. Test it against representative conversations, revise one behavior at a time, and keep the prompt under version control with its test cases.
Test the common path first, then cover:
- interruptions, corrections, and information provided out of order
- missing, ambiguous, or unsupported requests
- attempts to override the agent’s instructions
- function failures and handoffs
- boundaries where the agent should say it doesn’t know
When a test fails, identify the right layer before adding prompt text. Fix incorrect data or hard rules in code, function timing in context steps, function selection in its description, and global behavior in the conscience.
Trim after each successful revision. Remove one line, rerun the same tests, and keep the deletion if behavior stays the same. This prevents duplicated rules and general knowledge from hiding the instructions specific to your application.