Skip to Content

Human-in-the-Loop

This example demonstrates how to create a workflow that involves human interaction and approval. We’ll build a content creation workflow that generates a draft document and waits for user confirmation before finalizing it.

Note: This example uses create_mock tools for demonstration purposes to keep the example simple and focused on core workflow concepts. In real-world use cases, you would replace these mock tools with actual tools that perform the specific processing operations your automation requires (such as API calls, data transformations, file operations, or LLM interactions).

Example: Content Creation with Human Approval

The following workflow demonstrates human-in-the-loop patterns through a content creation process that requires user confirmation.

In this example:

  1. System generates initial draft content
  2. Content presented to user for review in interactive form with switch control
  3. User can approve (switch on) for immediate publication
  4. User can reject (switch off) to request revision
  5. Revision process creates a feedback loop until approval

Workflow Configuration:

workflows: - name: blog_post_review type: stateMachine transitions: - name: create_draft # Step 1: Generate initial content draft from: start to: draft_created call: - tool: create_mock arguments: input: 'blog post about renewable energy' output: | # The Future of Renewable Energy Renewable energy sources are becoming increasingly important as we work toward a sustainable future. Solar and wind power have seen dramatic cost reductions, making them competitive with traditional fossil fuels. Key benefits include: - Reduced carbon emissions - Energy independence - Long-term cost savings The transition to renewable energy represents one of the most significant opportunities of our time. as: DRAFT_CONTENT - tool: create_chat_message arguments: role: 'assistant' content: 'Draft content has been generated and is ready for your review.' - name: show_approval_form # Step 2: Present draft to user for approval from: draft_created to: waiting_for_approval call: - tool: create_document arguments: document: approval_form content: draft_content: ${ DRAFT_CONTENT } approved: false feedback: "" - name: process_approval # Step 3: Handle user's approval decision from: waiting_for_approval to: - approved - needs_revision when: manual # Wait for user interaction call: - tool: create_mock arguments: input: ${ transition.payload } output: ${ transition.payload.approved } as: USER_DECISION - tool: switch_target arguments: target: "{{#if USER_DECISION}}approved{{else}}needs_revision{{/if}}" # Approval path - name: finalize_content # Handle approved content from: approved to: end call: - tool: create_mock arguments: input: ${ DRAFT_CONTENT } output: 'Content published successfully to blog.example.com' as: PUBLISH_RESULT - tool: create_chat_message arguments: role: 'assistant' content: | βœ… Content approved and published! {{ PUBLISH_RESULT }} # Revision path - name: handle_revision # Handle revision requests from: needs_revision to: draft_created # Return to draft creation for revision call: - tool: create_chat_message arguments: role: 'assistant' content: 'πŸ“ Revision requested. Generating updated draft with your feedback...' - tool: create_mock arguments: input: ${ DRAFT_CONTENT } output: | # The Future of Renewable Energy (Revised) Renewable energy sources are rapidly transforming our global energy landscape. Solar and wind power have experienced unprecedented cost reductions, making them not just environmentally responsible but economically superior to traditional fossil fuels. Key benefits include: - Significant reduction in carbon emissions - Enhanced energy independence and security - Substantial long-term cost savings - Job creation in emerging green industries The transition to renewable energy represents the most transformative opportunity of our generation, offering both environmental and economic advantages. as: DRAFT_CONTENT

The approval form provides user interface for content review and decision-making:

documents: - name: approval_form schema: type: object properties: draft_content: type: string approved: type: boolean feedback: type: string required: - draft_content - approved ui: properties: draft_content: widget: textarea-expand title: "Draft Content" readonly: true approved: widget: switch title: "Approve" feedback: widget: textarea title: "Feedback (optional)" placeholder: "Provide feedback for revisions..." order: - draft_content - feedback - approved buttons: - transition: process_approval label: "Submit Decision" enabledWhen: - waiting_for_approval

Key Concepts:

  • Boolean Decision: Switch widget provides clear approve/reject interaction
  • Field Ordering: order property controls the layout sequence of form elements
  • Optional Feedback: Textarea for revision comments when approval is not granted

Understanding Human-in-the-Loop Patterns

The workflow demonstrates key patterns for human interaction:

Content Generation

- name: create_draft from: start to: draft_created call: - tool: create_mock arguments: input: 'blog post about renewable energy' output: | # The Future of Renewable Energy Renewable energy sources are becoming increasingly important... as: DRAFT_CONTENT

Key Concepts:

  • Content Creation: Mock tool simulates content generation (could be LLM in real use)
  • Data Export: Content stored in variable for later use in approval process

Create Documents for User Interaction

- name: show_approval_form from: draft_created to: waiting_for_approval call: - tool: create_document arguments: document: approval_form content: draft_content: ${ DRAFT_CONTENT } approved: false feedback: ""

Key Concepts:

  • Document Creation: Creates interactive form with draft content
  • Default Values: Sets initial state with approval false and empty feedback
  • Data Passing: Draft content flows from generation to approval interface

Manual Decision Processing

