Add a second collection for follow-up questions
By the end of this lesson, you can add a collection to an agent by registering one more tool, and you can see what a conversation costs in tokens.
Ask a follow-up in the same conversation
Section titled “Ask a follow-up in the same conversation”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 answerl_result := aic_agent_api.run_as('AIC_LEGAL', 'aic_assistant' , 'And what does our travel policy say about hotel costs?', l_session);Register a second tool with the same tag
Section titled “Register a second tool with the same tag”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 questionQ: 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 toolQ: 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 toolsQ: 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"Compare the two runs
Section titled “Compare the two runs”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.