Felo API PlatformFelo API Platform

Hỗ trợ

Phân loại ticket hỗ trợ thành bản nháp trả lời có căn cứ

Che dữ liệu ticket, phân loại ý định và ưu tiên bằng Chat, lấy đoạn trả lời từ tài liệu, kiểm tra thảo luận sự cố công khai và để lại bản nháp đã định tuyến chờ người duyệt.

Thời gian20 phútMứcTrung cấpCập nhật2026-10-30
Dành cho aiTrưởng nhóm hỗ trợHelpdesk AgentKỹ sư hỗ trợ

Sao chép prompt

Thay các trường trong ngoặc vuông rồi dán vào Claude Code, Codex hoặc AI có quyền truy cập terminal. Nó cài skill Felo, hỏi trước khi dùng credit và chạy quy trình.

Phân loại ticket hỗ trợ này và viết bản nháp trả lời để con người xem xét: [dán ticket sau khi xóa tên, email, ID tài khoản, dữ liệu thanh toán và mọi thông tin nhận dạng].

Lĩnh vực sản phẩm: [sản phẩm]. Gói hoặc khu vực: [chỉ khi cần để trả lời]. Nguồn tài liệu: [URL trung tâm trợ giúp hoặc LiveDoc short_id].
Đường phê duyệt: [ai xem xét]. Hàng đợi chuyển cấp: [nhóm hoặc kênh].

Tạo:
1. Ý định: một danh mục và một câu lý do.
2. Ưu tiên: khẩn cấp / bình thường / thấp, kèm quy tắc áp dụng.
3. Bằng chứng: các đoạn tài liệu trả lời ticket, kèm tiêu đề và độ liên quan.
4. Kiểm tra sự cố: báo cáo công khai có gợi ý sự cố diện rộng không? Liên kết và ngày, hoặc “không có tín hiệu công khai”.
5. Định tuyến: nháp, hỏi thêm khách hàng hoặc chuyển cấp — và vì sao.
6. Bản nháp trả lời: hai đến bốn câu, chỉ dựa trên bằng chứng, nêu rõ nguồn đã dùng.

Quy tắc:
- Không đưa tên, email, số đơn, token hay dữ liệu thanh toán vào lệnh gọi API hoặc đầu ra. Chỉ làm việc với ticket đã che thông tin.
- Chỉ trả lời từ tài liệu đã truy xuất. Không có bằng chứng thì chuyển cấp, không đoán.
- Không hứa hoàn tiền, giảm giá, thời hạn hay thay đổi tài khoản; chuyển các trường hợp đó lên cấp trên.
- Tin đồn sự cố công khai là tín hiệu, không phải bằng chứng. Trích bài đăng và ngày.
- Trước khi tiêu tín dụng, hiển thị các lệnh gọi dự định và chờ tôi phê duyệt.
- Không gửi trả lời, không cập nhật ticket và không thao tác tài khoản. Trả bản nháp để xem xét.
- Ghi kết quả vào ./support-triage.md và tóm tắt trong chat.

Bản sao cũng gồm các bước cài đặt và quy tắc an toàn.

Bạn nhận được gì

Kết quả mẫu của một lần chạy. Không phải tạo trực tiếp.

Ví dụ phân loại (trích)

Phân loại — ticket ví dụ

Ý định

Câu hỏi thanh toán / gia hạn. Khách hỏi vì sao gói lại gia hạn.

Ưu tiên

Bình thường. Là câu hỏi thanh toán, không phải sự cố, khách không bị chặn.

Bằng chứng

  • “câu hỏi thường gặp về thanh toán” — thời điểm gia hạn và thử lại thẻ lỗi. Liên quan: cao.
  • “Thay đổi gói” — hạ cấp giữa các lần gia hạn. Liên quan: trung bình.

Kiểm tra sự cố

Không có báo cáo công khai trong 48 giờ qua.

Định tuyến

Nháp. Tài liệu bao phủ câu hỏi.

Bản nháp trả lời

Chào bạn — gói của bạn gia hạn vào ngày 1 hàng tháng, thẻ lỗi được thử lại ba ngày trước khi chỗ ngồi tạm dừng. Bạn có thể đổi thẻ trong Cài đặt thanh toán; câu hỏi thường gặp về thanh toán có hướng dẫn từng bước. Nếu cần dời ngày gia hạn, hãy trả lời và chúng tôi sẽ chuyển cho nhóm thanh toán.

Ghi chú cho người duyệt

Phê duyệt, chỉnh sửa hoặc chuyển lên hàng đợi thanh toán.

