К основному содержанию
скилл CX Codex GP ChatGPT официальный · OpenAI

twilio-taskrouter-routing — скилл для Codex

Настраивает маршрутизацию задач в Twilio TaskRouter. Скилл помогает создавать очереди, воркеров с навыками и правила распределения вызовов в контакт-центрах.

Установить в Codex · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add openai/plugins --skill twilio-taskrouter-routing -a codex
Открыть на GitHub

Что делает twilio-taskrouter-routing

Скилл генерирует код на Python и Node.js для настройки инфраструктуры Twilio TaskRouter. Он описывает создание рабочего пространства Workspace, статусов воркеров вроде Available или On Task, а также очередей задач Task Queues с фильтрами по атрибутам.

Маршрутизация опирается на Workflows с правилами отбора через оператор HAS и сравнение строк. При распределении задачи сервис отправляет webhook на assignment_callback_url, откуда агент возвращает команды dequeue или conference.

Для сборки атрибутов скилл требует использовать json.dumps() или JSON.stringify(). Обычная подстановка строк создаёт уязвимость перед инъекциями в JSON. Для работы понадобятся ключи TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN и установленная библиотека twilio.

Какие задачи решает

  • распределить звонки и задачи между операторами по их навыкам и языкам
  • настроить рабочее пространство TaskRouter с очередями и статусами воркеров
  • сконфигурировать Workflow с тайм-аутами и резервной очередью
  • обработать webhook назначения задачи через dequeue или перевод в конференцию

Примеры запросов агенту

  • Сгенерируй код на Python для создания Workspace в TaskRouter со статусами Available, Offline и On Task.
  • Настрой очередь TaskQueue для сотрудников со знанием испанского языка через оператор HAS.
  • Напиши обработчик webhook назначения для Express с инструкцией dequeue на рабочий номер.

Как установить twilio-taskrouter-routing

1Через Skills CLI (Vercel)

npx skills add openai/plugins --skill twilio-taskrouter-routing -a codex

2Вручную: положить файлы

.agents/skills/twilio-taskrouter-routing/SKILL.md

Для всех проектов — ~/.agents/skills/

По шагам, с командами для каждой платформы: Скиллы Codex: как установить, где лежат и как вызвать

Вопросы о twilio-taskrouter-routing

Как установить twilio-taskrouter-routing в Codex?

Выполните команду npx skills add openai/plugins --skill twilio-taskrouter-routing -a codex.

Что делает twilio-taskrouter-routing?

Скилл помогает спроектировать маршрутизацию Twilio TaskRouter, связать задачи с нужными воркерами по атрибутам и обработать события назначения вызовов.

Что нужно подготовить перед запуском кода для TaskRouter?

Нужен аккаунт Twilio, переменные окружения TWILIO_ACCOUNT_SID и TWILIO_AUTH_TOKEN, а также пакет twilio для Python или Node.js.

Исходный текст

SKILL.md · MIT
---
name: twilio-taskrouter-routing
description: >
  Route tasks to agents using Twilio TaskRouter. Covers Workers, Task
  Queues, Workflows, Reservations, skills-based routing, and common
  gotchas (hyphen attributes, HAS operator, reservation cascade). Use this
  skill for any multi-agent contact center, support queue, or AI agent
  escalation routing.
---

## Overview

TaskRouter is Twilio's skills-based routing engine. Instead of building custom queuing logic, you define Workers (agents), Task Queues (groups), and Workflows (routing rules). TaskRouter matches incoming tasks to the best available worker.

```
Incoming Task → Workflow (routing rules) → Task Queue (skill match) → Worker (agent)
                                                                        ↓
                                                                   Reservation
                                                                   (accept/reject)
```

**Common mistake:** Developers reinvent TaskRouter in custom Node.js — don't. If you're building skills-based routing, queue management, or agent assignment, use TaskRouter.

---

## Prerequisites

