Prompt engineering for LLMs: the basics that work with any model

A good prompt is not a spell but six concrete parts. We show them on one example where both the answer and the request price change.

5 min · · development · экономия

Prompt engineering for LLMs sounds grand, but at heart it is the skill of phrasing a task so the model does not have to guess. A bad answer is often explained not by a weak model but by an understated request: no format given, no context, no boundaries. Below are six parts of a good prompt, a before-and-after example and a calculation of how structure affects price. Prices are as of October 18, 2026.

What prompt engineering is and what it does not do

Prompt engineering is the design of a model's input text: instructions, data and examples. It needs no secret phrases. Spells like "you are the best expert in the world" without specifics add little, which is easy to check on your own tasks. What works is concrete: a clear goal, the necessary data, an understandable answer format.

It also does not replace verification. Even a perfect prompt does not guarantee correct facts, so answers must be checked. For more on the system part of a request, see the article How to write system prompts. The basics can be learned in an evening, but tuning a prompt to a specific model and task takes iteration.

Six parts of the structure

Not every part is needed in every prompt, but the checklist is handy to keep in view.

  1. Role. One line: who answers and for whom. "You are a support operator at an online store writing to customers." The role sets vocabulary and level of detail.
  2. Task. What exactly to do, with one verb. "Prepare a reply to the letter." One task per request; split a complex one into steps.
  3. Context. Facts the model does not have: company policy, order details, terminology. Everything needed for the answer must be in the request: the model does not know your internal rules.
  4. Format. Length, structure, language, form of address, JSON fields. "A letter up to 80 words, formal address, with the next step and deadline at the end."
  5. Examples. One to three samples of the desired result work better than long descriptions. More in the article on few-shot prompting.
  6. Constraints. What not to do: "do not promise what is not in the policy", "do not invent numbers and dates", "if data is missing, say exactly what".

A separate note on markup. Separate user data (a letter, a document, code) from instructions with delimiters, for example the tags <letter>...</letter>. That way the model does not take the letter text for instructions, and it is easier for you to insert data programmatically.

Example: a prompt before and after

A hypothetical store. A customer writes: "Order 4521 did not arrive, refund my money."

Version 1: a short request.

bash
Reply to the customer's letter: Order 4521 did not arrive, refund my money

The model has to guess. Most likely you will get a long letter with generic apologies, a promise to refund in an unknown time frame, a request to "clarify details", and possibly invented refund conditions.

Version 2: a structured request.

bash
Role: you are a support operator at an online store.
Task: prepare a reply to the customer's letter.
Context: we refund within 5 business days after non-delivery is confirmed.
Order 4521 was shipped on October 3, the tracking has not updated for 10 days.
Format: a letter up to 80 words, formal address, one apology, the next step
and a deadline at the end.
Constraints: do not promise anything that is not in the policy. Do not invent
numbers or dates. If data is missing, say exactly what.

<letter>
Order 4521 did not arrive, refund my money
</letter>

Now the model has facts, boundaries and a format. The answer becomes shorter, more predictable and ready to send after a quick check. Version 2 is convenient to keep as a template and fill in with the letter and facts in code.

What it looks like in code

Through the OpenAI format (pip install openai):

bash
from openai import OpenAI

client = OpenAI(base_url="https://api.zukko.pro/v1", api_key="fetch_your_key")

SYSTEM = """Role: you are a support operator at an online store.
Format: a letter up to 80 words, formal address, one apology, the next step and a deadline at the end.
Constraints: do not promise anything that is not in the policy. Do not invent numbers or dates.
If data is missing, say exactly what."""

def reply(letter, facts):
    user = f"Prepare a reply to the letter.\nContext: {facts}\n\n<letter>\n{letter}\n</letter>"
    r = client.chat.completions.create(
        model="gpt-6.1-sol",
        messages=[

In the Anthropic format the system instruction is passed as a separate system parameter (the address has no /v1):

bash
import anthropic

a = anthropic.Anthropic(base_url="https://api.zukko.pro", api_key="fetch_your_key")

m = a.messages.create(
    model="claude-sonnet-5-5",
    max_tokens=300,
    system=SYSTEM,
    messages=[{"role": "user", "content": "Prepare a reply to the letter.\n\n<letter>\nOrder 4521 did not arrive, refund my money\n</letter>"}],
)
print(m.content[0].text)

Note max_tokens=300: in the Anthropic format the parameter is required, and it also limits the answer length.

How structure affects price

Output tokens cost more than input tokens: for claude-sonnet-5-5 input is 0.4 and output is 2 dollars per 1M tokens, so output is five times more expensive. So extra words in the answer cost more than extra words in the request.

Assumptions for the calculation (not measurements, a rough guide): version 1 has 30 request tokens and 600 answer tokens; version 2 has 300 request tokens and 150 answer tokens.

  • Version 1: 30 × 0.4 / 1M + 600 × 2 / 1M = 0.000012 + 0.0012 = $0.001212.
  • Version 2: 300 × 0.4 / 1M + 150 × 2 / 1M = 0.00012 + 0.0003 = $0.00042.

For 10,000 letters: version 1 gives 10,000 × 0.001212 = $12.12, version 2 gives 10,000 × 0.00042 = $4.20. The request became ten times longer, yet the cost is lower, because the answer got shorter. Your real numbers will differ, so measure the usage field on your own data. If the system part is long and does not change, put it at the start of the request so the cache can work (see how cache reads and writes are billed). Check current prices in GET https://api.zukko.pro/v1/models.

Iterating and verifying

A prompt rarely works on the first try. A working cycle:

  1. Collect 10–20 real example inputs, including awkward ones.
  2. Run the prompt on all of them at once and read the answers in full.
  3. Change one thing at a time and compare. If you change three parameters at once, you will not know what helped.
  4. Lock in checks in code: length, required words, valid JSON.
  5. After switching models, rerun the set: the same prompt may behave differently.

How to automate such a run is shown in the article How to test prompts. You can start by creating a key in the dashboard; payment from Russia is by SBP (the payment page adds an 8.5% fee on top), a MasterCard or cryptocurrency.

FAQ

What is prompt engineering in simple terms?

It is the skill of composing a request so that the model gets the goal, the necessary data and the requirements for the answer, and does not have to guess. The basis is structure: role, task, context, format, examples and constraints.

Do prompts have to be long?

Not necessarily long, but specific enough. Extra words hurt as much as missing facts. A guide: the request contains everything needed for the answer and nothing that does not affect the result.

Will one prompt fit all models?

The basic principles are shared, but models behave differently, and exact wording is best tested on the chosen model. After switching models, rerun your examples.

How do I cut token spending on prompts?

Ask for a specific format and answer length, limit max_tokens, do not repeat long context needlessly, and put the unchanging part at the start of the request so the cache works.

zukko

Pay 25×
less

for Claude Code & ChatGPT

One fetch_* key and base URL api.zukko.pro — for Cursor, Claude Code, Codex, and any SDK.

Get API keyDocumentation

api.zukko.pro · fetch_*

Prompt engineering for LLMs: basics and examples · Zukko