사람에게 인계하는 프로토콜
인계 조건을 감지하고 실제 상담원에게 원활하게 전달합니다.
사람에게 인계하는 프로토콜은(는) CoddyKit의 무료 AI Agents 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Agents 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.
Agent는 언제 인계해야 하나요?
모든 대화를 AI agent가 처음부터 끝까지 처리해야 하는 것은 아닙니다. 언제 인계할지 아는 것은 어떻게 답변할지 아는 것만큼 중요합니다. 일반적인 조건은 다음과 같습니다.
- 고객이 명시적으로 사람을 요청함
- 분노나 고통이 감지됨
- agent의 담당 범위를 벗어난 복잡하거나 모호한 상황
- 법률, 안전 또는 규정 준수와 관련해 민감한 사안
인계 조건 감지
LLM 분류기를 사용해 실시간으로 인계 조건을 감지합니다. 첫 메시지뿐만 아니라 agent가 응답할 때마다 확인해야 합니다.
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)웜 인계와 콜드 인계
인계 방식에는 두 가지가 있습니다.
- 웜 인계: agent가 사람 agent에게 자신과 고객을 소개하고 대화를 요약한 다음, 종료하기 전에 사람이 확인할 때까지 기다립니다.
- 콜드 인계: 대화가 기록 요약과 함께 전달되고 agent는 즉시 연결을 종료합니다.
웜 인계는 고객의 불만을 줄이지만 사람 agent가 실시간으로 이용 가능해야 합니다.
대화 요약 생성
인계하기 전에 agent가 대화의 구조화된 요약을 생성합니다. 이 요약은 사람 agent에게 컨텍스트로 표시되므로 고객이 같은 내용을 반복해서 설명할 필요가 없습니다.
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 티켓을 만듭니다. 사람 agent는 티켓을 열어 즉시 컨텍스트를 확인할 수 있습니다.
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를 사용해 대화를 특정 팀이나 agent에게 할당하는 방식으로 인계합니다. 사람 agent는 이어서 처리할 준비가 된 대화와 함께 알림을 받습니다.
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)인계 후 Agent의 동작
인계를 실행한 후 agent는 문제를 계속 해결하려고 시도하지 않아야 합니다. 주문 상태나 정책 링크 같은 사실 기반 질문에는 계속 답할 수 있지만, 약속을 하거나 결정을 내려서는 안 됩니다.
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))
인계 지표 추적
인계율, 사유별 분포, 인계 후 해결 시간을 측정합니다. 특정 의도에서 인계율이 높다면 해당 주제에 대한 agent의 지원 범위를 개선해야 한다는 뜻입니다.
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() 함수로 결합하고, 조건이 감지되면 agent가 이 함수를 한 번 호출하도록 합니다.
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)웜 인계와 콜드 인계의 핵심적인 차이는 무엇인가요?
적절한 인계 방식을 선택하면 고객 경험과 운영 복잡성에 영향을 줍니다. 두 방식의 차이를 이해하면 적절한 절차를 구현할 수 있습니다.
사람에게 인계하는 절차 요약
효과적인 인계에는 조건 감지(분노, 명시적 요청, 복잡성), 사람 agent를 위한 요약 생성, 전체 대화 기록과 함께 Zendesk/Intercom에 티켓 만들기, 당직 담당자에게 알림 보내기, 고객에게 명확한 예상 안내 제공이 필요합니다.
인계 후 agent는 물러나 모든 결정을 사람에게 맡깁니다.
자주 묻는 질문
“사람에게 인계하는 프로토콜” 강의는 무료인가요?
네 — “사람에게 인계하는 프로토콜” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Agents 강의 전체를 잠금 해제할 수 있습니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.
“사람에게 인계하는 프로토콜”에서 뭘 배우나요?
인계 조건을 감지하고 실제 상담원에게 원활하게 전달합니다. 브라우저에서 직접 실행하는 실습 코드로 AI Agents을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
AI Agents을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 AI Agents은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“사람에게 인계하는 프로토콜” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 AI Agents 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 AI Agents 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.