- Twilio account — see `twilio-account-setup`
- `TWILIO_ACCOUNT_SID` and `TWILIO_AUTH_TOKEN` — see `twilio-iam-auth-setup`
- SDK: `pip install twilio` / `npm install twilio`
- For voice routing: a Twilio phone number with webhook configured — see `twilio-voice-twiml`
- For AI escalation: ConversationRelay with escalation tools — see `twilio-voice-conversation-relay`

---

## Quickstart

**Step 1 — Create a Workspace**

A Workspace is the top-level container for all TaskRouter resources.

**Python**
```python
import os
from twilio.rest import Client

client = Client(os.environ["TWILIO_ACCOUNT_SID"], os.environ["TWILIO_AUTH_TOKEN"])

workspace = client.taskrouter.v1.workspaces.create(
    friendly_name="Support Center",
    event_callback_url="https://yourapp.com/taskrouter-events"
)

workspace_sid = workspace.sid  # WSxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
print(workspace_sid)
```

**Node.js**
```node
const twilio = require("twilio");
const client = twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);

const workspace = await client.taskrouter.v1.workspaces.create({
    friendlyName: "Support Center",
    eventCallbackUrl: "https://yourapp.com/taskrouter-events",
});

const workspaceSid = workspace.sid;
```

**Step 2 — Create Activities (agent states)**

**Python**
```python
# Available — worker can receive tasks
available = client.taskrouter.v1.workspaces(workspace_sid).activities.create(
    friendly_name="Available", available=True
)

# Offline — worker cannot receive tasks
offline = client.taskrouter.v1.workspaces(workspace_sid).activities.create(
    friendly_name="Offline", available=False
)

# On a task — worker is busy
on_task = client.taskrouter.v1.workspaces(workspace_sid).activities.create(
    friendly_name="On Task", available=False
)
```

**Step 3 — Create Workers (agents)**

> **Security:** Always use `json.dumps()` (Python) or `JSON.stringify()` (Node.js) to construct attribute payloads. String interpolation is vulnerable to JSON injection.

**Python**
```python
worker = client.taskrouter.v1.workspaces(workspace_sid).workers.create(
    friendly_name="Alice",
    attributes='{"skills": ["billing", "technical"], "languages": ["en", "es"], "department": "support"}'
)
```

**Node.js**
```node
const worker = await client.taskrouter.v1.workspaces(workspaceSid).workers.create({
    friendlyName: "Alice",
    attributes: JSON.stringify({
        skills: ["billing", "technical"],
        languages: ["en", "es"],
        department: "support",
    }),
});
```

**Step 4 — Create Task Queues**

**Python**
```python
# Billing queue — matches workers with "billing" skill
billing_queue = client.taskrouter.v1.workspaces(workspace_sid).task_queues.create(
    friendly_name="Billing",
    target_workers='skills HAS "billing"'
)

# Technical queue
tech_queue = client.taskrouter.v1.workspaces(workspace_sid).task_queues.create(
    friendly_name="Technical",
    target_workers='skills HAS "technical"'
)

# Catch-all queue
default_queue = client.taskrouter.v1.workspaces(workspace_sid).task_queues.create(
    friendly_name="Default",
    target_workers='1==1'  # matches all workers
)
```

**Step 5 — Create a Workflow (routing rules)**

**Python**
```python
import json

workflow_config = {
    "task_routing": {
        "filters": [
            {
                "filter_friendly_name": "Billing",
                "expression": "department == 'billing'",
                "targets": [
                    {"queue": billing_queue.sid, "timeout": 120}
                ]
            },
            {
                "filter_friendly_name": "Technical",
                "expression": "department == 'technical'",
                "targets": [
                    {"queue": tech_queue.sid, "timeout": 120}
                ]
            }
        ],
        "default_filter": {
            "queue": default_queue.sid
        }
    }
}

workflow = client.taskrouter.v1.workspaces(workspace_sid).workflows.create(
    friendly_name="Support Routing",
    configuration=json.dumps(workflow_config),
    assignment_callback_url="https://yourapp.com/assignment"
)
```

