There are only two ways to build generative AI on top of enterprise data. You either move the data to the AI — extract it, ship it to a vector store, embed it somewhere else, orchestrate it in a Python framework running on a VM — or you move the AI to the data and leave the data where your security model already covers it.

Autonomous AI Database has been making the second bet for a while. What changed recently is that the bet is now complete enough to build real applications on. In this post I walk through ten Select AI capabilities available on Autonomous AI Database on Dedicated Infrastructure (ADB-D), what each one actually does at the SQL level, and — more importantly for ADB-D customers — the fleet and networking implications that don’t show up in general SelectAI walkthroughs.

If you only take one thing from this post: the AI profile is still the unit of configuration. Everything below is either a new provider for a profile, a new attribute on a profile, or a new verb you can point at a profile. That consistency is the whole design.

The starting point: one profile, many providers

A quick refresher, because everything else hangs off this:

BEGIN
  DBMS_CLOUD_AI.CREATE_PROFILE(
    profile_name => 'SALES_AI',
    attributes   => '{"provider": "oci",
                      "model": "meta.llama-3.3-70b-instruct",
                      "credential_name": "GENAI_CRED",
                      "comments": "true",
                      "object_list": [{"owner": "SALES", "name": "ORDERS"},
                                      {"owner": "SALES", "name": "CUSTOMERS"}]}');
END;
/
BEGIN DBMS_CLOUD_AI.SET_PROFILE('SALES_AI'); END;
/

That’s it. From here, SELECT AI <prompt> works, and every feature below is an extension of this object.

1. AWS Bedrock as a first-class provider

Select AI now supports AWS as a provider, which means Amazon Bedrock foundation models generate the SQL that runs against your Oracle data.

BEGIN
  DBMS_CLOUD.CREATE_CREDENTIAL(
    credential_name => 'AWS_CRED',
    username        => '<AWS_ACCESS_KEY_ID>',
    password        => '<AWS_SECRET_ACCESS_KEY>');
END;
/

BEGIN
  DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
    host => 'bedrock-runtime.us-east-1.amazonaws.com',
    ace  => xs$ace_type(privilege_list => xs$name_list('http'),
                        principal_name  => 'ADMIN',
                        principal_type  => xs_acl.ptype_db));
END;
/

BEGIN
  DBMS_CLOUD_AI.CREATE_PROFILE(
    profile_name => 'BEDROCK_AI',
    attributes   => '{"provider": "aws",
                      "credential_name": "AWS_CRED",
                      "model": "<bedrock-model-id-or-inference-profile>",
                      "object_list": [{"owner": "SALES", "name": "ORDERS"}]}');
END;
/

Two details worth internalizing. First, unlike most providers, the model attribute is not optional for AWS — there is no default. You supply either a base model ID, an inference profile ID, or the corresponding ARN. Second, the Bedrock runtime endpoint is region-specific, so the host in your ACE has to match the region you’re calling.

The ADB-D angle: on Dedicated, outbound access from the database to a public endpoint is your VCN’s problem, not the service’s. A network ACE grants the database permission to call out; it does not create a route. If your ADB-D instance sits in a private subnet with no NAT gateway, the ACE will be in place and the call will still fail. Check the route table before you debug the credential. This is the single most common false alarm I see when ADB-D customers enable an external LLM provider for the first time.

The strategic point is bigger than the syntax: for customers running ADB@AWS, or for customers whose AI governance has already standardized on Bedrock, this removes the “but our models live over there” objection entirely. The data stays in the Exadata infrastructure you control. Only schema metadata crosses the boundary to generate the SQL.

2. In-database transformers: embeddings that never leave

Select AI RAG can now use an ONNX-format embedding model imported into the database itself, evaluated by the in-database ONNX Runtime. You reference it in the profile with the database: prefix:

BEGIN
  DBMS_CLOUD_AI.CREATE_PROFILE(
    profile_name => 'RAG_LOCAL',
    attributes   => '{"provider": "oci",
                      "model": "meta.llama-3.3-70b-instruct",
                      "credential_name": "GENAI_CRED",
                      "vector_index_name": "DOCS_INDEX",
                      "embedding_model": "database: ALL_MINILM_L12_V2"}');
END;
/

This is the feature I’d push hardest with regulated customers, and the reason is arithmetic rather than ideology. In a hosted-embedding RAG pipeline, every document chunk and every user prompt makes a round trip to an external API. The chunks are the raw text — the actual sensitive content, not metadata. With an in-database transformer, the chunking and vectorization happen inside the database perimeter, and only the retrieved context goes to the LLM for the final answer.

The secondary effects are real too: you eliminate the per-token embedding charge and the network latency of thousands of sequential API calls, and the imported model becomes a first-class database object — it participates in backup, recovery, Data Guard, and your existing privilege model.

A caveat I’d want stated honestly: embedding inference consumes ECPUs on your infrastructure. On ADB-D, where you’ve sized the Exadata rack, a large initial vectorization run competes with your workload. Plan the first bulk load like you’d plan any batch job.

