Workflows
Workflows execute agents in a defined structure. The execution order is deterministic - you control exactly what happens and when.
Workflows reference profile agents by their agent_code to create deterministic pipelines.
Sequential workflow
Section titled “Sequential workflow”Agents run one after another. The output of each step is stored under its output_key and available to subsequent steps via the {$.steps.<output_key>} syntax.
DECLARE l_workflow_id NUMBER; l_session_id VARCHAR2(100); l_result json_object_t; l_workflow_def CLOB;BEGIN -- Define the workflow l_workflow_def := '{ "workflow_type": "sequential", "steps": [ { "agent_code": "math_agent", "input_mapping": { "question": "{$.input.question}" }, "output_key": "step1_result" }, { "agent_code": "summarizer_agent", "input_mapping": { "text": "{$.steps.step1_result}" }, "output_key": "step2_result" } ] }';
-- Create the workflow agent l_workflow_id := uc_ai_agents_api.create_agent( p_code => 'math_summary_pipeline', p_description => 'Solves a math question then summarizes the answer', p_agent_type => uc_ai_agents_api.c_type_workflow, p_workflow_definition => l_workflow_def, p_status => uc_ai_agents_api.c_status_active );
-- Execute l_session_id := uc_ai_agents_api.generate_session_id; l_result := uc_ai_agents_api.execute_agent( p_agent_code => 'math_summary_pipeline', p_input_parameters => json_object_t('{"question": "What is 7 + 8?"}'), p_session_id => l_session_id );
DBMS_OUTPUT.PUT_LINE('Result: ' || l_result.get_clob('final_message'));END;/How it works:
math_agentreceives{"question": "What is 7 + 8?"}from the input- Its output is stored under
step1_result summarizer_agentreceives{"text": "<math agent's response>"}from the previous step’s output- The final result is the output of the last step
Loop workflow
Section titled “Loop workflow”Agents run in a loop until an exit condition is met or the maximum number of iterations is reached. This is useful for iterative refinement where you want to keep improving output until it meets a quality bar.
DECLARE l_workflow_id NUMBER; l_result json_object_t; l_workflow_def CLOB;BEGIN l_workflow_def := '{ "workflow_type": "loop", "pre_steps": [ { "agent_code": "haiku_creator_agent", "input_mapping": { "topic": "{$.input.topic}" }, "output_key": "current_haiku" } ], "steps": [ { "agent_code": "haiku_rater_agent", "input_mapping": { "haiku": "{$.steps.current_haiku}", "topic": "{$.input.topic}" }, "output_key": "haiku_rating" }, { "agent_code": "haiku_improver_agent", "input_mapping": { "topic": "{$.input.topic}", "feedback": "{$.steps.haiku_rating.rating_feedback}", "haiku": "{$.steps.current_haiku}" }, "output_key": "current_haiku" } ], "post_steps": [ { "agent_code": "haiku_translator_agent", "input_mapping": { "language": "german", "haiku": "{$.steps.current_haiku}" }, "output_key": "translated_haiku" } ], "loop_config": { "max_iterations": 3, "exit_condition": "{$.steps.haiku_rating.quality} >= 8" }, "final_message": "{$.steps.translated_haiku}" }';
l_workflow_id := uc_ai_agents_api.create_agent( p_code => 'haiku_refinement', p_description => 'Creates, refines, and translates a haiku', p_agent_type => uc_ai_agents_api.c_type_workflow, p_workflow_definition => l_workflow_def, p_max_iterations => 3, p_status => uc_ai_agents_api.c_status_active );
l_result := uc_ai_agents_api.execute_agent( p_agent_code => 'haiku_refinement', p_input_parameters => json_object_t('{"topic": "Star Wars"}'), p_session_id => uc_ai_agents_api.generate_session_id );
DBMS_OUTPUT.PUT_LINE('Final haiku: ' || l_result.get_clob('final_message'));END;/How it works:
- Pre-steps run once before the loop: the haiku creator generates an initial haiku
- Loop steps repeat: the rater scores the haiku, then the improver refines it based on feedback
- The loop exits when
quality >= 8or after 3 iterations - Post-steps run once after the loop: the translator converts the final haiku to German
final_messagedefines which step output becomes the overall result
Using structured output for exit conditions
Section titled “Using structured output for exit conditions”Loop exit conditions typically depend on a structured value from an agent’s response. The haiku rater above returns a JSON object with quality and rating_feedback fields via a response schema:
DECLARE l_profile_id NUMBER; l_schema CLOB := '{ "type": "object", "properties": { "quality": { "type": "number", "minimum": 1, "maximum": 10, "description": "Quality rating from 1 to 10" }, "rating_feedback": { "type": "string", "description": "One-sentence feedback for improvement" } }, "required": ["quality", "rating_feedback"] }';BEGIN l_profile_id := uc_ai_prompt_profiles_api.create_prompt_profile( p_code => 'haiku_rater_profile', p_description => 'Rates haikus on a 1-10 scale', p_system_prompt_template => 'You are a haiku critic. Rate haikus based on form, imagery, and emotional impact.', p_user_prompt_template => 'Rate this haiku about "{topic}": {haiku}', p_provider => uc_ai.c_provider_openai, p_model => uc_ai_openai.c_model_gpt_4o_mini, p_response_schema => l_schema, p_status => uc_ai_prompt_profiles_api.c_status_active );
COMMIT;END;/The workflow references the structured fields directly:
"exit_condition": "{$.steps.haiku_rating.quality} >= 8"Loop without pre/post steps
Section titled “Loop without pre/post steps”For simpler loops, you can put everything in steps and use the optional flag to handle the first iteration where feedback doesn’t exist yet:
{ "workflow_type": "loop", "steps": [ { "agent_code": "haiku_creator_agent", "input_mapping": { "topic": "{$.input.topic}", "feedback": { "path": "{$.steps.haiku_rating.rating_feedback}", "optional": true } }, "output_key": "haiku_result" }, { "agent_code": "haiku_rater_agent", "input_mapping": { "haiku": "{$.steps.haiku_result}", "topic": "{$.input.topic}" }, "output_key": "haiku_rating" } ], "loop_config": { "max_iterations": 3, "exit_condition": "{$.steps.haiku_rating.quality} >= 8" }}In the first iteration, feedback doesn’t exist yet so it is omitted. From the second iteration onwards, the rater’s feedback is passed to the creator.
Input mapping reference
Section titled “Input mapping reference”A string value that resolves a path from the workflow state:
"question": "{$.input.question}"Available paths
Section titled “Available paths”| Path | Description |
|---|---|
{$.input.*} | Original input parameters passed to the workflow |
{$.steps.<output_key>} | Full output of a previous step |
{$.steps.<output_key>.<field>} | Specific field from a step’s structured output |