**Step 6 — Create a Task (from an incoming call)**

**Python**
```python
task = client.taskrouter.v1.workspaces(workspace_sid).tasks.create(
    attributes='{"department": "billing", "caller": "+15558675310", "priority": 1}',
    workflow_sid=workflow.sid
)
```

**Step 7 — Handle the Assignment Callback**

When TaskRouter finds a matching worker, it POSTs to your `assignment_callback_url`:

**Python (Flask)**
```python
@app.route("/assignment", methods=["POST"])
def assignment():
    task_sid = request.form["TaskSid"]
    worker_sid = request.form["WorkerSid"]
    reservation_sid = request.form["ReservationSid"]

    # Option A: Dequeue to the worker's phone
    return jsonify({
        "instruction": "dequeue",
        "from": "+15551234567",  # your Twilio number
        "post_work_activity_sid": available_activity_sid
    })

    # Option B: Conference the caller and agent
    # return jsonify({
    #     "instruction": "conference",
    #     "from": "+15551234567",
    #     "post_work_activity_sid": available_activity_sid
    # })
```

**Node.js (Express)**
```node
app.post("/assignment", (req, res) => {
    res.json({
        instruction: "dequeue",
        from: "+15551234567",
        post_work_activity_sid: availableActivitySid,
    });
});
```

---

## Key Patterns

### Skills-Based Routing

Match tasks to workers based on attributes:

| Worker expression | Matches |
|-------------------|---------|
| `skills HAS "billing"` | Workers whose `skills` array contains "billing" |
| `languages HAS "es"` | Spanish-speaking workers |
| `department == "support"` | Workers in support department |
| `experience > 5` | Workers with 5+ years experience |
| `skills HAS "billing" AND languages HAS "es"` | Spanish-speaking billing agents |

### Priority Routing

Tasks with higher priority are assigned first:

```python
# VIP customer — priority 10 (higher = first)
task = client.taskrouter.v1.workspaces(workspace_sid).tasks.create(
    attributes='{"department": "billing", "priority": 10, "vip": true}',
    workflow_sid=workflow.sid,
    priority=10
)
```

### AI Agent Escalation

When an AI agent (via TAC) escalates to a human, create a TaskRouter task with the AI's context:

```python
# From your escalation webhook handler
def handle_escalation(escalation_data):
    task = client.taskrouter.v1.workspaces(workspace_sid).tasks.create(
        attributes=json.dumps({
            "department": escalation_data["reason_code"],
            "conversation_id": escalation_data["conversation_id"],
            "profile_id": escalation_data["profile_id"],
            "ai_summary": escalation_data["summary"],
            "priority": 5
        }),
        workflow_sid=workflow.sid
    )
```

The human agent receives the AI's conversation summary and customer profile.

### Workflow with Timeout Escalation

Route to specialized queue first, then overflow to general:

```python
workflow_config = {
    "task_routing": {
        "filters": [
            {
                "filter_friendly_name": "Billing Specialist First",
                "expression": "department == 'billing'",
                "targets": [
                    {"queue": billing_queue.sid, "timeout": 60},      # Try billing queue for 60s
                    {"queue": default_queue.sid, "timeout": 120}      # Overflow to general
                ]
            }
        ],
        "default_filter": {
            "queue": default_queue.sid
        }
    }
}
```

### Worker Activity Management

```python
# Set worker to available
client.taskrouter.v1.workspaces(workspace_sid) \
    .workers(worker_sid) \
    .update(activity_sid=available_activity_sid)

# Get real-time worker statistics
stats = client.taskrouter.v1.workspaces(workspace_sid) \
    .workers \
    .statistics() \
    .fetch()

print(f"Available: {stats.realtime['total_available_workers']}")
```

---

## Scale Guidance

| Agents | Architecture | Notes |
|--------|-------------|-------|
| < 10 | Single workflow, one queue per skill | No Flex needed — agents use phone |
| 10-50 | Multi-queue workflows, skills-based routing | Flex recommended for desktop |
| 50+ | Multi-tier workflows, priority routing, real-time monitoring | Full Flex + supervisor tools |

