# Human-in-the-Loop: Feedback Loop Pattern

This example demonstrates a sophisticated "human-in-the-loop" pattern: **Feedback Loop**. It showcases a multi-agent workflow where one agent generates content, another agent requests human feedback, and the system supports iterative refinement based on that feedback.

## How It Works

This implementation uses a **multi-agent architecture** with two specialized agents working together:

1. **Writer Agent**: A specialized agent that generates creative content (poems in this example). It produces the initial draft and can incorporate feedback to create revised versions.

2. **Review Agent**: An agent that acts as a bridge between the Writer Agent and the human reviewer. It:
   - Captures the content generated by the Writer Agent
   - Triggers an interrupt to request human feedback
   - Handles the resume process with human feedback
   - Either passes the feedback to the Writer Agent or exits the loop if no edits are needed

### Workflow Sequence

1. **Initial Request**: The user requests content creation (e.g., "write a short poem about potato")
2. **Content Generation**: The Writer Agent generates the initial content
3. **Feedback Interrupt**: The Review Agent captures the content and triggers an interrupt, presenting it to the human for feedback
4. **Human Feedback**: The human can either:
   - Provide specific feedback for improvements
   - Indicate "NO NEED TO EDIT" if the content is satisfactory
5. **Resume and Iterate**: The system resumes with the human's feedback:
   - If feedback is provided, the Writer Agent generates a revised version
   - If "NO NEED TO EDIT" is selected, the workflow completes
6. **Loop Continuation**: The process can repeat for multiple iterations of feedback and refinement

## Key Features Demonstrated

- **Multi-Agent Collaboration**: Shows how different agents can work together in a coordinated workflow
- **Stateful Interrupts**: The Review Agent maintains state about the content being reviewed
- **Iterative Refinement**: Supports multiple rounds of human feedback and content improvement
- **Flexible Exit Conditions**: Allows the human to indicate when the content is satisfactory

## How to Configure Environment Variables

Before running the example, you need to set up the required environment variables for the LLM API. You have two options:

### Option 1: OpenAI-Compatible Configuration
```bash
export OPENAI_API_KEY="{your api key}"
export OPENAI_BASE_URL="{your model base url}"
# Only configure this if you are using Azure-like LLM providers
export OPENAI_BY_AZURE=true
# 'gpt-4o' is just an example, configure the model name provided by your LLM provider
export OPENAI_MODEL="gpt-4o-2024-05-13"
```

### Option 2: ARK Configuration
```bash
export MODEL_TYPE="ark"
export ARK_API_KEY="{your ark api key}"
export ARK_MODEL="{your ark model name}"
```

Alternatively, you can create a `.env` file in the project root with these variables.

## How to Run

Ensure you have your environment variables set (e.g., for the LLM API key). Then, run the following command from the root of the `eino-examples` repository:

```sh
go run ./adk/human-in-the-loop/3_feedback-loop
```

You will see:
1. The Writer Agent generating a poem about potatoes
2. A prompt asking for your feedback
3. Options to either provide specific feedback or type "NO NEED TO EDIT"
4. The system incorporating your feedback and generating revised content

## Workflow Diagram

```mermaid
graph TD
    A[User: Content Request] --> B{Writer Agent};
    B --> C[Generates Content] --> D{Review Agent};
    D --> E[Interrupt: Request Feedback] --> F{Human Feedback};
    F -- "Provide Feedback" --> G[Targeted Resume: With Feedback] --> B;
    F -- "NO NEED TO EDIT" --> H[Targeted Resume: No Edit Needed] --> I[Workflow Complete];
    G --> C;
```

## Practical Example

Here's a real trace from running the example, showing how the iterative feedback process works:

```
name: WriterAgent
path: [{Writer MultiAgent} {WriterAgent}]
answer: Hidden beneath earth's gentle fold,
A humble potato, golden and bold.

name: ReviewerAgent
path: [{Writer Multi-Agent} {WriterAgent} {ReviewerAgent}]
Original content to review:
`
Hidden beneath earth's gentle fold,
A humble potato, golden and bold.
`.
If you think the content is good as it is, please reply with "No need to edit".
Otherwise, please provide your feedback.

your input here: Make it more funny.

name: ReviewerAgent
path: [{Writer Multi-Agent} {WriterAgent} {ReviewerAgent}]
answer: Make it more funny.

name: WriterAgent
path: [{Writer Multi-Agent} {WriterAgent} {ReviewerAgent} {WriterAgent}]
answer: I'm just a spud, not a fancy tomato,
But mash me up, I'm a party potato!

name: ReviewerAgent
path: [{Writer Multi-Agent} {WriterAgent} {ReviewerAgent} {WriterAgent} {ReviewerAgent}]
Original content to review:
`
I'm just a spud, not a fancy tomato,
But mash me up, I'm a party potato!
`.
If you think the content is good as it is, please reply with "No need to edit".
Otherwise, please provide your feedback.

your input here: No need to edit

name: ReviewerAgent
path: [{Writer Multi-Agent} {WriterAgent} {ReviewerAgent} {WriterAgent} {ReviewerAgent}]
action: exit
```

This trace demonstrates:
- **Initial generation**: The Writer Agent creates a serious poem about potatoes
- **Human feedback**: The user requests a more humorous tone
- **Iterative improvement**: The Writer Agent incorporates the feedback and creates a funnier version
- **Workflow completion**: The user approves the revised version, ending the process

The path notation shows the hierarchical agent structure and how the workflow progresses through multiple iterations.

## Implementation Details

### Agent Architecture
- **WriterAgent**: Uses `adk.NewChatModelAgent` with specific instructions for poem writing
- **ReviewAgent**: Custom agent implementing the `adk.Agent` interface with interrupt/resume logic
- **LoopAgent**: Wraps both agents using `adk.NewLoopAgent` to create the multi-agent workflow

### State Management
- The `FeedbackInfo` struct maintains:
  - `OriginalContent`: The content being reviewed
  - `Feedback`: Human feedback for improvements
  - `NoNeedToEdit`: Flag indicating content is satisfactory

### Interrupt/Resume Logic
- Uses `adk.StatefulInterrupt()` to pause execution and request human input while preserving state
- Implements `Resume()` method to handle different resume scenarios
- Supports both feedback-based iteration and workflow completion

## Use Cases

This pattern is ideal for:
- Content creation and refinement (writing, design, code generation)
- Quality assurance workflows
- Collaborative editing processes
- Any scenario requiring human judgment and iterative improvement

The implementation demonstrates how complex human-in-the-loop workflows can be built using the Eino framework's interrupt and resume capabilities.