> ## Documentation Index
> Fetch the complete documentation index at: https://agno-v2.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Human-in-the-Loop

> Pause agents for approval before executing sensitive tools.

[Human-in-the-Loop](https://agno-v2.mintlify.site/hitl/overview.md) solves three problems that appear when agents move from answering questions to taking actions:

1. **Irreversible operations.** Sending an email, deleting a record, or posting to a channel cannot be undone. A human checkpoint prevents mistakes that require cleanup or apologies.

2. **Missing context.** The agent knows what action to take but lacks a critical detail. A deployment needs a target environment. A booking needs a budget. Rather than guessing, the agent pauses and asks.

3. **Audit trail.** Sensitive operations need accountability. Slack threads already contain the discussion that led to the action. Rendering the approval in the same thread keeps the decision and its context together.

<video autoPlay muted loop playsInline controls src="https://mintcdn.com/agno-v2/z6h2nawFeRojiJ5r/videos/slack-hitl.mp4?fit=max&auto=format&n=z6h2nawFeRojiJ5r&q=85&s=a46ed2fce85b470f191208fee2ef1f06" />

Agent pausing for approval before creating a calendar event and sending an email

## Quick start

The Slack interface renders HITL pauses as interactive cards in the thread. Users approve, reject, or provide input without leaving Slack.

**Agent**

```python agent.py theme={null}
from agno.agent import Agent
from agno.db.sqlite import SqliteDb
from agno.models.openai import OpenAIResponses
from agno.os import AgentOS
from agno.os.interfaces.slack import Slack
from agno.tools import tool

@tool(requires_confirmation=True)
def send_email(to: str, subject: str, body: str) -> str:
    """Send an email."""
    ...

db = SqliteDb(db_file="agent.db")

agent = Agent(
    name="Assistant",
    model=OpenAIResponses(id="gpt-5.4"),
    tools=[send_email],
    db=db,
)

agent_os = AgentOS(
    agents=[agent],
    db=db,
    interfaces=[Slack(agent=agent)],
)
app = agent_os.get_app()

if __name__ == "__main__":
    agent_os.serve(app="agent:app", reload=True)
```

**Team**

```python team.py theme={null}
from agno.agent import Agent
from agno.team import Team
from agno.db.sqlite import SqliteDb
from agno.models.openai import OpenAIResponses
from agno.os import AgentOS
from agno.os.interfaces.slack import Slack
from agno.tools import tool

@tool(requires_confirmation=True)
def send_email(to: str, subject: str, body: str) -> str:
    """Send an email."""
    ...

db = SqliteDb(db_file="agent.db")

researcher = Agent(name="Researcher", model=OpenAIResponses(id="gpt-5.4"))
writer = Agent(name="Writer", model=OpenAIResponses(id="gpt-5.4"), tools=[send_email])

support_team = Team(
    name="Support Team",
    mode="coordinate",
    members=[researcher, writer],
    model=OpenAIResponses(id="gpt-5.4"),
    db=db,
)

agent_os = AgentOS(
    teams=[support_team],
    db=db,
    interfaces=[Slack(team=support_team)],
)
app = agent_os.get_app()

if __name__ == "__main__":
    agent_os.serve(app="team:app", reload=True)
```

When a member agent calls a tool that requires confirmation, the team pauses.

**Workflow**

```python workflow.py theme={null}
from agno.agent import Agent
from agno.workflow import Step, Workflow
from agno.db.sqlite import SqliteDb
from agno.models.openai import OpenAIResponses
from agno.os import AgentOS
from agno.os.interfaces.slack import Slack
from agno.tools import tool

@tool(requires_confirmation=True)
def send_email(to: str, subject: str, body: str) -> str:
    """Send an email."""
    ...

db = SqliteDb(db_file="agent.db")

researcher = Agent(name="Researcher", model=OpenAIResponses(id="gpt-5.4"))
writer = Agent(name="Writer", model=OpenAIResponses(id="gpt-5.4"), tools=[send_email])

research_flow = Workflow(
    name="Research",
    steps=[
        Step(name="Research", agent=researcher),
        Step(name="Write", agent=writer),
    ],
    db=db,
)

agent_os = AgentOS(
    workflows=[research_flow],
    db=db,
    interfaces=[Slack(workflow=research_flow)],
)
app = agent_os.get_app()

if __name__ == "__main__":
    agent_os.serve(app="workflow:app", reload=True)
```

Workflow step pauses surface in Slack the same way.

> [!TIP]
>
> HITL requires a [database](https://agno-v2.mintlify.site/features/storage.md) to persist paused runs.

## Pause types

| Pause type | Slack card | Trigger |
| - | - | - |
| [Confirmation](https://agno-v2.mintlify.site/hitl/user-confirmation.md) | Approve/Deny buttons | `@tool(requires_confirmation=True)` |
| [User input](https://agno-v2.mintlify.site/hitl/user-input.md) | Text fields or dropdowns | `@tool(requires_user_input=True)` |
| [External execution](https://agno-v2.mintlify.site/hitl/external-execution.md) | Result field, submitted back to the run | `@tool(external_execution=True)` |
| [User feedback](https://agno-v2.mintlify.site/tools/toolkits/others/user-feedback.md) | Question forms with checkboxes or dropdowns | `UserFeedbackTools()` |

See the [HITL overview](https://agno-v2.mintlify.site/hitl/overview.md) for details on each pause type.

## Next steps

> **[HITL Overview](https://agno-v2.mintlify.site/hitl/overview.md)**
>
> All pause types and how to use them

> **[Reference](https://agno-v2.mintlify.site/agent-os/interfaces/slack/reference.md)**
>
> All parameters and endpoints


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.