Skip to content

File analysis

UC AI is multimodal. With it, you can analyze a PDF, an image, or another document directly in your Oracle database. An AI model then extracts information from the file, answers a question about it, or analyzes its content.

UC AI converts each file to base64 content, and sends it in your message array to the AI provider. You can combine the file content with a text prompt.

Supported file types:

  • PDF - extract text, analyze a table, answer a question about the content
  • Image (JPEG, PNG, WebP, and more) - describe an image, identify an object, read text in an image
  • Other document formats - each provider supports its own set

This guide shows how to build file analysis with the UC AI message API. It has one example for a PDF, and one for an image.

This example uses a PDF with a table of characters from the TV show “The Office”. The table holds this data:

First NameLast NameEmail
MichaelScottmichael.scott@dundermifflin.com
PamBeeslypam.beesly@dundermifflin.com
JimHalpertjim.halpert@dundermifflin.com
AngelaMartinangela.martin@dundermifflin.com
DwightSchrutedwight.schrute@dundermifflin.com
KevinMalonekevin.malone@dundermifflin.com

The call must carry the file, so build the message array yourself. It holds a system message, a user message, and the file content.

declare
l_messages json_array_t := json_array_t();
l_content json_array_t := json_array_t();
l_result json_object_t;
l_final_message clob;
l_blob blob;
begin
-- Select the file first: a subquery is not allowed as a parameter of a PL/SQL call
select blob_content into l_blob from your_table where id = 1;
-- Create a system message to set the context for the AI
l_messages.append(uc_ai_message_api.create_system_message(
'You are an assistant answering trivia questions about TV Shows. Please answer in super short sentences.'));
-- The user message consists of two parts: the file content and a text content
-- Add the file content to the user message
l_content.append(uc_ai_message_api.create_file_content(
p_media_type => 'application/pdf',
p_data_blob => l_blob,
p_filename => 'change_me.pdf'
));
-- Add text content to the user message
l_content.append(uc_ai_message_api.create_text_content(
'What is the TV show called of the characters that are inside the attached PDF?'
));
-- Add the user message with the file content and text content to the messages array
l_messages.append(uc_ai_message_api.create_user_message(l_content));
-- Call the AI service to generate a response based on the messages
l_result := uc_ai_google.generate_text(
p_messages => l_messages,
p_model => uc_ai_google.c_model_gemini_3_7_flash,
p_max_tool_calls => 3
);
l_final_message := l_result.get_clob('final_message');
sys.dbms_output.put_line('Last message: ' || l_final_message);
-- > The AI should respond with "The Office" or similar
end;

This example uses an image of an apple. The call sends the image to the AI service and asks for a description.

declare
l_messages json_array_t := json_array_t();
l_content json_array_t := json_array_t();
l_result json_object_t;
l_res_clob clob;
l_final_message clob;
begin
-- Create a system message to set the context for the AI
l_messages.append(uc_ai_message_api.create_system_message(
'You are an image analysis assistant.'));
-- The user message consists of two parts: the file content and a text content
-- Add the file content to the user message
l_content.append(uc_ai_message_api.create_file_content(
p_media_type => 'image/webp',
p_data_blob => uc_ai_test_utils.get_apple_webp,
p_filename => 'data.webp'
));
-- Add text content to the user message
l_content.append(uc_ai_message_api.create_text_content(
'What is the fruit depicted in the attached image?'
));
-- Add the user message with the file content and text content to the messages array
l_messages.append(uc_ai_message_api.create_user_message(l_content));
l_result := uc_ai_anthropic.generate_text(
p_messages => l_messages,
p_model => uc_ai_anthropic.c_model_claude_4_5_haiku,
p_max_tool_calls => 3
);
l_final_message := l_result.get_clob('final_message');
sys.dbms_output.put_line('Last message: ' || l_final_message);
-- > The AI should respond with "Apple"

Every provider uses the same message API for file input. The accepted file types differ by provider and by model. If the framework cannot map a file to the format of the provider, it rejects the file with ORA-20303 (unhandled format).

ProviderImagesDocumentsNotes
AnthropicJPEG, PNG, GIF, WebPPDF
OpenAIJPEG, PNG, GIF, WebPPDF
GoogleJPEG, PNG, GIF, WebPPDF (+ more)
MistralJPEG, PNG, WebPPDFUC AI sends a PDF as a document_url
Ollamadepends on the model—UC AI sends every file as an image
OCIPNG, JPG only (≤ 5 MB)PDF onlyGENERIC-format vision models only. A Cohere model accepts no file

OCI Generative AI supports file input only through its GENERIC chat format. Use a GENERIC-format vision model, for example Meta Llama vision, Google Gemini, or xAI Grok. A Cohere model rejects file content. An image must be a PNG or a JPG, and not larger than 5 MB. A document must be a PDF. OCI rejects WebP, GIF, and every other type with ORA-20303.

You can also pass a detail hint in the provider options. The values are AUTO (the default), HIGH, and LOW:

l_content.append(uc_ai_message_api.create_file_content(
p_media_type => 'image/png',
p_data_blob => :my_png,
p_filename => 'chart.png',
p_provider_options => json_object_t('{"detail":"HIGH"}')
));

To get the text and the structure of a document, and not an answer about it, use OCR. uc_ai.ocr reads a PDF or an image with Mistral, OCI Document Understanding or Ollama. It returns Markdown, pages, and the position and confidence of each text block.

This guide sends a file and gets an answer. To turn that answer into rows, you need a response schema, checks that decide what you can post unattended, and an inbox loop.