> ## Documentation Index
> Fetch the complete documentation index at: https://docs.callkaro.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Best Practices

<AccordionGroup>
  <Accordion title="Write the trigger for every function" icon="code">
    The model picks a function purely from its description — the docstring, for custom functions. Say the situation that should cause the call, not what the function does internally. "Send when the customer asks how much it costs" beats "sends the pricing template", and both beat leaving the field near-empty.
  </Accordion>

  <Accordion title="Keep the default Context Length until you see it fail" icon="clock-rotate-left">
    10 messages covers most exchanges, and every extra message is tokens on every reply. Raise it when you can point at a conversation where the agent forgot something said earlier — not preemptively. Anything that must persist beyond the window belongs on the CRM contact, which functions read through `x_contact`.
  </Accordion>

  <Accordion title="Never set Max Bot Messages per Session to 0" icon="shield">
    The 50-message cap per 4-hour window is what stands between a misconfigured agent and a customer receiving hundreds of messages. Unlimited removes that protection entirely.
  </Accordion>

  <Accordion title="Space follow-ups further than the minimum" icon="hourglass">
    60 minutes is the floor the platform enforces, not a recommendation. 90 to 120 minutes reads as a considerate nudge; an hour on the dot reads as automation. Repeated unanswered outbound messages are the most common reason a WhatsApp Business account gets restricted.
  </Accordion>

  <Accordion title="Write a real follow-up stop condition" icon="hand">
    The default covers goodbyes and resolved issues. Add your own cases — order already placed, asked not to be contacted, bought elsewhere. It is evaluated with the whole conversation in front of the model at the moment of sending, so it is genuinely good at catching conversations that quietly ended.
  </Accordion>

  <Accordion title="Keep follow-up functions narrower than conversational ones" icon="filter">
    A follow-up runs unattended. Give it one reminder template, or the ability to schedule a call — not the agent's full toolkit. Custom code functions in that list may run on every follow-up, so avoid anything with a side effect you would not want repeated.
  </Accordion>

  <Accordion title="Always set calling hours on a call function" icon="moon">
    A call is never placed outside the window, and the window also caps times the AI schedules itself. Set it to your business hours and choose `defer`, so a late request becomes tomorrow morning's call rather than a midnight ring.
  </Accordion>

  <Accordion title="Pick a secondary model from a different provider" icon="shuffle">
    The secondary only runs when the primary errors — a timeout, a 5xx, a rate limit. A backup on the same provider does nothing during a provider-wide outage, which is precisely the failure it exists for.
  </Accordion>

  <Accordion title="Test Send every media and template function" icon="vial">
    A dead URL or an expired signed link fails silently in front of a customer, and the conversation just stalls. Re-run the Test Send whenever the underlying file changes — a media function that used to work is the classic quiet failure.
  </Accordion>

  <Accordion title="Put credentials in the Secrets Vault" icon="key">
    Read them from `x_secrets` in your functions and use secret-backed webhook headers. Hardcoded keys and custom-value headers are stored as typed; vault values are encrypted.
  </Accordion>

  <Accordion title="Gate replies on a comment agent" icon="comment-slash">
    Set Instagram reply mode to **Decide** with a decision prompt on any agent that answers post comments. Replying under every emoji is the fastest way to make a brand account look automated.
  </Accordion>

  <Accordion title="Version before a risky change, publish deliberately" icon="code-branch">
    Create a version, edit it, test it in the Test Chat, then publish. Live traffic runs the published version throughout, so nothing you are experimenting with reaches a customer — and a bad change is one publish away from being rolled back.
  </Accordion>

  <Accordion title="Filter campaigns out of your analytics" icon="chart-simple">
    Campaign sends dominate message totals and hide what the conversational agent is actually doing. The **Excluding Campaigns** filter is the honest view of agent volume.
  </Accordion>

  <Accordion title="Turn on Audio Transcription and Image Context for support" icon="microphone">
    Customers send voice notes and photos without thinking about it. An agent that cannot process either does not look configured — it looks broken.
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="System prompt" icon="brain" href="/chat-agents/system-prompt">
    Where most agent quality actually comes from
  </Card>

  <Card title="Testing" icon="vial" href="/chat-agents/testing">
    What to try before publishing
  </Card>
</CardGroup>