---

## Gotchas

### 1. Hyphens in Attribute Names Break Silently

```python
# WRONG — hyphens in attribute keys break workflow expressions
worker = client.taskrouter.v1.workspaces(workspace_sid).workers.create(
    friendly_name="Alice",
    attributes='{"skill-level": 5}'  # hyphen breaks expression evaluation
)

# RIGHT — use underscores or camelCase
worker = client.taskrouter.v1.workspaces(workspace_sid).workers.create(
    friendly_name="Alice",
    attributes='{"skill_level": 5}'
)
```

No error — the expression silently fails to match.

### 2. HAS Operator on Non-Array Attributes

```python
# WRONG — "billing" is a string, not an array. HAS silently matches nothing.
target_workers = 'department HAS "billing"'

# RIGHT — use == for string attributes
target_workers = 'department == "billing"'

# RIGHT — use HAS only for arrays
target_workers = 'skills HAS "billing"'  # skills: ["billing", "technical"]
```

Tasks sit in queue forever with no error.

### 3. Reservation Timeout Cascade

When a reservation times out:
1. Worker moves to the timeout Activity (often "Offline")
2. Fewer workers available → other reservations also time out
3. Positive feedback loop → entire queue backs up

**Fix:** Set the timeout Activity to a short-duration state, not "Offline". Or implement a reservation timeout handler that keeps the worker available:

```python
@app.route("/taskrouter-events", methods=["POST"])
def taskrouter_event():
    event_type = request.form["EventType"]
    if event_type == "reservation.timeout":
        worker_sid = request.form["WorkerSid"]
        # Keep worker available instead of moving to offline
        client.taskrouter.v1.workspaces(workspace_sid) \
            .workers(worker_sid) \
            .update(activity_sid=available_activity_sid)
    return "", 200
```

### 4. Activity Available Flag

Updating an Activity's `available` flag returns 200 OK but may not change the value if workers are currently in that activity. Create new activities instead of modifying existing ones.

---

## CANNOT

- **Hyphens in attribute names break expressions** — `skill-level` is treated as subtraction (`skill` minus `level`). Error 20001. Always use underscores: `skill_level`.
- **`HAS` on non-array silently matches nothing** — `department HAS "billing"` on a string attribute is accepted at creation but never matches. Tasks sit in queue forever with no error.
- **Expression validation is syntactic only** — Queue creation validates parse but NOT worker matching. Semantically wrong expressions create successfully with zero matching workers.
- **Activity `available` flag is silently immutable** — Updating returns 200 OK but does not change the value. Must delete and recreate the Activity.
- **`multiTaskEnabled` cannot be reverted to false** — Once enabled on a Workspace, cannot be disabled. One-way door.
- **Reservation timeout moves worker to timeout Activity** — Worker automatically moved to Offline. Must manually set back. This cascades: fewer available workers → more timeouts → queue collapse. See Gotcha #3.
- **Workflow target timeout auto-cancels tasks** — When all targets exhaust timeouts, task is canceled. Always include a `default_filter` as catch-all.
- **Worker `friendlyName` is case-insensitive unique** — "alice" collides with "Alice".
- **`workflowSid` is required for task creation** — API does not auto-select a default Workflow.
- **Cannot update task status and attributes in same request** — Must be two separate API calls.
- **Assignment callback must respond in 5 seconds** — If both primary and fallback URLs fail, reservation is canceled.
- **Tasks auto-cancel after 1,000 rejections** — If a task cycles through 1,000 reservation rejections, it is automatically canceled.
- **`page` query param not supported** — Use `PageToken` for pagination. `page` returns error 40153.
- **Cannot use malformed JSON in worker attributes** — Silently breaks matching with no error
- **Cannot use regex in workflow expressions** — Only supports ==, !=, <, >, HAS, IN, CONTAINS, AND, OR, NOT
- **Cannot exceed 50,000 Workers per Workspace** — Hard limit
- **Cannot exceed 250 Task Queues per Workspace** — Hard limit
- **Cannot delay reservation callback response beyond 15 seconds** — Timeout results in reservation failure

