Na era da IA, o valor dos dados não está apenas em armazená-los, mas na capacidade de transformá-los em informação no exato momento em que uma decisão precisa ser tomada.
Deste modo, este é o primeiro artigo da série sobre Casos de Uso em Oracle AI Database 26ai e Autonomous AI Database. O ponto de partida é um caso de uso do agronegócio para demonstrar um cenário com vetorização e RAG: como combinar imagens de campo, conhecimento técnico e inteligência artificial para apoiar uma análise mais rápida e obter hipóteses de diagnóstico consistentes.
Para isto, vamos armazenar uma imagem de uma cultura agrícola no banco, vetorizá-la com embedding local, embedding externo, realizar pesquisa por similaridade e RAG. Na etapa de testes, teremos uma integração MCP para consumir a(s) tool(s) gerada através do Codex e Claude Desktop, além de realizar uma exposição em REST para testes.
O objetivo deste artigo não é criar uma aplicação completa, mas demonstrar como novos recursos do banco podem trazer agilidade ao desenvolvimento de aplicações modernas, usando recursos do banco convergente:

Figura 1 – Banco Convergente
Inovação com responsabilidade
Este caso sobre Agro não substitui a avaliação de um agrônomo. Ele mostra como visão computacional, RAG, vetores e AI podem formar um agente especializado, rastreável e ampliável. A inovação está justamente em transformar conhecimento técnico em uma capacidade operacional dentro da plataforma de dados.
Pré-requisitos
- Para consumo de LLMs da OCI: https://docs.oracle.com/en-us/iaas/Content/generative-ai/iam-policies.htm. Para LLMs de outros cloud providers apenas liberar ACL e criar credencial de acesso.
- Concessões de execução sobre packages do banco (executado como ADMIN no banco, estes GRANTs de EXECUTE devem existir):
grant execute on DBMS_CLOUD_AI to <my_schema>;
grant execute on DBMS_CLOUD to <my_schema>;
grant execute on DBMS_CLOUD_AI_AGENT to <my_schema>;
grant execute on DBMS_CLOUD_PIPELINE to <my_schema>;
Para atividades com vetores:
grant execute on DBMS_VECTOR to <my_schema>;
grant execute on DBMS_VECTOR_CHAIN to <my_schema>;
Para o desenvolvimento dos objetos:
grant DB_DEVELOPER_ROLE to <my_schema>;
grant CREATE PROCEDURE to <my_schema>;
grant CREATE SEQUENCE to <my_schema>;
grant CREATE VIEW to <my_schema>;
grant CREATE TABLE to <my_schema>;
Para importação de modelos ONNX:
grant CREATE MINING MODEL to <my_schema>;
- Liberação de ACL no banco (executado como ADMIN no banco)
ACLs de rede devem liberar somente hosts e portas necessários. Uma wildcard como *.oraclecloud.com é conveniente em laboratório. Não reproduza essa ACL em produção; permita apenas hosts, portas e principals (esquemas de banco) necessários.
BEGIN
DBMS_NETWORK_ACL_ADMIN.append_host_ace (
host => '*.oraclecloud.com',
ace => xs$ace_type(privilege_list => xs$name_list('http','connect','resolve'),
principal_name => '<my_schema>',
principal_type => xs_acl.ptype_db));
END;
/
Neste artigo, a credencial foi criada a partir de dbms_vector.create_credential com nome OCI_CRED. Nesta URL há detalhes para criação da credencial para OCI, mas reforçando, você pode criar esta credencial para outros AI Providers / Cloud Providers.
Ponto de atenção: consumo de LLM implica em custos. Avalie com time responsável.
Os comandos abaixo foram realizados e testados em: Oracle AI Database 26ai Enterprise Edition Release 23.26.4
Etapa 1: função para vetorizar imagens
Primeiramente vamos construir a rotina de embedding, de duas maneiras:
A opção local – ONNX, utiliza a capacidade computacional do banco para gerar vetores, e dispensa a chamada a um serviço externo de embedding. A etapa generativa, exibida mais à frente, continuará utilizando um LLM.
Para download de ONNX via documentação (+rápida): https://docs.oracle.com/en/database/oracle/oracle-database/26/vecse/import-pretrained-models-onnx-format-vector-generation-database.html
Para download de ONNX via OML4Py (+opções): https://docs.oracle.com/en/database/oracle/oracle-database/26/vecse/convert-pretrained-models-onnx-model-end-end-instructions.html
Segue um exemplo de importação de ONNX ao banco (previamente baixado e armazenado no Object Storage):
Este modelo abaixo é o CLIP Multimodal, ou seja, modelo que pode fazer embedding tanto de texto quanto de imagem. Note que são 2 modelos ONNX importados, um para TEXTO outro para IMAGEM ( sufixos “_IMG” e “_TXT” no model_name abaixo ):
Ponto de atenção: (1) a partir deste comando, executamos com owner/schema criado para esta frente, e não como ADMIN. A credencial e o download prévio do ONNX em algum bucket é essencial para correta carga ao banco.
(2) Atenção com tipos de imagens permitidos e restrições existentes: JPEG baseline de 8 bits. Um .jpg progressivo pode retornar NULL. https://docs.oracle.com/en/database/oracle/oracle-database/26/vecse/onnx-pipeline-models-image-embedding.html#supported-input-for-image-embedding-models
BEGIN
DBMS_VECTOR.LOAD_ONNX_MODEL_CLOUD(
model_name => 'CLIP_VIT_BASE_PATCH32_IMG',
credential => 'OCI_CRED',
uri => 'https://objectstorage.sa-saopaulo-1.oraclecloud.com/p/<ajuste>/clip_vit_base_patch32_img.onnx',
metadata => JSON('{"function" : "embedding", "embeddingOutput" : "embedding" , "input": {"input": ["DATA"]}}')
);
DBMS_VECTOR.LOAD_ONNX_MODEL_CLOUD(
model_name => 'CLIP_VIT_BASE_PATCH32_TXT',
credential => 'OCI_CRED',
uri => 'https://objectstorage.sa-saopaulo-1.oraclecloud.com/p/<ajuste>/clip_vit_base_patch32_txt.onnx',
metadata => JSON('{"function" : "embedding", "embeddingOutput" : "embedding" , "input": {"input": ["DATA"]}}')
);
END;
Testes:
(1) vetorização com onnx a partir de texto:

(2) vetorização com onnx a partir de imagem (coluna BLOB na cláusula de dados):