- name: process_approval from: waiting_for_approval to: - approved - needs_revision when: manual # Pauses for user input call: - tool: create_mock arguments: input: ${ transition.payload } output: ${ transition.payload.approved } as: USER_DECISION - tool: switch_target arguments: target: "{{#if USER_DECISION}}approved{{else}}needs_revision{{/if}}"

Key Concepts:

  • Manual Transition: when: manual waits for user interaction
  • Payload Access: transition.payload contains form data with approval status and feedback
  • Boolean Logic: Decision based on true/false approval value
  • Conditional Routing: switch_target directs workflow based on boolean decision using Handlebars syntax

Approval Path

- name: finalize_content from: approved to: end call: - tool: create_mock arguments: input: ${ DRAFT_CONTENT } output: 'Content published successfully to blog.example.com' as: PUBLISH_RESULT - tool: create_chat_message arguments: role: 'assistant' content: | βœ… Content approved and published! {{ PUBLISH_RESULT }}

Revision Path

- name: handle_revision from: needs_revision to: draft_created # Return to draft state for revision call: - tool: create_chat_message arguments: role: 'assistant' content: 'πŸ“ Revision requested. Generating updated draft with your feedback...' - tool: create_mock arguments: input: ${ DRAFT_CONTENT } output: | # The Future of Renewable Energy (Revised) ...enhanced content with improvements... as: DRAFT_CONTENT

Running This Example

This example is already available in Loopstack Studio:

  1. Navigate to the Studio interface
  2. Switch to the examples workspace
  3. Select β€œExample 7: Human-in-the-Loop Workflow” from the available automations
  4. Review the generated draft content
  5. Optionally provide feedback in the feedback field
  6. Use the approve switch to make your decision (on = approve, off = reject)
  7. Click β€œSubmit Decision” to process your choice
  8. For rejections, review the updated content and make another decision

Configuration Location: You can also view the complete configuration file at src/config/examples/basic/workflow-human-in-the-loop-example.yaml

Complete Example:

include: - core/tools/create-mock.yaml - core/tools/create-chat-message.yaml - core/tools/create-document.yaml - core/tools/switch-target.yaml pipelines: - name: human_in_the_loop_example title: "Example 7: Human-in-the-Loop Workflow" type: root workspace: examples sequence: - workflow: blog_post_review workflows: - name: blog_post_review type: stateMachine transitions: - name: create_draft # Step 1: Generate initial content draft from: start to: draft_created call: - tool: create_mock arguments: input: 'blog post about renewable energy' output: | # The Future of Renewable Energy Renewable energy sources are becoming increasingly important as we work toward a sustainable future. Solar and wind power have seen dramatic cost reductions, making them competitive with traditional fossil fuels. Key benefits include: - Reduced carbon emissions - Energy independence - Long-term cost savings The transition to renewable energy represents one of the most significant opportunities of our time. as: DRAFT_CONTENT - tool: create_chat_message arguments: role: 'assistant' content: 'Draft content has been generated and is ready for your review.' - name: show_approval_form # Step 2: Present draft to user for approval from: draft_created to: waiting_for_approval call: - tool: create_document arguments: document: approval_form content: draft_content: ${ DRAFT_CONTENT } approved: false feedback: "" - name: process_approval # Step 3: Handle user's approval decision from: waiting_for_approval to: - approved - needs_revision when: manual # Wait for user interaction call: - tool: create_mock arguments: input: ${ transition.payload } output: ${ transition.payload.approved } as: USER_DECISION - tool: switch_target arguments: target: "{{#if (eq USER_DECISION true)}}approved{{else}}needs_revision{{/if}}" # Approval path - name: finalize_content # Handle approved content from: approved to: end call: - tool: create_mock arguments: input: ${ DRAFT_CONTENT } output: 'Content published successfully to blog.example.com' as: PUBLISH_RESULT - tool: create_chat_message arguments: role: 'assistant' content: | βœ… Content approved and published! {{ PUBLISH_RESULT }} # Revision path - name: handle_revision # Handle revision requests from: needs_revision to: draft_created # Return to draft creation for revision call: - tool: create_chat_message arguments: role: 'assistant' content: 'πŸ“ Revision requested. Generating updated draft with your feedback...' - tool: create_mock arguments: input: ${ DRAFT_CONTENT } output: | # The Future of Renewable Energy (Revised) Renewable energy sources are rapidly transforming our global energy landscape. Solar and wind power have experienced unprecedented cost reductions, making them not just environmentally responsible but economically superior to traditional fossil fuels. Key benefits include: - Significant reduction in carbon emissions - Enhanced energy independence and security - Substantial long-term cost savings - Job creation in emerging green industries The transition to renewable energy represents the most transformative opportunity of our generation, offering both environmental and economic advantages. as: DRAFT_CONTENT documents: - name: approval_form schema: type: object properties: draft_content: type: string approved: type: boolean feedback: type: string required: - draft_content - approved ui: properties: draft_content: widget: textarea-expand title: "Draft Content" readonly: true approved: widget: switch title: "Approve" feedback: widget: textarea title: "Feedback (optional)" placeholder: "Provide feedback for revisions..." order: - draft_content - feedback - approved buttons: - transition: process_approval label: "Submit Decision" enabledWhen: - waiting_for_approval
Last updated on