---

## Next Steps

- **Conference for transfers:** `twilio-conference-calls`
- **Call recording:** `twilio-call-recordings`
- **AI agent voice integration:** `twilio-voice-conversation-relay`
- **Voice IVR before routing:** `twilio-voice-twiml`

© Twilio · MIT · openai/plugins

Похожие скиллы

Все скиллы по теме «Бэкенд и API» →
mcp-builder официальный anthropics Скилл проводит через создание MCP-сервера на TypeScript или Python: от изучения протокола до тестов и оценки качества. 130 949установок claude-api официальный anthropics Справочник по Anthropic SDK и API Claude для генерации кода без устаревших параметров и выдуманных методов. 74 198установок lark-im larksuite Скилл подключает Lark IM к агенту: он отправляет сообщения, ищет историю, управляет чатами и файлами. Подойдёт для задач вокруг командных коммуникаций. CX Codex +1 472 900установок lark-event larksuite Слушает события Lark/Feishu и отдаёт их потоком NDJSON. Подходит для ботов, обработчиков сообщений и долгих подписчиков. CX Codex +1 466 800установок caveman-discover JuliusBrussee Находит точки вызова LLM в репозитории и размечает их воркфлоу для Caveman Cloud, чтобы расходы на токены не сливались в одну общую кучу. CX Codex +1 104 400установок migration JuliusBrussee Скилл задаёт правила безопасных миграций схем, данных и API с обязательным откатом. Пригодится при изменениях, где нельзя терять данные или ломать совместимость. CX Codex +1 103 900установок

Из того же набора593

Весь набор →
twilio-webhook-architecture Скилл помогает спроектировать обработчики HTTP-вебхуков Twilio и проверять подписи запросов. Пригодится для входящих сообщений и звонков, а также асинхронных статусных событий. CX Codex GP ChatGPT ★ 7 604звёзд репо twilio-voice-twiml Скилл для сборки голосовой логики звонков на TwiML: глаголы Say, Play, Gather, Dial, Record, Conference и пример IVR для входящего вызова. CX Codex GP ChatGPT ★ 7 604звёзд репо twilio-voice-outbound-calls Помогает запускать исходящие звонки через Twilio REST API, распознавать автоответчики и настраивать вебхуки с TwiML. CX Codex GP ChatGPT ★ 7 604звёзд репо twilio-verify-send-otp Скилл учит агента проводить полный цикл одноразовых кодов в Twilio Verify: создать сервис, отправить код, проверить его. CX Codex GP ChatGPT ★ 7 604звёзд репо twilio-sms-send-message Скилл помогает разбирать ошибки доставки SMS и MMS в Twilio: проверять коды ошибок, фильтрацию сообщений и признаки SMS pumping. CX Codex GP ChatGPT ★ 7 604звёзд репо twilio-isv-sms-best-practices Скилл для тех, кто встраивает SMS в SaaS-платформу и рассылает сообщения от имени клиентов. Разбирает регистрацию A2P 10DLC и toll-free, субаккаунты и биллинг. CX Codex GP ChatGPT ★ 7 604звёзд репо twilio-sendgrid-webhooks Скилл помогает обрабатывать 11 типов событий SendGrid Event Webhooks, проверять подписи ECDSA и настраивать приём батчей для отслеживания доставки и отписок. CX Codex GP ChatGPT ★ 7 604звёзд репо twilio-sendgrid-suppressions Скилл помогает разбирать подавления SendGrid: выяснять, почему письма не доходят, и настраивать отписки по категориям. Нужен для диагностики доставки и работы с unsubscribe-сценариями. CX Codex GP ChatGPT ★ 7 604звёзд репо

Спонсоры проекта

Компании, которые помогают держать аналитику открытой