Article
What We Learned Giving an AI Agent 40+ Oracle Tools
1 November 2026
The first question a DBA asks about an AI assistant is not how smart it is. It is what the thing can do to the database, and where the data goes.
We built an agent for Oracle DBAs and gave it more than 40 tools. This article covers why we did not give it free SQL, what we changed about the tools, and how we measure it. The numbers come from our own evaluation runs on a test estate with planted incidents, not from customer databases.
Why not just let the model write SQL
Text-to-SQL demos well and fails in three ways on a real database.
It is unsafe. A generated query can read application rows, run a costly plan on a busy system, or both. A prompt telling the model to be careful is not a control.
The data is often gone. Ask why a database was slow at 14:10 at four in the afternoon, and V$SESSION only knows about now. The answer has to come from history that someone collected.
A correct query is not a correct answer. A count of commits does not say whether an application commits too often. A DBA needs a rate, a baseline and the window it covers. We wanted those to come with the data, not depend on what the model thought of.
So one rule runs through the design: a fixed, human-reviewed list of read-only queries is the only way SQL reaches a monitored database. Each returns at most 100 rows and stops after 15 seconds. Nearly everything else is read from a repository that the product filled itself: session samples, SQL statistics, metrics, space and alerts. If generated SQL is switched on, it can reach only that repository, behind a lexer, an allowlist, a cost check on EXPLAIN PLAN and a row cap, and with no connection to any monitored database.
The agent never reads the rows of application tables, never runs SQL pasted into the chat, and does not read AWR, ASH, ADDM or SQL Monitor. The one exception, a plan outline for a plan fix card, uses the Diagnostics and Tuning Packs and sits behind a license switch.
What the tools cover
The tools follow the way a DBA works through a problem:
- Activity: sessions, blocking episodes, wait events, and a report on an incident window
- SQL: a statement's history per plan, plan changes, and the statements touching an object
- Metrics: one database against its baseline, or two windows against each other
- Space: tablespaces, segments, growth and datafile history
- Health: backups, Data Guard, memory, OS log findings and Exadata cells
- Across databases: rankings, wait breakdowns and overviews
- Your procedures: a search over your runbooks and past incidents
- Changes: cards that propose a change and wait for a person
What we had to change about the tools
Fewer doors. Many of the tools sit behind one entry point now. analyze_sql, for example, chooses between a quick read and a deep analysis, and three fleet tools front seven older ones. The model chooses from a shorter list than the total, and the entry point picks the detail.
List order matters. When get_metrics was first in the tool list, a question about one statement often opened with a get_metrics call whose result was never used. So the SQL tools now come first. Nobody would guess this from reading the prompt.
Tools do the thinking they can. In our latest run, half of the graded turns needed one tool call, and the longest took seven. Here is a question from that run: who held the lock between 09:00 and 10:00, and why did they not commit? It took one call, get_sessions with aspect=blocking and that window, 8 seconds and about 93,000 tokens. The answer named the root blocker, 09:05 to 09:49, with 40 sessions waiting on enq: TX - row lock contention. Then came the part we care about most. The holder was active for 320 of 2,695 seconds, about 12%, so the answer said the samples did not prove why it never committed, only that the transaction stayed open while the session sat mostly idle. It reported a likely cause and labelled it as likely.
The safety rules
Masking happens before the call leaves. Database, host and user names become aliases, and values in SQL text become typed placeholders. The model sees status = '?s:3KQ7MZ', and the real names come back in the answer. Bind values and table rows are never sent, because the product does not read them.
Nothing changes without a click. To kill a session, the agent prepares a card with the statement, the database and what it checked. Only a click on that card's button runs it. Typing "yes, do it" does not. Only the person who asked can click, the card expires after 10 to 30 minutes, and the product reads again before acting, so a session that has stopped blocking is not killed.
Every question has a budget. 15 rounds, 1.2 million tokens and 8 minutes. Then it answers with what it found.
How we grade it
The catalog has 200 active questions: 134 we rate expert, 65 hard and 1 medium. Some continue a chat, such as "what happened in the first one, and why?". The test estate has planted incidents, so the grader knows what should have been found. Grading mixes a judge model and plain code:
- A required tool that was never called fails the question, whatever the judge thought.
- Each number in an answer is checked against the numbers the tools returned.
- A contradicted fact caps the score at 35.
- Presenting something unmeasured as clean is among the most severely graded errors. The code name is
unmeasured_reported_as_clean. - When judge opinions disagree, more are taken and the median counts. One answer in our latest run drew 35, 91 and 35.
- Each run stores a fingerprint of the prompt and of the grading rules. Two runs are compared only when both match. Otherwise a better score may just mean a kinder grader.
For most of our runs, a model graded its own answers. We recorded that on each run as a known bias, and later made two models from different vendors grade each other. Cross-grading confirmed the results: 163 of 186 graded questions passed when self-graded, 166 of 192 when graded by the other vendor's model. We now grade only across vendors.
The results
Our two latest runs share the same prompt and the same grading rules. Each model was graded by the other.
| Model A | Model B, high reasoning | |
|---|---|---|
| Passed | 166 of 192 (86%) | 146 of 192 (76%) |
| Average score | 86.9 | 80.9 |
| Numbers found in tool results | 98.8% of 1,204 | 96.5% of 3,208 |
| Median tokens per question | 96,030 | 165,995 |
| Median time | 11 s | 22 s |
Two things stand out.
The two models trade off differently. Model B says far more, with 2.7 times as many numbers, every one of them checked against the tool results; Model A is twice as fast and passes more. A single pass rate would hide that, which is why we publish both, and why you choose the model.
Evaluation pays for itself. Model B started that night at 103 passed of 186. Five runs later it was at 146 of 192, after the prompt, the tools and the grading rules were tightened and its reasoning setting raised.
Prompt caching matters a lot here: about 92% of the tokens in Model A's run were read from cache.
What we would tell anyone building this
- Do not start with the model. Start by collecting the history it will need.
- Make the tool say what it did not measure, in words, and grade the model hard on repeating that. A false "all clear" does more harm than "I don't know".
- Plant the incidents, so the grader knows the answer.
- Fingerprint the prompt and the grader, or your trend line will tell you stories.
- Read every graded answer, not the average. The average hides what a grader catches.
- Keep the person on the button. A change should always wait for a click.
Trying it
This assistant is Scops AI, part of Scops, an Oracle monitoring platform. You connect your own model. The free Community edition includes it for up to 2 databases, and the live demo shows saved chats on made-up data.
Sources
- Scops docs: Ask Scops AI, Privacy and data masking
- Evaluation figures: our own runs of 28 September and 29 October 2026, on a test estate with planted incidents