3. Synthetic data generation

Test data management is one of those problems everybody solves badly and nobody writes about.

BEGIN
  DBMS_CLOUD_AI.GENERATE_SYNTHETIC_DATA(
    profile_name => 'SALES_AI',
    object_name  => 'CUSTOMERS',
    owner_name   => 'SALES',
    record_count => 500,
    user_prompt  => 'Diverse UK-based retail customers, mixed segments');
END;
/

The generation is schema-aware — data types, constraints, and referential integrity inform what the LLM produces, so the rows insert rather than bounce. Large multi-table generations are split into chunks and run in parallel, with per-chunk status tracked in a SYNTHETIC_DATA$<operation_id>_STATUS table and the operation logged in USER_LOAD_OPERATIONS.

Two things this replaces. It replaces masked production clones, which carry the residual re-identification risk that your DPO is right to worry about. And it replaces hand-written data generators, which always produce data that is too clean — uniformly distributed, no nulls, no edge cases. You can explicitly ask for the pathological rows: unicode names, boundary dates, malformed postal codes. That is genuinely hard to get from a production dump.

4. Feedback: teaching the model your schema

Generic LLMs don’t know that your REV_AMT_NET column is the one finance actually uses, or that “active customer” means something specific in your business. Select AI Feedback closes that loop and persists it.

-- Confirm a good generation
EXEC DBMS_CLOUD_AI.FEEDBACK(profile_name => 'SALES_AI', -
     sql_id => '852w8u83gktc1', feedback_type => 'positive', operation => 'add');

-- Correct a bad one
EXEC DBMS_CLOUD_AI.FEEDBACK(profile_name => 'SALES_AI', -
     sql_text => 'select ai showsql how many movies', -
     feedback_type => 'negative', -
     response => 'SELECT SUM(1) FROM "ADB_USER"."MOVIES"', -
     feedback_content => 'Use SUM instead of COUNT');

The mechanism is worth understanding because it explains the feature’s limits. On first use, Select AI creates a vector index named <profile_name>_FEEDBACK_VECINDEX, backed by a $VECTAB table holding embeddings of your prompts and corrections. On a subsequent prompt, vector search retrieves the top matches (default match_limit is 3) and injects them into the augmented prompt as hints.

So this is not fine-tuning. Nothing is retrained, and no corporate knowledge leaves the database. It’s automated, persistent, retrieval-based prompt engineering — which is a better fit for schema semantics anyway, because schemas change and fine-tunes don’t. Drop the profile and the index goes with it.

Note the feature is scoped to NL2SQL actions (runsqlshowsqlexplainsql) and requires a profile configured for SQL generation rather than RAG.

5. Conversations: multi-turn without rebuilding context

Real analysts don’t ask one perfect question. They ask, filter, pivot, and drill.

DECLARE
  l_conv_id VARCHAR2(50);
BEGIN
  l_conv_id := DBMS_CLOUD_AI.CREATE_CONVERSATION(
                 attributes => '{"title": "Q3 pipeline review"}');
  DBMS_CLOUD_AI.SET_CONVERSATION_ID(l_conv_id);
END;
/

SELECT AI show me top customers by revenue this quarter;
SELECT AI keep only the ones in Japan;
SELECT AI now graph their monthly trend;

Both short-term (session) and long-term (persistent, resumable, shareable) conversations are supported, and they work across runsqlchat, and narrate.

The part application developers should notice: this removes the chat-history caching layer from your application. The database holds conversation state, which means it also holds the audit trail — prompts are queryable via USER_CLOUD_AI_CONVERSATION_PROMPTS. For any customer who has to answer “what did people ask the AI about our data last quarter,” that view is the answer, and it’s already inside the compliance perimeter.

6. Property graphs: NL2GRAPH

SQL/PGQ is powerful and genuinely hard. GRAPH_TABLE with variable-length path patterns is not something a business analyst writes on a Tuesday.

Add the property graph to the profile’s object_list and Select AI reads the CREATE PROPERTY GRAPH metadata — nodes, edges, labels, properties — to translate a relationship question into a GRAPH_TABLE query. “Which accounts are connected to this flagged entity through two hops of shared ownership?” becomes a pattern match you didn’t have to write.

This is the democratization argument with actual substance behind it. Graph analytics have stayed niche largely because of syntax, not because the use cases are exotic — fraud rings, supply chain dependency, customer influence networks are all mainstream problems. And because it’s the same profile and the same SELECT AI interface, users don’t have to know whether the answer came from a relational join or a graph traversal.

7. Metadata-aware SQL generation

The cheapest accuracy win on this list, and the one customers most often skip.

Select AI can enrich the LLM’s context with table and column comments, schema annotations, and foreign key constraints — enabled through attributes on CREATE_PROFILE:

attributes => '{"provider": "oci",
                "comments": "true",
                "annotations": "true",
                "constraints": "true",
                "object_list": [...]}'

