关于 customer-success
面向客户支持与成功运营的工程实践技能,帮助团队设计支持系统、知识库、聊天机器人和自动化流程。内容涵盖 SLA、客户健康评分及反馈路由。
主要功能
- 01支持工单集成与分流
- 02知识库与站内帮助设计
- 03SLA 管理和升级自动化
- 04客户健康评分模型
- 05反馈收集与产品趋势分析
适用场景
- 01构建或整合客户支持系统
- 02设计聊天机器人和自助门户
- 03实施 SLA 跟踪及升级提醒
- 04识别有流失风险的客户
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ travisjneuman/ .claude --skill customer-success安装后在 Claude Code 中输入/customer-success确认已加载。
详细介绍
客户成功工程
概述
这项技能涵盖构建支撑客户支持与成功运营的技术系统,包括支持工单系统集成(Zendesk、Intercom、Freshdesk)、知识库架构、对话式 AI 聊天机器人设计、客户反馈收集与分流、SLA 管理与执行、升级工作流自动化、自助服务门户实施,以及客户健康评分模型。
在构建或集成支持系统、设计聊天机器人流程、创建自助服务文档门户、实施 SLA 跟踪、构建客户健康仪表板或自动化支持工作流时,请使用这项技能。
核心原则
- 优先自助服务——最好的支持互动,就是根本不需要发生的互动。在扩大人工支持规模之前,应投资建设可搜索的知识库、应用内帮助和上下文引导。
- 自动化分诊,而非解决问题——AI 可以有效地对工单进行分类、确定优先级并分流。复杂问题则交由人工处理。过度自动化问题解决流程会让客户感到沮丧。
- 衡量问题解决时间,而非工单数量——快速关闭工单毫无意义,如果客户的问题并未解决。应跟踪首次联系解决率、客户付出度评分和重新开启率。
- 工单应携带完整上下文——每次交接(机器人转人工、L1 转 L2)都必须包含完整的对话历史、用户账户数据和已尝试的解决方案。重复提供信息是客户投诉中最常见的问题。
- 反馈是产品信号——支持工单是非结构化的产品反馈。应添加标签、分类并向产品团队展示趋势。最常见的支持话题应成为下一项产品改进。
关键模式
模式 1:知识库架构
适用场景: 构建可搜索的文档,既服务客户(自助服务),也供支持人员参考(内部参考)。
实现:
// Knowledge base article schema
interface Article {
id: string;
slug: string;
title: string;
content: string; // Markdown
excerpt: string; // For search results
category: string;
subcategory: string;
tags: string[];
audience: "customer" | "internal" | "both";
visibility: "public" | "authenticated" | "internal";
relatedArticles: string[];
metadata: {
createdAt: Date;
updatedAt: Date;
author: string;
reviewedAt: Date | null;
helpfulVotes: number;
notHelpfulVotes: number;
viewCount: number;
};
}
// Search implementation with vector + full-text hybrid
async function searchKnowledgeBase(
query: string,
options?: { category?: string; audience?: string; limit?: number }
): Promise<SearchResult[]> {
const limit = options?.limit ?? 10;
// 1. Semantic search (catches paraphrased queries)
const embedding = await getEmbedding(query);
const semanticResults = await vectorDb.search({
vector: embedding,
filter: {
audience: options?.audience ?? "customer",
...(options?.category && { category: options.category }),
},
limit,
});
// 2. Full-text search (catches exact terminology)
const textResults = await db.$queryRaw`
SELECT id, title, excerpt,
ts_rank(search_vector, plainto_tsquery('english', ${query})) AS rank
FROM articles
WHERE search_vector @@ plainto_tsquery('english', ${query})
AND audience IN ('customer', 'both')
${options?.category ? Prisma.sql`AND category = ${options.category}` : Prisma.empty}
ORDER BY rank DESC
LIMIT ${limit}
`;
// 3. Merge and deduplicate results
const merged = mergeSearchResults(semanticResults, textResults);
// 4. Track search for analytics
await trackSearch(query, merged.length);
return merged;
}
// Feedback loop - track article helpfulness
async function rateArticle(
articleId: string,
helpful: boolean,
feedback?: string
): Promise<void> {
await db.articleFeedback.create({
data: {
articleId,
helpful,
feedback,
createdAt: new Date(),
},
});
// Update aggregate counts
await db.article.update({
where: { id: articleId },
data: helpful
? { helpfulVotes: { increment: 1 } }
: { notHelpfulVotes: { increment: 1 } },
});
// Flag articles with low helpfulness for review
const article = await db.article.findUnique({ where: { id: articleId } });
if (article) {
const total = article.helpfulVotes + article.notHelpfulVotes;
const helpfulRate = total > 10 ? article.helpfulVotes / total : 1;
if (helpfulRate < 0.5 && total > 10) {
await createReviewTask(articleId, "Low helpfulness score");
}
}
}
// In-app contextual help widget
function HelpWidget({ context }: { context: string }) {
const [articles, setArticles] = useState<Article[]>([]);
const [isOpen, setIsOpen] = useState(false);
useEffect(() => {
// Fetch relevant articles based on current page/feature context
if (isOpen) {
searchKnowledgeBase("", { category: context, limit: 5 })
.then(setArticles);
}
}, [isOpen, context]);
return (
<div className="help-widget">
<button
onClick={() => setIsOpen(!isOpen)}
aria-label="Help"
aria-expanded={isOpen}
>
?
</button>
{isOpen && (
<div role="dialog" aria-label="Help articles">
<SearchInput onSearch={(q) => searchKnowledgeBase(q, { category: context }).then(setArticles)} />
<ArticleList articles={articles} />
<a href="/support">Contact support</a>
</div>
)}
</div>
);
}
原因: 混合搜索(语义搜索 + 全文搜索)既能处理概念性查询(“如何分享我的项目?”),也能处理精确术语查询(“SSO SAML 配置”)。反馈闭环可确保标记低质量文章以便改进。上下文帮助会自动呈现相关文章,无需用户主动搜索。
模式 2:支持工单集成
适用场景: 将应用连接到工单系统,以实现结构化支持工作流。
实现:
// Unified support ticket interface (abstracts provider)
interface SupportTicket {
id: string;
externalId: string; // Provider's ticket ID
subject: string;
description: string;
status: "open" | "pending" | "in_progress" | "resolved" | "closed";
priority: "low" | "normal" | "high" | "urgent";
category: string;
tags: string[];
requester: {
id: string;
email: string;
name: string;
};
assignee?: {
id: string;
name: string;
group: string;
};
metadata: {
plan: string;
accountAge: number;
mrr: number; // Monthly recurring revenue
previousTickets: number;
};
createdAt: Date;
updatedAt: Date;
firstResponseAt?: Date;
resolvedAt?: Date;
}
// Auto-triage new tickets with AI classification
async function triageTicket(ticket: SupportTicket): Promise<TriageResult> {
const classification = await classifyTicket(ticket.subject, ticket.description);
// Priority escalation rules
let adjustedPriority = classification.priority;
// Enterprise customers get elevated priority
if (ticket.metadata.mrr >= 5000) {
adjustedPriority = elevate(adjustedPriority);
}
// Revenue at risk detection
if (containsCancellationIntent(ticket.description)) {
adjustedPriority = "urgent";
classification.tags.push("churn-risk");
}
// Route to appropriate team
const team = determineTeam(classification.category, adjustedPriority);
return {
category: classification.category,
priority: adjustedPriority,
team,
tags: classification.tags,
suggestedArticles: await findRelatedArticles(ticket.subject),
autoResponse: classification.confidence > 0.9
? generateAutoResponse(classification, ticket)
: null,
};
}
// SLA enforcement
interface SLAPolicy {
priority: string;
firstResponseMinutes: number;
resolutionMinutes: number;
}
const SLA_POLICIES: SLAPolicy[] = [
{ priority: "urgent", firstResponseMinutes: 30, resolutionMinutes: 240 },
{ priority: "high", firstResponseMinutes: 120, resolutionMinutes: 480 },
{ priority: "normal", firstResponseMinutes: 480, resolutionMinutes: 1440 },
{ priority: "low", firstResponseMinutes: 1440, resolutionMinutes: 4320 },
];
async function checkSLABreaches(): Promise<SLABreach[]> {
const openTickets = await getOpenTickets();
const breaches: SLABreach[] = [];
for (const ticket of openTickets) {
const policy = SLA_POLICIES.find((p) => p.priority === ticket.priority);
if (!policy) continue;
const now = new Date();
const age = (now.getTime() - ticket.createdAt.getTime()) / 60000;
// First response SLA
if (!ticket.firstResponseAt && age > policy.firstResponseMinutes) {
breaches.push({
ticketId: ticket.id,
type: "first_response",
minutesOverdue: Math.round(age - policy.firstResponseMinutes),
});
}
// Resolution SLA
if (!ticket.resolvedAt && age > policy.resolutionMinutes) {
breaches.push({
ticketId: ticket.id,
type: "resolution",
minutesOverdue: Math.round(age - policy.resolutionMinutes),
});
}
}
return breaches;
}
原因: AI 驱动的分诊能将工单更快地分配给合适的团队,从而缩短首次响应时间。基于收入的优先级升级机制可确保高价值客户得到适当关注。SLA 监控有助于明确责任并发现系统性问题(如果某个类别的工单经常违反 SLA,就说明产品或文档存在缺口)。
模式 3:客户健康评分
适用场景: 在客户流失之前主动识别有流失风险的客户。
实现:
// Health score calculation
interface HealthSignal {
name: string;
weight: number;
score: (customer: Customer) => number; // 0-100
}
const healthSignals: HealthSignal[] = [
{
name: "product_usage",
weight: 0.3,
score: (c) => {
const weeklyActive = c.loginDaysLast30 / 30 * 100;
return Math.min(100, weeklyActive * 1.5);
},
},
{
name: "feature_adoption",
weight: 0.2,
score: (c) => {
const total = CORE_FEATURES.length;
const adopted = c.featuresUsed.filter((f) => CORE_FEATURES.includes(f)).length;
return (adopted / total) * 100;
},
},
{
name: "support_sentiment",
weight: 0.15,
score: (c) => {
if (c.ticketsLast90Days === 0) return 70; // Neutral
const resolved = c.resolvedTicketsLast90Days / c.ticketsLast90Days;
return resolved * 100;
},
},
{
name: "expansion_signals",
weight: 0.15,
score: (c) => {
const usageGrowth = c.currentMonthUsage / (c.previousMonthUsage || 1);
if (usageGrowth > 1.2) return 100;
if (usageGrowth > 1.0) return 70;
if (usageGrowth > 0.8) return 40;
return 10;
},
},
{
name: "payment_health",
weight: 0.2,
score: (c) => {
if (c.failedPaymentsLast90Days > 2) return 20;
if (c.failedPaymentsLast90Days > 0) return 60;
return 100;
},
},
];
function calculateHealthScore(customer: Customer): {
score: number;
status: "healthy" | "at-risk" | "critical";
signals: Array<{ name: string; score: number; weight: number }>;
} {
const signals = healthSignals.map((signal) => ({
name: signal.name,
score: signal.score(customer),
weight: signal.weight,
}));
const weightedScore = signals.reduce(
(total, s) => total + s.score * s.weight,
0
);
return {
score: Math.round(weightedScore),
status: weightedScore >= 70 ? "healthy" : weightedScore >= 40 ? "at-risk" : "critical",
signals,
};
}
// Scheduled job: calculate health scores and alert CSMs
async function updateHealthScores(): Promise<void> {
const customers = await db.customer.findMany({
where: { subscriptionStatus: "active" },
include: { usage: true, tickets: true, payments: true },
});
for (const customer of customers) {
const health = calculateHealthScore(customer);
await db.customerHealth.upsert({
where: { customerId: customer.id },
create: { customerId: customer.id, ...health },
update: health,
});
// Alert CSM for critical customers
if (health.status === "critical" && customer.mrr >= 1000) {
await notifyCSM(customer.csmId, {
customer: customer.name,
score: health.score,
signals: health.signals.filter((s) => s.score < 40),
});
}
}
}
原因: 健康评分将被动支持(等待客户流失)转变为主动的客户成功管理(在客户流失前介入)。综合使用情况、支持情绪、功能采用情况和付款健康状况的评分,能够提供全面视图。针对关键账户的自动提醒可确保高价值客户及时获得 CSM 关注。
反模式
| 反模式 | 为什么不好 | 更好的做法 |
|---|---|---|
| 仅由机器人提供支持,且无法转接人工 | 客户感到沮丧并流失 | 机器人负责分诊和提供知识,人工负责解决问题 |
| 转接时未传递上下文 | 客户需要重复说明所有情况 | 传递完整的对话历史和账户数据 |
| 以已关闭工单数衡量成功 | 会促使过早关闭工单 | 衡量首次联系解决率和客户付出的精力 |
| 知识库没有反馈闭环 | 过时且无用的文章会一直存在 | 跟踪有用性投票,标记表现不佳的文章 |
| 所有客户采用相同的 SLA | 企业客户与免费用户获得相同的优先级 | 根据套餐和收入制定分级 SLA |
| 支持与产品反馈相互独立 | 错过可避免工单的规律 | 将工单标记为产品反馈,并展示趋势 |
检查清单
- 知识库可通过混合搜索(语义搜索 + 全文搜索)检索
- 在关键页面提供应用内情境化帮助组件
- 使用 AI 分类自动对支持工单进行分诊
- 按优先级定义 SLA 政策
- 监控 SLA 违约情况,并在需要升级时发出提醒
- 按计划计算客户健康度评分
- 高价值且有流失风险的客户会触发 CSM 提醒
- 每次升级时都提供完整上下文(对话 + 账户数据)
- 通过反馈闭环跟踪文章的有用性
- 每月向产品团队展示支持趋势
相关资源
- 技能:
llm-app-development(聊天机器人 RAG)、product-analytics(支持漏斗分析) - 技能:
email-systems(支持通知邮件)、accessibility-a11y(无障碍帮助组件) - 规则:
docs/reference/stacks/react-typescript.md(帮助组件)