---
title: "Human as Tool"
description: "Create LLM-callable tools that contact humans for input"
icon: "user"
---

- The [Basic Usage](#basic-usage) method is the easiest way to create a human contact tool
- The [Fetch Response](#fetch-response) method is useful if you want more control over the response handling
- The [Creating / Fetching](#creating-and-fetching) method gives you full control over the contact flow
- See [Advanced Usage](#advanced-usage) for concepts like response options and contact channels

## Structure

Human contact tools are built on the [Human Contact](/api-reference/human-contacts) API.

## Methods

There are three main jobs-to-be-done that you can control when using human contact tools:

- Creating the contact request
- Halting execution until the human responds
- Passing the response back to the LLM

In all cases, the HumanLayer SDK handles finding the right human and collecting their response.

### Basic Usage

You can use the `human_as_tool` method to create a tool that an LLM can use to contact a human.

The method returns a native python function that can be used as a tool in any LLM framework that supports
inferring tool structure from the function signature, docstring, and type hints.

```python
from humanlayer import HumanLayer

hl = HumanLayer()


tools = [
    langchain_tools.StructuredTool.from_function(hl.human_as_tool()),
]

# ... invoke the an agent with the tools
```

By default, the tool will use the default contact channel for the project associated with your HUMANLAYER_API_KEY.

You may want to give your LLM access to multiple humans as tools. This example uses a [Slack Contact Channel](/channels/slack), but you can use any of the [Contact Channels](/channels/introduction) supported by HumanLayer.

```python
from humanlayer import HumanLayer, ContactChannel, SlackContactChannel

hl = HumanLayer()

dm_with_ceo = ContactChannel(
    slack=SlackContactChannel(
        channel_or_user_id="U123456",
        context_about_channel_or_user="a DM with the CEO",
    )
)

email_with_head_of_compliance = ContactChannel(
    email=EmailContactChannel(
        email_address="head_of_compliance@example.com",
        context_about_user="an email with the Head of Compliance",
    )
)

tools = [
    langchain_tools.StructuredTool.from_function(
        hl.human_as_tool(
            contact_channel=dm_with_ceo,
        )
    ),
    langchain_tools.StructuredTool.from_function(
        hl.human_as_tool(
            contact_channel=email_with_head_of_compliance,
        )
    ),
]

# ... invoke the an agent with the tools
```

In this case, the HumanLayer SDK handles:

- Creating the contact request
- Halting execution until the human responds
- Passing the response back to the LLM

#### Example

See [04-human_as_tool_linkedin.py](https://github.com/humanlayer/humanlayer/tree/main/examples/langchain/04-human_as_tool_linkedin.py) for a full example.

### Fetch Response

You can use the `fetch_human_response` method to halt execution until the human responds,
and receive a result that you can use to decide what to do next.

```python
response = fetch_human_response(
    HumanContactSpec(
        msg="I'm trying to handle this compliance request and not sure how to proceed - can you help direct me?",
        channel=dm_with_ceo,
    ),
)

completed = response.as_completed()
print(f"Human responded: {completed}")
```

In this case, the HumanLayer SDK handles:

- Creating the contact request
- Halting execution until the human responds

And your code is responsible for:

- Handling the human's response

### Creating and Fetching

For maximum control over the contact flow, you can create and fetch responses separately.
This is useful if you want to implement your own waiting logic or integrate with a custom event loop.

```python
contact = hl.create_human_contact(
    spec=HumanContactSpec(
        msg="I'm trying to handle this compliance request and not sure how to proceed - can you help direct me?",
    ),
)

# Loop until we get a response
while (not contact.status) or (not contact.status.response):
    time.sleep(5)
    contact = hl.get_human_contact(contact.call_id)

print(f"Human responded: {contact.status.response}")
```

In this case, the HumanLayer SDK handles:

- Creating the contact request
- Fetching the response status

And your code is responsible for:

- Halting execution until the human responds
- Handling the response

## Advanced Usage

### Response Options

You can provide structured response options to guide the human's response:

```python
response_options = [
    ResponseOption(
        name="approve",
        title="Approve",
        description="Approve sending the email",
    ),
    ResponseOption(
        name="reject",
        title="Reject",
        description="Reject sending the email",
    ),
]

tools = [
    langchain_tools.StructuredTool.from_function(
        hl.human_as_tool(
            contact_channel=dm_with_ceo,
            response_options=response_options,
        )
    ),
]
```

### Contact Channels

HumanLayer supports multiple contact channels:

- Slack (`SlackContactChannel`)
- Email (`EmailContactChannel`)
- SMS (`SMSContactChannel`)
- WhatsApp (`WhatsAppContactChannel`)

See [Contact Channels](/channels/introduction) for more details.
