---
title: Messages
description: Learn how to construct messages for LLM communication using Mirascope's message system.
---

# Messages

Messages are the fundamental building blocks of LLM interactions. You provide context to the LLM via messages, and it responds by generating messages of its own.

<CodeExample file="python/examples/messages/basic.py" />

Each message has a `role` (system, user, or assistant) and `content`. Mirascope provides shorthand functions for creating messages: `llm.messages.system()`, `llm.messages.user()`, and `llm.messages.assistant()`.

## Message Roles

Every message is associated with one of three roles: "system", "user", or "assistant". These roles determine how the LLM interprets the message.

<CodeExample file="python/examples/messages/roles.py" />

### System Messages

System messages are instructions from the application developer and take priority over user messages. Use them to set the LLM's persona, provide specific directives, or include examples of intended behavior.

### User Messages

User messages represent input from the person interacting with the LLM—questions, requests, or any content the LLM should respond to.

### Assistant Messages

Assistant messages are responses from the LLM. You typically don't create these by hand; they come from LLM responses. However, you can construct them manually when building up a conversation history.

## Content Types

Messages can contain more than just text. Modern LLMs support multimodal content, allowing you to include images, audio, and documents.

### Text

Text is the most common content type. Plain strings are automatically wrapped as `llm.Text`:

<CodeExample file="python/examples/messages/text_content.py" lines="3-" />

### Images

Images can be provided via URL (the provider downloads directly) or as base64-encoded data:

<CodeExample file="python/examples/messages/image_content.py" lines="3-" />

### Audio

Audio content is useful for transcription or voice-based interactions:

<CodeExample file="python/examples/messages/audio_content.py" lines="3-" />

### Documents

Documents allow you to send PDFs and text files (JSON, plain text, code) to the LLM for analysis:

<CodeExample file="python/examples/messages/document_content.py" lines="3-" />

<Info title="Media Loading Methods" collapsible={true} defaultOpen={false}>
`Image`, `Audio`, and `Document` provide consistent class methods for loading:

| Method | Description |
| --- | --- |
| `from_url(url)` | Reference media by URL (provider downloads it). Image and Document only. |
| `from_file(path)` | Load and encode media from a local file |
| `from_bytes(data)` | Create from raw bytes |
| `download(url)` | Download from URL and encode as base64. Image and Audio only. |

Note: `from_url` creates a URL reference without downloading. Use `download` if you need the data locally encoded.
</Info>

### Multimodal Messages

A single message can contain multiple content pieces of different types:

<CodeExample file="python/examples/messages/multimodal.py" lines="3-" />

## Content Type Reference

| Content Type | Description | Roles |
| --- | --- | --- |
| `Text` | Plain text content | System, User, Assistant |
| `Image` | Image data (base64 or URL) | User |
| `Audio` | Audio data (base64) | User |
| `Document` | Document data (PDF, text files, code) | User |
| `ToolCall` | LLM's request to call a tool | Assistant |
| `ToolOutput` | Result from executing a tool | User |
| `Thought` | Model's reasoning process | Assistant |

<Note>
Provider support for content types varies. See the compatibility guide for details on which providers support which content types.
</Note>

## Next Steps

Now that you understand how to construct messages, see [Models](/docs/learn/llm/models) to learn how to use them to call an LLM.
