Prompts: Guiding AI generation with text
How positive and negative prompts steer generation, what each modality expects you to describe, and the techniques that hold across models.
Introduction
Prompts are the primary interface between you and the model. The positivePrompt parameter defines what you want to get back, while the optional negativePrompt defines what you want to avoid. Together, they steer the generation process at every step.
Behind the scenes, prompts are processed by a text encoder that converts natural language into numerical representations called embeddings. These embeddings capture semantic meaning and stylistic cues, guiding the model toward (or away from) the concepts you named.
This is one of the few parameters that works the same way across modalities. Image, video, audio and 3D models all take a positivePrompt, and the techniques below hold for all of them.
Positive prompts
The positivePrompt is the only required text parameter. It describes the content, style, composition, and mood you want the model to produce.

An astronaut floating inside a giant hourglass

An astronaut floating inside a giant hourglass in space, surrounded by stars and glowing dust, with galaxies swirling faintly above and golden sand below. Dreamy, surreal, cinematic
A few things affect how your prompt is interpreted:
- Term position matters most on CLIP-based models. CLIP reads a short window and the earliest tokens carry the most weight, so on the SD families you lead with the subject and key attributes and add style afterwards. An architecture built on T5 reads the prompt as a sentence, and the same reordering moves the result far less.
- Specificity drives quality. Vague prompts ("a nice picture") give the model too much freedom. Concrete nouns, adjectives, and spatial relationships ("a red car parked under a cherry blossom tree at sunset") produce more predictable results.
- Style and medium terms work. Terms like "oil painting", "cinematic lighting", "8k", "watercolor", or "low-poly 3D" effectively shift the aesthetic because models have learned strong associations between these terms and their visual representations.
What a prompt describes
The parameter is identical everywhere, but what belongs inside it changes with the output. A prompt written for a still frame underspecifies a clip, and a prompt written for a clip confuses a model that only returns an object.
| Output | What the prompt describes |
|---|---|
| Image | The subject, the composition, and the style of a single frame |
| Video | All of the above, plus what moves and how the camera behaves over the shot |
| Audio | Genre, instrumentation and mood, and for speech the words to be spoken |
| 3D | The object by itself, with no scene, lighting or camera around it |
The same request shape carries across all of them:
import { createClient } from '@runware/sdk'
const client = await createClient({ apiKey: process.env.RUNWARE_API_KEY })
await client.connect()
const [result] = await client.run({
model: '<image-model-air>',
positivePrompt: 'A professional headshot of a woman in a modern office',
width: 1024,
height: 1024,
steps: 30
})import asyncio
import os
from runware import Runware
async def main():
async with Runware(api_key=os.environ["RUNWARE_API_KEY"]) as client:
results = await client.run({
"model": "<image-model-air>",
"positivePrompt": "A professional headshot of a woman in a modern office",
"width": 1024,
"height": 1024,
"steps": 30
})
asyncio.run(main())curl https://api.runware.ai/v1 \
-H "Authorization: Bearer $RUNWARE_API_KEY" \
-H "Content-Type: application/json" \
-d '[
{
"taskType": "imageInference",
"taskUUID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"model": "<image-model-air>",
"positivePrompt": "A professional headshot of a woman in a modern office",
"width": 1024,
"height": 1024,
"steps": 30
}
]'runware run "<image-model-air>" \
positivePrompt="A professional headshot of a woman in a modern office" \
width=1024 \
height=1024 \
steps=30{
"taskType": "imageInference",
"taskUUID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"model": "<image-model-air>",
"positivePrompt": "A professional headshot of a woman in a modern office",
"width": 1024,
"height": 1024,
"steps": 30
}import { createClient } from '@runware/sdk'
const client = await createClient({ apiKey: process.env.RUNWARE_API_KEY })
await client.connect()
const [result] = await client.run({
model: '<video-model-air>',
positivePrompt: 'A pair of running shoes rotating slowly on a white studio turntable, the camera holds steady',
width: 1920,
height: 1080,
duration: 6
})import asyncio
import os
from runware import Runware
async def main():
async with Runware(api_key=os.environ["RUNWARE_API_KEY"]) as client:
results = await client.run({
"model": "<video-model-air>",
"positivePrompt": "A pair of running shoes rotating slowly on a white studio turntable, the camera holds steady",
"width": 1920,
"height": 1080,
"duration": 6
})
asyncio.run(main())curl https://api.runware.ai/v1 \
-H "Authorization: Bearer $RUNWARE_API_KEY" \
-H "Content-Type: application/json" \
-d '[
{
"taskType": "videoInference",
"taskUUID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"model": "<video-model-air>",
"positivePrompt": "A pair of running shoes rotating slowly on a white studio turntable, the camera holds steady",
"width": 1920,
"height": 1080,
"duration": 6
}
]'runware run "<video-model-air>" \
positivePrompt="A pair of running shoes rotating slowly on a white studio turntable, the camera holds steady" \
width=1920 \
height=1080 \
duration=6{
"taskType": "videoInference",
"taskUUID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"model": "<video-model-air>",
"positivePrompt": "A pair of running shoes rotating slowly on a white studio turntable, the camera holds steady",
"width": 1920,
"height": 1080,
"duration": 6
}import { createClient } from '@runware/sdk'
const client = await createClient({ apiKey: process.env.RUNWARE_API_KEY })
await client.connect()
const [result] = await client.run({
model: '<3d-model-air>',
positivePrompt: 'A matte black portable speaker with a fabric grille and a leather carry strap'
})import asyncio
import os
from runware import Runware
async def main():
async with Runware(api_key=os.environ["RUNWARE_API_KEY"]) as client:
results = await client.run({
"model": "<3d-model-air>",
"positivePrompt": "A matte black portable speaker with a fabric grille and a leather carry strap"
})
asyncio.run(main())curl https://api.runware.ai/v1 \
-H "Authorization: Bearer $RUNWARE_API_KEY" \
-H "Content-Type: application/json" \
-d '[
{
"taskType": "3dInference",
"taskUUID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"model": "<3d-model-air>",
"positivePrompt": "A matte black portable speaker with a fabric grille and a leather carry strap"
}
]'runware run "<3d-model-air>" \
positivePrompt="A matte black portable speaker with a fabric grille and a leather carry strap"{
"taskType": "3dInference",
"taskUUID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"model": "<3d-model-air>",
"positivePrompt": "A matte black portable speaker with a fabric grille and a leather carry strap"
}Note what moved between the three. The image prompt fixes a composition, the video prompt adds the turntable motion and pins the camera down, and the 3D prompt drops the scene entirely and describes materials instead.
Negative prompts
The negativePrompt parameter specifies what the model should steer away from. It works through the same embedding process as the positive prompt but exerts an opposing influence during generation.
Negative prompts are effective for:
- Removing common artifacts: "blurry, distorted, deformed hands, extra fingers, watermark"
- Excluding unwanted styles: "cartoon, anime, sketch, painting" when you want photorealism
- Avoiding specific elements: "text, logo, frame, border" for clean outputs
import { createClient } from '@runware/sdk'
const client = await createClient({ apiKey: process.env.RUNWARE_API_KEY })
await client.connect()
const [result] = await client.run({
model: '<model-air>',
positivePrompt: 'A professional headshot of a woman in a modern office',
negativePrompt: 'blurry, distorted, extra fingers, watermark, text',
width: 1024,
height: 1024,
steps: 30
})import asyncio
import os
from runware import Runware
async def main():
async with Runware(api_key=os.environ["RUNWARE_API_KEY"]) as client:
results = await client.run({
"model": "<model-air>",
"positivePrompt": "A professional headshot of a woman in a modern office",
"negativePrompt": "blurry, distorted, extra fingers, watermark, text",
"width": 1024,
"height": 1024,
"steps": 30
})
asyncio.run(main())curl https://api.runware.ai/v1 \
-H "Authorization: Bearer $RUNWARE_API_KEY" \
-H "Content-Type: application/json" \
-d '[
{
"taskType": "imageInference",
"taskUUID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"model": "<model-air>",
"positivePrompt": "A professional headshot of a woman in a modern office",
"negativePrompt": "blurry, distorted, extra fingers, watermark, text",
"width": 1024,
"height": 1024,
"steps": 30
}
]'runware run "<model-air>" \
positivePrompt="A professional headshot of a woman in a modern office" \
negativePrompt="blurry, distorted, extra fingers, watermark, text" \
width=1024 \
height=1024 \
steps=30{
"taskType": "imageInference",
"taskUUID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"model": "<model-air>",
"positivePrompt": "A professional headshot of a woman in a modern office",
"negativePrompt": "blurry, distorted, extra fingers, watermark, text",
"width": 1024,
"height": 1024,
"steps": 30
}Not all models support negative prompts. Guidance-distilled models like FLUX use a single-pass inference process that embeds guidance directly into the model weights. Without a separate unconditional prediction to contrast against, the negative prompt has nothing to work against. When using these models, the negativePrompt parameter is accepted by the API but will have no effect on the output. Support is also thinner outside image generation, so check the model's API reference before relying on it.
Tips
- Front-load the important stuff. Put your subject and key attributes at the beginning of the prompt. Style and atmosphere terms can come later.
- Be specific, not verbose. "A red 1967 Mustang on a coastal road at golden hour" outperforms "A really beautiful amazing car driving on a nice road with great lighting." Concrete beats adjective stacking.
- Use negative prompts for quality control. A standard negative prompt like "blurry, distorted, low quality, watermark" acts as a quality floor across any positive prompt you write. Keep a reusable one for your projects.
- Describe motion when the output moves. A video model given a still-frame description will pick its own camera move and its own pace. Say what moves and what holds still, and you get the shot you asked for.
- Iterate on terms, not sentences. When a prompt doesn't produce what you want, swap individual terms rather than rewriting everything. Change "sunset" to "golden hour" or "cinematic" to "dramatic" to isolate what's driving the output.