有人引き継ぎのプロトコル
引き継ぎのトリガーを検出し、ライブエージェントへスムーズに転送します。
「有人引き継ぎのプロトコル」はCoddyKit上の無料AI Agentsレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAI Agents学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 AI Agentsコースには全4レッスンが含まれています。
エージェントはいつ引き継ぐべきですか
すべての会話を最初から最後までAIエージェントだけで対応すべきとは限りません。いつ引き継ぐかを判断することは、答え方を知ることと同じくらい重要です。一般的なトリガーは次のとおりです。
- 顧客が人間の担当者を明示的に求めた場合
- 怒りや苦痛が検出された場合
- エージェントの対応範囲外にある、複雑または曖昧な状況
- 法務、安全性、コンプライアンスに関わるセンシティブな内容
引き継ぎトリガーの検出
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)ウォームハンドオフとコールドハンドオフ
引き継ぎには2つの形式があります。
- ウォームハンドオフ:エージェントが自分自身と顧客を人間の担当者に紹介し、会話を要約して、人間の担当者が引き継ぎを確認するまで待ってから終了します。
- コールドハンドオフ:会話をトランスクリプトの要約とともに転送し、エージェントはすぐに切断します。
ウォームハンドオフは顧客の不満を抑えられますが、人間の担当者がリアルタイムで対応できる必要があります。
会話の要約の生成
引き継ぐ前に、エージェントは会話の構造化された要約を生成します。この要約は人間の担当者にコンテキストとして表示されるため、顧客が同じ説明を繰り返す必要がなくなります。
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では、Intercom APIを使って会話を特定のチームまたはエージェントに割り当て、引き継ぎます。人間の担当者には、すぐに対応を続けられる状態の会話とともに通知が届きます。
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時間対応のAIチューター)、AI Agentsコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 AI Agentsコースには全4レッスンが含まれています。
「有人引き継ぎのプロトコル」で何を学びますか?
引き継ぎのトリガーを検出し、ライブエージェントへスムーズに転送します。 ブラウザで直接実行するハンズオンコードでAI Agentsを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
AI Agentsを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのAI Agentsは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「有人引き継ぎのプロトコル」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このAI Agentsレッスンでコードを書いて実行できますか?
はい。すべてのAI Agentsレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。