Skip to main content

Command Palette

Search for a command to run...

The Best APEX AI Tools Are Boring

Updated
6 min readView as Markdown
The Best APEX AI Tools Are Boring
J
Hi, thanks for stopping by! I am focused on designing and building innovative solutions using AI, the Oracle Database, Oracle APEX, and Oracle REST Data Services (ORDS). I hope you enjoy my blog.

The Temptation to Build a Smart Tool

When I started thinking about tools for APEX AI Agents, one of the first temptations was to create a single tool that could do everything. From a development perspective, it made sense. It means fewer tool definitions, less integration code, and one implementation to maintain.

The problem is that every additional capability adds more parameters, conditions, and possible outcomes for the agent to interpret. What looks like one convenient tool to us can become a difficult contract for the model to use correctly.

I have found that the best AI tools are a little boring. Their names describe what they do, their parameters are predictable, and they produce one clear business outcome.

My rule is:

One tool, one cohesive business operation.

This matters most for tools that change data. Retrieval tools can sometimes be broader, provided their parameters are different ways of querying the same dataset.

Why Broad Tools Create Problems

Consider a PL/SQL API from a bonus calculation app. Behind several APEX forms, the API can add a comment, change eligibility, open or close a review flag, adjust a bonus amount, manage workflow transitions, and write audit entries.

That is a perfectly reasonable API for the application. I would not, however, expose it directly to an AI Agent.

The agent would need to determine which operation the user requested, which parameters to provide, which values to preserve or clear, whether the workflow status should change, and which comments or reasons are required. Every option creates another path the model can misunderstand.

Instead, I would add a small tool-facing layer with operations such as:

  • mark_employee_ineligible

  • mark_employee_eligible

  • add_employee_comment

  • open_review_flag

  • close_review_flag

  • adjust_bonus_amount

The existing PL/SQL API continues to enforce the business rules. The narrower procedures and functions give the agent contracts that are easier to understand and use correctly.

-- The Application API: Great for APEX form processing, terrible for an LLM
PROCEDURE manage_bonus 
 (p_employee_id IN NUMBER,
  p_action      IN VARCHAR2, -- 'COMMENT', 'ELIG_CHANGE', 'FLAG', 'ADJUST'
  p_new_status  IN VARCHAR2 DEFAULT NULL,
  p_amount      IN NUMBER   DEFAULT NULL,
  p_reason      IN VARCHAR2 DEFAULT NULL,
  p_override    IN BOOLEAN  DEFAULT FALSE);

-- The AI Tool Layer: Boring, predictable, atomic contracts
PROCEDURE ai_mark_ineligible 
 (p_employee_id IN NUMBER,
  p_reason      IN VARCHAR2);

PROCEDURE ai_adjust_bonus_amount 
 (p_employee_id IN NUMBER,
  p_new_amount  IN NUMBER,
  p_reason      IN VARCHAR2);

Make Each Tool a Cohesive Operation

When I say one operation, I do not mean one SQL statement, field update, or PL/SQL procedure call.

Marking an employee ineligible may require changing their eligibility status, recording a required reason, updating the workflow state, and writing an audit entry. Those steps belong in one tool because they should succeed or fail together:

PROCEDURE ai_mark_ineligible 
 (p_employee_id IN NUMBER,
  p_reason      IN VARCHAR2);

Splitting the status change and required reason into separate tools creates a partial-completion problem. The first tool could succeed while the second fails, leaving an employee ineligible without the required explanation.

A tool should encompass all changes required to produce one atomic business outcome. That does not mean creating a tool for every database column. Too many small, overlapping tools can also make tool selection difficult. The goal is the clearest business contract with one atomic outcome.

Keep the Parameters Simple

Avoid generic action parameters that produce completely different behavior depending on one value. An update_employee tool with actions such as COMMENT, ELIGIBILITY, OPEN_REVIEW, and ADJUST_AMOUNT is still several tools hidden behind one definition.

When codes are necessary, define the permitted values and explain what they mean. Where practical, configure them as allowed values for the APEX tool parameter. The model should not have to infer internal codes or reverse-engineer a multipurpose API.

Keep Business Logic in PL/SQL

Most APEX applications already have views and PL/SQL APIs underpinning the user interface. I would reuse those APIs rather than put business logic into an agent tool.

Before exposing an existing API, consider adding a narrower, tool-facing procedure or function with a simpler contract. The wrapper translates a clear tool operation into calls to the existing API; it does not become a new home for the business rules.

The underlying API should still enforce validation, authorization, transaction integrity, and auditing. The agent chooses which approved operation to request. PL/SQL decides whether it is valid and performs the work.

Authorization Must Exist Below the Agent

An APEX Authorization Scheme can prevent a tool from being made available to users who should not use it. I would not rely on that alone.

The underlying PL/SQL API should also verify that the authenticated application user can perform the requested operation on the specified record. Authorization should never depend on the model correctly deciding what a user is allowed to do.

PROCEDURE ai_mark_ineligible (
    p_employee_id IN NUMBER,
    p_reason      IN VARCHAR2) IS
    l_app_user VARCHAR2(255) := V('APP_USER');
BEGIN
    -- 1. Enforce authorization below the LLM using APEX session state
    IF NOT hr_auth.can_modify_eligibility(p_actor => l_app_user, p_emp_id => p_employee_id) THEN
        raise_application_error(-20001, 'Unauthorized operation: user cannot modify eligibility.');
    END IF;

    -- 2. Delegate to the trusted core API; succeeds or fails as one atomic transaction
    hr_bonus_api.manage_bonus(
        p_employee_id => p_employee_id,
        p_action      => 'ELIG_CHANGE',
        p_new_status  => 'INELIGIBLE',
        p_reason      => p_reason
    );
END ai_mark_ineligible;

A Simple APEX Example

Suppose a user asks:

Mark employee 1234 ineligible for a bonus because they left before the end of the bonus period.

The agent selects mark_employee_ineligible and passes the employee identifier and reason. Because the tool changes data, I would enable Requires Confirmation so APEX asks the user to approve the operation before it runs.

The package-backed API verifies authorization, validates the employee's current status, and applies the eligibility change, reason, workflow update, and audit entry atomically. If any step fails, it rolls back the complete operation.

If the request is invalid or unauthorized, the tool returns a clear, business-safe error that the agent can report to the user. It should not expose internal implementation details, attempt to work around the error, or imply that the change succeeded.

A separate add_employee_comment tool is still useful because adding a general comment without changing eligibility is an independent business operation.

The Rule I Use

My rule is simple:

If trusted APEX application code cannot safely call an API with the same authenticated application user and authorization context, an AI agent should not call it either.

I do not think APEX AI tools need to be clever. I want them to be predictable, cohesive, authorized, and transactionally safe. In other words, they should be boring.

📷
The photo was taken at a pool on the Afon Sawdde, along the walking path to Llyn y Fan Fach, near Llanddeusant in the western Brecon Beacons. The mountain behind it is Picws Du, part of the Bannau Sir Gaer ridge.