Các lệnh gọi chính xác

Dành cho lập trình viên: cùng quy trình dưới dạng mã, theo thứ tự chạy.

Hiện lệnh gọi API thật
  1. Che dữ liệu và phân loại

    Bỏ email, điện thoại và mã đơn bằng mã, rồi dùng Chat xác định ý định và ưu tiên.

    triage.ts
    const BASE = "https://openapi.felo.ai";
    const headers = {
      Authorization: `Bearer ${process.env.FELO_API_KEY}`,
      "Content-Type": "application/json",
    };
    
    async function felo<T>(path: string, body?: unknown): Promise<T> {
      const res = await fetch(`${BASE}${path}`, {
        method: body ? "POST" : "GET",
        headers,
        body: body ? JSON.stringify(body) : undefined,
      });
      if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
      return res.json() as Promise<T>;
    }
    
    const redact = (text: string) =>
      text
        .replace(/[\w.+-]+@[\w.-]+\.\w+/g, "[email]")
        .replace(/\b(?:acct|account|order|invoice)[-_ ]?\w+\b/gi, "[id]")
        .replace(/\b(?:\d[ -]?){13,19}\b/g, "[card]");
    
    type Ticket = {
      id: string;
      product: string;
      subject: string;
      body: string;
      plan?: string;
      sensitive?: boolean;
    };
    
    const ticket: Ticket = {
      id: "T-1042",
      product: "Acme Workspace",
      subject: "Why did my plan renew?",
      body: "I was charged again and cannot find the renewal date on my account.",
      plan: "team",
    };
    
    const summary = redact(`${ticket.subject}\n\n${ticket.body}`).slice(0, 1500);
    
    type ChatData = {
      data: {
        answer: string;
        resources: { link: string; title: string; snippet: string }[];
      };
    };
    
    const triage = await felo<ChatData>("/v2/chat", {
      query: `Classify this support question by intent and priority, and list what is missing:\n\n${summary}`,
    });
    
    console.log(triage.data.answer);

    Kết quả mẫu

    {
      "answer": "Intent: billing / renewal question. Priority: normal. Missing: the renewal date the customer expects.",
      "resources": [
        { "link": "https://example.com/billing-faq", "title": "Billing FAQ", "snippet": "…" }
      ]
    }
  2. Lấy bằng chứng tài liệu

    Tìm đoạn liên quan trong LiveDoc hỗ trợ, giữ tiêu đề và điểm.

    triage.ts
    type Hit = { title: string; content: string; score: number };
    
    const KB = process.env.SUPPORT_LIVEDOC_ID!; // the help-center LiveDoc short_id
    
    const retrieved = await felo<{ data: Hit[] }>(
      `/v2/livedocs/${KB}/resources/retrieve`,
      { query: summary },
    );
    
    const hits = retrieved.data.filter((hit) => hit.score >= 0.7).slice(0, 4);
    
    if (hits.length === 0) {
      console.log("No grounded evidence: escalate instead of drafting");
    }

    Kết quả mẫu

    [
      {
        "title": "Billing FAQ",
        "content": "Your plan renews on the first of the month; a failed card retries for three days…",
        "score": 0.91
      }
    ]
  3. Kiểm tra sự cố công khai

    Tìm trên X sản phẩm và từ như “sự cố/ngừng” trong 48 giờ, chỉ như tín hiệu công khai.

    triage.ts
    type XData = {
      data: {
        tweets: {
          content: string;
          author: { username: string };
          created_at: string;
          url: string;
        }[];
      };
    };
    
    const since = Math.floor((Date.now() - 48 * 60 * 60 * 1000) / 1000);
    
    const incident = await felo<XData>("/v2/x/tweet/search", {
      query: `"${ticket.product}" (outage OR "not working" OR error)`,
      limit: 20,
      since_time: since,
    });
    
    const reports = incident.data.tweets.map((post) => ({
      text: post.content,
      handle: post.author.username,
      at: post.created_at.slice(0, 10),
      link: post.url,
    }));

    Kết quả mẫu

    [
      {
        "text": "Workspace login is failing for my whole team.",
        "handle": "example_user",
        "at": "2026-10-30",
        "link": "https://x.com/example_user/status/..."
      }
    ]
  4. Định tuyến và soạn trả lời

    Quy tắc quyết định hàng đợi; gộp bằng chứng, bước tiếp theo và bản nháp.

    triage.ts
    type Route = "draft" | "ask-customer" | "escalate";
    
    function decideRoute(): { route: Route; reason: string } {
      if (hits.length === 0) {
        return { route: "escalate", reason: "no grounded evidence in the knowledge base" };
      }
      if (ticket.sensitive) {
        return { route: "escalate", reason: "an account or billing action is requested" };
      }
      if (reports.length >= 3) {
        return { route: "escalate", reason: "public reports suggest a wider issue" };
      }
      if (!ticket.plan) {
        return { route: "ask-customer", reason: "the plan is needed to answer the question" };
      }
      return { route: "draft", reason: "the documentation covers the question" };
    }
    
    const decision = decideRoute();
    
    const packet = [
      `# Triage — ${ticket.id}`,
      "",
      `Route: ${decision.route} (${decision.reason})`,
      "",
      "## Intent and priority",
      triage.data.answer,
      "",
      "## Evidence",
      ...hits.map((hit) => `- ${hit.title} (score ${hit.score})`),
      "",
      "## Public signal",
      ...(reports.length
        ? reports.map((report) => `- @${report.handle} (${report.at}): ${report.text} — ${report.link}`)
        : ["No public reports in the last 48 hours."]),
      "",
      "## Reply draft",
      "[Written by the host Agent from the evidence above — human review required]",
    ].join("\n");
    
    console.log(packet);

    Kết quả mẫu

    # Triage — T-1042
    
    Route: draft (the documentation covers the question)
    
    ## Intent and priority
    Intent: billing / renewal question. Priority: normal.
    
    ## Evidence
    - Billing FAQ (score 0.91)
  5. Ghi lại phân loại

    Ghi kết quả vào LiveDoc để nhìn lại và audit.

    triage.ts
    type LiveDocData = { data: { short_id: string } };
    
    const log = await felo<LiveDocData>("/v2/livedocs", {
      name: "Support triage log",
      description: "One document resource per triaged ticket",
    });
    
    await felo(`/v2/livedocs/${log.data.short_id}/resources/doc`, {
      title: `Triage — ${ticket.id}`,
      content: packet,
    });
    
    console.log(log.data.short_id); // reuse it for the next ticket

    Kết quả mẫu

    { "short_id": "PvyKouzJirXjFdst4uKRK3" }

