Протоколы передачи оператору
Выявление условий передачи и плавное переключение на операторов.
«Протоколы передачи оператору» — бесплатный урок AI Agents на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения AI Agents, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс AI Agents содержит 4 уроков всего.
Когда агенту следует передавать разговор человеку
Не каждый разговор следует полностью поручать агенту ИИ. Знание того, когда передавать разговор человеку, так же важно, как и знание того, как отвечать. Распространённые условия:
- Клиент прямо просит связать его с человеком
- Обнаружены гнев или тревога
- Сложная или неоднозначная ситуация за пределами области применимости агента
- Ситуация затрагивает правовые вопросы, безопасность или соответствие требованиям
Обнаружение условий передачи человеку
Используйте классификатор LLM, чтобы обнаруживать условия передачи в реальном времени. Проверяйте это при каждом ходе агента, а не только в первом сообщении.
import openai, json
client = openai.OpenAI(api_key='YOUR_OPENAI_KEY')
def should_handoff(message: str, history: list[dict]) -> dict:
context = '\n'.join(f"{m['role']}: {m['content']}" for m in history[-4:])
prompt = (
f'Conversation context:\n{context}\n'
f'Latest message: "{message}"\n'
f'Should this be handed to a human agent? Reasons: '
f'angry_customer, explicit_human_request, complex_issue, legal_risk, other.\n'
f'JSON: {{"handoff": true/false, "reason": "..."}}'
)
resp = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}],
response_format={'type': 'json_object'}
)
return json.loads(resp.choices[0].message.content)Тёплая и холодная передача
Существует два стиля передачи:
- Тёплая передача: агент представляет себя и клиента оператору, кратко излагает разговор и ждёт подтверждения человека перед завершением работы.
- Холодная передача: разговор передаётся вместе с кратким содержанием расшифровки, а агент немедленно отключается.
Тёплые передачи снижают раздражение клиентов, но требуют доступности оператора в реальном времени.
Создание краткого содержания разговора
Перед передачей агент создаёт структурированное краткое содержание разговора. Это содержание показывается оператору как контекст, поэтому клиенту не приходится повторять всё сначала.
def generate_handoff_summary(history: list[dict]) -> str:
transcript = '\n'.join(
f"{m['role'].upper()}: {m['content']}" for m in history
)
prompt = (
f'Summarize this support conversation for a human agent.\n'
f'Include: customer issue, what was tried, current status, and urgency level.\n'
f'Be brief (3-5 sentences).\n\n'
f'TRANSCRIPT:\n{transcript}'
)
resp = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}]
)
return resp.choices[0].message.content
summary = generate_handoff_summary([
{'role': 'user', 'content': 'My account was charged twice for January'},
{'role': 'assistant', 'content': 'I can look into that for you...'}
])
print(summary)Создание обращения в Zendesk при передаче
При передаче создайте в Zendesk обращение с кратким содержанием и полной расшифровкой. Оператор открывает обращение и сразу получает необходимый контекст.
import requests
ZENDESK_DOMAIN = 'yourcompany.zendesk.com'
ZENDESK_TOKEN = 'YOUR_ZENDESK_API_TOKEN'
ZENDESK_EMAIL = 'agent@yourcompany.com'
def create_zendesk_ticket(customer_email: str, subject: str,
summary: str, transcript: str) -> str:
payload = {
'ticket': {
'subject': subject,
'comment': {'body': f'AI Agent Summary:\n{summary}\n\nFull Transcript:\n{transcript}'},
'requester': {'email': customer_email},
'tags': ['ai_handoff'],
'priority': 'high'
}
}
resp = requests.post(
f'https://{ZENDESK_DOMAIN}/api/v2/tickets.json',
json=payload,
auth=(f'{ZENDESK_EMAIL}/token', ZENDESK_TOKEN)
)
resp.raise_for_status()
return str(resp.json()['ticket']['id'])Передача разговора в Intercom
В Intercom передайте разговор, назначив его определённой команде или оператору с помощью API Intercom. Оператор получает уведомление о разговоре, готовом к продолжению.
import requests
INTERCOM_TOKEN = 'YOUR_INTERCOM_ACCESS_TOKEN'
def handoff_to_intercom_team(conversation_id: str, team_id: str,
note: str) -> bool:
headers = {
'Authorization': f'Bearer {INTERCOM_TOKEN}',
'Content-Type': 'application/json'
}
# Add a note with the AI summary
requests.post(
f'https://api.intercom.io/conversations/{conversation_id}/parts',
headers=headers,
json={'type': 'note', 'body': note}
)
# Assign to human team
resp = requests.put(
f'https://api.intercom.io/conversations/{conversation_id}/parts',
headers=headers,
json={'type': 'assignment', 'assignee_id': team_id,
'message_type': 'assignment'}
)
return resp.status_code == 200Сообщение клиенту при передаче
Сообщение, которое клиент получает во время передачи, имеет значение. Оно должно подтвердить передачу, обозначить ожидаемое время ожидания и показать, что к проблеме относятся серьёзно.
def generate_handoff_message(reason: str, wait_minutes: int = 5) -> str:
messages = {
'explicit_human_request':
f'Of course! I am connecting you with a human agent right now. '
f'Estimated wait: {wait_minutes} minutes. Your conversation history '
f'has been shared so you will not need to repeat anything.',
'angry_customer':
f'I completely understand your frustration. Let me get a senior '
f'team member on the line immediately. Wait: ~{wait_minutes} min.',
'complex_issue':
f'This situation needs specialist attention. I am escalating now '
f'and sharing all the context we have discussed. Wait: ~{wait_minutes} min.',
'legal_risk':
f'This matter requires our compliance team. Connecting you now.'
}
return messages.get(reason, f'Connecting you with a human agent. ~{wait_minutes} min wait.')
if __name__ == '__main__':
print(generate_handoff_message('angry_customer', wait_minutes=3))
print(generate_handoff_message('explicit_human_request'))
Постановка в очередь при отсутствии оператора
Вне рабочих часов или при высокой нагрузке оператор может быть недоступен сразу. Поставьте передачу в очередь, отправьте клиенту подтверждение с номером обращения и уведомите дежурных сотрудников через Slack или PagerDuty.
import requests
SLACK_WEBHOOK = 'https://hooks.slack.com/services/YOUR/WEBHOOK/URL'
def notify_on_call(ticket_id: str, summary: str, priority: str):
payload = {
'text': f'*New AI Handoff* [{priority.upper()}]',
'attachments': [{
'color': '#ff0000' if priority == 'high' else '#ffcc00',
'fields': [
{'title': 'Ticket ID', 'value': ticket_id, 'short': True},
{'title': 'Summary', 'value': summary[:500]}
]
}]
}
requests.post(SLACK_WEBHOOK, json=payload)Поведение агента после передачи
После запуска передачи агент должен прекратить попытки решить проблему. Он всё ещё может отвечать на фактические вопросы (статус заказа, ссылки на правила), но не должен давать обещаний или принимать решения.
def agent_post_handoff_response(message: str, handoff_complete: bool) -> str:
if not handoff_complete:
return 'Connecting you now...'
# Still answer simple factual questions
simple_keywords = ['status', 'where', 'when', 'policy', 'link']
if any(kw in message.lower() for kw in simple_keywords):
return 'I can help with that while you wait for the agent.'
# Defer everything else
return (
'Your case has been assigned to a specialist. '
'They will respond shortly. I will step back to avoid confusion.'
)
if __name__ == '__main__':
print(agent_post_handoff_response('Where is my order?', handoff_complete=True))
print(agent_post_handoff_response('I want a refund now', handoff_complete=True))
Отслеживание показателей передачи
Измеряйте долю передач, распределение причин и время решения после передачи. Высокая доля передач для определённого намерения указывает, что агенту нужно лучше охватывать эту тему.
from collections import Counter
import json
handoff_log = [] # In production: a database table
def record_handoff(session_id: str, reason: str, turn_number: int):
handoff_log.append({
'session_id': session_id,
'reason': reason,
'turns_before_handoff': turn_number
})
def handoff_analytics() -> dict:
reasons = Counter(h['reason'] for h in handoff_log)
avg_turns = sum(h['turns_before_handoff'] for h in handoff_log) / max(len(handoff_log), 1)
return {
'total_handoffs': len(handoff_log),
'reason_breakdown': dict(reasons),
'avg_turns_before_handoff': round(avg_turns, 1)
}
if __name__ == '__main__':
record_handoff('s1', 'angry_customer', 4)
record_handoff('s2', 'complex_issue', 7)
record_handoff('s3', 'angry_customer', 2)
stats = handoff_analytics()
print(f"Total handoffs: {stats['total_handoffs']}")
print(f"Reasons: {stats['reason_breakdown']}")
print(f"Avg turns before handoff: {stats['avg_turns_before_handoff']}")
Полная оркестрация передачи
Объедините все шаги в функцию execute_handoff(), которую агент вызывает после обнаружения условия передачи.
def execute_handoff(session: dict, reason: str) -> str:
# 1. Generate summary
summary = generate_handoff_summary(session['history'])
transcript = '\n'.join(
f"{m['role']}: {m['content']}" for m in session['history']
)
# 2. Create ticket
ticket_id = create_zendesk_ticket(
session['customer_email'],
f'AI Handoff: {reason}',
summary,
transcript
)
# 3. Notify on-call team
notify_on_call(ticket_id, summary, priority='high')
# 4. Record metrics
record_handoff(session['id'], reason, len(session['history']))
# 5. Return customer-facing message
wait = 5 # fetch from queue depth in production
return generate_handoff_message(reason, wait)В чём ключевое различие между тёплой и холодной передачей
Выбор подходящего стиля передачи влияет на опыт клиента и операционную сложность. Понимание различия помогает реализовать подходящий протокол.
Повторение протоколов передачи человеку
Эффективная передача требует: обнаружения условий (гнев, явная просьба, сложность), создания краткого содержания для оператора, создания обращения в Zendesk/Intercom с полной расшифровкой, уведомления дежурных сотрудников и предоставления клиенту понятного сообщения о том, чего ожидать.
После передачи агент отходит в сторону и оставляет все решения человеку.
Часто задаваемые вопросы
Урок «Протоколы передачи оператору» бесплатный?
Да — полный текст урока «Протоколы передачи оператору» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс AI Agents, подпишись на CoddyKit PRO. Курс AI Agents содержит 4 уроков всего.
Чему я научусь в уроке «Протоколы передачи оператору»?
Выявление условий передачи и плавное переключение на операторов. Ты практикуешь AI Agents с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать AI Agents?
Предыдущий опыт не требуется. AI Agents на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Протоколы передачи оператору»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке AI Agents?
Да. Каждый урок AI Agents включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Маршрутизация обращений и логика эскалации
- Интеграция с CRM: Salesforce и HubSpot
- Протоколы передачи оператору
- Управление контекстом и историей клиента