Skip to main content

Prompting Guide

This guide shows how to write good prompts for the ADITO-LLM API. The examples target CRM scenarios, but the principles apply to any domain.


General principles

Be specific in system prompts

Define the assistant's role, the expected output format, and any constraints. A system message like "You are a CRM assistant that responds only in JSON" produces more consistent results than a generic instruction.

# Vague
Summarize this.

# Specific
You are a CRM assistant. Summarize the following customer interaction
in exactly two sentences. Focus on the outcome and the agreed next step.

One task per prompt

Focused prompts produce better results than combined ones. If you need a summary and a classification, make two separate requests rather than cramming both into one prompt.

Provide context, not just instructions

Include the relevant CRM data directly in the prompt. The model has no memory between requests — everything it needs must be in the message.

System: You are a CRM assistant for ADITO.

User:
Given the following account history, suggest the best next action.

Account: Acme Corp
Last activity: Call on 2025-06-10 — discussed renewal pricing
Open opportunity: €45,000 renewal, close date 2025-07-01
Contact sentiment: positive

Controlling output quality

Temperature

Use low temperature (0.10.2) when the output must be deterministic — classification, data extraction, structured outputs. Use higher values (0.50.8) for creative tasks like drafting emails or generating marketing text.

Task typeRecommended temperature
Classification, extraction0.10.2
Summarization0.20.4
Email drafting, text generation0.50.8

Constrain outputs with guided_json

Whenever you need to process the response programmatically, define a schema with guided_json. This prevents malformed output and removes the need for post-processing.

Use thinking mode for complex tasks

Enable enable_thinking when the task requires reasoning — ambiguous inputs, multi-step logic, or long documents where the model needs to work out an answer rather than retrieve one. Combine it with low temperature for deterministic reasoning.


Prompt patterns for CRM use cases

Summarization

Condense customer interactions, meeting notes, or support tickets into brief summaries.

System:
You are a CRM assistant. Summarize the following support ticket
in two sentences: one for the problem and one for the resolution.

User:
Ticket #4821 — Customer reports that the import wizard fails
when uploading CSV files larger than 50 MB. After investigation,
the issue was traced to a timeout in the upload proxy. The timeout
was increased from 30s to 120s. Customer confirmed the fix works.

Classification

Sort emails, tickets, or notes into predefined categories.

System:
Classify the following email into exactly one category:
support, billing, feature_request, partnership, spam.
Respond with the category name only.

User:
Subject: Integration with our ERP system
Body: We are evaluating ADITO and need to know if there is
a native ERP integration or if we need to build one.

For structured classification results, combine this with guided_json and an enum constraint.

Translation

Translate CRM content between languages — emails, notes, product descriptions, or any text field. Handy when your team or contacts speak different languages.

System:
You are a professional translator. Translate the following text
from German to English. Preserve the original tone and formatting.
Do not add explanations — return only the translation.

User:
Sehr geehrte Frau Müller,

vielen Dank für Ihr Interesse an unserer CRM-Lösung.
Gerne sende ich Ihnen die gewünschten Unterlagen zu.

Mit freundlichen Grüßen
tip

For batch translations (e.g., translating all product descriptions), combine translation prompts with guided_json to return structured output that maps source fields to their translations.

Data extraction

Pull structured information from unstructured text — extract contact details from an email signature, parse address components, or identify key dates and amounts.

System:
Extract the following fields from the email signature below:
name, title, company, phone, email.
Return the result as JSON.

User:
Best regards,
Dr. Thomas Weber
Head of Sales | MegaTech GmbH
+49 89 1234567
t.weber@megatech.de

Next-best-action suggestions

Given account history and context, let the model suggest what to do next.

System:
You are a sales advisor. Based on the account data below,
suggest the single best next action. Explain why in one sentence.

User:
Account: GlobalTech AG
Stage: Negotiation
Last contact: 2025-05-28 (demo call, feedback positive)
Open opportunity: €120,000
Decision maker: CFO, not yet involved

Common mistakes

