system message, treat user messages as the inputs, be explicit about the output you want, and cap generation with max_completion_tokens.
System message = the function, user message = the arguments
Think of thesystem (or developer) message like a function definition: it fixes the model’s identity, rules, and output contract for every call. The user messages are the arguments: the concrete inputs for this invocation. Keep the two separated — rules do not belong in user turns, and per-request data does not belong in the system message.
The API is stateless: BRAHMA remembers nothing between requests. Resend the system message (and any needed history) on every turn. If you omit the system/developer message entirely, BRAHMA’s default system prompt applies instead.
Order the system message: identity → instructions → examples → context
A layout that consistently works:- Identity — who the model is and on whose behalf it speaks.
- Instructions — rules of behavior, tone, and the output contract.
- Examples — one or two short, ideal input/output pairs.
- Context — reference material (policy snippets, product data) the model should use.
Use delimiters for anything that is not an instruction
Wrap inputs, documents, and examples in clear delimiters — Markdown fences or XML-style tags both work — so the model never confuses data with instructions:Say what TO do, not what to avoid
Negative instructions (“don’t be verbose”, “never mention competitors”) steer weakly. State the desired behavior positively: “Answer in at most 3 sentences.” / “If asked about other vendors, redirect to PeachDesk’s own capabilities.”Prefer structured outputs over prose format instructions
If a machine reads the answer, do not ask for a format in prose (“reply as JSON with keys…”) — use structured outputs. Grammar-constrained decoding guarantees the shape; prompt-level format asks do not. Reserve prose format instructions for human-readable structure (“use a numbered list”).Few-shot examples go in user/assistant turns
For classification and extraction, show the pattern as example turns (or delimited examples inside the user message) rather than describing it abstractly:Ask for step-by-step reasoning on hard problems
For multi-step reasoning (calculations, policy decisions, debugging), instruct the model to work through the problem before answering: “Think through the policy step by step, then give the final decision on the last line prefixed withDECISION:.” Anchoring the final answer to a marker keeps it easy to parse. For simple lookups and classification, skip this — it adds tokens and latency for no gain.
Give the model an out
To reduce hallucination, always define the escape hatch: “If the context does not contain the answer, reply exactlyI don't have that information — do not guess.” Without an explicit out, the model will prefer a fluent wrong answer over admitting uncertainty.
Multi-turn conversations
Send the full history each time — system message first, then alternating turns, newest last:tool_calls turn and its role: "tool" result adjacent in history (see Function calling).
Latency checklist
- Set
max_completion_tokenson every request — it bounds worst-case generation time. - Ask for the shortest output that serves the purpose (labels, not paragraphs).
- Use
stream: truefor user-facing chat so first tokens render immediately. - Keep system prompts tight; move rarely-needed reference material out of the prompt.

