diff --git a/docs/en/enterprise/features/flow-hitl-management.mdx b/docs/en/enterprise/features/flow-hitl-management.mdx index 884dda4ee..c0b1fa957 100644 --- a/docs/en/enterprise/features/flow-hitl-management.mdx +++ b/docs/en/enterprise/features/flow-hitl-management.mdx @@ -1,6 +1,6 @@ --- title: "Flow HITL Management" -description: "Enterprise-grade human review for Flows with assignment, SLA management, escalation policies, and dynamic routing" +description: "Enterprise-grade human review for Flows with email-first notifications, routing rules, and auto-response capabilities" icon: "users-gear" mode: "wide" --- @@ -9,25 +9,33 @@ mode: "wide" Flow HITL Management features require the `@human_feedback` decorator, available in **CrewAI version 1.8.0 or higher**. These features apply specifically to **Flows**, not Crews. -CrewAI Enterprise provides a comprehensive Human-in-the-Loop (HITL) management system for Flows that transforms AI workflows into collaborative human-AI processes. Beyond simple approval gates, the platform offers enterprise-grade controls for assignment, accountability, and compliance. +CrewAI Enterprise provides a comprehensive Human-in-the-Loop (HITL) management system for Flows that transforms AI workflows into collaborative human-AI processes. The platform uses an **email-first architecture** that enables anyone with an email address to respond to review requests—no platform account required. ## Overview - - Review and respond to requests directly in the Enterprise dashboard + + Responders can reply directly to notification emails to provide feedback - - Route reviews to the right people based on rules and expertise + + Route requests to specific emails based on method patterns or flow state - - Ensure timely responses with automated escalation policies + + Configure automatic fallback responses when no human replies in time +### Key Benefits + +- **Simple mental model**: Email addresses are universal; no need to manage platform users or roles +- **External responders**: Anyone with an email can respond, even non-platform users +- **Dynamic assignment**: Pull assignee email directly from flow state (e.g., `sales_rep_email`) +- **Reduced configuration**: Fewer settings to configure, faster time to value +- **Email as primary channel**: Most users prefer responding via email over logging into a dashboard + ## Setting Up Human Review Points in Flows -Configure human review checkpoints within your Flows using the `@human_feedback` decorator. When execution reaches a review point, the system pauses and displays a "waiting for input" state in the UI. +Configure human review checkpoints within your Flows using the `@human_feedback` decorator. When execution reaches a review point, the system pauses, notifies the assignee via email, and waits for a response. ```python from crewai.flow.flow import Flow, start, listen @@ -62,95 +70,191 @@ class ContentApprovalFlow(Flow): For complete implementation details, see the [Human Feedback in Flows](/en/learn/human-feedback-in-flows) guide. -## Assignment & Routing +### Decorator Parameters -The Enterprise platform provides sophisticated assignment capabilities to ensure reviews reach the right team members. +| Parameter | Type | Description | +|-----------|------|-------------| +| `message` | `str` | The message displayed to the human reviewer | +| `emit` | `list[str]` | Valid response options (displayed as buttons in UI) | -### Responder Assignment +## Platform Configuration -Assign specific team members or groups as responders for different task types: +Access HITL configuration from: **Deployment → Settings → Human in the Loop Configuration** + + + HITL Configuration Settings + + +### Email Notifications + +Toggle to enable or disable email notifications for HITL requests. + +| Setting | Default | Description | +|---------|---------|-------------| +| Email Notifications | Enabled | Send emails when feedback is requested | + + +When disabled, responders must use the dashboard UI or you must configure webhooks for custom notification systems. + + +### SLA Target + +Set a target response time for tracking and metrics purposes. + +| Setting | Description | +|---------|-------------| +| SLA Target (minutes) | Target response time. Used for dashboard metrics and SLA tracking | + +Leave empty to disable SLA tracking. + +## Email Notifications & Responses + +The HITL system uses an email-first architecture where responders can reply directly to notification emails. + +### How Email Responses Work - - Go to your Flow settings and select the "Human Review" configuration section. + + When a HITL request is created, an email is sent to the assigned responder with the review content and context. - - Assign individual users or groups as default responders for review requests. + + The email includes a special reply-to address with a signed token for authentication. - - Define fallback responders when primary assignees are unavailable. + + The responder simply replies to the email with their feedback—no login required. + + + The platform receives the reply, verifies the signed token, and matches the sender email. + + + The feedback is recorded and the flow continues with the human's input. - - HITL Configuration Settings - +### Response Format -### Dynamic Routing Rules +Responders can reply with: -Set up intelligent routing based on flow state, content type, or custom conditions: +- **Emit option**: If the reply matches an `emit` option (e.g., "approved"), it's used directly +- **Free-form text**: Any text response is passed to the flow as feedback +- **Plain text**: The first line of the reply body is used as feedback -| Rule Type | Description | Example | -|-----------|-------------|---------| -| **Content-Based** | Route based on the content being reviewed | Legal content → Legal team | -| **Priority-Based** | Assign reviewers based on urgency level | High priority → Senior reviewers | -| **State-Based** | Route based on flow state variables | `state.amount > 10000` → Finance director | -| **Round-Robin** | Distribute reviews evenly across team | Balance workload automatically | +### Confirmation Emails + +After processing a reply, the responder receives a confirmation email indicating whether the feedback was successfully submitted or if an error occurred. + +### Email Token Security + +- Tokens are cryptographically signed for security +- Tokens expire after 7 days +- Sender email must match the token's authorized email +- Confirmation/error emails are sent after processing + +## Routing Rules + +Route HITL requests to specific email addresses based on method patterns. - HITL Routing Rules Configuration + HITL Routing Rules Configuration -### Role-Based Permissions +### Rule Structure -Control who can view, respond to, or escalate HITL requests: +```json +{ + "name": "Approvals to Finance", + "match": { + "method_name": "approve_*" + }, + "assign_to_email": "finance@company.com", + "assign_from_input": "manager_email" +} +``` - - - Can view HITL requests and their status but cannot respond or take action. - - - Can view and respond to assigned HITL requests with approve/reject decisions. - - - Can view all requests, respond, reassign to other team members, and override decisions. - - - Full access including configuration of routing rules, SLAs, and escalation policies. - - +### Matching Patterns + +| Pattern | Description | Example Match | +|---------|-------------|---------------| +| `approve_*` | Wildcard (any chars) | `approve_payment`, `approve_vendor` | +| `review_?` | Single char | `review_a`, `review_1` | +| `validate_payment` | Exact match | `validate_payment` only | + +### Assignment Priority + +1. **Dynamic assignment** (`assign_from_input`): If configured, pulls email from flow state +2. **Static email** (`assign_to_email`): Falls back to configured email +3. **Deployment creator**: If no rule matches, the deployment creator's email is used + +### Dynamic Assignment Example + +If your flow state contains `{"sales_rep_email": "alice@company.com"}`, configure: + +```json +{ + "name": "Route to Sales Rep", + "match": { + "method_name": "review_*" + }, + "assign_from_input": "sales_rep_email" +} +``` + +The request will be assigned to `alice@company.com` automatically. + + +**Use Case**: Pull the assignee from your CRM, database, or previous flow step to dynamically route reviews to the right person. + + +## Auto-Response + +Automatically respond to HITL requests if no human responds within a timeout. This ensures flows don't hang indefinitely. + +### Configuration + +| Setting | Description | +|---------|-------------| +| Enabled | Toggle to enable auto-response | +| Timeout (minutes) | Time to wait before auto-responding | +| Default Outcome | The response value (must match an `emit` option) | + + + HITL Auto-Response Configuration + + +### Use Cases + +- **SLA compliance**: Ensure flows don't hang indefinitely +- **Default approval**: Auto-approve low-risk requests after timeout +- **Graceful degradation**: Continue with a safe default when reviewers are unavailable + + +Use auto-response carefully. Only enable it for non-critical reviews where a default response is acceptable. + ## Review Process -### Review Interface +### Dashboard Interface The HITL review interface provides a clean, focused experience for reviewers: - **Markdown Rendering**: Rich formatting for review content with syntax highlighting - **Context Panel**: View flow state, execution history, and related information - **Feedback Input**: Provide detailed feedback and comments with your decision -- **Quick Actions**: One-click approve/reject buttons with optional comments +- **Quick Actions**: One-click emit option buttons with optional comments HITL Pending Requests List -### Review Modes +### Response Methods -Choose the review approach that fits your workflow: +Reviewers can respond via three channels: - - - **Block execution until approval** - - Flow pauses completely until a human provides feedback. Best for critical decisions that must not proceed without review. - - - **Queue items for efficient review** - - Collect multiple review requests and process them in focused sessions. Ideal for high-volume, lower-urgency reviews. - - +| Method | Description | +|--------|-------------| +| **Email Reply** | Reply directly to the notification email | +| **Dashboard** | Use the Enterprise dashboard UI | +| **API/Webhook** | Programmatic response via API | ### History & Audit Trail @@ -159,74 +263,22 @@ Every HITL interaction is tracked with a complete timeline: - Decision history (approve/reject/revise) - Reviewer identity and timestamp - Feedback and comments provided -- State changes and escalations +- Response method (email/dashboard/API) - Response time metrics -## SLA Management & Escalation - -Ensure timely responses with automated SLA tracking and escalation policies. - -### Configuring SLAs - -Set response time expectations for different review types: - -| SLA Level | Response Time | Use Case | -|-----------|---------------|----------| -| **Critical** | 15 minutes | Production incidents, security reviews | -| **High** | 1 hour | Customer-facing content, urgent approvals | -| **Standard** | 4 hours | Regular content review, routine approvals | -| **Low** | 24 hours | Non-blocking reviews, batch processing | - -### Escalation Rules - -Configure automatic escalation when SLAs are at risk: - - - - Send reminder notification to assigned reviewer (e.g., at 50% of SLA time). - - - Escalate to manager or backup reviewer when SLA threshold is reached. - - - Configure fallback behavior if no response after extended period: - - **Auto-approve**: Proceed with execution (for non-critical reviews) - - **Auto-reject**: Fail safely and notify stakeholders - - **Re-route**: Assign to different reviewer or team - - - -### Notifications - -Automated alerts keep stakeholders informed throughout the workflow: - -- **Assignment Notifications**: Alert reviewers when new requests arrive -- **SLA Warnings**: Remind reviewers before deadlines -- **Escalation Alerts**: Notify managers when reviews are escalated -- **Completion Updates**: Inform requesters when reviews are complete - - -**Slack Integration**: Direct Slack notifications for HITL requests coming soon. - - ## Analytics & Monitoring Track HITL performance with comprehensive analytics. ### Performance Dashboard -Monitor key metrics across your HITL workflows: - HITL Metrics Dashboard - - Track percentage of reviews completed within SLA thresholds. - - Monitor average and median response times by reviewer, team, or flow. + Monitor average and median response times by reviewer or flow. Analyze review volume patterns to optimize team capacity. @@ -234,17 +286,11 @@ Monitor key metrics across your HITL workflows: View approval/rejection rates across different review types. + + Track percentage of reviews completed within SLA targets. + -### Individual Metrics - -Track reviewer performance for accountability and workload balancing: - -- Approval/rejection rates by reviewer -- Average response time per reviewer -- Review completion rates -- Escalation frequency - ### Audit & Compliance Enterprise-ready audit capabilities for regulatory requirements: @@ -261,7 +307,7 @@ Enterprise-ready audit capabilities for regulatory requirements: **Use Case**: Internal security questionnaire automation with human validation - AI generates responses to security questionnaires - - Security team reviews and validates accuracy + - Security team reviews and validates accuracy via email - Approved responses are compiled into final submission - Full audit trail for compliance @@ -270,8 +316,7 @@ Enterprise-ready audit capabilities for regulatory requirements: **Use Case**: Marketing content requiring legal/brand review - AI generates marketing copy or social media content - - Route to brand team for voice/tone review - - Escalate to legal for compliance-sensitive content + - Route to brand team email for voice/tone review - Automatic publishing upon approval @@ -279,31 +324,28 @@ Enterprise-ready audit capabilities for regulatory requirements: **Use Case**: Expense reports, contract terms, budget allocations - AI pre-processes and categorizes financial requests - - Route based on amount thresholds to appropriate approvers - - Enforce segregation of duties with role-based access + - Route based on amount thresholds using dynamic assignment - Maintain complete audit trail for financial compliance - - **Use Case**: Regulatory review for sensitive operations + + **Use Case**: Route reviews to account owners from your CRM - - AI flags potential compliance issues - - Compliance officers review flagged items - - Escalate to legal counsel as needed - - Generate compliance reports with decision history + - Flow fetches account owner email from CRM + - Store email in flow state (e.g., `account_owner_email`) + - Use `assign_from_input` to route to the right person automatically **Use Case**: AI output validation before customer delivery - AI generates customer-facing content or responses - - QA team samples and reviews output quality + - QA team reviews via email notification - Feedback loops improve AI performance over time - - Track quality metrics across review cycles -## Custom Webhooks API +## Webhooks API When your Flows pause for human feedback, you can configure webhooks to send request data to your own application. This enables: @@ -313,6 +355,10 @@ When your Flows pause for human feedback, you can configure webhooks to send req - Mobile app notifications - Automated decision systems + + HITL Webhook Configuration + + ### Configuring Webhooks @@ -339,7 +385,6 @@ Your endpoint will receive HTTP POST requests for these events: | Event Type | When Triggered | |------------|----------------| | `new_request` | A flow pauses and requests human feedback | -| `escalation` | A pending request is escalated due to SLA timeout | ### Webhook Payload @@ -347,106 +392,37 @@ All webhooks receive a JSON payload with this structure: ```json { - "event_type": "new_request", - "id": "550e8400-e29b-41d4-a716-446655440000", - "status": "pending", - "flow_id": "flow_abc123", - "flow_class": "ContentReviewFlow", - "method_name": "review_article", - "message": "Please review this article for publication.", - "output": "# Article Title\n\nThis is the content that needs review...", - "emit": ["approve", "reject", "request_changes"], - "default_outcome": null, - "state": { - "article_id": 12345, - "author": "john@example.com", - "category": "technology" + "event": "new_request", + "request": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "flow_id": "flow_abc123", + "method_name": "review_article", + "message": "Please review this article for publication.", + "emit_options": ["approved", "rejected", "request_changes"], + "state": { + "article_id": 12345, + "author": "john@example.com", + "category": "technology" + }, + "metadata": {}, + "created_at": "2026-01-14T12:00:00Z" }, - "metadata": { - "priority": "high", - "source": "cms" + "deployment": { + "id": 456, + "name": "Content Review Flow", + "organization_id": 789 }, - "created_at": "2026-01-12T10:30:00Z", - "callback_url": "https://api.crewai.com/crewai_plus/api/v1/human_feedback_requests/550e8400.../respond?token=abc123...", - "response_token": "abc123def456...", - "deployment_id": 12345, - "deployment_name": "Content Review Crew", - "flow_execution_id": "exec_789", - "trace_batch_id": "trace_456", - "organization_id": "org_123", - "assigned_to": { - "id": 42, - "email": "reviewer@company.com", - "name": "Jane Reviewer" - }, - "assigned_at": "2026-01-12T10:30:05Z", - "escalated_at": null, - "sla_target_minutes": 120, - "triggered_by_user_id": 99, - "routing": { - "effective_responders": [ - {"id": 42, "email": "reviewer@company.com", "name": "Jane Reviewer"}, - {"id": 43, "email": "manager@company.com", "name": "Bob Manager"} - ], - "enforce_routing_rules": true - } + "callback_url": "https://api.crewai.com/...", + "assigned_to_email": "reviewer@company.com" } ``` -### Field Reference - - - - | Field | Type | Description | - |-------|------|-------------| - | `event_type` | string | `"new_request"` or `"escalation"` | - | `id` | UUID | Unique identifier for this request | - | `status` | string | Always `"pending"` for active requests | - | `method_name` | string | The decorated method that requested feedback | - | `message` | string | Human-readable prompt/question for the reviewer | - | `output` | string | Content to review (may contain Markdown) | - | `emit` | array | Valid response options from the decorator | - | `default_outcome` | string | Default outcome if auto-response triggers | - | `state` | object | Flow state at the moment of pause | - | `metadata` | object | Custom metadata from the decorator | - | `created_at` | ISO8601 | When the request was created | - - - - | Field | Type | Description | - |-------|------|-------------| - | `callback_url` | string | **POST to this URL to submit feedback** (token included) | - | `response_token` | string | Single-use auth token (already in callback_url) | - - - - | Field | Type | Description | - |-------|------|-------------| - | `deployment_id` | integer | Deployment identifier | - | `deployment_name` | string | Human-readable deployment name | - | `flow_execution_id` | UUID | Links to the execution trace | - | `organization_id` | UUID | Organization identifier | - | `sla_target_minutes` | integer | Configured SLA target (null if not set) | - | `triggered_by_user_id` | integer | User who kicked off the flow (if known) | - - - - | Field | Type | Description | - |-------|------|-------------| - | `assigned_to` | object | Pre-assigned reviewer (if any) | - | `assigned_at` | ISO8601 | When assignment was made | - | `escalated_at` | ISO8601 | When request was escalated (null if not escalated) | - | `routing.effective_responders` | array | Users configured to respond | - | `routing.enforce_routing_rules` | boolean | Whether only listed responders can respond | - - - ### Responding to Requests To submit feedback, **POST to the `callback_url`** included in the webhook payload. ```http -POST /crewai_plus/api/v1/human_feedback_requests/{id}/respond?token={token} +POST {callback_url} Content-Type: application/json { @@ -455,53 +431,6 @@ Content-Type: application/json } ``` -**The token is already included in `callback_url`**, so you can POST directly: - -```bash -curl -X POST "${callback_url}" \ - -H "Content-Type: application/json" \ - -d '{"feedback": "Approved with minor edits"}' -``` - -#### Parameters - -| Parameter | Required | Description | -|-----------|----------|-------------| -| `feedback` | Yes | Your feedback text (will be passed to the flow) | -| `source` | No | Identifier for your app (shows in history) | - -#### Response Examples - - -```json Success (200 OK) -{ - "status": "accepted", - "request": { - "id": "550e8400-e29b-41d4-a716-446655440000", - "status": "responded", - "feedback": "Approved with minor edits", - "outcome": null, - "responded_at": "2026-01-12T11:45:00Z", - "responded_via": "my_custom_app" - } -} -``` - -```json Already Responded (409 Conflict) -{ - "error": "already_responded", - "message": "Feedback already provided via dashboard at 2026-01-12T11:30:00Z" -} -``` - -```json Invalid Token (401 Unauthorized) -{ - "error": "unauthorized", - "message": "Invalid response token" -} -``` - - ### Security @@ -515,309 +444,33 @@ All webhook requests are cryptographically signed using HMAC-SHA256 to ensure au - **Encrypted at rest**: Signing secrets are encrypted in our database - **Timestamp verification**: Prevents replay attacks -#### Response Token Security - -- **Single-use**: Tokens are invalidated after a successful response -- **256-bit entropy**: Tokens use cryptographically secure random generation - -#### Best Practices - -1. **Verify signatures**: Always validate the `X-CrewAI-Signature` header -2. **Check timestamps**: Reject requests older than 5 minutes -3. **Store secrets securely**: Treat signing secrets like passwords -4. **Use HTTPS**: Your webhook endpoint must use TLS in production -5. **Rotate secrets**: Regenerate webhook secrets periodically via the dashboard - -### Example Integrations - - -```python Python (Flask) - Complete Example -from flask import Flask, request, jsonify -import requests -import hmac -import hashlib -import time - -app = Flask(__name__) - -WEBHOOK_SECRET = "whsec_your_signing_secret_here" -MAX_TIMESTAMP_AGE = 300 - -def verify_signature(payload: bytes, signature: str, timestamp: str) -> bool: - try: - ts = int(timestamp) - if abs(time.time() - ts) > MAX_TIMESTAMP_AGE: - return False - except (ValueError, TypeError): - return False - - signature_payload = f"{timestamp}.{payload.decode('utf-8')}" - expected = hmac.new( - WEBHOOK_SECRET.encode('utf-8'), - signature_payload.encode('utf-8'), - hashlib.sha256 - ).hexdigest() - - return hmac.compare_digest(f"sha256={expected}", signature) - -@app.route('/hitl-webhook', methods=['POST']) -def handle_hitl(): - # Verify signature first - signature = request.headers.get('X-CrewAI-Signature', '') - timestamp = request.headers.get('X-CrewAI-Timestamp', '') - - if not verify_signature(request.data, signature, timestamp): - return jsonify({'error': 'Invalid signature'}), 401 - - payload = request.json - - # Store for later review - store_request(payload) - - # Or auto-approve based on rules - if should_auto_approve(payload): - response = requests.post( - payload['callback_url'], - json={'feedback': 'Auto-approved by policy', 'source': 'auto_approver'} - ) - return jsonify({'status': 'auto_approved'}) - - return jsonify({'status': 'queued_for_review'}) -``` - -```javascript Node.js (Express) - Complete Example -const express = require('express'); -const crypto = require('crypto'); -const axios = require('axios'); - -const app = express(); -const WEBHOOK_SECRET = 'whsec_your_signing_secret_here'; -const MAX_TIMESTAMP_AGE = 300; - -// Capture raw body for signature verification -app.use('/hitl-webhook', express.raw({ type: 'application/json' })); - -function verifySignature(payload, signature, timestamp) { - const ts = parseInt(timestamp, 10); - if (isNaN(ts) || Math.abs(Date.now() / 1000 - ts) > MAX_TIMESTAMP_AGE) { - return false; - } - - const signaturePayload = `${timestamp}.${payload.toString()}`; - const expected = crypto - .createHmac('sha256', WEBHOOK_SECRET) - .update(signaturePayload) - .digest('hex'); - - return crypto.timingSafeEqual( - Buffer.from(`sha256=${expected}`), - Buffer.from(signature) - ); -} - -app.post('/hitl-webhook', async (req, res) => { - const signature = req.headers['x-crewai-signature'] || ''; - const timestamp = req.headers['x-crewai-timestamp'] || ''; - - if (!verifySignature(req.body, signature, timestamp)) { - return res.status(401).json({ error: 'Invalid signature' }); - } - - const { event_type, callback_url, message, output } = JSON.parse(req.body); - - console.log(`Received ${event_type}: ${message}`); - - // Notify your team via Slack, email, etc. - await notifyTeam(payload); - - // Later, when someone approves: - // await axios.post(callback_url, { feedback: 'Approved!' }); - - res.json({ received: true }); -}); -``` - - -### Webhook Signature Verification - -All webhook requests are signed using HMAC-SHA256. You should verify the signature to ensure requests are authentic and haven't been tampered with. - #### Signature Headers Each webhook request includes these headers: | Header | Description | |--------|-------------| -| `X-CrewAI-Signature` | HMAC-SHA256 signature: `sha256=` | -| `X-CrewAI-Timestamp` | Unix timestamp when the request was signed | +| `X-Signature` | HMAC-SHA256 signature: `sha256=` | +| `X-Timestamp` | Unix timestamp when the request was signed | -#### Verification Algorithm +#### Verification -The signature is computed as: - -``` -HMAC-SHA256(signing_secret, timestamp + "." + raw_body) -``` - -Where: -- `signing_secret` is your webhook's unique secret (shown in dashboard) -- `timestamp` is the value from `X-CrewAI-Timestamp` header -- `raw_body` is the raw JSON request body (before parsing) - -#### Python Verification Example +Verify by computing: ```python import hmac import hashlib -import time -from flask import Flask, request, jsonify -app = Flask(__name__) +expected = hmac.new( + signing_secret.encode(), + f"{timestamp}.{payload}".encode(), + hashlib.sha256 +).hexdigest() -WEBHOOK_SECRET = "whsec_your_signing_secret_here" -MAX_TIMESTAMP_AGE = 300 # 5 minutes - -def verify_signature(payload: bytes, signature: str, timestamp: str) -> bool: - """Verify the webhook signature.""" - # Check timestamp to prevent replay attacks - try: - ts = int(timestamp) - if abs(time.time() - ts) > MAX_TIMESTAMP_AGE: - return False - except (ValueError, TypeError): - return False - - # Compute expected signature - signature_payload = f"{timestamp}.{payload.decode('utf-8')}" - expected = hmac.new( - WEBHOOK_SECRET.encode('utf-8'), - signature_payload.encode('utf-8'), - hashlib.sha256 - ).hexdigest() - - expected_header = f"sha256={expected}" - - # Constant-time comparison to prevent timing attacks - return hmac.compare_digest(expected_header, signature) - -@app.route('/hitl-webhook', methods=['POST']) -def handle_hitl(): - signature = request.headers.get('X-CrewAI-Signature', '') - timestamp = request.headers.get('X-CrewAI-Timestamp', '') - - if not verify_signature(request.data, signature, timestamp): - return jsonify({'error': 'Invalid signature'}), 401 - - payload = request.json - # Process the verified webhook... - return jsonify({'status': 'received'}) +if hmac.compare_digest(expected, signature): + # Valid signature ``` -#### Node.js Verification Example - -```javascript -const express = require('express'); -const crypto = require('crypto'); - -const app = express(); -const WEBHOOK_SECRET = 'whsec_your_signing_secret_here'; -const MAX_TIMESTAMP_AGE = 300; // 5 minutes - -// Use raw body for signature verification -app.use('/hitl-webhook', express.raw({ type: 'application/json' })); - -function verifySignature(payload, signature, timestamp) { - // Check timestamp - const ts = parseInt(timestamp, 10); - if (isNaN(ts) || Math.abs(Date.now() / 1000 - ts) > MAX_TIMESTAMP_AGE) { - return false; - } - - // Compute expected signature - const signaturePayload = `${timestamp}.${payload.toString()}`; - const expected = crypto - .createHmac('sha256', WEBHOOK_SECRET) - .update(signaturePayload) - .digest('hex'); - - const expectedHeader = `sha256=${expected}`; - - // Constant-time comparison - return crypto.timingSafeEqual( - Buffer.from(expectedHeader), - Buffer.from(signature) - ); -} - -app.post('/hitl-webhook', (req, res) => { - const signature = req.headers['x-crewai-signature'] || ''; - const timestamp = req.headers['x-crewai-timestamp'] || ''; - - if (!verifySignature(req.body, signature, timestamp)) { - return res.status(401).json({ error: 'Invalid signature' }); - } - - const payload = JSON.parse(req.body); - // Process the verified webhook... - res.json({ status: 'received' }); -}); -``` - -#### Ruby Verification Example - -```ruby -require 'openssl' -require 'json' - -class HitlWebhookController < ApplicationController - WEBHOOK_SECRET = ENV['CREWAI_WEBHOOK_SECRET'] - MAX_TIMESTAMP_AGE = 300 # 5 minutes - - skip_before_action :verify_authenticity_token - - def receive - signature = request.headers['X-CrewAI-Signature'] - timestamp = request.headers['X-CrewAI-Timestamp'] - payload = request.raw_post - - unless verify_signature(payload, signature, timestamp) - render json: { error: 'Invalid signature' }, status: :unauthorized - return - end - - data = JSON.parse(payload) - # Process the verified webhook... - render json: { status: 'received' } - end - - private - - def verify_signature(payload, signature, timestamp) - return false if timestamp.blank? || signature.blank? - - # Check timestamp freshness - ts = timestamp.to_i - return false if (Time.now.to_i - ts).abs > MAX_TIMESTAMP_AGE - - # Compute expected signature - signature_payload = "#{timestamp}.#{payload}" - expected = OpenSSL::HMAC.hexdigest('SHA256', WEBHOOK_SECRET, signature_payload) - expected_header = "sha256=#{expected}" - - # Constant-time comparison - ActiveSupport::SecurityUtils.secure_compare(expected_header, signature) - end -end -``` - -#### Security Best Practices - -1. **Always verify signatures** before processing webhook data -2. **Check timestamp freshness** (we recommend 5-minute tolerance) -3. **Use constant-time comparison** to prevent timing attacks -4. **Store secrets securely** using environment variables or secret managers -5. **Rotate secrets periodically** (you can regenerate in the dashboard) - ### Error Handling Your webhook endpoint should return a 2xx status code to acknowledge receipt: @@ -828,68 +481,69 @@ Your webhook endpoint should return a 2xx status code to acknowledge receipt: | 4xx/5xx | Logged as failed, no retry | | Timeout (30s) | Logged as failed, no retry | -### Testing Your Integration +## Security & RBAC - - - Add a webhook pointing to your dev endpoint - - - For local development, use [ngrok](https://ngrok.com): - ```bash - ngrok http 3000 - # Use the HTTPS URL as your webhook endpoint - ``` - - - Run a flow with a `@human_feedback` decorator - - - Check that your endpoint receives the payload - - - POST to the `callback_url` to complete the flow - - +### Dashboard Access -## Other Integration Options +HITL access is controlled at the deployment level: -### API Access +| Permission | Capability | +|------------|------------| +| `manage_human_feedback` | Configure HITL settings, view all requests | +| `respond_to_human_feedback` | Respond to requests, view assigned requests | -Full programmatic control for custom integrations: +### Email Response Authorization -```python -# Example: Programmatically check HITL status -from crewai.enterprise import HITLClient +For email replies: +1. The reply-to token encodes the authorized email +2. Sender email must match the token's email +3. Token must not be expired (7-day default) +4. Request must still be pending -client = HITLClient() -pending_reviews = client.get_pending_reviews(flow_id="my-flow") +### Audit Trail -for review in pending_reviews: - print(f"Review {review.id}: {review.status} - Assigned to: {review.assignee}") -``` +All HITL actions are logged: +- Request creation +- Assignment changes +- Response submission (with source: dashboard/email/API) +- Flow resume status -### Coming Soon +## Troubleshooting -- **Slack Integration**: Respond to HITL requests directly from Slack -- **Microsoft Teams**: Teams-native review experience -- **Mobile App**: Review and approve on the go +### Emails Not Sending + +1. Check "Email Notifications" is enabled in configuration +2. Verify routing rules match the method name +3. Verify assignee email is valid +4. Check deployment creator fallback if no routing rules match + +### Email Replies Not Processing + +1. Check token hasn't expired (7-day default) +2. Verify sender email matches assigned email +3. Ensure request is still pending (not already responded) + +### Flow Not Resuming + +1. Check request status in dashboard +2. Verify callback URL is accessible +3. Ensure deployment is still running ## Best Practices -**Start Simple**: Begin with basic approval gates, then add routing and SLAs as your workflows mature. +**Start Simple**: Begin with email notifications to deployment creator, then add routing rules as your workflows mature. -1. **Define Clear Review Criteria**: Document what reviewers should look for to ensure consistent decisions. +1. **Use Dynamic Assignment**: Pull assignee emails from your flow state for flexible routing. -2. **Set Realistic SLAs**: Balance urgency with reviewer capacity to maintain sustainable workflows. +2. **Configure Auto-Response**: Set up a fallback for non-critical reviews to prevent flows from hanging. -3. **Use Escalation Wisely**: Reserve auto-approval for truly non-critical reviews to maintain quality. +3. **Monitor Response Times**: Use analytics to identify bottlenecks and optimize your review process. -4. **Monitor and Iterate**: Use analytics to identify bottlenecks and optimize reviewer assignments. +4. **Keep Review Messages Clear**: Write clear, actionable messages in the `@human_feedback` decorator. -5. **Train Your Team**: Ensure reviewers understand their role and the tools available to them. +5. **Test Email Flow**: Send test requests to verify email delivery before going to production. ## Related Resources diff --git a/docs/en/enterprise/guides/human-in-the-loop.mdx b/docs/en/enterprise/guides/human-in-the-loop.mdx index 00ec01da5..7824555bc 100644 --- a/docs/en/enterprise/guides/human-in-the-loop.mdx +++ b/docs/en/enterprise/guides/human-in-the-loop.mdx @@ -13,7 +13,7 @@ CrewAI offers two approaches for implementing human-in-the-loop workflows: | Approach | Best For | Version | |----------|----------|---------| -| **Flow-based** (`@human_feedback` decorator) | Production with Enterprise UI, managed workflows, full platform features | **1.8.0+** | +| **Flow-based** (`@human_feedback` decorator) | Production with Enterprise UI, email-first workflows, full platform features | **1.8.0+** | | **Webhook-based** | Custom integrations, external systems (Slack, Teams, etc.), legacy setups | All versions | ## Flow-Based HITL with Enterprise Platform @@ -22,29 +22,30 @@ CrewAI offers two approaches for implementing human-in-the-loop workflows: The `@human_feedback` decorator requires **CrewAI version 1.8.0 or higher**. -When using the `@human_feedback` decorator in your Flows, CrewAI Enterprise provides a dedicated **HITL Management UI** that gives you full control over human feedback workflows: +When using the `@human_feedback` decorator in your Flows, CrewAI Enterprise provides an **email-first HITL system** that enables anyone with an email address to respond to review requests: - - Review and respond to HITL requests directly within the Enterprise dashboard—no webhook setup required. + + Responders receive email notifications and can reply directly—no login required. - - Assign specific team members or groups as responders for different task types or crews. + + Review and respond to HITL requests in the Enterprise dashboard when preferred. - - Define who can view, respond to, or escalate HITL requests with granular permission controls. + + Route requests to specific emails based on method patterns or pull from flow state. - - Configure automatic escalation rules when responses are delayed or require senior review. - - - Set Service Level Agreements for response times with automatic notifications and tracking. - - - Route HITL requests based on content, priority, or custom rules with enforcement policies. + + Configure automatic fallback responses when no human replies within the timeout. +### Key Benefits + +- **External responders**: Anyone with an email can respond, even non-platform users +- **Dynamic assignment**: Pull assignee email from flow state (e.g., `account_owner_email`) +- **Simple configuration**: Email-based routing is easier to set up than user/role management +- **Deployment creator fallback**: If no routing rule matches, the deployment creator is notified + For implementation details on the `@human_feedback` decorator, see the [Human Feedback in Flows](/en/learn/human-feedback-in-flows) guide. @@ -148,7 +149,7 @@ HITL workflows are particularly valuable for: - Explore the full Enterprise Flow HITL platform capabilities including assignment, SLA management, escalation policies, and analytics. + Explore the full Enterprise Flow HITL platform capabilities including email notifications, routing rules, auto-response, and analytics. Implementation guide for the `@human_feedback` decorator in your Flows. diff --git a/docs/images/enterprise/hitl-settings-1.png b/docs/images/enterprise/hitl-settings-1.png deleted file mode 100644 index daf90b949..000000000 Binary files a/docs/images/enterprise/hitl-settings-1.png and /dev/null differ diff --git a/docs/images/enterprise/hitl-settings-2.png b/docs/images/enterprise/hitl-settings-2.png deleted file mode 100644 index adf2aa3a9..000000000 Binary files a/docs/images/enterprise/hitl-settings-2.png and /dev/null differ diff --git a/docs/images/enterprise/hitl-settings-auto-respond.png b/docs/images/enterprise/hitl-settings-auto-respond.png new file mode 100644 index 000000000..a2ebf667e Binary files /dev/null and b/docs/images/enterprise/hitl-settings-auto-respond.png differ diff --git a/docs/images/enterprise/hitl-settings-overview.png b/docs/images/enterprise/hitl-settings-overview.png new file mode 100644 index 000000000..ba4aaf8cd Binary files /dev/null and b/docs/images/enterprise/hitl-settings-overview.png differ diff --git a/docs/images/enterprise/hitl-settings-routing-rules.png b/docs/images/enterprise/hitl-settings-routing-rules.png new file mode 100644 index 000000000..652d85608 Binary files /dev/null and b/docs/images/enterprise/hitl-settings-routing-rules.png differ diff --git a/docs/images/enterprise/hitl-settings-webhook.png b/docs/images/enterprise/hitl-settings-webhook.png new file mode 100644 index 000000000..97c3c9d60 Binary files /dev/null and b/docs/images/enterprise/hitl-settings-webhook.png differ diff --git a/docs/ko/enterprise/features/flow-hitl-management.mdx b/docs/ko/enterprise/features/flow-hitl-management.mdx index 9ebf19a35..a760a4c44 100644 --- a/docs/ko/enterprise/features/flow-hitl-management.mdx +++ b/docs/ko/enterprise/features/flow-hitl-management.mdx @@ -1,6 +1,6 @@ --- title: "Flow HITL 관리" -description: "할당, SLA 관리, 에스컬레이션 정책 및 동적 라우팅을 갖춘 Flow용 엔터프라이즈급 인간 검토" +description: "이메일 우선 알림, 라우팅 규칙 및 자동 응답 기능을 갖춘 Flow용 엔터프라이즈급 인간 검토" icon: "users-gear" mode: "wide" --- @@ -9,25 +9,33 @@ mode: "wide" Flow HITL 관리 기능은 `@human_feedback` 데코레이터가 필요하며, **CrewAI 버전 1.8.0 이상**에서 사용할 수 있습니다. 이 기능은 Crew가 아닌 **Flow**에만 적용됩니다. -CrewAI Enterprise는 AI 워크플로우를 협업적인 인간-AI 프로세스로 전환하는 Flow용 포괄적인 Human-in-the-Loop(HITL) 관리 시스템을 제공합니다. 단순한 승인 게이트를 넘어, 플랫폼은 할당, 책임, 규정 준수를 위한 엔터프라이즈급 제어를 제공합니다. +CrewAI Enterprise는 AI 워크플로우를 협업적인 인간-AI 프로세스로 전환하는 Flow용 포괄적인 Human-in-the-Loop(HITL) 관리 시스템을 제공합니다. 플랫폼은 **이메일 우선 아키텍처**를 사용하여 이메일 주소가 있는 누구나 플랫폼 계정 없이도 검토 요청에 응답할 수 있습니다. ## 개요 - - Enterprise 대시보드에서 직접 요청을 검토하고 응답 + + 응답자가 알림 이메일에 직접 회신하여 피드백 제공 가능 - - 규칙과 전문성에 따라 적합한 담당자에게 검토 라우팅 + + 메서드 패턴 또는 Flow 상태에 따라 특정 이메일로 요청 라우팅 - - 자동화된 에스컬레이션 정책으로 적시 응답 보장 + + 시간 내에 인간이 응답하지 않을 경우 자동 대체 응답 구성 +### 주요 이점 + +- **간단한 멘탈 모델**: 이메일 주소는 보편적이며 플랫폼 사용자나 역할을 관리할 필요 없음 +- **외부 응답자**: 플랫폼 사용자가 아니어도 이메일이 있는 누구나 응답 가능 +- **동적 할당**: Flow 상태에서 직접 담당자 이메일 가져오기 (예: `sales_rep_email`) +- **간소화된 구성**: 설정할 항목이 적어 더 빠르게 가치 실현 +- **이메일이 주요 채널**: 대부분의 사용자는 대시보드 로그인보다 이메일로 응답하는 것을 선호 + ## Flow에서 인간 검토 포인트 설정 -`@human_feedback` 데코레이터를 사용하여 Flow 내에 인간 검토 체크포인트를 구성합니다. 실행이 검토 포인트에 도달하면 시스템이 일시 중지되고 UI에 "입력 대기 중" 상태가 표시됩니다. +`@human_feedback` 데코레이터를 사용하여 Flow 내에 인간 검토 체크포인트를 구성합니다. 실행이 검토 포인트에 도달하면 시스템이 일시 중지되고, 담당자에게 이메일로 알리며, 응답을 기다립니다. ```python from crewai.flow.flow import Flow, start, listen @@ -62,95 +70,191 @@ class ContentApprovalFlow(Flow): 완전한 구현 세부 사항은 [Flow에서 인간 피드백](/ko/learn/human-feedback-in-flows) 가이드를 참조하세요. -## 할당 및 라우팅 +### 데코레이터 파라미터 -Enterprise 플랫폼은 검토가 적합한 팀원에게 전달되도록 정교한 할당 기능을 제공합니다. +| 파라미터 | 유형 | 설명 | +|---------|------|------| +| `message` | `str` | 인간 검토자에게 표시되는 메시지 | +| `emit` | `list[str]` | 유효한 응답 옵션 (UI에서 버튼으로 표시) | -### 응답자 할당 +## 플랫폼 구성 -다양한 작업 유형에 대해 특정 팀원 또는 그룹을 응답자로 할당합니다: +HITL 구성에 접근: **배포** → **설정** → **Human in the Loop 구성** + + + HITL 구성 설정 + + +### 이메일 알림 + +HITL 요청에 대한 이메일 알림을 활성화하거나 비활성화하는 토글입니다. + +| 설정 | 기본값 | 설명 | +|-----|-------|------| +| 이메일 알림 | 활성화됨 | 피드백 요청 시 이메일 전송 | + + +비활성화되면 응답자는 대시보드 UI를 사용하거나 커스텀 알림 시스템을 위해 webhook을 구성해야 합니다. + + +### SLA 목표 + +추적 및 메트릭 목적으로 목표 응답 시간을 설정합니다. + +| 설정 | 설명 | +|-----|------| +| SLA 목표 (분) | 목표 응답 시간. 대시보드 메트릭 및 SLA 추적에 사용 | + +SLA 추적을 비활성화하려면 비워 두세요. + +## 이메일 알림 및 응답 + +HITL 시스템은 응답자가 알림 이메일에 직접 회신할 수 있는 이메일 우선 아키텍처를 사용합니다. + +### 이메일 응답 작동 방식 - - Flow 설정으로 이동하여 "인간 검토" 구성 섹션을 선택합니다. + + HITL 요청이 생성되면 검토 콘텐츠와 컨텍스트가 포함된 이메일이 할당된 응답자에게 전송됩니다. - - 검토 요청에 대한 기본 응답자로 개별 사용자 또는 그룹을 할당합니다. + + 이메일에는 인증을 위한 서명된 토큰이 포함된 특별한 reply-to 주소가 있습니다. - - 주 담당자가 부재 시 대체 응답자를 정의합니다. + + 응답자는 이메일에 피드백으로 회신하면 됩니다—로그인 필요 없음. + + + 플랫폼이 회신을 받고, 서명된 토큰을 확인하고, 발신자 이메일을 매칭합니다. + + + 피드백이 기록되고 인간의 입력으로 Flow가 계속됩니다. - - HITL 구성 설정 - +### 응답 형식 -### 동적 라우팅 규칙 +응답자는 다음과 같이 회신할 수 있습니다: -Flow 상태, 콘텐츠 유형 또는 사용자 정의 조건에 따라 지능형 라우팅을 설정합니다: +- **Emit 옵션**: 회신이 `emit` 옵션과 일치하면 (예: "approved") 직접 사용됨 +- **자유 형식 텍스트**: 모든 텍스트 응답이 피드백으로 Flow에 전달됨 +- **일반 텍스트**: 회신 본문의 첫 번째 줄이 피드백으로 사용됨 -| 규칙 유형 | 설명 | 예시 | -|-----------|------|------| -| **콘텐츠 기반** | 검토 대상 콘텐츠에 따라 라우팅 | 법률 콘텐츠 → 법무팀 | -| **우선순위 기반** | 긴급도에 따라 검토자 할당 | 높은 우선순위 → 시니어 검토자 | -| **상태 기반** | Flow 상태 변수에 따라 라우팅 | `state.amount > 10000` → 재무 이사 | -| **라운드 로빈** | 팀 전체에 검토를 균등 분배 | 워크로드 자동 균형 | +### 확인 이메일 + +회신을 처리한 후 응답자는 피드백이 성공적으로 제출되었는지 또는 오류가 발생했는지 나타내는 확인 이메일을 받습니다. + +### 이메일 토큰 보안 + +- 토큰은 보안을 위해 암호화 서명됨 +- 토큰은 7일 후 만료됨 +- 발신자 이메일은 토큰의 인증된 이메일과 일치해야 함 +- 처리 후 확인/오류 이메일 전송됨 + +## 라우팅 규칙 + +메서드 패턴에 따라 HITL 요청을 특정 이메일 주소로 라우팅합니다. - HITL 라우팅 규칙 구성 + HITL 라우팅 규칙 구성 -### 역할 기반 권한 +### 규칙 구조 -HITL 요청을 보거나, 응답하거나, 에스컬레이션할 수 있는 사람을 제어합니다: +```json +{ + "name": "재무팀으로 승인", + "match": { + "method_name": "approve_*" + }, + "assign_to_email": "finance@company.com", + "assign_from_input": "manager_email" +} +``` - - - HITL 요청과 상태를 볼 수 있지만 응답하거나 조치를 취할 수 없습니다. - - - 할당된 HITL 요청을 보고 승인/거부 결정으로 응답할 수 있습니다. - - - 모든 요청을 보고, 응답하고, 다른 팀원에게 재할당하고, 결정을 재정의할 수 있습니다. - - - 라우팅 규칙, SLA 및 에스컬레이션 정책 구성을 포함한 전체 접근 권한. - - +### 매칭 패턴 + +| 패턴 | 설명 | 매칭 예시 | +|-----|------|----------| +| `approve_*` | 와일드카드 (모든 문자) | `approve_payment`, `approve_vendor` | +| `review_?` | 단일 문자 | `review_a`, `review_1` | +| `validate_payment` | 정확히 일치 | `validate_payment`만 | + +### 할당 우선순위 + +1. **동적 할당** (`assign_from_input`): 구성된 경우 Flow 상태에서 이메일 가져옴 +2. **정적 이메일** (`assign_to_email`): 구성된 이메일로 대체 +3. **배포 생성자**: 규칙이 일치하지 않으면 배포 생성자의 이메일이 사용됨 + +### 동적 할당 예제 + +Flow 상태에 `{"sales_rep_email": "alice@company.com"}`이 포함된 경우: + +```json +{ + "name": "영업 담당자에게 라우팅", + "match": { + "method_name": "review_*" + }, + "assign_from_input": "sales_rep_email" +} +``` + +요청이 자동으로 `alice@company.com`에 할당됩니다. + + +**사용 사례**: CRM, 데이터베이스 또는 이전 Flow 단계에서 담당자를 가져와 적합한 사람에게 검토를 동적으로 라우팅하세요. + + +## 자동 응답 + +시간 내에 인간이 응답하지 않으면 HITL 요청에 자동으로 응답합니다. 이를 통해 Flow가 무한정 중단되지 않도록 합니다. + +### 구성 + +| 설정 | 설명 | +|-----|------| +| 활성화됨 | 자동 응답 활성화 토글 | +| 타임아웃 (분) | 자동 응답 전 대기 시간 | +| 기본 결과 | 응답 값 (`emit` 옵션과 일치해야 함) | + + + HITL 자동 응답 구성 + + +### 사용 사례 + +- **SLA 준수**: Flow가 무한정 중단되지 않도록 보장 +- **기본 승인**: 타임아웃 후 저위험 요청 자동 승인 +- **우아한 저하**: 검토자가 없을 때 안전한 기본값으로 계속 + + +자동 응답을 신중하게 사용하세요. 기본 응답이 허용되는 중요하지 않은 검토에만 활성화하세요. + ## 검토 프로세스 -### 검토 인터페이스 +### 대시보드 인터페이스 HITL 검토 인터페이스는 검토자에게 깔끔하고 집중된 경험을 제공합니다: - **마크다운 렌더링**: 구문 강조가 포함된 풍부한 형식의 검토 콘텐츠 - **컨텍스트 패널**: Flow 상태, 실행 기록 및 관련 정보 보기 - **피드백 입력**: 결정과 함께 상세한 피드백 및 코멘트 제공 -- **빠른 작업**: 선택적 코멘트가 있는 원클릭 승인/거부 버튼 +- **빠른 작업**: 선택적 코멘트가 있는 원클릭 emit 옵션 버튼 HITL 대기 중인 요청 목록 -### 검토 모드 +### 응답 방법 -워크플로우에 맞는 검토 방식을 선택합니다: +검토자는 세 가지 채널을 통해 응답할 수 있습니다: - - - **승인까지 실행 차단** - - 인간이 피드백을 제공할 때까지 Flow가 완전히 일시 중지됩니다. 검토 없이 진행해서는 안 되는 중요한 결정에 적합합니다. - - - **효율적인 검토를 위해 항목 대기열에 추가** - - 여러 검토 요청을 수집하고 집중 세션에서 처리합니다. 대량이지만 긴급도가 낮은 검토에 이상적입니다. - - +| 방법 | 설명 | +|-----|------| +| **이메일 회신** | 알림 이메일에 직접 회신 | +| **대시보드** | Enterprise 대시보드 UI 사용 | +| **API/Webhook** | API를 통한 프로그래밍 방식 응답 | ### 기록 및 감사 추적 @@ -159,74 +263,22 @@ HITL 검토 인터페이스는 검토자에게 깔끔하고 집중된 경험을 - 결정 기록 (승인/거부/수정) - 검토자 신원 및 타임스탬프 - 제공된 피드백 및 코멘트 -- 상태 변경 및 에스컬레이션 +- 응답 방법 (이메일/대시보드/API) - 응답 시간 메트릭 -## SLA 관리 및 에스컬레이션 - -자동화된 SLA 추적 및 에스컬레이션 정책으로 적시 응답을 보장합니다. - -### SLA 구성 - -다양한 검토 유형에 대한 응답 시간 기대치를 설정합니다: - -| SLA 레벨 | 응답 시간 | 사용 사례 | -|----------|----------|----------| -| **긴급** | 15분 | 프로덕션 인시던트, 보안 검토 | -| **높음** | 1시간 | 고객 대면 콘텐츠, 긴급 승인 | -| **표준** | 4시간 | 일반 콘텐츠 검토, 일상적인 승인 | -| **낮음** | 24시간 | 비차단 검토, 배치 처리 | - -### 에스컬레이션 규칙 - -SLA가 위험에 처할 때 자동 에스컬레이션을 구성합니다: - - - - 할당된 검토자에게 알림 전송 (예: SLA 시간의 50% 도달 시). - - - SLA 임계값에 도달하면 관리자 또는 백업 검토자에게 에스컬레이션. - - - 연장된 기간 후에도 응답이 없을 경우 대체 동작 구성: - - **자동 승인**: 실행 진행 (중요하지 않은 검토의 경우) - - **자동 거부**: 안전하게 실패하고 이해관계자에게 알림 - - **재라우팅**: 다른 검토자 또는 팀에 할당 - - - -### 알림 - -자동화된 알림이 워크플로우 전반에 걸쳐 이해관계자에게 정보를 제공합니다: - -- **할당 알림**: 새 요청이 도착하면 검토자에게 알림 -- **SLA 경고**: 마감 전 검토자에게 리마인더 -- **에스컬레이션 알림**: 검토가 에스컬레이션되면 관리자에게 알림 -- **완료 업데이트**: 검토가 완료되면 요청자에게 알림 - - -**Slack 통합**: HITL 요청에 대한 직접 Slack 알림이 곧 제공됩니다. - - ## 분석 및 모니터링 포괄적인 분석으로 HITL 성능을 추적합니다. ### 성능 대시보드 -HITL 워크플로우 전반의 주요 메트릭을 모니터링합니다: - HITL 메트릭 대시보드 - - SLA 임계값 내에 완료된 검토 비율 추적. - - 검토자, 팀 또는 Flow별 평균 및 중앙값 응답 시간 모니터링. + 검토자 또는 Flow별 평균 및 중앙값 응답 시간 모니터링. 팀 용량 최적화를 위한 검토 볼륨 패턴 분석. @@ -234,17 +286,11 @@ HITL 워크플로우 전반의 주요 메트릭을 모니터링합니다: 다양한 검토 유형에 대한 승인/거부 비율 보기. + + SLA 목표 내에 완료된 검토 비율 추적. + -### 개별 메트릭 - -책임 추적 및 워크로드 균형을 위한 검토자 성과 추적: - -- 검토자별 승인/거부 비율 -- 검토자별 평균 응답 시간 -- 검토 완료율 -- 에스컬레이션 빈도 - ### 감사 및 규정 준수 규제 요구 사항을 위한 엔터프라이즈급 감사 기능: @@ -261,7 +307,7 @@ HITL 워크플로우 전반의 주요 메트릭을 모니터링합니다: **사용 사례**: 인간 검증이 포함된 내부 보안 설문지 자동화 - AI가 보안 설문지에 대한 응답 생성 - - 보안팀이 정확성 검토 및 검증 + - 보안팀이 이메일로 정확성 검토 및 검증 - 승인된 응답이 최종 제출물로 편집 - 규정 준수를 위한 완전한 감사 추적 @@ -270,8 +316,7 @@ HITL 워크플로우 전반의 주요 메트릭을 모니터링합니다: **사용 사례**: 법무/브랜드 검토가 필요한 마케팅 콘텐츠 - AI가 마케팅 카피 또는 소셜 미디어 콘텐츠 생성 - - 브랜드팀에 목소리/톤 검토를 위해 라우팅 - - 규정 준수에 민감한 콘텐츠는 법무팀으로 에스컬레이션 + - 브랜드팀 이메일로 목소리/톤 검토를 위해 라우팅 - 승인 시 자동 게시 @@ -279,31 +324,28 @@ HITL 워크플로우 전반의 주요 메트릭을 모니터링합니다: **사용 사례**: 경비 보고서, 계약 조건, 예산 배분 - AI가 재무 요청을 사전 처리하고 분류 - - 금액 임계값에 따라 적절한 승인자에게 라우팅 - - 역할 기반 접근으로 직무 분리 시행 + - 동적 할당을 사용하여 금액 임계값에 따라 라우팅 - 재무 규정 준수를 위한 완전한 감사 추적 유지 - - **사용 사례**: 민감한 작업에 대한 규제 검토 + + **사용 사례**: CRM에서 계정 담당자에게 검토 라우팅 - - AI가 잠재적 규정 준수 문제 플래그 - - 규정 준수 담당자가 플래그된 항목 검토 - - 필요에 따라 법률 고문에게 에스컬레이션 - - 결정 기록이 포함된 규정 준수 보고서 생성 + - Flow가 CRM에서 계정 담당자 이메일 가져옴 + - 이메일을 Flow 상태에 저장 (예: `account_owner_email`) + - `assign_from_input`을 사용하여 적합한 사람에게 자동 라우팅 **사용 사례**: 고객 전달 전 AI 출력 검증 - AI가 고객 대면 콘텐츠 또는 응답 생성 - - QA팀이 출력 품질 샘플링 및 검토 + - QA팀이 이메일 알림을 통해 검토 - 피드백 루프가 시간이 지남에 따라 AI 성능 개선 - - 검토 주기 전반의 품질 메트릭 추적 -## 커스텀 Webhook API +## Webhook API Flow가 인간 피드백을 위해 일시 중지되면, 요청 데이터를 자체 애플리케이션으로 보내도록 webhook을 구성할 수 있습니다. 이를 통해 다음이 가능합니다: @@ -313,6 +355,10 @@ Flow가 인간 피드백을 위해 일시 중지되면, 요청 데이터를 자 - 모바일 앱 알림 - 자동화된 결정 시스템 + + HITL Webhook 구성 + + ### Webhook 구성 @@ -339,7 +385,6 @@ Flow가 인간 피드백을 위해 일시 중지되면, 요청 데이터를 자 | 이벤트 유형 | 트리거 시점 | |------------|------------| | `new_request` | Flow가 일시 중지되고 인간 피드백을 요청할 때 | -| `escalation` | SLA 타임아웃으로 인해 대기 중인 요청이 에스컬레이션될 때 | ### Webhook 페이로드 @@ -347,106 +392,37 @@ Flow가 인간 피드백을 위해 일시 중지되면, 요청 데이터를 자 ```json { - "event_type": "new_request", - "id": "550e8400-e29b-41d4-a716-446655440000", - "status": "pending", - "flow_id": "flow_abc123", - "flow_class": "ContentReviewFlow", - "method_name": "review_article", - "message": "이 기사의 게시를 검토해 주세요.", - "output": "# 기사 제목\n\n검토가 필요한 콘텐츠입니다...", - "emit": ["approve", "reject", "request_changes"], - "default_outcome": null, - "state": { - "article_id": 12345, - "author": "john@example.com", - "category": "technology" + "event": "new_request", + "request": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "flow_id": "flow_abc123", + "method_name": "review_article", + "message": "이 기사의 게시를 검토해 주세요.", + "emit_options": ["approved", "rejected", "request_changes"], + "state": { + "article_id": 12345, + "author": "john@example.com", + "category": "technology" + }, + "metadata": {}, + "created_at": "2026-01-14T12:00:00Z" }, - "metadata": { - "priority": "high", - "source": "cms" + "deployment": { + "id": 456, + "name": "Content Review Flow", + "organization_id": 789 }, - "created_at": "2026-01-12T10:30:00Z", - "callback_url": "https://api.crewai.com/crewai_plus/api/v1/human_feedback_requests/550e8400.../respond?token=abc123...", - "response_token": "abc123def456...", - "deployment_id": 12345, - "deployment_name": "Content Review Crew", - "flow_execution_id": "exec_789", - "trace_batch_id": "trace_456", - "organization_id": "org_123", - "assigned_to": { - "id": 42, - "email": "reviewer@company.com", - "name": "Jane Reviewer" - }, - "assigned_at": "2026-01-12T10:30:05Z", - "escalated_at": null, - "sla_target_minutes": 120, - "triggered_by_user_id": 99, - "routing": { - "effective_responders": [ - {"id": 42, "email": "reviewer@company.com", "name": "Jane Reviewer"}, - {"id": 43, "email": "manager@company.com", "name": "Bob Manager"} - ], - "enforce_routing_rules": true - } + "callback_url": "https://api.crewai.com/...", + "assigned_to_email": "reviewer@company.com" } ``` -### 필드 참조 - - - - | 필드 | 유형 | 설명 | - |------|------|------| - | `event_type` | string | `"new_request"` 또는 `"escalation"` | - | `id` | UUID | 이 요청의 고유 식별자 | - | `status` | string | 활성 요청의 경우 항상 `"pending"` | - | `method_name` | string | 피드백을 요청한 데코레이터 메서드 | - | `message` | string | 검토자를 위한 사람이 읽을 수 있는 프롬프트/질문 | - | `output` | string | 검토할 콘텐츠 (Markdown 포함 가능) | - | `emit` | array | 데코레이터의 유효한 응답 옵션 | - | `default_outcome` | string | 자동 응답 트리거 시 기본 결과 | - | `state` | object | 일시 중지 시점의 Flow 상태 | - | `metadata` | object | 데코레이터의 커스텀 메타데이터 | - | `created_at` | ISO8601 | 요청 생성 시간 | - - - - | 필드 | 유형 | 설명 | - |------|------|------| - | `callback_url` | string | **피드백 제출을 위해 이 URL로 POST** (토큰 포함) | - | `response_token` | string | 일회용 인증 토큰 (이미 callback_url에 포함) | - - - - | 필드 | 유형 | 설명 | - |------|------|------| - | `deployment_id` | integer | 배포 식별자 | - | `deployment_name` | string | 사람이 읽을 수 있는 배포 이름 | - | `flow_execution_id` | UUID | 실행 트레이스에 연결 | - | `organization_id` | UUID | 조직 식별자 | - | `sla_target_minutes` | integer | 구성된 SLA 목표 (설정되지 않은 경우 null) | - | `triggered_by_user_id` | integer | Flow를 시작한 사용자 (알려진 경우) | - - - - | 필드 | 유형 | 설명 | - |------|------|------| - | `assigned_to` | object | 사전 할당된 검토자 (있는 경우) | - | `assigned_at` | ISO8601 | 할당된 시간 | - | `escalated_at` | ISO8601 | 요청이 에스컬레이션된 시간 (아닌 경우 null) | - | `routing.effective_responders` | array | 응답하도록 구성된 사용자 | - | `routing.enforce_routing_rules` | boolean | 나열된 응답자만 응답할 수 있는지 여부 | - - - ### 요청에 응답하기 피드백을 제출하려면 webhook 페이로드에 포함된 **`callback_url`로 POST**합니다. ```http -POST /crewai_plus/api/v1/human_feedback_requests/{id}/respond?token={token} +POST {callback_url} Content-Type: application/json { @@ -455,53 +431,6 @@ Content-Type: application/json } ``` -**토큰은 이미 `callback_url`에 포함되어 있으므로** 직접 POST할 수 있습니다: - -```bash -curl -X POST "${callback_url}" \ - -H "Content-Type: application/json" \ - -d '{"feedback": "약간의 수정과 함께 승인됨"}' -``` - -#### 파라미터 - -| 파라미터 | 필수 | 설명 | -|---------|------|------| -| `feedback` | 예 | 피드백 텍스트 (flow로 전달됨) | -| `source` | 아니오 | 앱 식별자 (기록에 표시) | - -#### 응답 예시 - - -```json 성공 (200 OK) -{ - "status": "accepted", - "request": { - "id": "550e8400-e29b-41d4-a716-446655440000", - "status": "responded", - "feedback": "약간의 수정과 함께 승인됨", - "outcome": null, - "responded_at": "2026-01-12T11:45:00Z", - "responded_via": "my_custom_app" - } -} -``` - -```json 이미 응답됨 (409 Conflict) -{ - "error": "already_responded", - "message": "2026-01-12T11:30:00Z에 대시보드를 통해 이미 피드백이 제공되었습니다" -} -``` - -```json 유효하지 않은 토큰 (401 Unauthorized) -{ - "error": "unauthorized", - "message": "유효하지 않은 응답 토큰" -} -``` - - ### 보안 @@ -515,310 +444,33 @@ curl -X POST "${callback_url}" \ - **저장 시 암호화**: 서명 시크릿은 데이터베이스에서 암호화됨 - **타임스탬프 검증**: 리플레이 공격 방지 -#### 응답 토큰 보안 - -- **일회용**: 토큰은 성공적인 응답 후 무효화됨 -- **256비트 엔트로피**: 토큰은 암호학적으로 안전한 랜덤 생성 사용 -- **타이밍 안전 비교**: 타이밍 공격 방지 - -#### 모범 사례 - -1. **서명 검증**: 항상 `X-CrewAI-Signature` 헤더를 검증하세요 -2. **타임스탬프 확인**: 5분 이상 된 요청은 거부하세요 -3. **시크릿 안전 저장**: 서명 시크릿을 비밀번호처럼 취급하세요 -4. **HTTPS 사용**: 프로덕션에서 webhook 엔드포인트는 TLS를 사용해야 합니다 -5. **시크릿 순환**: 대시보드를 통해 주기적으로 webhook 시크릿을 재생성하세요 - -### 통합 예제 - - -```python Python (Flask) - 전체 예제 -from flask import Flask, request, jsonify -import requests -import hmac -import hashlib -import time - -app = Flask(__name__) - -WEBHOOK_SECRET = "whsec_your_signing_secret_here" -MAX_TIMESTAMP_AGE = 300 - -def verify_signature(payload: bytes, signature: str, timestamp: str) -> bool: - try: - ts = int(timestamp) - if abs(time.time() - ts) > MAX_TIMESTAMP_AGE: - return False - except (ValueError, TypeError): - return False - - signature_payload = f"{timestamp}.{payload.decode('utf-8')}" - expected = hmac.new( - WEBHOOK_SECRET.encode('utf-8'), - signature_payload.encode('utf-8'), - hashlib.sha256 - ).hexdigest() - - return hmac.compare_digest(f"sha256={expected}", signature) - -@app.route('/hitl-webhook', methods=['POST']) -def handle_hitl(): - # 먼저 서명 검증 - signature = request.headers.get('X-CrewAI-Signature', '') - timestamp = request.headers.get('X-CrewAI-Timestamp', '') - - if not verify_signature(request.data, signature, timestamp): - return jsonify({'error': '유효하지 않은 서명'}), 401 - - payload = request.json - - # 나중에 검토하기 위해 저장 - store_request(payload) - - # 또는 규칙에 따라 자동 승인 - if should_auto_approve(payload): - response = requests.post( - payload['callback_url'], - json={'feedback': '정책에 의해 자동 승인됨', 'source': 'auto_approver'} - ) - return jsonify({'status': 'auto_approved'}) - - return jsonify({'status': 'queued_for_review'}) -``` - -```javascript Node.js (Express) - 전체 예제 -const express = require('express'); -const crypto = require('crypto'); -const axios = require('axios'); - -const app = express(); -const WEBHOOK_SECRET = 'whsec_your_signing_secret_here'; -const MAX_TIMESTAMP_AGE = 300; - -// 서명 검증을 위해 raw body 캡처 -app.use('/hitl-webhook', express.raw({ type: 'application/json' })); - -function verifySignature(payload, signature, timestamp) { - const ts = parseInt(timestamp, 10); - if (isNaN(ts) || Math.abs(Date.now() / 1000 - ts) > MAX_TIMESTAMP_AGE) { - return false; - } - - const signaturePayload = `${timestamp}.${payload.toString()}`; - const expected = crypto - .createHmac('sha256', WEBHOOK_SECRET) - .update(signaturePayload) - .digest('hex'); - - return crypto.timingSafeEqual( - Buffer.from(`sha256=${expected}`), - Buffer.from(signature) - ); -} - -app.post('/hitl-webhook', async (req, res) => { - const signature = req.headers['x-crewai-signature'] || ''; - const timestamp = req.headers['x-crewai-timestamp'] || ''; - - if (!verifySignature(req.body, signature, timestamp)) { - return res.status(401).json({ error: '유효하지 않은 서명' }); - } - - const { event_type, callback_url, message, output } = JSON.parse(req.body); - - console.log(`수신됨 ${event_type}: ${message}`); - - // Slack, 이메일 등을 통해 팀에 알림 - await notifyTeam(payload); - - // 나중에 누군가가 승인할 때: - // await axios.post(callback_url, { feedback: '승인됨!' }); - - res.json({ received: true }); -}); -``` - - -### Webhook 서명 검증 - -모든 webhook 요청은 HMAC-SHA256을 사용하여 서명됩니다. 요청이 진본이고 변조되지 않았음을 확인하기 위해 서명을 검증해야 합니다. - #### 서명 헤더 각 webhook 요청에는 다음 헤더가 포함됩니다: | 헤더 | 설명 | |------|------| -| `X-CrewAI-Signature` | HMAC-SHA256 서명: `sha256=` | -| `X-CrewAI-Timestamp` | 요청이 서명된 Unix 타임스탬프 | +| `X-Signature` | HMAC-SHA256 서명: `sha256=` | +| `X-Timestamp` | 요청이 서명된 Unix 타임스탬프 | -#### 검증 알고리즘 +#### 검증 -서명은 다음과 같이 계산됩니다: - -``` -HMAC-SHA256(signing_secret, timestamp + "." + raw_body) -``` - -여기서: -- `signing_secret`은 webhook의 고유 시크릿입니다 (대시보드에 표시) -- `timestamp`는 `X-CrewAI-Timestamp` 헤더의 값입니다 -- `raw_body`는 원시 JSON 요청 본문입니다 (파싱 전) - -#### Python 검증 예제 +다음과 같이 계산하여 검증합니다: ```python import hmac import hashlib -import time -from flask import Flask, request, jsonify -app = Flask(__name__) +expected = hmac.new( + signing_secret.encode(), + f"{timestamp}.{payload}".encode(), + hashlib.sha256 +).hexdigest() -WEBHOOK_SECRET = "whsec_your_signing_secret_here" -MAX_TIMESTAMP_AGE = 300 # 5분 - -def verify_signature(payload: bytes, signature: str, timestamp: str) -> bool: - """Webhook 서명을 검증합니다.""" - # 리플레이 공격 방지를 위한 타임스탬프 확인 - try: - ts = int(timestamp) - if abs(time.time() - ts) > MAX_TIMESTAMP_AGE: - return False - except (ValueError, TypeError): - return False - - # 예상 서명 계산 - signature_payload = f"{timestamp}.{payload.decode('utf-8')}" - expected = hmac.new( - WEBHOOK_SECRET.encode('utf-8'), - signature_payload.encode('utf-8'), - hashlib.sha256 - ).hexdigest() - - expected_header = f"sha256={expected}" - - # 타이밍 공격 방지를 위한 상수 시간 비교 - return hmac.compare_digest(expected_header, signature) - -@app.route('/hitl-webhook', methods=['POST']) -def handle_hitl(): - signature = request.headers.get('X-CrewAI-Signature', '') - timestamp = request.headers.get('X-CrewAI-Timestamp', '') - - if not verify_signature(request.data, signature, timestamp): - return jsonify({'error': '유효하지 않은 서명'}), 401 - - payload = request.json - # 검증된 webhook 처리... - return jsonify({'status': 'received'}) +if hmac.compare_digest(expected, signature): + # 유효한 서명 ``` -#### Node.js 검증 예제 - -```javascript -const express = require('express'); -const crypto = require('crypto'); - -const app = express(); -const WEBHOOK_SECRET = 'whsec_your_signing_secret_here'; -const MAX_TIMESTAMP_AGE = 300; // 5분 - -// 서명 검증을 위해 raw body 사용 -app.use('/hitl-webhook', express.raw({ type: 'application/json' })); - -function verifySignature(payload, signature, timestamp) { - // 타임스탬프 확인 - const ts = parseInt(timestamp, 10); - if (isNaN(ts) || Math.abs(Date.now() / 1000 - ts) > MAX_TIMESTAMP_AGE) { - return false; - } - - // 예상 서명 계산 - const signaturePayload = `${timestamp}.${payload.toString()}`; - const expected = crypto - .createHmac('sha256', WEBHOOK_SECRET) - .update(signaturePayload) - .digest('hex'); - - const expectedHeader = `sha256=${expected}`; - - // 상수 시간 비교 - return crypto.timingSafeEqual( - Buffer.from(expectedHeader), - Buffer.from(signature) - ); -} - -app.post('/hitl-webhook', (req, res) => { - const signature = req.headers['x-crewai-signature'] || ''; - const timestamp = req.headers['x-crewai-timestamp'] || ''; - - if (!verifySignature(req.body, signature, timestamp)) { - return res.status(401).json({ error: '유효하지 않은 서명' }); - } - - const payload = JSON.parse(req.body); - // 검증된 webhook 처리... - res.json({ status: 'received' }); -}); -``` - -#### Ruby 검증 예제 - -```ruby -require 'openssl' -require 'json' - -class HitlWebhookController < ApplicationController - WEBHOOK_SECRET = ENV['CREWAI_WEBHOOK_SECRET'] - MAX_TIMESTAMP_AGE = 300 # 5분 - - skip_before_action :verify_authenticity_token - - def receive - signature = request.headers['X-CrewAI-Signature'] - timestamp = request.headers['X-CrewAI-Timestamp'] - payload = request.raw_post - - unless verify_signature(payload, signature, timestamp) - render json: { error: '유효하지 않은 서명' }, status: :unauthorized - return - end - - data = JSON.parse(payload) - # 검증된 webhook 처리... - render json: { status: 'received' } - end - - private - - def verify_signature(payload, signature, timestamp) - return false if timestamp.blank? || signature.blank? - - # 타임스탬프 최신성 확인 - ts = timestamp.to_i - return false if (Time.now.to_i - ts).abs > MAX_TIMESTAMP_AGE - - # 예상 서명 계산 - signature_payload = "#{timestamp}.#{payload}" - expected = OpenSSL::HMAC.hexdigest('SHA256', WEBHOOK_SECRET, signature_payload) - expected_header = "sha256=#{expected}" - - # 상수 시간 비교 - ActiveSupport::SecurityUtils.secure_compare(expected_header, signature) - end -end -``` - -#### 보안 모범 사례 - -1. **항상 서명 검증** webhook 데이터 처리 전에 서명을 검증하세요 -2. **타임스탬프 최신성 확인** (5분 허용 오차 권장) -3. **상수 시간 비교 사용** 타이밍 공격을 방지합니다 -4. **시크릿 안전 저장** 환경 변수나 시크릿 매니저를 사용하세요 -5. **주기적 시크릿 순환** (대시보드에서 재생성 가능) - ### 오류 처리 webhook 엔드포인트는 수신 확인을 위해 2xx 상태 코드를 반환해야 합니다: @@ -829,68 +481,69 @@ webhook 엔드포인트는 수신 확인을 위해 2xx 상태 코드를 반환 | 4xx/5xx | 실패로 기록됨, 재시도 없음 | | 타임아웃 (30초) | 실패로 기록됨, 재시도 없음 | -### 통합 테스트 +## 보안 및 RBAC - - - 개발 엔드포인트를 가리키는 webhook 추가 - - - 로컬 개발의 경우 [ngrok](https://ngrok.com) 사용: - ```bash - ngrok http 3000 - # HTTPS URL을 webhook 엔드포인트로 사용 - ``` - - - `@human_feedback` 데코레이터가 있는 flow 실행 - - - 엔드포인트가 페이로드를 수신하는지 확인 - - - `callback_url`로 POST하여 flow 완료 - - +### 대시보드 접근 -## 기타 통합 옵션 +HITL 접근은 배포 수준에서 제어됩니다: -### API 접근 +| 권한 | 기능 | +|-----|------| +| `manage_human_feedback` | HITL 설정 구성, 모든 요청 보기 | +| `respond_to_human_feedback` | 요청에 응답, 할당된 요청 보기 | -커스텀 통합을 위한 완전한 프로그래밍 제어: +### 이메일 응답 인증 -```python -# 예: 프로그래밍 방식으로 HITL 상태 확인 -from crewai.enterprise import HITLClient +이메일 회신의 경우: +1. reply-to 토큰이 인증된 이메일을 인코딩 +2. 발신자 이메일이 토큰의 이메일과 일치해야 함 +3. 토큰이 만료되지 않아야 함 (기본 7일) +4. 요청이 여전히 대기 중이어야 함 -client = HITLClient() -pending_reviews = client.get_pending_reviews(flow_id="my-flow") +### 감사 추적 -for review in pending_reviews: - print(f"검토 {review.id}: {review.status} - 할당된 사람: {review.assignee}") -``` +모든 HITL 작업이 기록됩니다: +- 요청 생성 +- 할당 변경 +- 응답 제출 (소스: 대시보드/이메일/API) +- Flow 재개 상태 -### 곧 출시 예정 +## 문제 해결 -- **Slack 통합**: Slack에서 직접 HITL 요청에 응답 -- **Microsoft Teams**: Teams 네이티브 검토 경험 -- **모바일 앱**: 이동 중 검토 및 승인 +### 이메일이 전송되지 않음 + +1. 구성에서 "이메일 알림"이 활성화되어 있는지 확인 +2. 라우팅 규칙이 메서드 이름과 일치하는지 확인 +3. 담당자 이메일이 유효한지 확인 +4. 라우팅 규칙이 일치하지 않는 경우 배포 생성자 대체 확인 + +### 이메일 회신이 처리되지 않음 + +1. 토큰이 만료되지 않았는지 확인 (기본 7일) +2. 발신자 이메일이 할당된 이메일과 일치하는지 확인 +3. 요청이 여전히 대기 중인지 확인 (아직 응답되지 않음) + +### Flow가 재개되지 않음 + +1. 대시보드에서 요청 상태 확인 +2. 콜백 URL에 접근 가능한지 확인 +3. 배포가 여전히 실행 중인지 확인 ## 모범 사례 -**간단하게 시작**: 기본 승인 게이트로 시작한 다음, 워크플로우가 성숙해지면 라우팅과 SLA를 추가하세요. +**간단하게 시작**: 배포 생성자에게 이메일 알림으로 시작한 다음, 워크플로우가 성숙해지면 라우팅 규칙을 추가하세요. -1. **명확한 검토 기준 정의**: 일관된 결정을 보장하기 위해 검토자가 무엇을 확인해야 하는지 문서화하세요. +1. **동적 할당 사용**: 유연한 라우팅을 위해 Flow 상태에서 담당자 이메일을 가져오세요. -2. **현실적인 SLA 설정**: 지속 가능한 워크플로우를 유지하기 위해 긴급도와 검토자 용량의 균형을 맞추세요. +2. **자동 응답 구성**: 중요하지 않은 검토에 대해 Flow가 중단되지 않도록 대체를 설정하세요. -3. **에스컬레이션을 현명하게 사용**: 품질을 유지하기 위해 진정으로 중요하지 않은 검토에만 자동 승인을 사용하세요. +3. **응답 시간 모니터링**: 분석을 사용하여 병목 현상을 식별하고 검토 프로세스를 최적화하세요. -4. **모니터링 및 반복**: 분석을 사용하여 병목 현상을 식별하고 검토자 할당을 최적화하세요. +4. **검토 메시지를 명확하게 유지**: `@human_feedback` 데코레이터에 명확하고 실행 가능한 메시지를 작성하세요. -5. **팀 교육**: 검토자가 자신의 역할과 사용 가능한 도구를 이해하도록 하세요. +5. **이메일 흐름 테스트**: 프로덕션에 가기 전에 테스트 요청을 보내 이메일 전달을 확인하세요. ## 관련 리소스 diff --git a/docs/ko/enterprise/guides/human-in-the-loop.mdx b/docs/ko/enterprise/guides/human-in-the-loop.mdx index 3ffd2533b..924fddc6c 100644 --- a/docs/ko/enterprise/guides/human-in-the-loop.mdx +++ b/docs/ko/enterprise/guides/human-in-the-loop.mdx @@ -13,7 +13,7 @@ CrewAI는 human-in-the-loop 워크플로우를 구현하기 위한 두 가지 | 접근 방식 | 적합한 용도 | 버전 | |----------|----------|---------| -| **Flow 기반** (`@human_feedback` 데코레이터) | Enterprise UI를 사용한 프로덕션, 관리형 워크플로우, 전체 플랫폼 기능 | **1.8.0+** | +| **Flow 기반** (`@human_feedback` 데코레이터) | Enterprise UI를 사용한 프로덕션, 이메일 우선 워크플로우, 전체 플랫폼 기능 | **1.8.0+** | | **Webhook 기반** | 커스텀 통합, 외부 시스템 (Slack, Teams 등), 레거시 설정 | 모든 버전 | ## Enterprise 플랫폼과 Flow 기반 HITL @@ -22,29 +22,30 @@ CrewAI는 human-in-the-loop 워크플로우를 구현하기 위한 두 가지 `@human_feedback` 데코레이터는 **CrewAI 버전 1.8.0 이상**이 필요합니다. -Flow에서 `@human_feedback` 데코레이터를 사용하면, CrewAI Enterprise는 인간 피드백 워크플로우를 완벽하게 제어할 수 있는 전용 **HITL 관리 UI**를 제공합니다: +Flow에서 `@human_feedback` 데코레이터를 사용하면, CrewAI Enterprise는 이메일 주소가 있는 누구나 검토 요청에 응답할 수 있는 **이메일 우선 HITL 시스템**을 제공합니다: - - Enterprise 대시보드에서 직접 HITL 요청을 검토하고 응답하세요—webhook 설정이 필요 없습니다. + + 응답자가 이메일 알림을 받고 직접 회신할 수 있습니다—로그인이 필요 없습니다. - - 다양한 작업 유형이나 crew에 대해 특정 팀원 또는 그룹을 응답자로 할당하세요. + + 원할 때 Enterprise 대시보드에서 HITL 요청을 검토하고 응답하세요. - - 세분화된 권한 제어로 HITL 요청을 보거나, 응답하거나, 에스컬레이션할 수 있는 사람을 정의하세요. + + 메서드 패턴에 따라 특정 이메일로 요청을 라우팅하거나 Flow 상태에서 가져오세요. - - 응답이 지연되거나 상급 검토가 필요할 때 자동 에스컬레이션 규칙을 구성하세요. - - - 응답 시간에 대한 서비스 수준 계약을 설정하고 자동 알림 및 추적을 활성화하세요. - - - 콘텐츠, 우선순위 또는 사용자 정의 규칙을 기반으로 적용 정책과 함께 HITL 요청을 라우팅하세요. + + 타임아웃 내에 인간이 응답하지 않을 경우 자동 대체 응답을 구성하세요. +### 주요 이점 + +- **외부 응답자**: 플랫폼 사용자가 아니어도 이메일이 있는 누구나 응답 가능 +- **동적 할당**: Flow 상태에서 담당자 이메일 가져오기 (예: `account_owner_email`) +- **간단한 구성**: 이메일 기반 라우팅은 사용자/역할 관리보다 설정이 쉬움 +- **배포 생성자 대체**: 라우팅 규칙이 일치하지 않으면 배포 생성자에게 알림 + `@human_feedback` 데코레이터의 구현 세부 사항은 [Flow에서 인간 피드백](/ko/learn/human-feedback-in-flows) 가이드를 참조하세요. @@ -148,7 +149,7 @@ HITL 워크플로우는 특히 다음과 같은 경우에 유용합니다: - 할당, SLA 관리, 에스컬레이션 정책 및 분석을 포함한 전체 Enterprise Flow HITL 플랫폼 기능을 살펴보세요. + 이메일 알림, 라우팅 규칙, 자동 응답 및 분석을 포함한 전체 Enterprise Flow HITL 플랫폼 기능을 살펴보세요. Flow에서 `@human_feedback` 데코레이터 구현 가이드. diff --git a/docs/pt-BR/enterprise/features/flow-hitl-management.mdx b/docs/pt-BR/enterprise/features/flow-hitl-management.mdx index f7673988c..1a6651203 100644 --- a/docs/pt-BR/enterprise/features/flow-hitl-management.mdx +++ b/docs/pt-BR/enterprise/features/flow-hitl-management.mdx @@ -1,6 +1,6 @@ --- title: "Gerenciamento HITL para Flows" -description: "Revisão humana de nível empresarial para Flows com atribuição, gerenciamento de SLA, políticas de escalação e roteamento dinâmico" +description: "Revisão humana de nível empresarial para Flows com notificações por email, regras de roteamento e capacidades de resposta automática" icon: "users-gear" mode: "wide" --- @@ -9,25 +9,33 @@ mode: "wide" Os recursos de gerenciamento HITL para Flows requerem o decorador `@human_feedback`, disponível no **CrewAI versão 1.8.0 ou superior**. Estes recursos aplicam-se especificamente a **Flows**, não a Crews. -O CrewAI Enterprise oferece um sistema abrangente de gerenciamento Human-in-the-Loop (HITL) para Flows que transforma fluxos de trabalho de IA em processos colaborativos humano-IA. Além de simples portões de aprovação, a plataforma oferece controles de nível empresarial para atribuição, responsabilidade e conformidade. +O CrewAI Enterprise oferece um sistema abrangente de gerenciamento Human-in-the-Loop (HITL) para Flows que transforma fluxos de trabalho de IA em processos colaborativos humano-IA. A plataforma usa uma **arquitetura email-first** que permite que qualquer pessoa com um endereço de email responda a solicitações de revisão—sem necessidade de conta na plataforma. ## Visão Geral - - Revise e responda a solicitações diretamente no dashboard Enterprise + + Respondentes podem responder diretamente aos emails de notificação para fornecer feedback - - Direcione revisões para as pessoas certas com base em regras e expertise + + Direcione solicitações para emails específicos com base em padrões de método ou estado do flow - - Garanta respostas oportunas com políticas de escalação automatizadas + + Configure respostas automáticas de fallback quando nenhum humano responder a tempo +### Principais Benefícios + +- **Modelo mental simples**: Endereços de email são universais; não é necessário gerenciar usuários ou funções da plataforma +- **Respondentes externos**: Qualquer pessoa com email pode responder, mesmo não sendo usuário da plataforma +- **Atribuição dinâmica**: Obtenha o email do responsável diretamente do estado do flow (ex: `sales_rep_email`) +- **Configuração reduzida**: Menos configurações para definir, tempo mais rápido para gerar valor +- **Email como canal principal**: A maioria dos usuários prefere responder via email do que fazer login em um dashboard + ## Configurando Pontos de Revisão Humana em Flows -Configure checkpoints de revisão humana em seus Flows usando o decorador `@human_feedback`. Quando a execução atinge um ponto de revisão, o sistema pausa e exibe um estado de "aguardando entrada" na UI. +Configure checkpoints de revisão humana em seus Flows usando o decorador `@human_feedback`. Quando a execução atinge um ponto de revisão, o sistema pausa, notifica o responsável via email e aguarda uma resposta. ```python from crewai.flow.flow import Flow, start, listen @@ -62,95 +70,191 @@ class ContentApprovalFlow(Flow): Para detalhes completos de implementação, consulte o guia [Feedback Humano em Flows](/pt-BR/learn/human-feedback-in-flows). -## Atribuição e Roteamento +### Parâmetros do Decorador -A plataforma Enterprise oferece capacidades sofisticadas de atribuição para garantir que as revisões cheguem aos membros certos da equipe. +| Parâmetro | Tipo | Descrição | +|-----------|------|-----------| +| `message` | `str` | A mensagem exibida para o revisor humano | +| `emit` | `list[str]` | Opções de resposta válidas (exibidas como botões na UI) | -### Atribuição de Respondentes +## Configuração da Plataforma -Atribua membros específicos da equipe ou grupos como respondentes para diferentes tipos de tarefas: +Acesse a configuração HITL em: **Deployment** → **Settings** → **Human in the Loop Configuration** + + + Configurações HITL + + +### Notificações por Email + +Toggle para ativar ou desativar notificações por email para solicitações HITL. + +| Configuração | Padrão | Descrição | +|--------------|--------|-----------| +| Notificações por Email | Ativado | Enviar emails quando feedback for solicitado | + + +Quando desativado, os respondentes devem usar a UI do dashboard ou você deve configurar webhooks para sistemas de notificação personalizados. + + +### Meta de SLA + +Defina um tempo de resposta alvo para fins de rastreamento e métricas. + +| Configuração | Descrição | +|--------------|-----------| +| Meta de SLA (minutos) | Tempo de resposta alvo. Usado para métricas do dashboard e rastreamento de SLA | + +Deixe vazio para desativar o rastreamento de SLA. + +## Notificações e Respostas por Email + +O sistema HITL usa uma arquitetura email-first onde os respondentes podem responder diretamente aos emails de notificação. + +### Como Funcionam as Respostas por Email - - Vá para as configurações do seu Flow e selecione a seção de configuração "Revisão Humana". + + Quando uma solicitação HITL é criada, um email é enviado ao respondente atribuído com o conteúdo e contexto da revisão. - - Atribua usuários individuais ou grupos como respondentes padrão para solicitações de revisão. + + O email inclui um endereço reply-to especial com um token assinado para autenticação. - - Defina respondentes alternativos quando os designados principais não estiverem disponíveis. + + O respondente simplesmente responde ao email com seu feedback—nenhum login necessário. + + + A plataforma recebe a resposta, verifica o token assinado e corresponde o email do remetente. + + + O feedback é registrado e o flow continua com a entrada humana. - - Configurações HITL - +### Formato de Resposta -### Regras de Roteamento Dinâmico +Respondentes podem responder com: -Configure roteamento inteligente baseado no estado do flow, tipo de conteúdo ou condições personalizadas: +- **Opção emit**: Se a resposta corresponder a uma opção `emit` (ex: "approved"), ela é usada diretamente +- **Texto livre**: Qualquer resposta de texto é passada para o flow como feedback +- **Texto simples**: A primeira linha do corpo da resposta é usada como feedback -| Tipo de Regra | Descrição | Exemplo | -|---------------|-----------|---------| -| **Baseado em Conteúdo** | Roteie com base no conteúdo sendo revisado | Conteúdo legal → Equipe jurídica | -| **Baseado em Prioridade** | Atribua revisores com base no nível de urgência | Alta prioridade → Revisores seniores | -| **Baseado em Estado** | Roteie com base em variáveis de estado do flow | `state.amount > 10000` → Diretor financeiro | -| **Round-Robin** | Distribua revisões uniformemente pela equipe | Balanceie carga de trabalho automaticamente | +### Emails de Confirmação + +Após processar uma resposta, o respondente recebe um email de confirmação indicando se o feedback foi enviado com sucesso ou se ocorreu um erro. + +### Segurança do Token de Email + +- Tokens são assinados criptograficamente para segurança +- Tokens expiram após 7 dias +- Email do remetente deve corresponder ao email autorizado do token +- Emails de confirmação/erro são enviados após o processamento + +## Regras de Roteamento + +Direcione solicitações HITL para endereços de email específicos com base em padrões de método. - Configuração de Regras de Roteamento HITL + Configuração de Regras de Roteamento HITL -### Permissões Baseadas em Função +### Estrutura da Regra -Controle quem pode visualizar, responder ou escalar solicitações HITL: +```json +{ + "name": "Aprovações para Financeiro", + "match": { + "method_name": "approve_*" + }, + "assign_to_email": "financeiro@empresa.com", + "assign_from_input": "manager_email" +} +``` - - - Pode visualizar solicitações HITL e seu status, mas não pode responder ou tomar ações. - - - Pode visualizar e responder a solicitações HITL atribuídas com decisões de aprovar/rejeitar. - - - Pode visualizar todas as solicitações, responder, reatribuir a outros membros da equipe e sobrescrever decisões. - - - Acesso total incluindo configuração de regras de roteamento, SLAs e políticas de escalação. - - +### Padrões de Correspondência + +| Padrão | Descrição | Exemplo de Correspondência | +|--------|-----------|---------------------------| +| `approve_*` | Wildcard (qualquer caractere) | `approve_payment`, `approve_vendor` | +| `review_?` | Caractere único | `review_a`, `review_1` | +| `validate_payment` | Correspondência exata | apenas `validate_payment` | + +### Prioridade de Atribuição + +1. **Atribuição dinâmica** (`assign_from_input`): Se configurado, obtém email do estado do flow +2. **Email estático** (`assign_to_email`): Fallback para email configurado +3. **Criador do deployment**: Se nenhuma regra corresponder, o email do criador do deployment é usado + +### Exemplo de Atribuição Dinâmica + +Se seu estado do flow contém `{"sales_rep_email": "alice@empresa.com"}`, configure: + +```json +{ + "name": "Direcionar para Representante de Vendas", + "match": { + "method_name": "review_*" + }, + "assign_from_input": "sales_rep_email" +} +``` + +A solicitação será atribuída automaticamente para `alice@empresa.com`. + + +**Caso de Uso**: Obtenha o responsável do seu CRM, banco de dados ou etapa anterior do flow para direcionar revisões dinamicamente para a pessoa certa. + + +## Resposta Automática + +Responda automaticamente a solicitações HITL se nenhum humano responder dentro do timeout. Isso garante que os flows não fiquem travados indefinidamente. + +### Configuração + +| Configuração | Descrição | +|--------------|-----------| +| Ativado | Toggle para ativar resposta automática | +| Timeout (minutos) | Tempo de espera antes de responder automaticamente | +| Resultado Padrão | O valor da resposta (deve corresponder a uma opção `emit`) | + + + Configuração de Resposta Automática HITL + + +### Casos de Uso + +- **Conformidade com SLA**: Garante que flows não fiquem travados indefinidamente +- **Aprovação padrão**: Aprove automaticamente solicitações de baixo risco após timeout +- **Degradação graciosa**: Continue com um padrão seguro quando revisores não estiverem disponíveis + + +Use resposta automática com cuidado. Ative apenas para revisões não críticas onde uma resposta padrão é aceitável. + ## Processo de Revisão -### Interface de Revisão +### Interface do Dashboard A interface de revisão HITL oferece uma experiência limpa e focada para revisores: - **Renderização Markdown**: Formatação rica para conteúdo de revisão com destaque de sintaxe - **Painel de Contexto**: Visualize estado do flow, histórico de execução e informações relacionadas - **Entrada de Feedback**: Forneça feedback detalhado e comentários com sua decisão -- **Ações Rápidas**: Botões de aprovar/rejeitar com um clique com comentários opcionais +- **Ações Rápidas**: Botões de opção emit com um clique com comentários opcionais Lista de Solicitações HITL Pendentes -### Modos de Revisão +### Métodos de Resposta -Escolha a abordagem de revisão que se adapta ao seu fluxo de trabalho: +Revisores podem responder por três canais: - - - **Bloqueie execução até aprovação** - - O flow pausa completamente até que um humano forneça feedback. Melhor para decisões críticas que não devem prosseguir sem revisão. - - - **Enfileire itens para revisão eficiente** - - Colete múltiplas solicitações de revisão e processe-as em sessões focadas. Ideal para revisões de alto volume e menor urgência. - - +| Método | Descrição | +|--------|-----------| +| **Resposta por Email** | Responda diretamente ao email de notificação | +| **Dashboard** | Use a UI do dashboard Enterprise | +| **API/Webhook** | Resposta programática via API | ### Histórico e Trilha de Auditoria @@ -159,74 +263,22 @@ Toda interação HITL é rastreada com uma linha do tempo completa: - Histórico de decisões (aprovar/rejeitar/revisar) - Identidade do revisor e timestamp - Feedback e comentários fornecidos -- Mudanças de estado e escalações +- Método de resposta (email/dashboard/API) - Métricas de tempo de resposta -## Gerenciamento de SLA e Escalação - -Garanta respostas oportunas com rastreamento automatizado de SLA e políticas de escalação. - -### Configurando SLAs - -Defina expectativas de tempo de resposta para diferentes tipos de revisão: - -| Nível de SLA | Tempo de Resposta | Caso de Uso | -|--------------|-------------------|-------------| -| **Crítico** | 15 minutos | Incidentes de produção, revisões de segurança | -| **Alto** | 1 hora | Conteúdo voltado ao cliente, aprovações urgentes | -| **Padrão** | 4 horas | Revisão regular de conteúdo, aprovações rotineiras | -| **Baixo** | 24 horas | Revisões não bloqueantes, processamento em lote | - -### Regras de Escalação - -Configure escalação automática quando os SLAs estiverem em risco: - - - - Envie notificação de lembrete ao revisor atribuído (ex: em 50% do tempo de SLA). - - - Escale para gerente ou revisor de backup quando o limite de SLA for atingido. - - - Configure comportamento alternativo se não houver resposta após período estendido: - - **Auto-aprovação**: Prossiga com a execução (para revisões não críticas) - - **Auto-rejeição**: Falhe com segurança e notifique stakeholders - - **Re-roteamento**: Atribua a diferente revisor ou equipe - - - -### Notificações - -Alertas automatizados mantêm stakeholders informados durante todo o fluxo de trabalho: - -- **Notificações de Atribuição**: Alerte revisores quando novas solicitações chegarem -- **Avisos de SLA**: Lembre revisores antes dos prazos -- **Alertas de Escalação**: Notifique gerentes quando revisões forem escaladas -- **Atualizações de Conclusão**: Informe solicitantes quando revisões forem concluídas - - -**Integração com Slack**: Notificações diretas do Slack para solicitações HITL em breve. - - ## Análise e Monitoramento Acompanhe o desempenho HITL com análises abrangentes. ### Dashboard de Desempenho -Monitore métricas-chave em seus fluxos de trabalho HITL: - Dashboard de Métricas HITL - - Acompanhe a porcentagem de revisões concluídas dentro dos limites de SLA. - - Monitore tempos de resposta médios e medianos por revisor, equipe ou flow. + Monitore tempos de resposta médios e medianos por revisor ou flow. Analise padrões de volume de revisão para otimizar capacidade da equipe. @@ -234,17 +286,11 @@ Monitore métricas-chave em seus fluxos de trabalho HITL: Visualize taxas de aprovação/rejeição em diferentes tipos de revisão. + + Acompanhe a porcentagem de revisões concluídas dentro das metas de SLA. + -### Métricas Individuais - -Acompanhe o desempenho do revisor para responsabilidade e balanceamento de carga de trabalho: - -- Taxas de aprovação/rejeição por revisor -- Tempo médio de resposta por revisor -- Taxas de conclusão de revisão -- Frequência de escalação - ### Auditoria e Conformidade Capacidades de auditoria prontas para empresas para requisitos regulatórios: @@ -261,7 +307,7 @@ Capacidades de auditoria prontas para empresas para requisitos regulatórios: **Caso de Uso**: Automação de questionários de segurança internos com validação humana - IA gera respostas para questionários de segurança - - Equipe de segurança revisa e valida precisão + - Equipe de segurança revisa e valida precisão via email - Respostas aprovadas são compiladas na submissão final - Trilha de auditoria completa para conformidade @@ -270,8 +316,7 @@ Capacidades de auditoria prontas para empresas para requisitos regulatórios: **Caso de Uso**: Conteúdo de marketing que requer revisão legal/marca - IA gera texto de marketing ou conteúdo de mídia social - - Roteie para equipe de marca para revisão de voz/tom - - Escale para jurídico para conteúdo sensível a conformidade + - Roteie para email da equipe de marca para revisão de voz/tom - Publicação automática após aprovação @@ -279,31 +324,28 @@ Capacidades de auditoria prontas para empresas para requisitos regulatórios: **Caso de Uso**: Relatórios de despesas, termos de contrato, alocações de orçamento - IA pré-processa e categoriza solicitações financeiras - - Roteie com base em limites de valor para aprovadores apropriados - - Aplique segregação de funções com acesso baseado em função + - Roteie com base em limites de valor usando atribuição dinâmica - Mantenha trilha de auditoria completa para conformidade financeira - - **Caso de Uso**: Revisão regulatória para operações sensíveis + + **Caso de Uso**: Direcione revisões para proprietários de conta do seu CRM - - IA sinaliza potenciais problemas de conformidade - - Oficiais de conformidade revisam itens sinalizados - - Escale para consultoria jurídica conforme necessário - - Gere relatórios de conformidade com histórico de decisões + - Flow obtém email do proprietário da conta do CRM + - Armazene email no estado do flow (ex: `account_owner_email`) + - Use `assign_from_input` para direcionar automaticamente para a pessoa certa **Caso de Uso**: Validação de saída de IA antes da entrega ao cliente - IA gera conteúdo ou respostas voltadas ao cliente - - Equipe de QA amostra e revisa qualidade da saída + - Equipe de QA revisa via notificação por email - Loops de feedback melhoram desempenho da IA ao longo do tempo - - Acompanhe métricas de qualidade em ciclos de revisão -## API de Webhooks Personalizados +## API de Webhooks Quando seus Flows pausam para feedback humano, você pode configurar webhooks para enviar dados da solicitação para sua própria aplicação. Isso permite: @@ -313,6 +355,10 @@ Quando seus Flows pausam para feedback humano, você pode configurar webhooks pa - Notificações em apps mobile - Sistemas de decisão automatizados + + Configuração de Webhook HITL + + ### Configurando Webhooks @@ -339,7 +385,6 @@ Seu endpoint receberá requisições HTTP POST para estes eventos: | Tipo de Evento | Quando é Disparado | |----------------|-------------------| | `new_request` | Um flow pausa e solicita feedback humano | -| `escalation` | Uma solicitação pendente é escalada devido a timeout de SLA | ### Payload do Webhook @@ -347,106 +392,37 @@ Todos os webhooks recebem um payload JSON com esta estrutura: ```json { - "event_type": "new_request", - "id": "550e8400-e29b-41d4-a716-446655440000", - "status": "pending", - "flow_id": "flow_abc123", - "flow_class": "ContentReviewFlow", - "method_name": "review_article", - "message": "Por favor, revise este artigo para publicação.", - "output": "# Título do Artigo\n\nEste é o conteúdo que precisa de revisão...", - "emit": ["approve", "reject", "request_changes"], - "default_outcome": null, - "state": { - "article_id": 12345, - "author": "john@example.com", - "category": "technology" + "event": "new_request", + "request": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "flow_id": "flow_abc123", + "method_name": "review_article", + "message": "Por favor, revise este artigo para publicação.", + "emit_options": ["approved", "rejected", "request_changes"], + "state": { + "article_id": 12345, + "author": "john@example.com", + "category": "technology" + }, + "metadata": {}, + "created_at": "2026-01-14T12:00:00Z" }, - "metadata": { - "priority": "high", - "source": "cms" + "deployment": { + "id": 456, + "name": "Content Review Flow", + "organization_id": 789 }, - "created_at": "2026-01-12T10:30:00Z", - "callback_url": "https://api.crewai.com/crewai_plus/api/v1/human_feedback_requests/550e8400.../respond?token=abc123...", - "response_token": "abc123def456...", - "deployment_id": 12345, - "deployment_name": "Content Review Crew", - "flow_execution_id": "exec_789", - "trace_batch_id": "trace_456", - "organization_id": "org_123", - "assigned_to": { - "id": 42, - "email": "reviewer@company.com", - "name": "Jane Reviewer" - }, - "assigned_at": "2026-01-12T10:30:05Z", - "escalated_at": null, - "sla_target_minutes": 120, - "triggered_by_user_id": 99, - "routing": { - "effective_responders": [ - {"id": 42, "email": "reviewer@company.com", "name": "Jane Reviewer"}, - {"id": 43, "email": "manager@company.com", "name": "Bob Manager"} - ], - "enforce_routing_rules": true - } + "callback_url": "https://api.crewai.com/...", + "assigned_to_email": "reviewer@company.com" } ``` -### Referência de Campos - - - - | Campo | Tipo | Descrição | - |-------|------|-----------| - | `event_type` | string | `"new_request"` ou `"escalation"` | - | `id` | UUID | Identificador único para esta solicitação | - | `status` | string | Sempre `"pending"` para solicitações ativas | - | `method_name` | string | O método decorado que solicitou feedback | - | `message` | string | Prompt/pergunta legível para o revisor | - | `output` | string | Conteúdo a revisar (pode conter Markdown) | - | `emit` | array | Opções de resposta válidas do decorador | - | `default_outcome` | string | Resultado padrão se resposta automática for acionada | - | `state` | object | Estado do flow no momento da pausa | - | `metadata` | object | Metadados personalizados do decorador | - | `created_at` | ISO8601 | Quando a solicitação foi criada | - - - - | Campo | Tipo | Descrição | - |-------|------|-----------| - | `callback_url` | string | **Faça POST para esta URL para enviar feedback** (token incluído) | - | `response_token` | string | Token de autenticação de uso único (já em callback_url) | - - - - | Campo | Tipo | Descrição | - |-------|------|-----------| - | `deployment_id` | integer | Identificador do deployment | - | `deployment_name` | string | Nome legível do deployment | - | `flow_execution_id` | UUID | Link para o trace de execução | - | `organization_id` | UUID | Identificador da organização | - | `sla_target_minutes` | integer | Meta de SLA configurada (null se não definida) | - | `triggered_by_user_id` | integer | Usuário que iniciou o flow (se conhecido) | - - - - | Campo | Tipo | Descrição | - |-------|------|-----------| - | `assigned_to` | object | Revisor pré-atribuído (se houver) | - | `assigned_at` | ISO8601 | Quando a atribuição foi feita | - | `escalated_at` | ISO8601 | Quando a solicitação foi escalada (null se não) | - | `routing.effective_responders` | array | Usuários configurados para responder | - | `routing.enforce_routing_rules` | boolean | Se apenas respondentes listados podem responder | - - - ### Respondendo a Solicitações Para enviar feedback, **faça POST para a `callback_url`** incluída no payload do webhook. ```http -POST /crewai_plus/api/v1/human_feedback_requests/{id}/respond?token={token} +POST {callback_url} Content-Type: application/json { @@ -455,53 +431,6 @@ Content-Type: application/json } ``` -**O token já está incluído na `callback_url`**, então você pode fazer POST diretamente: - -```bash -curl -X POST "${callback_url}" \ - -H "Content-Type: application/json" \ - -d '{"feedback": "Aprovado com pequenas edições"}' -``` - -#### Parâmetros - -| Parâmetro | Obrigatório | Descrição | -|-----------|-------------|-----------| -| `feedback` | Sim | Seu texto de feedback (será passado para o flow) | -| `source` | Não | Identificador do seu app (aparece no histórico) | - -#### Exemplos de Resposta - - -```json Sucesso (200 OK) -{ - "status": "accepted", - "request": { - "id": "550e8400-e29b-41d4-a716-446655440000", - "status": "responded", - "feedback": "Aprovado com pequenas edições", - "outcome": null, - "responded_at": "2026-01-12T11:45:00Z", - "responded_via": "my_custom_app" - } -} -``` - -```json Já Respondido (409 Conflict) -{ - "error": "already_responded", - "message": "Feedback já fornecido via dashboard em 2026-01-12T11:30:00Z" -} -``` - -```json Token Inválido (401 Unauthorized) -{ - "error": "unauthorized", - "message": "Token de resposta inválido" -} -``` - - ### Segurança @@ -515,310 +444,33 @@ Todas as requisições de webhook são assinadas criptograficamente usando HMAC- - **Criptografado em repouso**: Os secrets de assinatura são criptografados no nosso banco de dados - **Verificação de timestamp**: Previne ataques de replay -#### Segurança do Token de Resposta - -- **Uso único**: Tokens são invalidados após uma resposta bem-sucedida -- **Entropia de 256 bits**: Tokens usam geração aleatória criptograficamente segura -- **Comparação segura contra timing**: Previne ataques de timing - -#### Melhores Práticas - -1. **Verifique assinaturas**: Sempre valide o header `X-CrewAI-Signature` -2. **Verifique timestamps**: Rejeite requisições com mais de 5 minutos -3. **Armazene secrets com segurança**: Trate os secrets de assinatura como senhas -4. **Use HTTPS**: Seu endpoint de webhook deve usar TLS em produção -5. **Rotacione secrets**: Regenere os secrets de webhook periodicamente via dashboard - -### Exemplos de Integração - - -```python Python (Flask) - Exemplo Completo -from flask import Flask, request, jsonify -import requests -import hmac -import hashlib -import time - -app = Flask(__name__) - -WEBHOOK_SECRET = "whsec_your_signing_secret_here" -MAX_TIMESTAMP_AGE = 300 - -def verify_signature(payload: bytes, signature: str, timestamp: str) -> bool: - try: - ts = int(timestamp) - if abs(time.time() - ts) > MAX_TIMESTAMP_AGE: - return False - except (ValueError, TypeError): - return False - - signature_payload = f"{timestamp}.{payload.decode('utf-8')}" - expected = hmac.new( - WEBHOOK_SECRET.encode('utf-8'), - signature_payload.encode('utf-8'), - hashlib.sha256 - ).hexdigest() - - return hmac.compare_digest(f"sha256={expected}", signature) - -@app.route('/hitl-webhook', methods=['POST']) -def handle_hitl(): - # Verifique a assinatura primeiro - signature = request.headers.get('X-CrewAI-Signature', '') - timestamp = request.headers.get('X-CrewAI-Timestamp', '') - - if not verify_signature(request.data, signature, timestamp): - return jsonify({'error': 'Assinatura inválida'}), 401 - - payload = request.json - - # Armazene para revisão posterior - store_request(payload) - - # Ou aprove automaticamente com base em regras - if should_auto_approve(payload): - response = requests.post( - payload['callback_url'], - json={'feedback': 'Aprovado automaticamente por política', 'source': 'auto_approver'} - ) - return jsonify({'status': 'auto_approved'}) - - return jsonify({'status': 'queued_for_review'}) -``` - -```javascript Node.js (Express) - Exemplo Completo -const express = require('express'); -const crypto = require('crypto'); -const axios = require('axios'); - -const app = express(); -const WEBHOOK_SECRET = 'whsec_your_signing_secret_here'; -const MAX_TIMESTAMP_AGE = 300; - -// Capture raw body para verificação de assinatura -app.use('/hitl-webhook', express.raw({ type: 'application/json' })); - -function verifySignature(payload, signature, timestamp) { - const ts = parseInt(timestamp, 10); - if (isNaN(ts) || Math.abs(Date.now() / 1000 - ts) > MAX_TIMESTAMP_AGE) { - return false; - } - - const signaturePayload = `${timestamp}.${payload.toString()}`; - const expected = crypto - .createHmac('sha256', WEBHOOK_SECRET) - .update(signaturePayload) - .digest('hex'); - - return crypto.timingSafeEqual( - Buffer.from(`sha256=${expected}`), - Buffer.from(signature) - ); -} - -app.post('/hitl-webhook', async (req, res) => { - const signature = req.headers['x-crewai-signature'] || ''; - const timestamp = req.headers['x-crewai-timestamp'] || ''; - - if (!verifySignature(req.body, signature, timestamp)) { - return res.status(401).json({ error: 'Assinatura inválida' }); - } - - const { event_type, callback_url, message, output } = JSON.parse(req.body); - - console.log(`Recebido ${event_type}: ${message}`); - - // Notifique sua equipe via Slack, email, etc. - await notifyTeam(payload); - - // Depois, quando alguém aprovar: - // await axios.post(callback_url, { feedback: 'Aprovado!' }); - - res.json({ received: true }); -}); -``` - - -### Verificação de Assinatura de Webhook - -Todas as requisições de webhook são assinadas usando HMAC-SHA256. Você deve verificar a assinatura para garantir que as requisições são autênticas e não foram adulteradas. - #### Headers de Assinatura Cada requisição de webhook inclui estes headers: | Header | Descrição | |--------|-----------| -| `X-CrewAI-Signature` | Assinatura HMAC-SHA256: `sha256=` | -| `X-CrewAI-Timestamp` | Timestamp Unix de quando a requisição foi assinada | +| `X-Signature` | Assinatura HMAC-SHA256: `sha256=` | +| `X-Timestamp` | Timestamp Unix de quando a requisição foi assinada | -#### Algoritmo de Verificação +#### Verificação -A assinatura é calculada como: - -``` -HMAC-SHA256(signing_secret, timestamp + "." + raw_body) -``` - -Onde: -- `signing_secret` é o secret único do seu webhook (mostrado no dashboard) -- `timestamp` é o valor do header `X-CrewAI-Timestamp` -- `raw_body` é o corpo da requisição JSON bruto (antes do parsing) - -#### Exemplo de Verificação em Python +Verifique computando: ```python import hmac import hashlib -import time -from flask import Flask, request, jsonify -app = Flask(__name__) +expected = hmac.new( + signing_secret.encode(), + f"{timestamp}.{payload}".encode(), + hashlib.sha256 +).hexdigest() -WEBHOOK_SECRET = "whsec_your_signing_secret_here" -MAX_TIMESTAMP_AGE = 300 # 5 minutos - -def verify_signature(payload: bytes, signature: str, timestamp: str) -> bool: - """Verifica a assinatura do webhook.""" - # Verifique timestamp para prevenir ataques de replay - try: - ts = int(timestamp) - if abs(time.time() - ts) > MAX_TIMESTAMP_AGE: - return False - except (ValueError, TypeError): - return False - - # Calcule assinatura esperada - signature_payload = f"{timestamp}.{payload.decode('utf-8')}" - expected = hmac.new( - WEBHOOK_SECRET.encode('utf-8'), - signature_payload.encode('utf-8'), - hashlib.sha256 - ).hexdigest() - - expected_header = f"sha256={expected}" - - # Comparação em tempo constante para prevenir ataques de timing - return hmac.compare_digest(expected_header, signature) - -@app.route('/hitl-webhook', methods=['POST']) -def handle_hitl(): - signature = request.headers.get('X-CrewAI-Signature', '') - timestamp = request.headers.get('X-CrewAI-Timestamp', '') - - if not verify_signature(request.data, signature, timestamp): - return jsonify({'error': 'Assinatura inválida'}), 401 - - payload = request.json - # Processe o webhook verificado... - return jsonify({'status': 'received'}) +if hmac.compare_digest(expected, signature): + # Assinatura válida ``` -#### Exemplo de Verificação em Node.js - -```javascript -const express = require('express'); -const crypto = require('crypto'); - -const app = express(); -const WEBHOOK_SECRET = 'whsec_your_signing_secret_here'; -const MAX_TIMESTAMP_AGE = 300; // 5 minutos - -// Use raw body para verificação de assinatura -app.use('/hitl-webhook', express.raw({ type: 'application/json' })); - -function verifySignature(payload, signature, timestamp) { - // Verifique timestamp - const ts = parseInt(timestamp, 10); - if (isNaN(ts) || Math.abs(Date.now() / 1000 - ts) > MAX_TIMESTAMP_AGE) { - return false; - } - - // Calcule assinatura esperada - const signaturePayload = `${timestamp}.${payload.toString()}`; - const expected = crypto - .createHmac('sha256', WEBHOOK_SECRET) - .update(signaturePayload) - .digest('hex'); - - const expectedHeader = `sha256=${expected}`; - - // Comparação em tempo constante - return crypto.timingSafeEqual( - Buffer.from(expectedHeader), - Buffer.from(signature) - ); -} - -app.post('/hitl-webhook', (req, res) => { - const signature = req.headers['x-crewai-signature'] || ''; - const timestamp = req.headers['x-crewai-timestamp'] || ''; - - if (!verifySignature(req.body, signature, timestamp)) { - return res.status(401).json({ error: 'Assinatura inválida' }); - } - - const payload = JSON.parse(req.body); - // Processe o webhook verificado... - res.json({ status: 'received' }); -}); -``` - -#### Exemplo de Verificação em Ruby - -```ruby -require 'openssl' -require 'json' - -class HitlWebhookController < ApplicationController - WEBHOOK_SECRET = ENV['CREWAI_WEBHOOK_SECRET'] - MAX_TIMESTAMP_AGE = 300 # 5 minutos - - skip_before_action :verify_authenticity_token - - def receive - signature = request.headers['X-CrewAI-Signature'] - timestamp = request.headers['X-CrewAI-Timestamp'] - payload = request.raw_post - - unless verify_signature(payload, signature, timestamp) - render json: { error: 'Assinatura inválida' }, status: :unauthorized - return - end - - data = JSON.parse(payload) - # Processe o webhook verificado... - render json: { status: 'received' } - end - - private - - def verify_signature(payload, signature, timestamp) - return false if timestamp.blank? || signature.blank? - - # Verifique atualidade do timestamp - ts = timestamp.to_i - return false if (Time.now.to_i - ts).abs > MAX_TIMESTAMP_AGE - - # Calcule assinatura esperada - signature_payload = "#{timestamp}.#{payload}" - expected = OpenSSL::HMAC.hexdigest('SHA256', WEBHOOK_SECRET, signature_payload) - expected_header = "sha256=#{expected}" - - # Comparação em tempo constante - ActiveSupport::SecurityUtils.secure_compare(expected_header, signature) - end -end -``` - -#### Melhores Práticas de Segurança - -1. **Sempre verifique assinaturas** antes de processar dados do webhook -2. **Verifique atualidade do timestamp** (recomendamos tolerância de 5 minutos) -3. **Use comparação em tempo constante** para prevenir ataques de timing -4. **Armazene secrets com segurança** usando variáveis de ambiente ou gerenciadores de secrets -5. **Rotacione secrets periodicamente** (você pode regenerar no dashboard) - ### Tratamento de Erros Seu endpoint de webhook deve retornar um código de status 2xx para confirmar o recebimento: @@ -829,68 +481,69 @@ Seu endpoint de webhook deve retornar um código de status 2xx para confirmar o | 4xx/5xx | Registrado como falha, sem retry | | Timeout (30s) | Registrado como falha, sem retry | -### Testando sua Integração +## Segurança e RBAC - - - Adicione um webhook apontando para seu endpoint de desenvolvimento - - - Para desenvolvimento local, use [ngrok](https://ngrok.com): - ```bash - ngrok http 3000 - # Use a URL HTTPS como seu endpoint de webhook - ``` - - - Execute um flow com um decorador `@human_feedback` - - - Confirme que seu endpoint recebeu o payload - - - Faça POST para a `callback_url` para completar o flow - - +### Acesso ao Dashboard -## Outras Opções de Integração +O acesso HITL é controlado no nível do deployment: -### Acesso via API +| Permissão | Capacidade | +|-----------|------------| +| `manage_human_feedback` | Configurar settings HITL, ver todas as solicitações | +| `respond_to_human_feedback` | Responder a solicitações, ver solicitações atribuídas | -Controle programático completo para integrações personalizadas: +### Autorização de Resposta por Email -```python -# Exemplo: Verificar status HITL programaticamente -from crewai.enterprise import HITLClient +Para respostas por email: +1. O token reply-to codifica o email autorizado +2. Email do remetente deve corresponder ao email do token +3. Token não deve estar expirado (padrão 7 dias) +4. Solicitação ainda deve estar pendente -client = HITLClient() -pending_reviews = client.get_pending_reviews(flow_id="my-flow") +### Trilha de Auditoria -for review in pending_reviews: - print(f"Revisão {review.id}: {review.status} - Atribuída a: {review.assignee}") -``` +Todas as ações HITL são registradas: +- Criação de solicitação +- Mudanças de atribuição +- Submissão de resposta (com fonte: dashboard/email/API) +- Status de retomada do flow -### Em Breve +## Solução de Problemas -- **Integração com Slack**: Responda a solicitações HITL diretamente do Slack -- **Microsoft Teams**: Experiência de revisão nativa do Teams -- **App Mobile**: Revise e aprove em qualquer lugar +### Emails Não Enviando + +1. Verifique se "Notificações por Email" está ativado na configuração +2. Verifique se as regras de roteamento correspondem ao nome do método +3. Verifique se o email do responsável é válido +4. Verifique o fallback do criador do deployment se nenhuma regra de roteamento corresponder + +### Respostas de Email Não Processando + +1. Verifique se o token não expirou (padrão 7 dias) +2. Verifique se o email do remetente corresponde ao email atribuído +3. Garanta que a solicitação ainda está pendente (não respondida ainda) + +### Flow Não Retomando + +1. Verifique o status da solicitação no dashboard +2. Verifique se a URL de callback está acessível +3. Garanta que o deployment ainda está rodando ## Melhores Práticas -**Comece Simples**: Comece com portões de aprovação básicos, depois adicione roteamento e SLAs conforme seus fluxos de trabalho amadurecem. +**Comece Simples**: Comece com notificações por email para o criador do deployment, depois adicione regras de roteamento conforme seus fluxos de trabalho amadurecem. -1. **Defina Critérios de Revisão Claros**: Documente o que os revisores devem procurar para garantir decisões consistentes. +1. **Use Atribuição Dinâmica**: Obtenha emails de responsáveis do seu estado do flow para roteamento flexível. -2. **Defina SLAs Realistas**: Equilibre urgência com capacidade do revisor para manter fluxos de trabalho sustentáveis. +2. **Configure Resposta Automática**: Defina um fallback para revisões não críticas para evitar que flows fiquem travados. -3. **Use Escalação com Sabedoria**: Reserve auto-aprovação para revisões verdadeiramente não críticas para manter a qualidade. +3. **Monitore Tempos de Resposta**: Use análises para identificar gargalos e otimizar seu processo de revisão. -4. **Monitore e Itere**: Use análises para identificar gargalos e otimizar atribuições de revisores. +4. **Mantenha Mensagens de Revisão Claras**: Escreva mensagens claras e acionáveis no decorador `@human_feedback`. -5. **Treine Sua Equipe**: Garanta que os revisores entendam seu papel e as ferramentas disponíveis para eles. +5. **Teste o Fluxo de Email**: Envie solicitações de teste para verificar a entrega de email antes de ir para produção. ## Recursos Relacionados diff --git a/docs/pt-BR/enterprise/guides/human-in-the-loop.mdx b/docs/pt-BR/enterprise/guides/human-in-the-loop.mdx index 8834ac44a..7d853d1e4 100644 --- a/docs/pt-BR/enterprise/guides/human-in-the-loop.mdx +++ b/docs/pt-BR/enterprise/guides/human-in-the-loop.mdx @@ -13,7 +13,7 @@ CrewAI oferece duas abordagens para implementar workflows human-in-the-loop: | Abordagem | Melhor Para | Versão | |----------|----------|---------| -| **Baseada em Flow** (decorador `@human_feedback`) | Produção com UI Enterprise, workflows gerenciados, recursos completos da plataforma | **1.8.0+** | +| **Baseada em Flow** (decorador `@human_feedback`) | Produção com UI Enterprise, workflows email-first, recursos completos da plataforma | **1.8.0+** | | **Baseada em Webhook** | Integrações customizadas, sistemas externos (Slack, Teams, etc.), configurações legadas | Todas as versões | ## HITL Baseado em Flow com Plataforma Enterprise @@ -22,29 +22,30 @@ CrewAI oferece duas abordagens para implementar workflows human-in-the-loop: O decorador `@human_feedback` requer **CrewAI versão 1.8.0 ou superior**. -Ao usar o decorador `@human_feedback` em seus Flows, o CrewAI Enterprise oferece uma **UI de Gerenciamento HITL** dedicada que proporciona controle total sobre os workflows de feedback humano: +Ao usar o decorador `@human_feedback` em seus Flows, o CrewAI Enterprise oferece um **sistema HITL email-first** que permite que qualquer pessoa com um endereço de email responda a solicitações de revisão: - - Revise e responda a solicitações HITL diretamente no dashboard Enterprise—sem necessidade de configuração de webhook. + + Respondentes recebem notificações por email e podem responder diretamente—nenhum login necessário. - - Atribua membros específicos da equipe ou grupos como respondentes para diferentes tipos de tarefas ou crews. + + Revise e responda a solicitações HITL no dashboard Enterprise quando preferir. - - Defina quem pode visualizar, responder ou escalar solicitações HITL com controles de permissão granulares. + + Direcione solicitações para emails específicos com base em padrões de método ou obtenha do estado do flow. - - Configure regras de escalação automática quando as respostas atrasarem ou exigirem revisão sênior. - - - Defina Acordos de Nível de Serviço para tempos de resposta com notificações e rastreamento automáticos. - - - Roteie solicitações HITL com base em conteúdo, prioridade ou regras personalizadas com políticas de aplicação. + + Configure respostas automáticas de fallback quando nenhum humano responder dentro do timeout. +### Principais Benefícios + +- **Respondentes externos**: Qualquer pessoa com email pode responder, mesmo não sendo usuário da plataforma +- **Atribuição dinâmica**: Obtenha o email do responsável do estado do flow (ex: `account_owner_email`) +- **Configuração simples**: Roteamento baseado em email é mais fácil de configurar do que gerenciamento de usuários/funções +- **Fallback do criador do deployment**: Se nenhuma regra de roteamento corresponder, o criador do deployment é notificado + Para detalhes de implementação do decorador `@human_feedback`, consulte o guia [Feedback Humano em Flows](/pt-BR/learn/human-feedback-in-flows). @@ -148,7 +149,7 @@ Workflows HITL são particularmente valiosos para: - Explore os recursos completos da plataforma HITL para Flows, incluindo atribuição, gerenciamento de SLA, políticas de escalação e análises. + Explore os recursos completos da plataforma HITL para Flows, incluindo notificações por email, regras de roteamento, resposta automática e análises. Guia de implementação para o decorador `@human_feedback` em seus Flows.