Bao gồm

  • Ý định và ưu tiên sau khi che dữ liệu
  • Bằng chứng tài liệu kèm điểm
  • Kiểm tra sự cố công khai
  • Bản nháp trả lời đã định tuyến
  • LiveDoc với bản ghi phân loại

Không làm gì

  • Không gửi trả lời, không đóng ticket và không thao tác tài khoản
  • Không gửi mật khẩu, dữ liệu thanh toán hay dữ liệu khách đầy đủ tới API
  • Thiếu kết quả tài liệu thì bắt buộc escalation
  • X là tín hiệu sự cố công khai, không phải trạng thái hệ thống hỗ trợ
  • Quy tắc ưu tiên do bạn đặt; model chỉ đề xuất

Câu hỏi

Được gửi dữ liệu ticket nào?

Chỉ bối cảnh cần thiết sau khi che: sản phẩm, mô tả, gói và khu vực. Không gửi mật khẩu, thanh toán, địa chỉ đầy đủ hay hội thoại riêng.

Câu trả lời đến từ đâu?

Từ đoạn lấy trong LiveDoc tài liệu. Không kết quả thì quy trình escalation thay vì đoán.

Có trả lời hay đóng ticket không?

Không. Chỉ tạo bản nháp và tuyến; gửi và đóng do người hoặc hệ thống của bạn.

Ưu tiên được quyết thế nào?

Theo quy tắc của bạn; model đề xuất và nêu lý do, tuyến xác nhận ưu tiên cuối.

Nếu tài liệu không đủ?

Escalation tới hàng đợi người, ghi “chưa đủ” trong gói phân loại.

Một lần phân loại tốn bao nhiêu?

Chat, tìm kiếm và X Search tính theo mức dùng; giá hiện tại ở trang giá và prompt hỏi duyệt trước khi chi.

Quy trình liên quan

Tùy biến

Cùng công thức, điều chỉnh theo cách bạn thực sự triển khai.

Chỉ phân loại

Không trả lời: chỉ ý định, ưu tiên và hàng đợi đề xuất.

Nối vào hệ thống ticket

Dùng webhook của bạn ghi gói vào ticket, không tự gửi.

Chuyển sang cơ sở tri thức

Có kết quả tài liệu thì chuyển sang quy trình cơ sở tri thức để trả lời đầy đủ hơn.

Các trang tham chiếu đằng sau công thức và nơi đi tiếp.