One program instead of twenty-six calls
By the end of this lesson, you can use code mode to calculate the shipment totals inside the database.
Reduce the data sent to the model
Section titled “Reduce the data sent to the model”Lesson 1 has the right answer at a high price. Twenty-six tool calls, 34 413 input
tokens, and 48 KB of temperature readings that pass through the context window of
the model. The part of the answer that a system uses is one line:
RESULT: SHP-2047, SHP-2052, SHP-2061 | 1920.
The readings are not there to be read. They are there to be counted. Nothing in this question needs a language model to look at 1176 numbers. It needs something to apply one rule to them.
Without code mode, the loop runs in the model, and every value it loops over has to reach the model. With code mode, the loop runs in the database, and only the result reaches the model.
Turn code mode on
Section titled “Turn code mode on”02_code_mode.sql asks the question of lesson 1, against the tools of lesson 1.
One line is new:
uc_ai.g_enable_tools := true;uc_ai.g_tool_tags := apex_t_varchar2('coldchain');-- The one line that this whole lesson is about.uc_ai.g_enable_programmatic_tools := true;That flag adds one more tool to the list the model sees. UC AI builds this tool
itself, so it is a meta-tool: a tool whose job is to run your other tools. It is
called uc_ai__run_code, and its one argument is a string of JavaScript.
Tools the model sees with code mode on: CC_LIST_SHIPMENTS CC_GET_READINGS CC_GET_LIMITS uc_ai__run_codeThe three tools are unchanged. Code mode adds a possibility and removes nothing. The model can still call a tool directly, and it can write a program instead.
The same question with code mode: 5 tool calls instead of 26
Section titled “The same question with code mode: 5 tool calls instead of 26”run program calls in out trips secs finish_reason------------------------------------------------------------------------------------classic, 40 calls no 26 34413 3723 3 46.6 stopcode mode yes 5 20280 3380 5 48 stop| Shipment | Class | Claimable run | Ceil hours | Claim |
|---|---|---|---|---|
| SHP-2047 | FROZEN | 150 min (1 run > 60 min) | 3 h | € 720 |
| SHP-2052 | CHILLED | 90 min (1 run > 60 min) | 2 h | € 240 |
| SHP-2061 | FROZEN | 210 min (1 run > 60 min) | 4 h | € 960 |
RESULT: SHP-2047, SHP-2052, SHP-2061 | 1920
Your wording will differ. What must match is the data, and the checks below.
One detail in that table is wrong. SHP-2061 has
two breaks, of 120 and 90 minutes, not one of 210. The total is right and the
claim is right, because the program added them correctly. The sentence the model
wrote about its own work is not. Lesson 6 comes back to this.
Same answer. Five tool calls instead of 26, and 41 percent fewer input tokens.
Five tool calls fit inside the default budget of 10. Lesson 1 needed a budget of 40 to finish. This run uses the default. Nothing in the script raises it. The next section shows what happens when a run declines the program.
Why it is five calls and not one
Section titled “Why it is five calls and not one”The model did not write one program. It wrote several, because the first one was wrong. Here is the trace of another recording of this same script, which needed four:
CALL uc_ai__run_code RESULT {"error":"code execution failed: {shipment_id: 1, readings: Array(49)} is not iterable","hint":"..."}CALL uc_ai__run_code RESULT {"brokenShipments":[],"totalClaimEur":0}CALL uc_ai__run_code <- a program that only prints the shapes RESULT {"shipment_sample":[{"shipment_id":1,"shipment_no":"SHP-2041", ...CALL uc_ai__run_code RESULT {"brokenShipments":[{"shipment_no":"SHP-2047", ... "claimEur":720}, ...- The first program assumed
CC_GET_READINGSreturns an array. It returns an object with areadingskey, so the loop failed. - The second program ran and found nothing. No error, and a wrong answer.
- The third program is the model debugging itself. It called the tools and returned a sample of each result, to find out what the fields are called.
- The fourth program was right.
The model paid for four programs to discover the shape of your data. Nothing told it, and lesson 4 is about why.
What the model received, and what stayed in the database
Section titled “What the model received, and what stayed in the database”The program ran inside the database. It called CC_GET_READINGS 24 times, and it
received all 1176 readings. Not one of them went to Anthropic.
What went back to the model was the value of one variable:
{ "brokenShipments": [ ... 3 rows ... ], "totalClaimEur": 1920 }The intermediate data stays where the data is. Only the conclusion travels.
Which providers this works on
Section titled “Which providers this works on”Code mode is not tied to one provider. UC AI builds uc_ai__run_code in the shape
that each provider expects, so the meta-tool appears for every provider constant,
next to your normal tools.
What differs is the quality of the JavaScript the model writes. These are runs of the question above, on the same database and the same three tools:
| Provider and model | Program | Calls | Input | Secs | Answer |
|---|---|---|---|---|---|
openai gpt-5.6-terra | yes | 8 | 4 910 | 24.1 | correct |
xai grok-4.6 | yes | 4 | 7 120 | 39.4 | correct |
openrouter openai/gpt-5.6-terra | yes | 3 | 2 841 | 11.8 | correct |
anthropic claude-sonnet-4-6 | yes | 4 | 13 309 | 32.2 | correct |
mistral mistral-large-latest | yes | 1 | 2 331 | 7.4 | wrong |
Three providers are not in that table. There is no measurement for google: the
API answered with an HTTP 503 and then a transfer timeout, which says nothing about
code mode. oci had no key in this database. ollama was not measured from the
database. None of the three is known to fail.
Code mode does not change your tools
Section titled “Code mode does not change your tools”Three things stay exactly as they were:
- Your tools are the same rows. Lesson 1 registered them, and this lesson changed none of them.
- The tools run in the transaction of the caller. A tool that a program calls behaves the same as a tool the model calls directly. A tool that commits, commits.
- The tool set is the same. A program can call the tools of this run, and no other tool in your schema.
If the sandbox is not installed
Section titled “If the sandbox is not installed”Code mode has no fallback without the sandbox. If it is not installed, the run stops with a message that names the fix:
ORA-20502: Code mode requires the MLE sandbox, which is not installed for thisschema (no valid UC_AI_PTC_RUNNER synonym). Run scripts/install_ptc_sandbox.sqlas a DBA to enable code mode.Check 4 of 00_precheck.sql finds this before you spend a token on it.
Verification
Section titled “Verification”Two things must be true after this lesson.
First, the meta-tool is in the list. The section What the model was offered in
02_code_mode.sql prints the names of the tools the model got. Run it, and read the
four names.
Second, the answer still matches the database:
select s.shipment_no , cc_analyst_pkg.minutes_over(s.id) as minutes_over from cc_shipments s where cc_analyst_pkg.minutes_over(s.id) > 0 order by s.shipment_no;SHIPMENT_NO MINUTES_OVERSHP-2047 150SHP-2052 90SHP-2061 210A code-mode run that gives a different answer is not a reason to distrust code mode. It is a reason to read the program, which is the next lesson.
Key takeaways
Section titled “Key takeaways”uc_ai.g_enable_programmatic_tools := trueadds one tool,uc_ai__run_code, and changes nothing else.- The meta-tool appears only when at least one tool is code-callable. When it is absent, there is no error to read.
- Code mode is an offer. The model can still call tools directly, and it does.
- The saving comes from the data that stays in the database. A direct call to a bulk tool gives that saving back.
- Code mode works on every provider that supports tool calling. The JavaScript the model writes is what varies, and a wrong field name gives a plausible zero rather than an error.
Full reference: Programmatic tool calling has the security model and every option.