0Pricing
AI Agents · 课时

人工接管协议

检测接管触发条件,并顺畅地转交给人工客服

人工接管协议 是 CoddyKit 上的免费 AI Agents 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 AI Agents 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 AI Agents 课程共包含 4 节课。

代理何时应进行转交?

并非每次对话都应由人工智能代理从头到尾处理。了解何时进行转交与了解如何回答同样重要。常见触发条件包括:

  • 客户明确要求人工客服
  • 检测到愤怒或 distress 情绪
  • 情况复杂或含义不明确,超出代理的范围
  • 涉及法律、安全或合规敏感性

检测转交触发条件

使用 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 时,请通过 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 中创建包含完整对话记录的工单、通知值班人员,以及向客户提供清晰的预期说明。

转交后,代理应退居幕后,将所有决定交由人工客服处理。

常见问题解答

「人工接管协议」课时是免费的吗?

是的 — 「人工接管协议」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 AI Agents 课程的其余内容,请升级到 CoddyKit PRO。 AI Agents 课程共包含 4 节课。

「人工接管协议」这节课中我会学到什么?

检测接管触发条件,并顺畅地转交给人工客服 你通过在浏览器中直接运行的动手代码来练习 AI Agents,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 AI Agents 需要有经验吗?

无需任何先前经验。CoddyKit 上的 AI Agents 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「人工接管协议」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 AI Agents 课中编写并运行代码吗?

能。每节 AI Agents 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 工单路由与升级逻辑
  2. CRM 集成:Salesforce 与 HubSpot
  3. 人工接管协议
  4. 客户上下文与历史记录管理
← 返回 AI Agents