Figura 2: testes com ONNX
Para consumir modelos da OCI, e usar um modelo externo de embedding, confirme a disponibilidade regional do modelo, assim como subscrições destas regiões ao seu tenancy.
Ponto de atenção: desde que seu tenancy tenha subscrição a múltiplas regiões, um banco na região SP pode chamar um LLM da região Chicago por exemplo. Mas subscrição por si só não garante acesso: também contam modelo, endereço de endpoint, políticas e conectividade. Em cenários com dados reais, avalie residência, transferência internacional, políticas corporativas, contratos e requisitos regulatórios antes de enviar prompts, resultados ou documentos a modelos em outra região.
Veja que nos dois primeiros blocos abaixo (p_code_mode = 1 e 2) há uso do embedding externo, cohere.embed-v4.0, sendo dois exemplos de construção, com mesmo resultado. O primeiro costuma ser usado em cenários de imagens maiores, onde é preciso montar o request_body por partes.
Para custos de modelos: https://www.oracle.com/cloud/price-list/#pricing-ai
O último bloco da função abaixo, p_code_mode = 3, faz uso do modelo de embedding em ONNX, importado para imagens a partir de DBMS_VECTOR.LOAD_ONNX_MODEL_CLOUD: definido com nome CLIP_VIT_BASE_PATCH32_IMG.
Assim, a função abaixo terá papel de vetorizar imagens, e tem como exemplos 3 modos diferentes para o fazer:
create or replace FUNCTION fnc_26ai_embed_image
(image_name in VARCHAR2 default 'test.png',
base64_image in CLOB,
oci_cred IN VARCHAR2 default 'OCI_CRED',
p_comp_id in VARCHAR2,
p_code_mode in NUMBER default 1 )
return clob
as
embed_resp DBMS_CLOUD_TYPES.RESP;
gen_ai_endpoint VARCHAR2(500) := 'https://inference.generativeai.us-chicago-1.oci.oraclecloud.com';
gen_ai_model VARCHAR2(500) := 'cohere.embed-v4.0';
file_extension VARCHAR2(5);
invalid_image EXCEPTION;
image_too_big EXCEPTION;
request_json_part1 CLOB;
request_json_part2 CLOB;
request_body BLOB;
v_vector vector;
BEGIN
if p_code_mode = 1 then
-- get file extension from file name and validate
file_extension := lower(regexp_replace(image_name, '.*\.([a-zA-Z0-9]+)$', '\1')) ;
-- create temp blob
dbms_lob.createtemporary(request_body, FALSE);
-- define beginning of request payload
request_json_part1 := to_clob('{"inputs": ["data:image/' || file_extension || ';base64,');
-- define ending of request payload
request_json_part2 := to_clob('"],
"servingMode": {
"servingType": "ON_DEMAND",
"modelId": "' || gen_ai_model || '"
},
"truncate": "NONE",
"inputType": "IMAGE",
"compartmentId": "' || p_comp_id || '"}');
-- append part1 json to request blob
dbms_lob.append(request_body, apex_util.clob_to_blob(p_clob => request_json_part1,p_charset => 'AL32UTF8'));
-- append base64 image to request blob
dbms_lob.append(request_body, apex_util.clob_to_blob(p_clob => base64_image,p_charset => 'AL32UTF8'));
-- append part2 json to request blob
dbms_lob.append(request_body, apex_util.clob_to_blob(p_clob => request_json_part2,p_charset => 'AL32UTF8'));
-- Call GenAI Embed Service
embed_resp := dbms_cloud.send_request(
credential_name => oci_cred,
uri => gen_ai_endpoint || '/20231130/actions/embedText',
method => dbms_cloud.METHOD_POST,
body => request_body
);
-- free temp blob
dbms_lob.freetemporary(request_body);
-- return embed reponse
RETURN json_value( dbms_cloud.get_response_text(embed_resp), '$.embeddings[*].vector()'
RETURNING CLOB ERROR ON ERROR) ;
elsif p_code_mode = 2 then -- outra maneira de criar chamada a modelo externo
RETURN to_clob( DBMS_VECTOR.UTL_TO_EMBEDDING(
APEX_WEB_SERVICE.CLOBBASE642BLOB(base64_image),
'image',
JSON('{
"provider": "OCIGenAI",
"credential_name": "' || oci_cred || '",
"url": "' || gen_ai_endpoint || '/20231130/actions/embedText' || '",
"model": "' || gen_ai_model || '"
}')
) ) ;
elsif p_code_mode = 3 then -- com ONNX
SELECT VECTOR_EMBEDDING( CLIP_VIT_BASE_PATCH32_IMG
USING APEX_WEB_SERVICE.CLOBBASE642BLOB(base64_image) AS data ) as embedding
into v_vector;
return to_clob( v_vector );
end if;
END;
/
Ponto de atenção: apresentei 3 maneiras distintas de gerar o embedding de imagens para fins de explicação e exemplos, e obtemos vetores válidos de imagens com qualquer um destes métodos acima. Se não houver importação prévia do ONNX com nome “CLIP_VIT_BASE_PATCH32_IMG” a função acima ficará inválida.
Cuidado: com ONNX CLIP*, os encoders de texto e imagem são distintos, mas fazem parte do mesmo modelo multimodal e foram treinados para produzir representações alinhadas.
Etapa 2: armazenando imagens de culturas diferentes
Para este nosso artigo, vamos simplificar o processo mantendo imagens de 3 culturas diferentes numa mesma tabela:
CREATE TABLE TB_26AI_AGRO
( "ID" NUMBER GENERATED ALWAYS AS IDENTITY,
"UPLOAD_ID" varchar2(32),
"FILE_NAME" VARCHAR2(200),
"FILE_MIMETYPE" VARCHAR2(200),
"FILE_CHARSET" VARCHAR2(200),
"BASE64_IMAGEM" CLOB,
"UPDATED_DATE" DATE,
"TIPO_CULTURA" VARCHAR2(20) DEFAULT 'Soja' CONSTRAINT "CK_TP_CULT" CHECK ("TIPO_CULTURA" IN ('Soja', 'Café', 'Citros')),
"CREATED_BY" VARCHAR2(200) DEFAULT 'ADMIN');
A coluna TIPO_CULTURA descreve o tipo de cultura: Soja, Café ou Citros. Esta coluna será utilizada como filtro na pesquisa por similaridade mais adiante.
Com a carga de algumas imagens na tabela, temos por exemplo:

