In earlier posts, I showed how to call the Oracle Private AI Services Container from PL/SQL to generate vector embeddings. Those examples used the container’s embedding endpoint and demonstrated how Oracle AI Database 26ai can send text to the container and receive a vector back.
In this post, we’ll use a similar approach, but instead of generating vector embeddings, we’ll call the Oracle Private AI Services Container LLM Service to generate a text response with an LLM.
The main objective is to allow developers to invoke LLM text generation directly from the database.
The package function DBMS_VECTOR_CHAIN.UTL_TO_GENERATE_TEXT is a native Oracle AI Database 26ai feature designed to interact with Large Language Models. It allows a user to send a prompt from the database to an AI model, such as the Oracle Private AI Services Container LLM Service, and receive a generated text response.
A similar text-generation API is also available in the lighter-weight DBMS_VECTOR package through DBMS_VECTOR.UTL_TO_GENERATE_TEXT.
We’ll ask an LLM a simple question:
input := 'What is SQL?';
For this example, Oracle AI Database 26ai communicates with the Oracle Private Services Container over HTTP. This keeps the setup simple and is useful for development, testing, or internal proof-of-concept environments. For production deployments, you should use HTTP/SSL so that traffic between Oracle AI Database 26ai and the Oracle Private AI Services Container is encrypted and authenticated.
It is also good practice to run the Oracle Private AI Services Container on a separate host from Oracle AI Database 26ai. LLM inference can require significant CPU, memory, or GPU resources. Running the service separately helps keep database workloads isolated from model inference workloads.
To get a quick overview about the topics covered, the post is divided into the following sections:
- Accessing the Oracle Private AI Services Container LLM Service
- Call the LLM Service and generate text from PL/SQL
- Call the LLM Service and generate text from SQL
- Increasing the transfer timeout
- Troubleshooting
- Summary
- Resources
Let’s get started.
Accessing the Oracle Private AI Services Container LLM Service
Prerequisite – A running Oracle Private AI Services Container
I’m going to assume that the Oracle Private AI Services Container is already installed, configured, and running.
Please refer to the Oracle Private AI Services Container User Guide for download, setup, and installation instructions.
For this blog post, the container exposes the LLM Service over HTTP on port 8080.
In this example, I use the container image private-ai:large-gpu-infer-26.2.1.0.0. This image includes vLLM and GPU support, which allows the Oracle Private AI Services Container LLM Service to serve the Ministral-3-3B-Reasoning-2512 model through the chat completions endpoint exposed on the server “your-fully-qualified-hostname”.
This model is included in the container, so no additional download is required. You can also use other models; those will need to be downloaded separately.
Step 1. Verify the HTTP endpoint
Before calling the service from the database, verify that the endpoint is reachable.
Run the following command from a machine that has network access to the container host:
curl -i http://your-fully-qualified-hostname:8080/health
A successful response looks similar to this:
HTTP/1.1 200 OK
date: Thu, 23 Jun 2026 12:14:11 GMT
x-ratelimit-limit-requests: 60
x-ratelimit-remaining-requests: 59
x-ratelimit-reset-requests: 1
x-server-id: 3c66bfe8-b586-4b8f-b258-a93d058ce074
content-length: 0
The 200 OK status confirms that the container is available.
After verifying that the container is running, you can query the models endpoint to see which models are currently available through the Oracle Private AI Services Container LLM Service.
Run the following command:
curl http://your-fully-qualified-hostname:8080/v1/models | jq
The jq utility formats the JSON response for easier reading.
On Oracle Linux, you can install jq with:
sudo dnf install –y jq
On Ubuntu Linux, use:
sudo apt install –y jq
The response should include the available models, including the Ministral-3-3B-Reasoning-2512 model.
{
"data": [
{
"id": "Ministral-3-3B-Reasoning-2512",
"modelDeployedTime": "2026-07-31T14:38:47.516225405Z",
"modelSize": "7.20G",
"modelCapabilities": [
"TEXT_GENERATION"
]
...
}
Next, test the LLM Service endpoint directly with curl.
The text generation endpoint is:
/v1/chat/completions
Run the following command:
curl -i http://your-fully-qualified-hostname:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Ministral-3-3B-Reasoning-2512",
"messages": [
{
"role": "user",
"content": "What is SQL?"
}
],
"max_tokens": 128,
"temperature": 0
}'
If the service is configured correctly, the response payload should contain generated text for the question “What is SQL?”, for example:
SQL, or Structured Query Language, is a standard language used to manage and query data stored in relational databases.
...
Testing the endpoint with curl before calling it from Oracle Database helps separate container or network issues from database configuration issues.
Step 2. Grant network access from the database
Oracle Database controls outbound network access with network ACLs. Before a database user can call the Oracle Private AI Services Container LLM Service over HTTP, a DBA must grant the required network permission.
In this example, the database user is:
vectordb
The container host is:
your-fully-qualified-hostname
The HTTP port is:
8080
Run the following PL/SQL block as the PDB’s SYS or SYSTEM user:
BEGIN
DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
host => 'your-fully-qualified-hostname',
lower_port => 8080,
upper_port => 8080,
ace => xs$ace_type(
privilege_list => xs$name_list('http'),
principal_name => 'vectordb',
principal_type => xs_acl.ptype_db));
END;
/
This grants the vectordb schema permission to make HTTP calls to the specified host and port.
The example uses the http privilege because we only need outbound HTTP access for this scenario. You could also grant connect, but that provides broader capabilities than required here.
Step 2.1 Verify the network ACL
Run the following command as user vectordb and check the ACL entry:
SELECT host, lower_port, upper_port, privilege, status
FROM user_host_aces;
The expected output should include a row similar to this:
HOST LOWER_PORT UPPER_PORT PRIVILEGE STATUS
----------------------------- ---------- ---------- --------- -------
your-fully-qualified-hostname 8080 8080 HTTP GRANTED
This confirms that the current schema can call:
http://your-fully-qualified-hostname:8080/...
If the ACL is missing or incorrect, the PL/SQL call will fail. A common error is:
ORA-29273: HTTP request failed
To get more details, run:
SELECT UTL_HTTP.GET_DETAILED_SQLERRM;
A response looks similar to this:
GET_DETAILED_SQLERRM
--------------------------------------------------------------------------------
ORA-24247: network access denied by access control list (ACL)
This usually means that the ACL was not granted, was granted to the wrong user, or was created for the wrong host or port. Please see the Troubleshooting section of this post for steps to resolve the issue.
Call the LLM Service and generate text from PL/SQL
We can now call the Oracle Private AI Services Container LLM Service from PL/SQL.
The following block sends the question “What is SQL?” to the model and prints the generated answer.
SET SERVEROUTPUT ON
DECLARE
input CLOB;
params CLOB;
output CLOB;
BEGIN
input := 'What is SQL?';
params := '
{
"provider": "privateai",
"url": "http://your-fully-qualified-hostname:8080/v1/chat/completions",
"host": "local",
"model": "Ministral-3-3B-Reasoning-2512",
"temperature": 0,
"max_tokens": 256,
"transfer_timeout: 30
}';
output := DBMS_VECTOR_CHAIN.UTL_TO_GENERATE_TEXT(
input,
json(params));
DBMS_OUTPUT.PUT_LINE(output);
IF output IS NOT NULL THEN
DBMS_LOB.FREETEMPORARY(output);
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
DBMS_OUTPUT.PUT_LINE(SQLCODE);
END;
/
A typical response may look like this:
SQL, or Structured Query Language, is a standard language used to store, query, update, and manage data in relational databases.
Let’s look at the important parts of the JSON payload.
{
"provider": "privateai",
"url": "http://your-fully-qualified-hostname:8080/v1/chat/completions",
"host": "local",
"model": "Ministral-3-3B-Reasoning-2512",
"temperature": 0,
"max_tokens": 256,
"transfer_timeout": 30
}
The parameters are:
- provider: “privateai” – Identifies the Oracle Private AI Services LLM Service provider.
- url: Points to the HTTP text generation endpoint.
- host: Uses the provider-specific “local” setting. So no database credential is required for HTTP.
- model: Identifies the model used to generate the response, for example “Ministral-3-3B-Reasoning-2512”.
- temperature: Controls the variability of the generated text.
- max_tokens: Sets the maximum response length.
- transfer_timeout: Maximum wait time before timeout.
DBMS_VECTOR_CHAIN.UTL_TO_GENERATE_TEXT sends the prompt and parameters to the configured LLM Service and returns the generated text response.
The first request to the model may take a little longer than later requests. This is expected because the model may need to be loaded into memory before it can generate a response. Once loaded, subsequent requests are usually faster.
Call the LLM Service and generate text from SQL
The same LLM Service can also be called directly from SQL.
First, define the parameter JSON as a SQL*Plus bind variable:
VAR params CLOB;
BEGIN
:params := '{
"provider": "privateai",
"url": "http://your-fully-qualified-hostname:8080/v1/chat/completions",
"host": "local",
"model": "Ministral-3-3B-Reasoning-2512",
"temperature": 0,
"max_tokens": 256,
"transfer_timeout": 30
}';
END;
/
Configure the SQL*Plus output:
SET LONG 100000
SET LONGCHUNKSIZE 100000
SET LINESIZE 200
SET PAGESIZE 0
SET HEADING OFF
SET FEEDBACK OFF
SET TRIMSPOOL ON
Run the follwowing query:
SELECT DBMS_VECTOR_CHAIN.UTL_TO_GENERATE_TEXT
('What is SQL?',
JSON(:params)
) AS generated_text;
The generated output should be similar to this:
SQL, or Structured Query Language, is a standard language used to manage and query data stored in relational databases.
...
This SQL pattern is useful when you want to integrate text generation into SQL-driven workflows, demos, or application logic.
Increasing the transfer timeout
LLM requests can take longer than embedding requests. This is especially true when the model is loaded for the first time or when the prompt asks for a longer answer.
If the request fails with:
ORA-29276: transfer timeout
increase transfer_timeout in the parameter JSON:
"transfer_timeout": 120
The value is specified in seconds. In this example, the database waits up to 120 seconds for the service to return a response.
You can also reduce max_tokens if you want the model to return a shorter answer
"max_tokens": 128
In this case, we reduce max_tokens from 256 to 128.
Troubleshooting
- ORA-29273 / ORA-24247: Network ACL missing or incorrect. Verify with SELECT host, lower_port, upper_port, privilege, status FROM user_host_aces;
- ORA-29276: Model cold-start or slow inference. Increase transfer_timeout or reduce max_tokens.
- Other Checks: Is the hostname correct? Is port 8080 open? Does the firewall allows traffic? Is the container listening on expected interface? Is the model loaded? Does the container have sufficient CPU, GPU, and memory?
Summary
In this post, you called the Oracle Private AI Services Container LLM Service from Oracle AI Database 26ai over HTTP.
You verified that the container was running, tested the REST endpoint, checked the available models, granted the required network ACL, and then generated text from both PL/SQL and SQL using DBMS_VECTOR_CHAIN.UTL_TO_GENERATE_TEXT.
The example used the Ministral-3-3B-Reasoning-2512 model and the simple question:
input := 'What is SQL?';
HTTP is convenient for development and internal testing. For production deployments, use HTTP/SSL so that requests are encrypted and authenticated.
Resources
- Oracle Private AI Services Container (oracle.com)
- Oracle Private AI Services Container (Download Oracle Container Registry)
- Oracle Private AI Services Container User Guide
- Oracle AI Vector Search User’s Guide
- Oracle AI Database 26ai Documentation
- DBMS_VECTOR_CHAIN.UTL_TO_GENERATE_TEXT
- DBMS_VECTOR.UTL_TO_GENERATE_TEXT
- Getting Started with Private Large Language Model Service – Part 1
- How to use the Oracle Private AI Services Container LLM Service with HTTP/SSL in PL/SQL
- How to use the Oracle Private Services Container with HTTP in PL/SQL (Vector Embeddings)
- How to use the Oracle Private Services Container with HTTP/SSL in PL/SQL (Vector Embeddings)