Foreign keys are the highest-leverage of the three. Without them, the model infers join paths from column-name similarity, which is exactly where hallucinated joins come from. With them, the join graph is declared rather than guessed.

Most enterprise schemas already carry this semantic information — DBAs have been writing column comments for thirty years and nobody read them. Now something does. If you’re piloting Select AI and accuracy is disappointing, turn these on before you go shopping for a bigger model.

8. Translation

SELECT AI TRANSLATE <text>;
-- or
DBMS_CLOUD_AI.TRANSLATE(...)

Backed by OCI Language services, configured with a target_language attribute on the profile, and callable from SQL, PL/SQL, or inside GENERATE and NARRATE flows.

The interesting use isn’t user-facing translation — it’s RAG normalization. If your document corpus is multilingual and your embedding model was trained predominantly on one language, retrieval quality degrades in ways that are hard to diagnose. Translating to a single language before embedding is a preprocessing step that measurably improves vector search, and now it’s one SQL call inside the same pipeline instead of an external service in the middle of your ingestion job.

9. Summarization at document scale

SELECT AI SUMMARIZE, or DBMS_CLOUD_AI.SUMMARIZE when you want control over length, output format, and extraction level. Input can be inline text, stored text, or a document referenced by location_uri in Object Storage. Large inputs are handled by chunking with map-reduce or iterative refinement, and the supported input size runs to roughly a gigabyte depending on the provider.

That chunking strategy is the feature. Anyone who has built a summarization pipeline knows that the code is 10% prompting and 90% chunk management, context-window arithmetic, and reassembly. Having that inside the database means the document never has to land on an application server first.

10. Select AI Agent: the framework, not just the answer

The other nine features make the database answer questions. This one makes it do work.

DBMS_CLOUD_AI_AGENT provides agents, tasks, tools, and teams, running the ReAct (Reasoning and Acting) pattern with short- and long-term memory, powered by the LLM in an AI profile.

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_AGENT(
    agent_name => 'ReturnsAgent',
    attributes => '{"profile_name": "SALES_AI",
                    "role": "You are an experienced customer agent handling product returns"}');
END;
/

Tools come in two flavors. Built-in: NL2SQL, RAG, web search, notification (Slack via DBMS_CLOUD_NOTIFICATION, email via OCI SMTP). Custom: any PL/SQL procedure. That second category is the one to sit with for a moment — if you have a PL/SQL package that calls a REST API, applies a business rule, or writes to a downstream system, it is now an agent tool with no adapter code. Thirty years of accumulated business logic becomes an agent’s action space.

Teams add a supervisor agent (supervisor attribute set to true) that routes subtasks to specialized worker agents, each paired with a task. And human-in-the-loop lets an agent suspend before a sensitive action — approving a refund, issuing a credit — and wait for a person, with the wait state visible in the history views.

Why this matters architecturally. The standard agentic stack today runs orchestration in an external framework: the agent process pulls data out of the database, reasons over it in application memory, and writes results back. Every loop iteration is a network round trip, and your data has left the perimeter to be reasoned about. Select AI Agent inverts that. Orchestration happens where the data lives, inheriting the database’s security model, auditing, and performance characteristics.

I’d be careful about overclaiming here — this doesn’t replace every external framework, and complex multi-agent systems with heavy non-database tooling still belong outside. But for workflows whose center of gravity is enterprise data, running the loop in the database eliminates an entire tier.

What ADB-D customers specifically need to check

On Dedicated, four things are different with regards to SelectAI, and all four are on you rather than on the service:

Release update level. Select AI Agent and DBMS_CLOUD_AI_AGENT require Oracle Database 19c 19.29 or later, or 26ai 23.26 or later. On ADB-D you control the maintenance cadence of your Autonomous Container Database, which is a feature until the day you wonder why a documented procedure doesn’t exist in your instance. Check the ACD’s RU first.

Egress. As covered above: network ACEs grant permission, the VCN provides the route. External providers need a NAT gateway or equivalent; OCI Generative AI does not require a network ACL but still needs a network path.

Privileges. These packages are typically enabled for ADMIN out of the box and need explicit EXECUTE grants plus per-principal ACEs for application schemas. On a fleet with dozens of PDBs, decide early whether AI profiles are centrally curated or self-service per schema. That’s a governance decision, not a technical one, and it’s much cheaper to make now than to retrofit.

Capacity. In-database embedding generation and parallel synthetic data generation consume the ECPUs you provisioned. On Dedicated, it shold be part of your fleet’s capacity planning.

Try it

I walked through three of these features end-to-end — synthetic data generation, in-database vectorization, and AWS Bedrock integration — in a recorded developer coaching session, building a secure RAG application with zero data movement:

Start with the metadata attributes on an existing profile. It costs nothing, it takes five minutes, and it will tell you more about your NL2SQL accuracy ceiling than any other single change.

Documentation