Figura 3: exemplo de diversas imagens carregadas para teste
Numa aplicação, teríamos uma imagem capturada pela câmera do celular sendo salva nesta tabela, o que pode ser feito com APEX PWA: ambiente de desenvolvimento low-code, onde podemos criar aplicações modernas, contar com componentes responsivos e publicar a aplicação em PWA – Progressive Web Application.
Este recurso permite acesso via navegador sendo adaptável a dispositivos móveis: pode ser instalado na tela inicial ou no ambiente de aplicativos do dispositivo, conforme o navegador e o sistema.
Para este caso, poderíamos obter a imagem com captura nativa da câmera, tanto do Android quanto iOS:

Figura 4: configuração em APEX para integração com câmera do celular
Neste momento temos uma função com capacidade de embedding de imagens, e uma tabela com algumas imagens de teste. Para criação do front-end em APEX, fiz um vídeo explicativo em APEX Office Hours, que cobre alguns casos de uso.
Etapa 3: Arquitetura da solução
O passo seguinte é criar nossa base de conhecimento (Data Source), conforme imagem abaixo. Note que nesse caso usaremos documentos públicos da Embrapa – referência nacional para agricultura e pecuária no Brasil, e exibirei o passo a passo usando um documento da cultura de Soja.
Assim, nosso objetivo será comparar vetores das imagens com vetores destes documentos da Embrapa (Similarity Search), e deste modo, obter os hipóteses de diagnóstico das possíveis doenças encontradas (RAG).

Figura 5: Vector Search Pipeline
Em resumo:
- Data Source: Para base de conhecimento, podemos usar diversos arquivos e fontes, mas para este artigo usei PDF público da Embrapa, a exemplo deste: https://www.infoteca.cnptia.embrapa.br/infoteca/bitstream/doc/991687/1/Doc256OL.pdf
- Document Loaders: podemos levar estes arquivos ao banco, ou vetorizá-los a partir do object storage
- Document Transformation: não iremos vetorizar os PDFs completos, mas em pequenas partes, como parágrafos. Definimos estes trechos como chunkings (detalhes mais abaixo).
- Embedding Model: semelhante ao embedding de imagens, teremos opção de vetorizar os documentos PDF com ONNX (previamente importado ao banco) ou com modelos externos
- Vector Database: criaremos uma tabela em banco para receber os vetores destes documentos
- Similarity Search: nesta etapa iremos comparar os vetores das imagens com vetores dos trechos textuais extraídos dos PDFs
- RAG: para obter uma resposta bem construída levaremos o resultado da pesquisa por similaridade a um LLM externo, e assim, teremos nossa hipótese de diagnóstico.
Após baixar o documento PDF, vamos enviá-lo ao objeto storage.

