Skip to main content
Clarify enables agents to pause mid-task and ask focused questions instead of guessing, improving decision accuracy and user control.

Quick Start

1

Enable Clarify

from praisonaiagents import Agent
from praisonaiagents.tools.clarify import clarify

agent = Agent(
    name="Writer",
    instructions="Write code. If requirements are ambiguous, ask clarifying questions.",
    tools=[clarify],
)

agent.start("Build me a web scraper")
# Agent may call: clarify(question="Which language?", choices=["python", "rust"])
2

With Custom Handler

from praisonaiagents import Agent
from praisonaiagents.tools.clarify import clarify, create_cli_clarify_handler

# Setup CLI handler for interactive questions
handler = create_cli_clarify_handler()

agent = Agent(
    name="Researcher",
    instructions="Research topics. Ask for clarification when needed.",
    tools=[clarify],
    ctx={"clarify_handler": handler}
)

How It Works

ComponentPurposeBehavior
ClarifyToolCore tool implementationPauses execution for user input
ClarifyHandlerChannel-specific behaviorRoutes questions to CLI/bot/UI
Context IntegrationRuntime handler resolutionUses ctx[‘clarify_handler’] if available

Channel Integration

CLI Usage

from praisonaiagents.tools.clarify import create_cli_clarify_handler

handler = create_cli_clarify_handler()
# Shows: 🤔 Which language?
# Choices:
#   1. python
#   2. rust
# Your choice (number or text): 1
# Returns: "python"

Bot Usage

from praisonaiagents.tools.clarify import create_bot_clarify_handler

async def send_message(channel_id, text):
    # Send to Telegram/Discord/Slack
    pass

async def wait_for_reply():
    # Wait for user response
    return "python"

handler = create_bot_clarify_handler(send_message, wait_for_reply)

Custom Context Handler

from praisonaiagents import Agent
from praisonaiagents.tools.clarify import clarify

async def my_clarify_handler(question, choices):
    # Custom UI/web interface
    return await show_dialog(question, choices)

agent = Agent(
    name="Assistant",
    tools=[clarify],
    ctx={"clarify_handler": my_clarify_handler}
)

Handler Resolution

The tool uses this priority order for handling questions:
  1. Context Handler: kwargs["ctx"]["clarify_handler"] (highest priority)
  2. Tool Handler: self.handler (default ClarifyHandler())
  3. Fallback: Returns guidance message when no interactive channel available

Configuration Options

Tool Schema

# LLM sees this tool signature:
{
    "name": "clarify",
    "description": "Ask the user a focused clarifying question when genuinely ambiguous. Use sparingly - only when you cannot proceed without their input.",
    "parameters": {
        "type": "object",
        "properties": {
            "question": {
                "type": "string",
                "description": "The clarifying question to ask"
            },
            "choices": {
                "type": "array", 
                "items": {"type": "string"},
                "description": "Optional list of predefined answer choices"
            }
        },
        "required": ["question"]
    }
}

Bot Auto-Approval

from praisonaiagents.bots import BotConfig

config = BotConfig(
    default_tools=["clarify"],  # Included by default
    auto_approve_tools=True     # No approval prompt for clarify
)
The clarify tool is included in the bot’s default auto-approve list, so it won’t require manual approval in bot environments.

Common Patterns

Progressive Clarification

from praisonaiagents import Agent
from praisonaiagents.tools.clarify import clarify

agent = Agent(
    name="CodeWriter",
    instructions="""
    Write code based on user requests. Use clarify for:
    1. Language/framework choice when unspecified
    2. Feature priorities when scope is broad
    3. Architecture decisions when requirements are complex
    """,
    tools=[clarify]
)

# Example interaction:
# User: "Build a REST API"
# Agent: clarify("Which language?", ["python", "node.js", "go"])
# User: "python"  
# Agent: clarify("Which framework?", ["fastapi", "flask", "django"])

Context-Aware Questions

async def smart_clarify_handler(question, choices):
    """Handler that considers conversation context"""
    # Check previous messages for hints
    context = get_conversation_context()
    
    if "python" in context and "web" in question.lower():
        # Auto-suggest based on context
        return "fastapi"
    
    return await show_user_dialog(question, choices)

Fallback Behavior

# When no interactive channel available:
result = await clarify("Which database?", ["postgres", "mysql"])
# Returns: "No interactive channel available. Please proceed with your best judgment for: Which database?"

# Agent can handle this gracefully:
if "no interactive channel" in result.lower():
    # Use reasonable defaults
    database = "postgres"  # Pick sensible default

Best Practices

Only call clarify when you genuinely cannot proceed without user input. Don’t ask for preferences that have reasonable defaults.Good: “Which API endpoint format?” when building an API Bad: “Should I use descriptive variable names?” (obvious default)
When possible, offer specific choices rather than open-ended questions.Good: choices=["fastapi", "flask", "django"] Bad: "What Python web framework should I use?" (no choices)
Always check if the response indicates no interactive channel and proceed with sensible defaults.
response = await clarify("Pick a color", ["blue", "red"])
if "no interactive channel" in response.lower():
    color = "blue"  # Use default
else:
    color = response
Frame questions with enough context for users to make informed decisions.Good: “Which authentication method for your user API?” Bad: “Which auth?” (unclear context)

Tools Overview

Core tool system and custom tools

Agent Configuration

Agent setup and tool integration