Skip to content

Add a second collection for follow-up questions

This lesson continues with the agent of lesson 2. An agent run belongs to a conversation, which is every run with the same session id. A follow-up message carries the earlier messages with it. The script 11_aic_second_tool.sql asks a contract question, and then a follow-up about the travel policy, as AIC_LEGAL. The agent has only the contracts tool so far. Run the script. It deletes the tool AIC_SEARCH_POLICIES if it exists, so that you start from one tool, and it makes three agent runs. It takes under a minute:

l_session := uc_ai_agents_api.generate_session_id;
l_result := aic_agent_api.run_as('AIC_LEGAL', 'aic_assistant'
, 'What notice period applies to the Alpenwerk maintenance contract?', l_session);
l_session := l_result.get_string('session_id');
-- the same session id: the agent sees the first question and its answer
l_result := aic_agent_api.run_as('AIC_LEGAL', 'aic_assistant'
, 'And what does our travel policy say about hotel costs?', l_session);

The script then registers a second tool, AIC_SEARCH_POLICIES, with the tag aic_demo. The tool calls the same package with another function for the other collection. It does not change the profile:

l_tool_id := uc_ai_tools_api.merge_tool_from_schema(
p_tool_code => 'AIC_SEARCH_POLICIES'
, p_description => 'Search the policies of the company (travel, remote work, handbook, salary bands). ...'
, p_function_call => 'return aic_rag_tools_api.search_policies(:parameters);'
, p_json_schema => ... -- the same parameters as the contracts tool
, p_tags => apex_t_varchar2('aic_demo')
);

The profile selects tools by the tag aic_demo, so the agent has the new tool at its next run. A tool for each collection lets the model pick the collection from the descriptions, and keeps the ADM access check inside each tool. The script asks the follow-up again in the same conversation. The labels in the output are the steps of the script: step 1 asks two questions (1a and 1b), step 2 registers the tool and prints one line, and step 3 asks the follow-up again. Step 2 has no question, so the output goes from 1b to 3. The label 3 shows that this is the run after the registration of the second tool.

--- 1a. a contract question
Q: What notice period applies to the Alpenwerk maintenance contract?
A: The notice period is **30 days to the end of a calendar month**, and notice must be in writing: “Either party may terminate this Contract with a notice period of 30 days to the end of a calendar month. The notice must be in writing.” (contract_alpenwerk_maintenance.pdf)
tool calls 1, tokens 1112 in / 98 out, 5.9 s
--- 1b. the follow-up: one tool
Q: And what does our travel policy say about hotel costs?
A: I found nothing about hotel costs or the travel policy in the documents I can see.
tool calls 2, tokens 2672 in / 86 out, 6.8 s
(registered AIC_SEARCH_POLICIES with the tag aic_demo; the profile was not changed)
--- 3. the follow-up again: two tools
Q: And what does our travel policy say about hotel costs?
A: The hotel limits depend on the travel date:
- **From 1 January 2026:** “Hotel, per night, large cities EUR 165” and “Hotel, per night, other places EUR 120.” The newer policy states: “Valid from 1 January 2026. This version replaces the Travel Policy 2025.” (travel_policy_2026.pdf)
- **Through 31 December 2025:** “Hotel, per night, large cities EUR 140” and “Hotel, per night, other places EUR 110.” This policy is “Valid until 31 December 2025.” (travel_policy_2025.pdf)
tool calls 1, tokens 2798 in / 167 out, 6 s
Tool calls of this conversation (status is always success, even when the tool returned no_passages or an error: read tool_output):
SEQ TOOL_NAME TOOL_INPUT TOOL_STATUS RESULT_STATUS
______ _______________________ ______________________________________________________________________________ ______________ _________________________
2 AIC_SEARCH_CONTRACTS {"max_sources":5,"query":"Alpenwerk maintenance notice period termination"} success "status":"ok"
6 AIC_SEARCH_CONTRACTS {"max_sources":5,"query":"travel policy hotel costs"} success "status":"no_passages"
8 AIC_SEARCH_CONTRACTS {"max_sources":5,"query":"Reiserichtlinie Hotel Übernachtungskosten"} success "status":"no_passages"
12 AIC_SEARCH_POLICIES {"max_sources":5,"query":"travel policy hotel costs"} success "status":"ok"

With one tool, the agent searched the contracts twice, found nothing, and said so. Rule 5 of the prompt and the status no_passages made the answer honest: it does not invent a hotel limit. With two tools, the agent searched the policies and found both versions of the travel policy. Rule 4 of the prompt makes it name both, and say which one is newer. Model answers differ between runs, so your run can differ from the recording.

The follow-up costs more tokens than the first question for two reasons: the conversation carries its history, and the run with one tool made a second search. The recording shows 2,672 input tokens for the follow-up with one tool, 2,798 with two tools, and 1,112 for the first question. The agent keeps at most the last 20 messages (p_max_history_messages of the agent), so the cost of a long conversation has a limit.