Figura 6 – upload de PDFs ao bucket
Ponto de atenção (1): Note que podemos acessar object storage de outros cloud providers, fazendo acesso a partir de credenciais, ACLs e liberações de rede.
(2) Para criar um fluxo periódico de cargas, usamos o Autonomous Data Pipeline.
Teremos a partir de agora uma tabela que terá de fato os vetores dos trechos dos PDFs (Vector Database e Document Transformation):
CREATE TABLE "TB_26AI_AGRO_VECTOR"
(
"EMBED_ID" NUMBER,
"EMBED_DATA" VARCHAR2(4000),
"EMBED_VECTOR" VECTOR,
"TIPO_CULTURA" VARCHAR2(20) DEFAULT 'Soja' CONSTRAINT "CK_VEC_TP_C" CHECK ("TIPO_CULTURA" IN ('Soja', 'Café', 'Citros')),
"DOC_ORIGEM" VARCHAR2(200)
);
Inicialmente, como testes, vamos vetorizar o arquivo manualmente, usando embedding externo com cohere.embed-v4.0 e o arquivo baixado da Embrapa: Doc-256-2030L-1.pdf
Vetorização com embedding externo (modo manual):
DECLARE
L_TEXTO CLOB;
P_TIPO_CULTURA VARCHAR2(200) := 'Soja';
P_DOC_ORIGEM VARCHAR2(200) := 'Doc-256-2030L-1.pdf';
BEGIN
L_TEXTO := DBMS_VECTOR_CHAIN.UTL_TO_TEXT(
DBMS_CLOUD.GET_OBJECT(
CREDENTIAL_NAME => 'OCI_CRED',
OBJECT_URI => 'https://objectstorage.sa-saopaulo-1.oraclecloud.com/n/xx/b/bucket-agro/o/' || P_DOC_ORIGEM
)
);
INSERT INTO TB_26AI_AGRO_VECTOR (
EMBED_ID,
EMBED_DATA,
EMBED_VECTOR,
TIPO_CULTURA,
DOC_ORIGEM
)
SELECT
E.EMBED_ID,
E.EMBED_DATA,
TO_VECTOR(E.EMBED_VECTOR),
P_TIPO_CULTURA,
P_DOC_ORIGEM
FROM TABLE(
DBMS_VECTOR_CHAIN.UTL_TO_EMBEDDINGS(
DBMS_VECTOR_CHAIN.UTL_TO_CHUNKS(
L_TEXTO,
JSON('{
"by": "words",
"max": 220,
"split": "sentence",
"normalize": "all",
"overlap": 40
}')
),
JSON('{
"provider": "ocigenai",
"credential_name": "OCI_CRED",
"url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText",
"model": "cohere.embed-v4.0"
}')
)
) T
CROSS JOIN JSON_TABLE(
T.COLUMN_VALUE,
'$[*]' ERROR ON ERROR
COLUMNS (
EMBED_ID NUMBER PATH '$.embed_id',
EMBED_DATA VARCHAR2(4000) PATH '$.embed_data',
EMBED_VECTOR CLOB PATH '$.embed_vector'
)
) E;
COMMIT;
END;
/
Pontos de atenção:
(1) Técnicas de Chunking: https://docs.oracle.com/en/database/oracle/oracle-database/23/vecse/explore-chunking-techniques-and-examples.html
(2) Para overlap, a documentação estabelece sobreposição entre 5% e 20% de max
É muito importante dar agilidade a este processo, seja com Data Pipelines, ou com rotinas de vetorização em massa. Assim, segue um exemplo para ler todos arquivos do bucket. A principal diferença é usar uma varredura dos arquivos do bucket, e não um arquivo fixo, usando DBMS_CLOUD.LIST_OBJECTS:
SELECT object_name
FROM DBMS_CLOUD.LIST_OBJECTS('OCI_CRED', 'https://objectstorage.sa-saopaulo-1.oraclecloud.com/n/xx/b/bucket-agro/o/')
Agora ampliaremos a carga para percorrer os documentos do bucket, mantendo o modelo externo Cohere. Ao final, mostraremos a configuração alternativa para execução local com ONNX.
DECLARE
L_TEXTO CLOB;
P_TIPO_CULTURA VARCHAR2(200) := 'Soja';
BEGIN
FOR R1 IN (SELECT object_name
FROM DBMS_CLOUD.LIST_OBJECTS('OCI_CRED', 'https://objectstorage.sa-saopaulo-1.oraclecloud.com/n/xx/b/bucket-agro/o/')) LOOP
L_TEXTO := DBMS_VECTOR_CHAIN.UTL_TO_TEXT(
DBMS_CLOUD.GET_OBJECT(
CREDENTIAL_NAME => 'OCI_CRED',
OBJECT_URI => 'https://objectstorage.sa-saopaulo-1.oraclecloud.com/n/xx/b/bucket-agro/o/' || R1.object_name
)
);
INSERT INTO TB_26AI_AGRO_VECTOR (
EMBED_ID,
EMBED_DATA,
EMBED_VECTOR,
TIPO_CULTURA,
DOC_ORIGEM
)
SELECT
E.EMBED_ID,
E.EMBED_DATA,
TO_VECTOR(E.EMBED_VECTOR),
P_TIPO_CULTURA,
R1.object_name -- arquivo da lista (cursor R1)
FROM TABLE(
DBMS_VECTOR_CHAIN.UTL_TO_EMBEDDINGS(
DBMS_VECTOR_CHAIN.UTL_TO_CHUNKS(
L_TEXTO,
JSON('{
"by": "words",
"max": 220,
"split": "sentence",
"normalize": "all",
"overlap": 40
}')
),
JSON('{
"provider": "ocigenai",
"credential_name": "OCI_CRED",
"url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText",
"model": "cohere.embed-v4.0"
}')
)
) T
CROSS JOIN JSON_TABLE(
T.COLUMN_VALUE,
'$[*]' ERROR ON ERROR
COLUMNS (
EMBED_ID NUMBER PATH '$.embed_id',
EMBED_DATA VARCHAR2(4000) PATH '$.embed_data',
EMBED_VECTOR CLOB PATH '$.embed_vector'
)
) E;
END LOOP;
COMMIT;
END;
/
Ponto de atenção: (1) Note que para embedding externo (cohere) usamos este trecho no código acima:
JSON('{
"provider": "ocigenai",
"credential_name": "OCI_CRED",
"url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText",
"model": "cohere.embed-v4.0"
}')
Para usar o ONNX previamente importado, podemos ajustar o JSON para:
JSON('{"provider":"database", "model":"CLIP_VIT_BASE_PATCH32_TXT"}')
Cuidados: Para utilizar CLIP localmente, altere o provedor, ajuste o chunking aos limites do modelo e regenere os embeddings da base documental. Na consulta, utilize o encoder de imagem correspondente. Mantenha esses vetores separados dos gerados com Cohere.
O nome do ONNX citado, foi o mesmo da importação realizada na etapa 1, a partir de DBMS_VECTOR.LOAD_ONNX_MODEL_CLOUD. Tratando-se de PDFs, usamos o ONNX de sufixo “_TXT”
(2) Para comparar uma imagem com trechos textuais, os embeddings devem ser gerados por um modelo multimodal compatível e possuir a mesma dimensionalidade e representação semântica. Vetores produzidos por modelos distintos não devem ser comparados diretamente.
No exemplo acima, vetorizamos os PDFs com cohere.embed-v4.0. A vetorização da imagem deverá ser com mesmo modelo (sempre fique atento para não ter erros na similaridade, usando mesmo embedding na(s) fonte(s) e no vetor a ser comparado).
(3) Se for usado para um processo contínuo de cargas, pode ser criado também uma tabela de log, que será atualizada ao término da vetorização (insert), mas que no cursor principal exclua arquivos já processados (not in), sendo deste modo uma solução incremental.
Etapa 4: Pesquisa por Similaridade
A pesquisa por similaridade no Oracle AI Database compara vetores de embeddings para recuperar os registros semanticamente mais próximos de uma consulta. Neste caso, o vetor da imagem é comparado aos vetores dos trechos agrícolas, retornando os trechos dos documentos com maior proximidade de conteúdo para compor o contexto do RAG.
A função VECTOR_DISTANCE calcula a distância entre dois vetores. Como a consulta é ordenada de forma crescente, os menores valores representam os trechos mais similares ao vetor pesquisado. A função retorna uma distância; ela não retorna um percentual de similaridade. Menor distância significa maior proximidade.
Detalhes do uso da função VECTOR_DISTANCE: https://docs.oracle.com/en/database/oracle/oracle-database/26/sqlrf/vector_distance.html
select embed_data, doc_origem
from TB_26AI_AGRO_VECTOR
where TIPO_CULTURA = 'Soja'
order by VECTOR_DISTANCE(EMBED_VECTOR, v_vector, COSINE)
fetch exact first 10 rows only
A métrica COSINE é adequada quando se busca similaridade semântica. Outras métricas de cálculo de distância: https://docs.oracle.com/en/database/oracle/oracle-database/26/vecse/vector-distance-metrics.html

