# AutoGen (Microsoft) + RentAHuman

Integrate RentAHuman with Microsoft AutoGen for human-in-the-loop AI agent workflows. Build conversable agents that delegate physical tasks to real humans.

## AutoGen + RentAHuman: Human-in-the-Loop Agents

Microsoft AutoGen is a framework for building multi-agent systems where agents converse with each other — and with humans — to solve complex tasks. RentAHuman extends AutoGen's human-in-the-loop capability beyond the local user: your agents can hire any of 500,000+ humans on the marketplace to perform physical-world tasks.

### Why AutoGen + RentAHuman

AutoGen's core design revolves around conversable agents that can interact with both AI and humans. RentAHuman takes this further by turning "human-in-the-loop" from a local interaction into a global marketplace. Instead of blocking on a single human's input, your AutoGen agents can post tasks to a pool of qualified humans, select the best match, and continue working while the human executes. AutoGen's conversation patterns (two-agent chat, group chat, nested chat) all work with RentAHuman tools.

### Installation

```bash
pip install autogen-agentchat autogen-ext[openai] requests
```

### Define RentAHuman Functions

```python
import requests
from typing import Annotated
RENTAHUMAN_API = "https://rentahuman.ai/api"
API_KEY = "rah_your_api_key_here"
headers = {"Content-Type": "application/json", "x-api-key": API_KEY}

def search_humans(
    query: Annotated[str, "Skills or task description to search for"],
    location: Annotated[str, "City or region"] = "",
) -> str:
    """Search for available humans on the RentAHuman marketplace."""
    params = {"q": query, "limit": 10}
    if location:
        params["location"] = location
    resp = requests.get(f"{RENTAHUMAN_API}/search", params=params, headers=headers)
    return resp.text

def create_bounty(
    title: Annotated[str, "Short task title"],
    description: Annotated[str, "Detailed task description"],
    pay_amount: Annotated[float, "Payment in USD"],
    location: Annotated[str, "Task location"] = "",
) -> str:
    """Post a task bounty on RentAHuman for humans to apply to."""
    data = {
        "title": title,
        "description": description,
        "payAmount": pay_amount,
        "payType": "fixed",
        "location": location,
        "isRemote": not bool(location),
    }
    resp = requests.post(f"{RENTAHUMAN_API}/bounties", json=data, headers=headers)
    return resp.text

def start_conversation(
    human_id: Annotated[str, "The human's profile ID"],
    message: Annotated[str, "Initial message to send"],
) -> str:
    """Start a conversation with a human to discuss a task."""
    data = {"humanId": human_id, "message": message}
    resp = requests.post(f"{RENTAHUMAN_API}/conversations", json=data, headers=headers)
    return resp.text

def get_bounty_applications(
    bounty_id: Annotated[str, "The bounty ID to check applications for"],
) -> str:
    """List all applications for a posted bounty."""
    resp = requests.get(
        f"{RENTAHUMAN_API}/bounties/{bounty_id}/applications", headers=headers
    )
    return resp.text

def accept_application(
    bounty_id: Annotated[str, "The bounty ID"],
    application_id: Annotated[str, "The application ID to accept"],
) -> str:
    """Accept a human's application to a bounty."""
    resp = requests.post(
        f"{RENTAHUMAN_API}/bounties/{bounty_id}/applications/{application_id}/accept",
        headers=headers,
    )
    return resp.text
```

### Two-Agent Chat: Planner + Executor

```python
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.conditions import TextMentionTermination
from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_ext.models.openai import OpenAIChatCompletionClient
model_client = OpenAIChatCompletionClient(model="gpt-4o")
# Task planner that decides what needs to be done
planner = AssistantAgent(
    name="TaskPlanner",
    model_client=model_client,
    system_message="""You plan physical-world tasks. Break down user requests into
    specific, actionable tasks that a human can execute. Specify location, time
    requirements, skills needed, and fair pay rates. When the executor has posted
    the bounty and confirmed, say TERMINATE.""",
)
# Executor that interacts with RentAHuman
executor = AssistantAgent(
    name="HiringExecutor",
    model_client=model_client,
    system_message="""You execute the task plan by interacting with the RentAHuman
    marketplace. Search for humans, evaluate candidates, post bounties, and manage
    the hiring process. Report results back to the planner.""",
    tools=[search_humans, create_bounty, start_conversation, get_bounty_applications, accept_application],
)
termination = TextMentionTermination("TERMINATE")
team = RoundRobinGroupChat(
    [planner, executor],
    termination_condition=termination,
)
# Run the team
import asyncio
async def main():
    result = await team.run(
        task="I need someone to deliver 50 flyers to businesses in downtown Chicago by Friday. Budget: $75."
    )
    print(result)
asyncio.run(main())
```

### Group Chat with Human Proxy

AutoGen's UserProxyAgent lets a local human supervise the process, approving key decisions like accepting applicants or confirming payments:

```python
from autogen_agentchat.agents import AssistantAgent, UserProxyAgent
# Human supervisor who approves key decisions
supervisor = UserProxyAgent(
    name="HumanSupervisor",
    description="A human supervisor who approves hiring decisions and payment amounts.",
)
# AI agent that searches and recommends
recruiter = AssistantAgent(
    name="Recruiter",
    model_client=model_client,
    system_message="""You search for and recommend humans on RentAHuman. Present
    candidates with their qualifications and rates. Always get supervisor approval
    before posting bounties or starting conversations.""",
    tools=[search_humans, get_human_profile],
)
# AI agent that handles hiring logistics
hiring_manager = AssistantAgent(
    name="HiringManager",
    model_client=model_client,
    system_message="""You handle the logistics of hiring — posting bounties,
    messaging candidates, and managing applications. Only act after getting
    approval from the supervisor.""",
    tools=[create_bounty, start_conversation, accept_application],
)
```

### Common Use Cases

- **Supervised hiring** — Human approves each hiring decision while AI handles search and communication
- **Autonomous task execution** — Fully automated agents that plan, hire, and manage humans for recurring tasks
- **Quality control loops** — Agent hires a human, reviews their deliverable, and requests revisions through RentAHuman messaging
- **Multi-city operations** — Group chat with location-specific agents, each hiring humans in their respective city

### Best Practices

- **Use termination conditions** — Define clear termination conditions so conversations don't loop forever. "TERMINATE" after the bounty is posted and confirmed works well.
- **Add a supervisor for payments** — For any workflow involving money, include a UserProxyAgent as a human supervisor who must approve transactions.
- **Leverage nested chats** — Use AutoGen's nested chat feature for sub-workflows, such as a nested conversation to evaluate multiple candidates before selecting one.
- **Store conversation context** — AutoGen agents maintain conversation history automatically. Use this to reference earlier search results when posting bounties.
- **Handle async task completion** — Physical tasks take time. Build your workflow to check back on bounty status periodically rather than blocking.
