Vision: Analyzing Images with AI
Send images to vision-capable models for analysis, description, and understanding. This example shows how to analyze an image from a URL using GPT-4o with high detail processing for better accuracy.Image Generation: Generating Images with AI
Generate images from text prompts using OpenAI-compatible image generation models via the Go SDK.Audio Understanding: Analyzing Audio with AI
If your chat application supports text input, you can add audio input and output-just include audio in the modalities array and use an audio model, like gpt-4o-audio-preview.Audio Input to Model
Text-to-Speech: Converting Text to Audio
Convert text into natural-sounding speech using AI voice models. This example demonstrates generating an MP3 audio file from text using the “alloy” voice. The result is saved to a local file for playback.Speech-to-Text: Transcribing Audio Files
Convert audio files into text using AI transcription models. This example shows how to transcribe an MP3 file using OpenAI’s Whisper model, with an optional context prompt to improve accuracy.Advanced Vision Examples
Multiple Images
Send multiple images in a single request for comparison or analysis. This is useful for comparing products, analyzing changes over time, or understanding relationships between different visual elements.Base64 Images
Process local images by encoding them as base64 data URLs. This approach is ideal when you need to analyze images stored locally on your system without uploading them to external URLs first.Audio Configuration Options
Voice Selection for Speech Synthesis
OpenAI provides six distinct voice options, each with different characteristics. This example generates sample audio files for each voice so you can compare and choose the one that best fits your application.Audio Formats
Generate audio in different formats depending on your use case. MP3 for general use, Opus for web streaming, AAC for mobile apps, and FLAC for high-quality audio applications.Transcription Options
Language Specification
Improve transcription accuracy by specifying the source language. This is particularly helpful for non-English audio or when the audio contains technical terms or specific domain vocabulary.Response Formats
Choose between simple text output or detailed JSON responses with timestamps. The verbose JSON format provides word-level and segment-level timing information, useful for creating subtitles or analyzing speech patterns.Multimodal Embeddings
Bifrost supports multimodal embeddings — generating vector representations that capture text, images, audio, video, and documents together. TheInput field on BifrostEmbeddingRequest is a []EmbeddingInputItem; each item’s Content is an EmbeddingContent, a slice of typed parts, and all the parts in one item produce one vector.
Data or URL. ValidateEmbeddingInput runs before dispatch, so a malformed part fails before any plugin or provider sees it.
EmbeddingParameters carries the request-level defaults: EncodingFormat, Dimensions, TaskType, Title, AutoTruncate, plus ExtraParams for provider-specific fields that are forwarded as-is.
Response fields
EmbeddingData gained three optional fields, set only when the provider needs them:
EncodingFormat: "base64" works on every provider; where the model has no native base64 output Bifrost encodes the float vector as little-endian float32 base64.
Provider support
A part the target model cannot carry returns an
InvalidRequestError naming the modality. Bifrost never drops a part silently. The per-model rules below are the same as on the HTTP gateway; see the gateway guide for the wire-level detail.
Text Embedding (all providers)
Gemini
gemini-embedding-2-preview accepts text, image, audio, video and file (PDF) parts in any combination in one item. gemini-embedding-001 is text-only.
- Inline
Datais sent asinlineData. - A
URLis sent asfileData.fileUri, which the Gemini API only resolves for Files API URIs. Upload large media first, or send it inline.gs://is rejected on the Gemini provider; use Vertex for Cloud Storage media. - Multiple items go out as one
:batchEmbedContentscall.TaskTypeandTitleapply to every entry, and this is the only provider that honours per-itemParams. documentOcrandaudioTrackExtractiongo inExtraParams["embedContentConfig"].
file part type with MIMEType: "application/pdf", and enable OCR through embedContentConfig:
Vertex AI
Vertex has three embedding APIs, and Bifrost picks the right one from the model name. Project and region come from the Vertex key configuration.multimodalembedding@001 returns a separate 1408-dimension vector per modality, all in the same embedding space. Image and video URLs must be gs://; inline base64 data URIs are also accepted.
VideoConfig on the video part (IntervalSec minimum is 4 seconds) and each segment comes back as its own EmbeddingData with a VideoSegment:
Cohere
Cohere’s API has three mutually exclusive input fields, and Bifrost picks one from the content:texts[] when every item is a single text part, images[] when every item is a single image part, and inputs[] content blocks (Embed v4 only) for anything else, such as text and image in one item.
Images must be inline: a data URI in URL or Data, or raw base64 in Data with MIMEType set. Cohere does not fetch remote URLs. input_type defaults to search_document. EncodingFormat maps to Cohere’s embedding_types; when Cohere returns several representations for one input, each is a separate EmbeddingData labelled with its EncodingFormat. Image tokens are reported in Usage.PromptTokensDetails.ImageTokens, not PromptTokens.
Bedrock
Bedrock embedding models are routed by family, each with its own wire format and constraints. Titan.amazon.titan-embed-image-v1 accepts one item with text and at most one image, inline in Data only (a URL is rejected). Dimensions (256, 384 or 1024) maps to embeddingConfig.outputEmbeddingLength. The text models amazon.titan-embed-text-v1 / v2:0 take one item per request; a batch is an InvalidRequestError rather than a collapsed vector.
cohere.embed-* models follow the same texts[] / images[] / inputs[] selection as direct Cohere. Image-only requests go out as images[] with input_type defaulting to image, which both Embed v3 and v4 accept; mixed text + image items use inputs[] and need Embed v4.
Amazon Nova. amazon.nova-2-multimodal-embeddings-v1:0 embeds text, image, audio or video, one modality per item and one item per request. Media comes from inline Data or an s3://bucket/key URL; any other URL is rejected. Nova needs a declared format per media part, derived from MIMEType or the S3 key’s extension (png, jpeg, webp, gif; mp3, wav, ogg; mp4, mov, mkv, webm, flv, mpeg, wmv, 3gp). TaskType maps to embeddingPurpose (GENERIC_INDEX default, GENERIC_RETRIEVAL, TEXT_RETRIEVAL, IMAGE_RETRIEVAL, VIDEO_RETRIEVAL, AUDIO_RETRIEVAL, DOCUMENT_RETRIEVAL, CLASSIFICATION, CLUSTERING), Dimensions is 256, 384, 1024 or 3072, and Nova’s own knobs ride in ExtraParams: truncationMode (END, START, NONE), detailLevel (STANDARD_IMAGE, DOCUMENT_IMAGE; image parts only) and embeddingMode (video only).
Video returns one audio_video vector by default. With embeddingMode: "AUDIO_VIDEO_SEPARATE" one input returns an audio vector and a video vector:
Usage.
OpenAI-compatible providers
OpenAI, Azure OpenAI, Mistral, Parasail and every other provider that speaks the OpenAI embeddings dialect accepttext and tokens parts only, and the two cannot be mixed in one request. Only EncodingFormat and Dimensions are sent on the wire; TaskType, Title and AutoTruncate are not part of the OpenAI format and are not forwarded.
Per-Item Parameters
LeaveParams nil on an item and it inherits the request-level defaults; set it and that item
alone uses the override — a query embedded with RETRIEVAL_QUERY alongside documents embedded
with RETRIEVAL_DOCUMENT, say.
Params replaces the request-level params wholesale — the two are not
merged field by field, so repeat any request-level value you still want (as Dimensions is
repeated above). EmbeddingInputItem.EffectiveParams(defaults) returns the params an item will
actually be sent with.
Things to know
- Token usage is uneven across multimodal models. Vertex
multimodalembedding@001returns a nilUsage, Titan image-only inputs report zero tokens, and Cohere image tokens live underPromptTokensDetails. Budgets and cost metered onPromptTokensdo not see those inputs. - Semantic cache keys include
TaskType,TitleandAutoTruncate, so aRETRIEVAL_QUERYrequest is never served a cachedRETRIEVAL_DOCUMENTvector. - Migrating from the old
EmbeddingInputstruct:&schemas.EmbeddingInput{Texts: []string{"hello"}}becomes[]schemas.EmbeddingInputItem{{Content: schemas.EmbeddingContent{{Type: schemas.EmbeddingContentPartTypeText, Text: &text}}}}. The helpersEmbeddingInput(items).Texts()and.TokenIDs()flatten the new shape back to the old one when you only need the strings or token IDs.
Check the Supported Providers page for more information on multimodal capabilities supported by each provider.
Next Steps
- Streaming Responses - Real-time multimodal processing
- Tool Calling - Combine with external tools
- Provider Configuration - Multiple providers for different capabilities
- Core Features - Advanced Bifrost capabilities