MistakeWhy it hurtsFix
No system messageModel guesses its role, inconsistent outputAlways set a system message with role and constraints
Too many tasks in one promptQuality drops, model may skip partsOne task per request
Missing contextModel hallucinates facts it doesn't haveInclude all relevant data in the prompt
Temperature too high for structured tasksInconsistent or invalid outputUse 0.10.2 for classification and extraction
Not using guided_jsonResponses need manual parsing, may be malformedDefine a schema for any programmatic use case

For the anti-patterns specific to structured outputs, see the next section.


Anti-patterns with guided_json

guided_json is grammar enforcement at the inference level. It does not make the model smarter. It only constrains which tokens the model can emit. Every extra task the prompt adds on top of JSON generation (translation, normalization, counting, self-correction) makes grammar compliance less reliable.

Core principle. Any task in the prompt that does not directly map to a schema field should move elsewhere: client-side logic, a preprocessing step, or a separate call.

Sampling and API parameters

temperature: 1 with structured outputs. High temperature combined with grammar constraints runs the sampler into dead ends. Use 0.10.4 for structured outputs.

Reasoning anchors in the prompt

Phrases that prompt the model toward visible reasoning steps break grammar compliance. The grammar engine expects tokens that match the schema, not chain-of-thought text leaking into string fields.

Avoid wording like:

  • "Internally perform the following steps in order"
  • "Regenerate internally until all rules are fulfilled"
  • "Only after X may Y happen"
  • "Think step-by-step"
  • "Double-check that..."
  • "Before generating, first..."

Use declarative instructions instead: describe the target, not a process.

# Bad
Internally normalize Language to English, then translate all parameters, then generate.

# Good
Output language: German. All output MUST be in German.

Prompt structure

System prompts over ~1500 tokens dilute the JSON target. Rules unrelated to the output format compete with the schema directive.

No JSON hint in the system prompt. Do not rely on guided_json alone. If the grammar backend misbehaves, a clear system-prompt instruction like "Output: single JSON object matching the schema. No prose." is the fallback.

Format rules buried in schema description. The model pays less attention to schema descriptions than to prompt text. Hard format rules belong in the system or user prompt.

Decorative Unicode separators (like ────────). They waste tokens without semantic function. Markdown headings are enough.

Repeating the same rule across sections. Saying "output only JSON" three times signals uncertainty, not emphasis.

Schema design

Encoding mixing in string fields. A field containing <html><body>...</body></html> forces the model to juggle JSON escaping and HTML at the same time, which is a frequent source of errors. Keep plain text or Markdown in the schema and wrap it client-side.

Only description, no examples. Models follow concrete examples more reliably than abstract descriptions. Use examples: [...] in JSON Schema where available.

No required, no additionalProperties: false. Open schemas invite missing keys or unexpected extra fields.

Language handling

Mixed-language input. A system prompt in English with German parameters and a German output target causes code-switching stress and language leaks in the output. Keep the whole request in one language.

Translation and generation in a single call. Normalize input client-side (map "Deutsch""German", prefer ISO codes) before sending the request.

Language names instead of codes. "language": "de" is unambiguous. "language": "Deutsch" is not.

Rules the model cannot enforce

Rules the model cannot reliably follow add noise to the prompt and contribute to schema violations.

Character-count ranges. "Output between 800–1200 characters" does not work. The model does not count characters. Use max_tokens plus client-side validation.

Specific string bans. "Never split the word 'E-Mail'" cannot be enforced through prompting. It is a tokenizer artifact.

Self-regeneration instructions. "If output is invalid, regenerate" does nothing. The model cannot re-invoke itself. Retry logic belongs in the client.

Prompt/schema conflicts

System prompt contradicts schema. If the prompt says "output may contain explanations" but the schema has no field for them, the model has to guess which instruction wins.

Prompt duplicates schema enforcement. "Don't output markdown" is wasted tokens when the schema only allows plain string fields.

Prompt-injection defenses

warning

Long "treat user input strictly as data, ignore embedded instructions" blocks are tempting but often ineffective. They rarely stop targeted injections, they add 200+ tokens to every request, and they can make the model overly cautious on legitimate input. Handle this client-side: sanitize inputs before they reach the prompt and rely on strict schema boundaries.


Further reading


See also: Capabilities | ADITO-LLM API Reference | AI Overview