Quick Start
1
Screenshot tool returning an image
A The user asks for a screenshot summary; the tool returns multimodal content the model can read.
@tool-decorated function captures a screenshot and hands the PNG bytes back to the agent. The vision model sees the actual image on the next turn.2
Remote image via URL
No downloading needed — pass
url= directly and the model fetches it.3
Bare list (lightweight shape)
Skip the helper — return a plain list of part-dicts. The runtime normalises it automatically.
- A
toolmessage satisfying thetool_call_idcontract (containing a short text fallback). - A follow-up
usermessage carrying theimage_urlparts.
image_url parts inside tool-role messages. You don’t need to do anything — it’s automatic. When an assistant turn contains multiple tool calls, all tool replies stay consecutive and the media user message is appended only after the full batch flushes.
Choosing the Return Shape
All four shapes are auto-detected by the runtime — pick whichever feels natural:Configuration Options
There is no separate config class. Import the helpers frompraisonaiagents.tools:
image_part accepts any of:
- Raw
bytes - Base64
str - A
data:URI string - A remote
url=keyword argument
Common Patterns
Screenshot tool
Chart renderer (matplotlib → PNG)
MCP image passthrough
MCP servers often return image blocks with amimeType key. Return the block as-is — the runtime normalises mimeType → mime automatically.
Best Practices
Keep images under 5 MB
Keep images under 5 MB
The runtime enforces a 5 MB cap per image part (
MULTIMODAL_IMAGE_BYTE_LIMIT = 5_000_000). Images over this limit are silently dropped with a warning — the model only sees the text fallback.Resize before returning:Use a vision-capable LLM
Use a vision-capable LLM
Image parts are only perceived by models that support vision. Use:
gpt-4o/gpt-4o-mini(OpenAI)claude-3-5-sonnet-20241022or any Claude 3+ model (Anthropic)gemini-1.5-pro/gemini-1.5-flash(Google)
Always include a text caption alongside the image
Always include a text caption alongside the image
A caption improves grounding and is the only signal a non-vision model gets. Always pair This also helps when the image is dropped due to the 5 MB cap — the agent still gets useful context.
image_part with text_part:Files aren't pixels
Files aren't pixels
file_part is currently surfaced to the model as a text annotation [file: name (mime)]. Most LLM providers cannot ingest arbitrary binary files inline.For PDFs or other documents you want the model to see, rasterise to images first:Security
Text parts returned by external or untrusted tools are automatically wrapped in a prompt-injection fence — the same protection used for text-only tool output. You don’t need to do anything, but know that if you mark a tool as external, its text parts will be fenced before the model sees them.
Related
Multimodal Agents
Send images to the agent via
Task(images=[...]) or agent.chat(attachments=[...]) — the symmetric direction.Image Generation
Generate new images with AI models and use them in agent workflows.