Figura 7 – exemplos de métrica de distância
Na busca EXACT, o Oracle calcula a distância de cada vetor, garantindo a seleção correta do Top-K. O custo cresce com o número de vetores. Na busca APPROXIMATE, o Oracle navega pela estrutura do índice vetorial e avalia apenas candidatos mais promissores. Exemplo:
fetch approximate first 10 rows only
with target accuracy 90
Índices para busca APPROXIMATE: https://docs.oracle.com/en/database/oracle/oracle-database/26/vecse/create-vector-indexes-and-hybrid-vector-indexes.html. Nesse exemplo, 90 representa a precisão alvo da busca aproximada, e não uma garantia absoluta de que todos os 10 resultados serão iguais aos da busca exata.
Para que um índice vetorial seja usado na busca aproximada, a métrica declarada no índice deve corresponder à métrica usada na consulta. Se o índice foi criado com DISTANCE COSINE, a consulta deve informar COSINE. Caso haja divergência, o Oracle deixa de usar o índice vetorial e executa busca exata: Regras de compatibilidade entre métrica e índice
Esta pesquisa por similaridade será utilizada na rotina fnc_26ai_agro (item 6).
Etapa 5: RAG
A função fnc_26ai_rag_agro executa a geração multimodal: recebe o prompt enriquecido, a imagem e chama o modelo generativo.
Embora a recuperação dos documentos ocorra anteriormente, por meio de VECTOR_DISTANCE, esta função integra o conteúdo recuperado, a imagem e as instruções de análise em uma única requisição ao modelo. Dessa forma, o modelo pode relacionar os sintomas visuais presentes na imagem com os conhecimentos recuperados na base documental.
O fluxo executado pela função é:
- Recebe o prompt enriquecido (
p_ai_prompt), que contém as instruções de análise e os trechos retornados pela etapa de recuperação semântica. - Usa a imagem no formato Base64, necessário para inclusão da imagem na requisição JSON.
- Monta a requisição JSON para o serviço OCI Generative AI. A mensagem enviada ao modelo contém dois tipos de conteúdo:
TEXT: o prompt com os dados recuperados pelo RAG;IMAGE: a imagem da planta ou cultura a ser analisada.
- Envia a requisição ao endpoint de inferência do OCI usando
DBMS_CLOUD.SEND_REQUEST. A credencial do OCI é informada porp_oci_cred, evitando expor chaves de acesso diretamente no código. - Extrai e retorna apenas o texto da primeira resposta gerada pelo modelo, usando a expressão JSON:
'$.chatResponse.choices[0].message.content[0].text'
A função utiliza o modelo xai.grok-4.3, configurado no modo sob demanda (ON_DEMAND). O parâmetro temperature foi definido como 0.4, mas pode ser revisado e ajustado.
create or replace function fnc_26ai_rag_agro(
p_ai_prompt in clob,
p_oci_cred in varchar2,
p_base64_image in clob,
p_comp_id in varchar2
)
return clob
as
gen_ai_endpoint varchar2(500) := 'https://inference.generativeai.us-chicago-1.oci.oraclecloud.com';
gen_ai_model varchar2(500) := 'xai.grok-4.3';
chat_resp dbms_cloud_types.resp;
request_json_part1 clob;
request_json_part2 clob;
request_body blob;
v_ext varchar2(20);
begin
-- Cria o BLOB temporário para o corpo da requisição.
dbms_lob.createtemporary(
request_body,
false
);
request_json_part1 := to_clob(
'{
"compartmentId": "' || p_comp_id || '",
"servingMode": {
"modelId": "' || gen_ai_model || '",
"servingType": "ON_DEMAND"
},
"chatRequest": {
"apiFormat": "GENERIC",
"serviceTier": "PRIORITY",
"messages": [
{
"role": "USER",
"content": [
{
"type": "TEXT",
"text": "' || replace(replace(replace(replace( p_ai_prompt ,chr(10),null),chr(13),null),'"',''),'''','') || '"
},
{
"type": "IMAGE",
"imageUrl": {
"url": "data:image/jpg;base64,' );
request_json_part2 := to_clob('" } } ] } ],
"temperature": 0.4,
"topK": 1
}
}'
);
-- Adiciona a primeira parte do JSON ao BLOB da requisição.
dbms_lob.append(
request_body,
apex_util.clob_to_blob(
p_clob => request_json_part1,
p_charset => 'AL32UTF8') );
-- Adiciona a imagem codificada em Base64 ao BLOB da requisição.
dbms_lob.append(
request_body,
apex_util.clob_to_blob(
p_clob => p_base64_image,
p_charset => 'AL32UTF8' ) );
-- Adiciona a segunda parte do JSON ao BLOB da requisição.
dbms_lob.append(
request_body,
apex_util.clob_to_blob(
p_clob => request_json_part2,
p_charset => 'AL32UTF8' ) );
-- Chamada ao serviço Generative AI Chat.
chat_resp := dbms_cloud.send_request(
credential_name => p_oci_cred,
uri => gen_ai_endpoint || '/20231130/actions/chat',
method => dbms_cloud.method_post,
body => request_body
);
-- Libera o BLOB temporário.
dbms_lob.freetemporary(request_body);
return json_value(
dbms_cloud.get_response_text(chat_resp),
'$.chatResponse.choices[0].message.content[0].text'
RETURNING CLOB ERROR ON ERROR
);
end;
Assim, a função implementa a etapa final do RAG multimodal: transforma o conhecimento recuperado e a imagem em uma resposta textual contextualizada. O resultado pode apresentar a hipótese de doença ou praga, os sintomas observados e a relação entre a imagem e os documentos recuperados.
Ponto de atenção: (1) detalhes dos atributos usados na requisição em https://docs.oracle.com/en-us/iaas/api/#/en/generative-ai-inference/20231130/
(2) Priority Processing foi usado neste exemplo com xai.grok-4.3, a partir da definição do atributo: “serviceTier”: “PRIORITY” . Ele impacta principalmente tempo de resposta. Fonte: https://docs.x.ai/developers/advanced-api-usage/priority-processing
Documentação Oracle: docs.oracle.com/en-us/iaas/Content/generative-ai/xai-grok-4-3.htm (Priority Processing: Supported)
Etapa 6: Função completa com Similaridade e RAG
A função fnc_26ai_agro é a orquestradora completa: cria o embedding da imagem, recupera os trechos por similaridade, monta o prompt e chama a função de geração.
Inicialmente, a função fnc_26ai_embed_image transforma a imagem armazenada na tabela TB_26AI_AGRO em um vetor de embedding. Esse vetor representa características visuais da imagem em formato numérico, permitindo compará-la com os vetores dos documentos técnicos cadastrados na tabela TB_26AI_AGRO_VECTOR.
A recuperação ocorre com a função VECTOR_DISTANCE, usando a métrica COSINE. A consulta filtra os documentos pela cultura informada, como soja, e seleciona os 50 trechos semanticamente mais próximos da imagem:
create or replace function fnc_26ai_agro(
p_upload_id in varchar2,
p_tipo_cultura in varchar2 default 'Soja',
p_comp_id in varchar2 default 'ocid1.compartment.oc1..xxxxxxx',
p_credential in varchar2 default 'OCI_CRED'
)
return clob
as
v_messages clob;
v_vector clob;
v_prompt clob;
v_prompt2 clob;
v_base64_image clob;
v_file_name varchar2(200);
begin
select base64_imagem, file_name
into v_base64_image, v_file_name
from TB_26AI_AGRO
where upload_id = p_upload_id
for update nowait;
v_vector := fnc_26ai_embed_image(
v_file_name,
v_base64_image,
p_credential,
p_comp_id
) ;
for message_cursor in (
--
-- pesquisa por similaridade
--
select embed_data, doc_origem
from TB_26AI_AGRO_VECTOR
where TIPO_CULTURA = p_tipo_cultura
order by VECTOR_DISTANCE(EMBED_VECTOR, v_vector, COSINE)
fetch exact first 50 rows only
) loop
v_messages := v_messages || '"' || replace(replace(replace(replace(message_cursor.embed_data || '- Fonte:' || message_cursor.doc_origem ,chr(10),null),chr(13),null),'"',''),'''','') || '",' ;
end loop;
v_prompt := 'Você é um especialista em fitopatologia treinado para analisar sinais e sintomas de doenças e pragas em plantas.
##Seu objetivo é:
Ao receber uma imagem e os textos recuperados pelo RAG, identificar:
Sintomas visíveis na imagem, descrevendo:
cor
formato das lesões
padrão/distribuição
textura
presença de manchas, necrose, deformações, podridão etc.
##A provável doença ou praga, citando:
nome da doença
agente causal (fungo, bactéria, vírus, inseto, nematoide, parasita etc.)
nome científico quando disponível nos trechos recuperados.
##Explicação mostrando quais informações recuperadas justificam a conclusão.
##Regras rígidas:
Nunca invente sintomas, doenças ou causas.
Só responda se houver correspondência clara entre a imagem e as informações dos trechos.
Se o RAG não permitir identificar com segurança, responda “informação insuficiente nos trechos recuperados para diagnóstico.”
##Nas explicações, cite sempre o trecho recuperado que embasou a conclusão.';
v_prompt2 := v_prompt
|| '. Estes dados referem-se à cultura de '
|| p_tipo_cultura
|| ': '
|| v_messages
|| '. Cite o documento de origem dos dados em destaque.';
return fnc_26ai_rag_agro(
v_prompt2,
p_credential,
v_base64_image,
p_comp_id
);
end;
Ponto de atenção: 1- cuidado com temperatura usando “.” ou “,” para valores decimais. Neste caso, cheque sua sessão e ajuste se preciso: execute immediate(‘alter session set nls_numeric_characters=”.,” ‘);
2- o embedding da imagem acontece com a função fnc_26ai_embed_image no ato da chamada desta rotina, para facilitar o entendimento ( mas acaba onerando o tempo de execução ). Uma estratégia para sua solução é vetorizar ( realizar o embedding da imagem ) com a função fnc_26ai_embed_image a cada imagem carregada ao banco. Assim, não seria necessário vetorizar a cada chamada, mas sim herdar o vetor já salvo.
3- como evolução, podemos recuperar um conjunto maior de candidatos e aplicar um reranker para selecionar os trechos mais relevantes antes da geração. Neste cenário, é necessário definir a consulta usada pelo reranker — por exemplo, uma descrição textual dos sintomas visíveis, acompanhada da cultura informada — e verificar as modalidades aceitas pelo modelo escolhido. A etapa pode reduzir o ruído no contexto enviado ao modelo generativo, mas deve ser avaliada quanto à qualidade da recuperação, ao custo e à latência. O código apresentado não usou este recurso, mas será usado em outros artigos da série.
Modelo Re-Rank na OCI (dado de Out/2026): https://docs.oracle.com/en-us/iaas/Content/generative-ai/cohere-rerank-4-0.htm
Cada trecho recuperado é concatenado com sua respectiva fonte documental. Esse procedimento permite que a resposta final apresente evidências e referências, favorecendo rastreabilidade e transparência na recomendação gerada.
Em seguida, a função constrói um prompt especializado em fitopatologia. O prompt orienta o modelo a observar sintomas visuais, como cor, formato e distribuição das lesões, e a relacioná-los exclusivamente às informações recuperadas. Também determina que o modelo informe quando os dados forem insuficientes para um diagnóstico seguro.
Por fim, a função chama fnc_26ai_rag_agro, responsável por encaminhar o prompt enriquecido e a imagem ao modelo multimodal do OCI Generative AI. Esse fluxo reduz a dependência exclusiva do conhecimento interno do modelo generativo. A resposta passa a ser fundamentada em documentos específicos da cultura analisada, com indicação das fontes utilizadas. Dessa forma, a solução demonstra como usar dados privados para apoiar aplicações de precisão por meio de busca vetorial, RAG multimodal e IA generativa.
Etapa 7: Criação da Tool no banco
Para MCP, precisamos de uma função para upload de imagem em base64 acontecendo por partes, visto algumas limitações de tamanho de payload encontradas até esta data, em Outubro/2026:
create or replace function FNC_26AI_AGRO_BASE64(
p_upload_id in varchar2,
p_posicao in number,
p_parte in varchar2
) return varchar2 authid definer
as
pragma autonomous_transaction;
l_base64 clob;
l_json json_object_t := json_object_t();
begin
begin
select base64_imagem
into l_base64
from TB_26AI_AGRO
where upload_id = p_upload_id
for update nowait;
exception when no_data_found then
insert into TB_26AI_AGRO(file_name, file_mimetype, upload_id, base64_imagem)
values('test.jpg', 'image/jpeg', p_upload_id, empty_clob())
returning base64_imagem into l_base64;
end;
if p_posicao = dbms_lob.getlength(l_base64) + 1 then
dbms_lob.writeappend(l_base64, length(p_parte), p_parte);
end if;
l_json.put('status','SUCCESS');
l_json.put('recebidos',dbms_lob.getlength(l_base64));
commit;
return l_json.to_string();
end;
/
Criação da tool associada às funções:
declare
l_erros number;
begin
dbms_cloud_ai_agent.create_tool(
tool_name => 'TOOL_26AI_AGRO_UPLOAD_BASE64',
attributes => q'~{
"function":"FNC_26AI_AGRO_BASE64",
"instruction":"Receba uma parte Base64 por chamada, ate 16000 caracteres, em ordem. O cliente local le os bytes e gera o Base64. Use o mesmo ID para todas as partes.",
"tool_inputs":[
{"name":"P_UPLOAD_ID","description":"UUID sem hifens gerado no cliente."},
{"name":"P_POSICAO","description":"Posicao inicial no Base64, comecando em 1."},
{"name":"P_PARTE","description":"Parte Base64 de ate 16000 caracteres."}]
}~');
dbms_cloud_ai_agent.create_tool(
tool_name => 'TOOL_26AI_AGRO',
attributes => q'~{
"function":"FNC_26AI_AGRO",
"instruction":"Depois de enviar todas as partes, confira o tamanho e analise a imagem agricola. Executa o pipeline OCI e retorna analise de ate 4000 caracteres.",
"tool_inputs":[
{"name":"P_UPLOAD_ID","description":"Mesmo ID usado no envio das partes."},
{"name":"P_COMP_ID","description":"OCID do compartment."},
{"name":"P_TIPO_CULTURA","description":"Cultura, por exemplo Soja."},
{"name":"P_CREDENTIAL","description":"Nome da credencial, por exemplo OCI_CRED."}]
}~');
end;
/
Para conferir os metadados e os argumentos registrados:
SELECT DBMS_CLOUD_AI_AGENT.DESCRIBE_TOOL(
tool_name => 'TOOL_26AI_AGRO' ) teste_tool
Referências para definição de tool e atributos: DBMS_CLOUD_AI_AGENT
Etapa 8: Integração MCP
MCP (Model Context Protocol) é um padrão que define como os agentes descobrem e usam ferramentas (tools). Em vez de criar integrações personalizadas para cada plataforma de IA, você disponibiliza as ferramentas por meio do MCP uma única vez, e qualquer agente compatível com MCP pode utilizá-las.

Figura 8 – MCP
Para Autonomous Database, utilize este padrão de URL do endpoint MCP:
https://dataaccess.adb.{region-identifier}.oraclecloudapps.com/adb/mcp/v1/databases/{database-ocid}
Substitua {region-identifier} pela sua região (por exemplo, us-ashburn-1) e {database-ocid} pelo OCID do seu banco de dados.
No Console OCI, abra seu Autonomous Database e adicione esta Free-form tag:
Nome: adb$feature
Valor: {"name":"mcp_server","enable":true}
Procedimento em detalhes neste link.
Na etapa de integração abaixo, podemos usar o usuário do banco que possui acesso a elas, ou gerar um Bearer Token.
8.1 – Para Claude Desktop:
{
"mcpServers": {
"oracle_sales": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://dataaccess.adb.{region-identifier}.oraclecloudapps.com/adb/mcp/v1/databases/{database-ocid}",
"--allow-http"
],
"transport": "streamable-http"
}
}
}
Ponto de atenção: (1) em https ajuste o ocid do seu Autonomous Database; (2) o servidor / client que executar deve ter o binário do npx instalado; (3) cuidado com regras de acesso / security list / firewall.
Ao iniciar o Claude Desktop, uma tela de login será exibida para inserir as credenciais do banco de dados.
Como alternativa, use a autenticação por token Bearer:
# Gerar token (válido por 1 hora)
curl --location 'https://dataaccess.adb.{region}.oraclecloudapps.com/adb/auth/v1/databases/{db-ocid}/token' \
--header 'Content-Type: application/json' \
--data '{
"grant_type": "password",
"username": "<db-username>",
"password": "<db-password>"
}'
Ponto principal: o cliente de AI coordena a chamada da ferramenta; o banco executa o pipeline e aciona os serviços externos configurados
8.2 – Para Codex:
O fluxo será:
- Acessa o arquivo colado na console e gera o Base64.
- Divide e envia as partes e chama a tool TOOL_26AI_AGRO_UPLOAD_BASE64.
- Chama a tool TOOL_26AI_AGRO.
Através da console do Codex: Settings > Plugins > MCP > Add

Figura 9 – Exemplo de uso via Codex
Pontos de atenção:
Accept application/json
Content-Type application/json
Para gerar o bearer token: (válido por 1 hora)
curl --location 'https://dataaccess.adb.{region}.oraclecloudapps.com/adb/auth/v1/databases/{db-ocid}/token' \
--header 'Content-Type: application/json' \
--data '{
"grant_type": "password",
"username": "<db-username>",
"password": "<db-password>"
}'
Ajuste username e password conforme schemas de banco onde foram criadas as tools, e ajuste o endpoint conforme {region} e {db-ocid} do Autonomous Database. Exemplo:
Ponto de atenção: (1) usaremos apenas o “access_token“; (2) apontamos o schema de banco e a senha apenas nesta etapa de geração do token; (3) cuidado com acesso deste client ao banco de dados: firewall / security list

Figura 10 – Exemplo de geração de token
Neste ponto, definimos a variável de ambiente citada, MCP_BEARER_TOOL_V1, com o valor do access_token gerado. Exemplo com PowerShell em Windows, setando o token gerado acima na variável de ambiente:

Figura 11 – Exemplo de geração de variável de ambiente
Comando utilizado em PS:
[Environment]::SetEnvironmentVariable('MCP_BEARER_TOOL_V1', '<access_token>', 'User')
Após restart do Codex, podemos testar:
“Liste as ferramentas disponíveis no MCP do Autonomous”

Figura 12 – Primeiro teste em Codex
E em seguida, enviar uma imagem para testes (colando na console do Codex):

Figura 13 – Resposta em Codex com diagnóstico e citação do PDF
Através do documento previamente vetorizado em banco, Doc-256-2030L-1.pdf da Embrapa, podemos resgatar detalhes para validar o resultado:

Figura 14 – Referência do PDF vetorizado
Com sucesso destas etapas, veja as possibilidades de vetorizar outras fontes, com culturas diferentes como Citros, Café, … e com isso ampliar as capacidades de resposta por parte da tool exposta ao MCP.
Exemplos usando APEX PWA para Soja, Citros e Café respectivamente (etapas para criação APEX PWA em APEX Office Hours)

Figura 15 – Outros cenários de teste, com outras culturas
Resultados dos exemplos para as três culturas acima:

Figura 16 – Resultados obtidos
Etapa 9: Integração REST
Nesta etapa vamos obter o mesmo resultado dos testes, mas fazendo uma integração por REST para executar a função – mesma usada pela tool do MCP. Exemplo:
Definição do REST via console do Autonomous:

Figura 17 – Definições REST na console de Database Actions do Autonomous
Definições utilizadas:
- Módulo: mod1
- Template: temp1
- Handler: POST com código (mesmo da imagem acima) :
DECLARE
V_RESPONSE CLOB;
V_UPLOAD_ID VARCHAR(32);
BEGIN
V_UPLOAD_ID := LOWER(RAWTOHEX(SYS_GUID()));
insert into TB_26AI_AGRO(file_name, file_mimetype, upload_id, base64_imagem)
values('test_rest.jpg', 'image/jpeg', V_UPLOAD_ID, :body_text ) ;
V_RESPONSE := DBMS_CLOUD_AI_AGENT.RUN_TOOL(
tool_name => 'TOOL_26AI_AGRO',
input => '{"P_UPLOAD_ID":"'|| V_UPLOAD_ID || '",
"P_COMP_ID":"ocid1.compartment.oc1..xxxxxxxxxx",
"P_TIPO_CULTURA":"Soja",
"P_CREDENTIAL":"OCI_CRED"}'
);
:P_RESPONSE := substr(V_RESPONSE,1,32000) ;
END;
Obs.: para este teste não precisamos do nome do arquivo, mas pode ser usado via parâmetro de entrada
- Parâmetro de saída:

Figura 18 – Definições de parâmetros REST
Ponto de atenção: (1) parâmetro para a entrada da imagem, em base64, definida por :body_text ( usado no insert )

(2) a criação de endpoints REST num esquema de banco faz uso do ORDS, e precisa ter uma habilitação ao esquema obrigatoriamente:
begin
ORDS.ENABLE_SCHEMA(
p_enabled => TRUE,
p_schema => '<seu esquema de banco>',
p_url_mapping_type => 'BASE_PATH',
p_url_mapping_pattern => 'agro',
p_auto_rest_auth => FALSE);
end;
O trecho variável da URL mostrado vem de p_url_mapping_pattern, conforme destaque do endereço no teste via Postman abaixo:
https://<servidor com ORDS>/<p_url_mapping_pattern>/<modulo>/<template>
Teste via Postman:

Figura 19 – Teste da chamada do endpoint (imagem enviada como base64 no body)
Neste exemplo REST, enviamos o Base64 diretamente no corpo da requisição, através de :body_text . Assim, o base64 da imagem é enviado diretamente no body da requisição REST e a tool TOOL_26AI_AGRO é executada. Veja que obtemos a mesma resposta do teste anterior.
(3) Definições REST em Oracle AI Database exigem ORDS, e podem ser realizadas de várias maneiras:
- Console REST em Database Actions do Autonomous
- Command Line usando ORDS.DEFINE_MODULE, ORDS.DEFINE_TEMPLATE e ORDS.DEFINE_HANDLER
- Oracle SQL Developer, menu REST Data Services

Figura 20
- Console do Oracle Application Express, Restful Services:

Figura 21
Segurança:
A exposição do pipeline por MCP e REST exige controles sobre quem pode executar as funções, quais dados podem ser consultados e quais informações podem ser enviadas aos serviços de AI. Neste exemplo, o embedding local com ONNX evita a chamada externa nessa etapa, mas a geração da resposta continua enviando a imagem e os trechos recuperados ao modelo configurado (RAG). Ao utilizar embedding externo, a imagem também é transmitida ao serviço responsável pela vetorização.
As credenciais devem ser mantidas nos mecanismos apropriados do banco e do cliente, sem inclusão de senhas, chaves ou tokens em código-fonte, capturas de tela e logs. As permissões de banco, políticas IAM e ACLs de rede devem se limitar aos objetos, serviços e destinos necessários.
Políticas VPD podem complementar essa proteção, desde que o contexto de identidade e as regras sejam definidos e testados também nas chamadas realizadas pelas ferramentas.
Para a integração REST, habilitar o esquema no ORDS não substitui a proteção do módulo publicado. O endpoint deve exigir autenticação e privilégios adequados, além de validar o formato e o tamanho das imagens. Também devem ser definidos limites de chamadas e de consumo, pois uma requisição pode acionar serviços externos com custo. Na interface MCP, parâmetros de infraestrutura, como credencial e compartment, devem preferencialmente ser resolvidos no servidor ou restritos a valores previamente autorizados.
Os documentos recuperados devem ser tratados como evidências, sem autoridade para alterar as instruções da aplicação. Orientações nas tools e no prompt ajudam a reduzir o risco de prompt injection, mas precisam ser combinadas com validação de entradas, ferramentas de escopo limitado e controles de acesso. A solução deve registrar a identidade do solicitante, a operação, os documentos recuperados, o modelo utilizado e o resultado da execução, evitando armazenar segredos e conteúdo sensível desnecessário. Esses registros apoiam a investigação de falhas e a rastreabilidade das análises.
O banco convergente oferece diversos recursos para cobrir estes e outros pontos de segurança:

Figura 22 – Database Security
Pontos a reforçar:
- O MCP pode operar com as políticas de VPD configuradas no banco; é necessário definir e testar as regras de acesso para os usuários envolvidos.
- Deep Data Security é um novo recurso do Oracle 26ai : https://www.oracle.com/security/database-security/features/deep-data-security/

Figura 23 – Deep Data Security
Pontos de atenção:
- O exemplo utiliza o MCP gerenciado do Autonomous AI Database. Em instalações próprias, o ORDS oferece suporte a MCP, mas a exposição de ferramentas personalizadas exige verificar as versões de banco. Para DBMS_CLOUD veja esta documentação: https://docs.oracle.com/en/database/oracle/oracle-database/26/sutil/using-dbms_cloud-family-packages.html
- O teste realizado requer um cliente compatível com MCP que ofereça suporte ao transporte
streamable-http, a exemplo de Codex e Claude Desktop. - O token expira após uma hora na autenticação por token Bearer.
Conclusão
Neste primeiro artigo, apresentei um fluxo que combina imagens de culturas agrícolas, documentos técnicos e inteligência artificial para apoiar a investigação de possíveis doenças e pragas. O Oracle AI Database reúne o armazenamento das imagens, a busca vetorial e a execução das rotinas, enquanto o modelo generativo recebe a imagem e os trechos recuperados para produzir uma análise contextualizada, com indicação das fontes.
A qualidade dessa análise depende de escolhas que vão além do prompt: imagens adequadas, documentos relevantes e atualizados, embeddings compatíveis e validação dos resultados por profissionais da área. A proximidade entre vetores ajuda a selecionar informações, por isso, a solução deve apresentar hipóteses, explicitar as evidências disponíveis e reconhecer quando elas são insuficientes.
A disponibilização da mesma lógica por MCP e REST amplia suas possibilidades de uso, desde clientes de IA até aplicações móveis desenvolvidas com Oracle APEX, por exemplo. Essa reutilização permite centralizar as regras do pipeline e evoluí-las de forma consistente, acompanhadas dos controles de autenticação, autorização e rastreabilidade necessários.
Para avançar da demonstração a uma aplicação de campo, o próximo passo é avaliar imagens e casos revisados por especialistas, medindo a relevância dos trechos recuperados, a fidelidade das referências, a capacidade de reconhecer situações inconclusivas, a latência e o custo por análise. Essa validação orientará a escolha dos modelos, o ajuste do chunking e a eventual adoção de reranking, preservando o propósito apresentado: apoiar decisões agronômicas com IA em Oracle AI Database.
