Conversations (Autonomous)
A conversation agent lets several agents collaborate in a dialogue. Each agent takes a turn and adds to a shared chat history.
Two modes are available:
- Round-robin: agents take turns in a fixed order
- AI-driven: a moderator agent decides who speaks next
Round-robin conversation
Section titled âRound-robin conversationâAgents speak in the order of the list. Each agent sees the full conversation history and adds its perspective. The conversation continues to a termination condition, or to the maximum number of turns.
Example: party planning
Section titled âExample: party planningâThree agents collaborate on a party plan. A brainstormer proposes ideas. A critic evaluates each idea. A synthesizer merges the best ideas into a plan.
Step 1: Create prompt profiles for each participant:
DECLARE l_profile_id NUMBER;BEGIN l_profile_id := uc_ai_prompt_profiles_api.create_prompt_profile( p_code => 'party_brainstormer_profile', p_description => 'Brainstorms creative party ideas', p_system_prompt_template => 'You are Brainstormer. Propose 2-3 creative party ideas based on the task and chat history. Be enthusiastic! Structure: "Idea 1: [desc]. Idea 2: [desc]." Reference recent messages.', p_user_prompt_template => 'Generate or refine party ideas: {prompt}. Your role: {role}.', p_provider => uc_ai.c_provider_openai, p_model => uc_ai_openai.c_model_gpt_5_6_luna, p_status => uc_ai_prompt_profiles_api.c_status_active );
l_profile_id := uc_ai_prompt_profiles_api.create_prompt_profile( p_code => 'party_critic_profile', p_description => 'Critiques party ideas for budget, safety, and feasibility', p_system_prompt_template => 'You are Critic. Analyze previous ideas: check budget, safety, and practical limits. Suggest fixes or reject bad ideas. Structure: "Critique: [idea] is [good/bad because...]. Fix: [suggestion]." Be realistic.', p_user_prompt_template => 'Chat history: {prompt}. Your role: {role}.', p_provider => uc_ai.c_provider_openai, p_model => uc_ai_openai.c_model_gpt_5_6_luna, p_status => uc_ai_prompt_profiles_api.c_status_active );
l_profile_id := uc_ai_prompt_profiles_api.create_prompt_profile( p_code => 'party_synthesizer_profile', p_description => 'Synthesizes ideas into a cohesive party plan with cost estimates', p_system_prompt_template => 'You are Synthesizer. Merge good ideas from history into 1 polished plan. Estimate total cost. Structure: "Combined Plan: 1. [activity] ($X). 2. [food] ($Y). Total: $Z." If you finalize, say "Final Plan: ..."', p_user_prompt_template => 'Chat history: {prompt}. Your role: {role}.', p_provider => uc_ai.c_provider_openai, p_model => uc_ai_openai.c_model_gpt_5_6_luna, p_status => uc_ai_prompt_profiles_api.c_status_active );
COMMIT;END;/Step 2: Create profile agents for each participant:
DECLARE l_agent_id NUMBER;BEGIN l_agent_id := uc_ai_agents_api.create_agent( p_code => 'brainstormer_agent', p_description => 'Creative brainstormer who proposes party ideas', p_agent_type => uc_ai_agents_api.c_type_profile, p_prompt_profile_code => 'party_brainstormer_profile', p_status => uc_ai_agents_api.c_status_active );
l_agent_id := uc_ai_agents_api.create_agent( p_code => 'critic_agent', p_description => 'Practical critic who checks feasibility and budget', p_agent_type => uc_ai_agents_api.c_type_profile, p_prompt_profile_code => 'party_critic_profile', p_status => uc_ai_agents_api.c_status_active );
l_agent_id := uc_ai_agents_api.create_agent( p_code => 'synthesizer_agent', p_description => 'Synthesizer who merges ideas into a final plan', p_agent_type => uc_ai_agents_api.c_type_profile, p_prompt_profile_code => 'party_synthesizer_profile', p_status => uc_ai_agents_api.c_status_active );
COMMIT; -- agents must be committed before they can be executedEND;/Step 3: Create the conversation agent:
DECLARE l_conv_id NUMBER; l_conv_config CLOB;BEGIN l_conv_config := '{ "pattern_type": "conversation", "conversation_mode": "round_robin", "agents": [ { "agent_code": "brainstormer_agent", "input_mapping": { "prompt": "{$.chat_history}", "role": "{$.agent_description}" } }, { "agent_code": "critic_agent", "input_mapping": { "prompt": "{$.chat_history}", "role": "{$.agent_description}" } }, { "agent_code": "synthesizer_agent", "input_mapping": { "prompt": "{$.chat_history}", "role": "{$.agent_description}" } } ], "max_turns": 3, "termination_condition": { "type": "keyword_in_response", "keyword": "Final Plan" } }';
l_conv_id := uc_ai_agents_api.create_agent( p_code => 'party_planning_roundrobin', p_description => 'Party planning with brainstormer, critic, and synthesizer', p_agent_type => uc_ai_agents_api.c_type_conversation, p_orchestration_config => l_conv_config, p_max_iterations => 2, p_status => uc_ai_agents_api.c_status_active );
COMMIT;END;/Step 4: Execute:
DECLARE l_result json_object_t;BEGIN l_result := uc_ai_agents_api.execute_agent( p_agent_code => 'party_planning_roundrobin', p_input_parameters => json_object_t('{ "prompt": "Plan a birthday party for a 12 year old who loves pirates and football. Max 14 kids, $200 budget." }'), p_session_id => uc_ai_agents_api.generate_session_id );
DBMS_OUTPUT.PUT_LINE('Result: ' || l_result.get_clob('final_message'));END;/How it works:
- Each turn, agents speak in order: brainstormer, critic, synthesizer
- Each agent receives the full conversation history via
{$.chat_history}and its own role description via{$.agent_description} - The conversation ends when an agent writes âFinal Planâ in its answer, or at
max_turns
AI-driven conversation
Section titled âAI-driven conversationâA moderator agent decides who speaks next. The order is therefore not fixed: the moderator directs the discussion at each turn.
Example: moderated party planning
Section titled âExample: moderated party planningâKeep the participant agents from above. Then add a moderator that steers the conversation:
Step 1: Create the moderator prompt profile:
DECLARE l_profile_id NUMBER;BEGIN l_profile_id := uc_ai_prompt_profiles_api.create_prompt_profile( p_code => 'party_moderator_profile', p_description => 'Moderates the party planning conversation', p_system_prompt_template => 'You are the Moderator. Oversee the party planning conversation. Decide who speaks next based on the chat history. If you think there is a solid plan ready, you can finalize the conversation. When done, summarize the final plan for the user.', p_user_prompt_template => '{prompt}', p_provider => uc_ai.c_provider_openai, p_model => uc_ai_openai.c_model_gpt_5_6_luna, p_status => uc_ai_prompt_profiles_api.c_status_active );
COMMIT;END;/Then create the moderator profile agent:
DECLARE l_agent_id NUMBER;BEGIN l_agent_id := uc_ai_agents_api.create_agent( p_code => 'moderator_agent', p_description => 'Moderator who decides which agent speaks next', p_agent_type => uc_ai_agents_api.c_type_profile, p_prompt_profile_code => 'party_moderator_profile', p_status => uc_ai_agents_api.c_status_active );END;/Step 2: Create the AI-driven conversation agent:
DECLARE l_conv_id NUMBER; l_conv_config CLOB;BEGIN l_conv_config := '{ "pattern_type": "conversation", "conversation_mode": "ai_driven", "moderator_agent": { "agent_code": "moderator_agent", "input_mapping": { "prompt": "Chat history: {$.chat_history} | Available agents: {$.available_agents}" }, "summary_mapping": { "prompt": "The conversation was ended. Please outline the final plan for the user. Max 2 sentences. | Chat history: {$.chat_history}" } }, "max_turns": 6, "agents": [ { "agent_code": "brainstormer_agent", "input_mapping": { "prompt": "{$.chat_history}", "role": "{$.agent_description} | Why you were picked: {$.moderator_rationale}" } }, { "agent_code": "critic_agent", "input_mapping": { "prompt": "{$.chat_history}", "role": "{$.agent_description} | Why you were picked: {$.moderator_rationale}" } }, { "agent_code": "synthesizer_agent", "input_mapping": { "prompt": "{$.chat_history}", "role": "{$.agent_description} | Why you were picked: {$.moderator_rationale}" } } ] }';
l_conv_id := uc_ai_agents_api.create_agent( p_code => 'party_planning_ai_driven', p_description => 'AI-moderated party planning discussion', p_agent_type => uc_ai_agents_api.c_type_conversation, p_orchestration_config => l_conv_config, p_max_iterations => 1, p_status => uc_ai_agents_api.c_status_active );
COMMIT;END;/Step 3: Execute:
DECLARE l_result json_object_t;BEGIN l_result := uc_ai_agents_api.execute_agent( p_agent_code => 'party_planning_ai_driven', p_input_parameters => json_object_t('{ "prompt": "Plan a birthday party for a 12 year old who loves pirates and football. Max 14 kids, $200 budget." }'), p_session_id => uc_ai_agents_api.generate_session_id );
DBMS_OUTPUT.PUT_LINE('Final plan: ' || l_result.get_clob('final_message'));END;/How it works:
- The moderator receives the chat history and the list of available agents via
{$.available_agents} - It decides which agent speaks next, and gives a reason
- The selected agent speaks. It receives the chat history, and the reason of the moderator in
{$.moderator_rationale} - When the moderator ends the conversation, UC AI uses the
summary_mappingfor a final summary - The conversation ends after
max_turns, or when the moderator finishes it
Message log at a glance
Section titled âMessage log at a glanceâUC AI stores a conversation turn in uc_ai_agent_messages as a full transcript. The opening input is a user row. Each participant turn is one assistant row, and its agent_code names the agent that produced it. In AI-driven mode, the closing summary of the moderator is the last row. There are no tool rows, because a conversation is a discussion and not tool use.
SELECT seq, role, agent_code, SUBSTR(content, 1, 60) AS content FROM uc_ai_agent_messages WHERE session_id = :session_id ORDER BY seq;| seq | role | agent_code | content |
|---|---|---|---|
| 1 | user | (null) | {"prompt":"Plan a birthday party for a 12 ... |
| 2 | assistant | brainstormer_agent | Idea 1: Pirate Football Treasure Hunt - ... |
| 3 | assistant | critic_agent | Critique: the treasure hunt is risky because... |
| 4 | assistant | synthesizer_agent | Combined Plan: 1. Pirate Football Scavenger... |
| 5 | assistant | moderator_agent | Final Party Plan: ... (AI-driven summary) |
Filter by agent_code to see the contributions of one participant. Read the rows in seq order to replay the discussion.
Config reference
Section titled âConfig referenceâ| Field | Type | Description |
|---|---|---|
pattern_type | String | Must be "conversation" |
conversation_mode | String | "round_robin" or "ai_driven" |
agents | Array | Participant agents with their input mappings |
max_turns | Number | Maximum conversation turns |
termination_condition | Object | (Round-robin) When to stop early |
moderator_agent | Object | (AI-driven) The moderator agent config |
moderator_agent.summary_mapping | Object | (AI-driven) Input mapping for generating the final summary |
Termination condition (round-robin)
Section titled âTermination condition (round-robin)â"termination_condition": { "type": "keyword_in_response", "keyword": "Final Plan"}The conversation stops early when the answer of any agent holds the keyword.
Moderator agent (AI-driven)
Section titled âModerator agent (AI-driven)âThe moderator has two input mappings:
input_mapping: UC AI uses it each turn, to decide who speaks nextsummary_mapping: UC AI uses it once at the end, for the final summary
Template variables
Section titled âTemplate variablesâAn input mapping of a conversation agent can use these variables:
| Variable | Description | Available to |
|---|---|---|
{$.chat_history} | Full conversation history | All participants |
{$.agent_description} | The description of the current agent | All participants |
{$.available_agents} | List of agents with descriptions | Moderator only |
{$.moderator_rationale} | Why this agent was picked to speak | Participants in AI-driven mode |
- Give each agent a distinct personality: write a clear role in the system prompt of each agent. An overlap gives repeated answers.
- Use the agent description as context: pass
{$.agent_description}to each agent, so that it knows its role in the conversation. One prompt template can then serve several roles. - Keep
max_turnssmall: each turn calls an AI model. A round-robin with 3 agents andmax_turns: 5makes up to 15 AI calls. - Termination keywords: in round-robin mode, instruct the last agent to write a keyword such as âFinal Planâ at the end of the discussion.
- Moderator instructions: in AI-driven mode, tell the moderator when to finish. Without this instruction, it continues to
max_turns.