# Ở AssemblyAI, FDE canh lúc usage tăng vọt rồi im bặt

> Vai trò onboarding chịu trách nhiệm từ cuộc gọi API đầu tiên tới tháng production đầu tiên, và prototype lấy transcript bằng polling là chỗ khách hay kẹt nhất.

Bản gốc: https://fdetimes.net/vi/bach-khoa/assemblyai-fde-onboarding-tu-cuoc-goi-api-den-production/

Thứ Hai, một developer tạo API key và gửi vài file ghi âm thử. Thứ Tư, số request của họ tăng gấp nhiều lần. Đến thứ Sáu thì gần như không còn request nào. Trên dashboard, đường usage đi lên rồi rơi thẳng xuống, và chẳng có ai gửi ticket nào giải thích chuyện gì đã xảy ra.

Với một FDE Onboarding, đường biểu đồ đó là một ca cần xử lý. AssemblyAI mô tả vai trò này là người thúc đẩy việc kích hoạt khách mới trên các dòng sản phẩm.

Người đó phụ trách quãng đường từ cuộc gọi API đầu tiên đến lúc khách dùng production đều đặn, cụ thể hơn là quãng thời gian giữa cuộc gọi đầu tiên và tháng traffic production đầu tiên.

Kỹ năng ở đây không nằm ở việc hiểu sản phẩm của mình. Nó nằm ở việc đoán được khách đang kẹt ở đâu khi họ không nói ra, vào code của họ để gỡ, rồi rời đi khi hệ thống đã chạy ổn.

Ca dễ hình dung nhất là một prototype lấy transcript bằng polling, vì chính tài liệu của AssemblyAI cảnh báo cách này sẽ chạm giới hạn tốc độ.

## Vì sao phải liên hệ ngay lúc usage đang tăng?

Tin tuyển dụng của AssemblyAI ghi rõ: FDE quản lý một danh mục khách đang trong quá trình onboarding và phải chủ động liên hệ ngay khi usage của một developer tăng lên, để gỡ vướng trước khi họ im lặng. Mốc này hợp lý, vì lúc usage tăng là lúc prototype bắt đầu gặp tải thật, và đó cũng là lúc nó dễ hỏng nhất.

**Điểm mấu chốt:** Khách im lặng sau khi usage tăng thường là đang kẹt, không phải đang ổn.

Vai trò này cũng gắn với kết quả kinh doanh. Tin tuyển dụng yêu cầu ứng viên từng có thành tích "carrying a number", tức là từng chịu và đạt một chỉ tiêu. Vì thế đừng coi mỗi cuộc gọi hỗ trợ là xong việc khi trả lời xong. Việc chỉ xong khi khách chạy production đều đặn.

## Một ca cụ thể: prototype dùng polling vỡ khi tăng tải

Thử hình dung một startup làm công cụ ghi chú cuộc họp. Developer của họ viết prototype theo cách tự nhiên nhất: gửi file audio lên, nhận transcript ID, rồi dùng một vòng lặp hỏi trạng thái vài giây một lần cho đến khi có kết quả. Với mười file thì cách này chạy tốt. Khi họ đẩy cả kho ghi âm lên, mọi thứ bắt đầu hỏng.

Lỗi đầu tiên đến từ giới hạn tốc độ. Tài liệu của AssemblyAI cho biết việc polling một transcript bị giới hạn theo từng key và từng transcript ID. Khi vượt giới hạn, API trả về HTTP 429 kèm header Retry-After. Nếu code của khách không đọc header này mà retry ngay, nó sẽ liên tục nhận 429 và log đầy lỗi.

Lỗi thứ hai là concurrency. Mặc định, tài khoản free chỉ chạy được 5 job transcription file ghi sẵn cùng lúc, còn tài khoản trả phí là 200+. Muốn giới hạn riêng thì phải làm việc với Sales hoặc support. Một nhóm đẩy hàng nghìn file lên bằng key free sẽ thấy hàng đợi gần như đứng yên và dễ kết luận rằng API chậm.

Hệ quả là developer im lặng. Họ không biết lỗi nằm ở thiết kế của mình hay ở phía nhà cung cấp, nên họ thôi thử. Nếu FDE liên hệ vào thứ Tư, khi đường usage còn đang lên, thì đã có thể chặn chuyện này từ đầu.

## Cách sửa: thay polling bằng webhook

Chính tài liệu của AssemblyAI khuyên dùng webhook để tránh 429, và mô tả webhook là cách dành cho production thay cho polling. Khách đăng ký một URL, và AssemblyAI gọi vào đó khi transcript đã xong. Có một điều kiện quan trọng: nếu endpoint không trả 2xx trong 10 giây, AssemblyAI sẽ gửi lại, tổng cộng tối đa 10 lần.

Từ điều kiện đó suy ra hai quy tắc thiết kế. Handler phải trả lời nhanh, nên không được lấy transcript, chạy tóm tắt hay ghi vào nhiều bảng ngay trong request. Handler cũng phải idempotent, tức là nhận cùng một sự kiện hai lần vẫn chỉ xử lý một lần, vì một lần gửi lại có thể đến sau khi bạn đã xử lý xong.

Về bảo mật, có thể xác thực webhook bằng một HTTP header riêng do bạn tự đặt trong request. Webhook cũng được gửi từ IP cố định, nên có thể đưa vào allowlist: 44.238.19.20 cho vùng US và 54.220.25.36 cho vùng EU.

Nếu đội security của khách hỏi webhook đến từ đâu, hai địa chỉ IP này cùng header xác thực là câu trả lời nên có sẵn trong tay.

Bản vá bạn ngồi viết cùng developer của khách có thể trông như sau. Tên header và tên trường trong payload chỉ là minh họa, hãy đối chiếu với tài liệu hiện hành.

```python
from flask import Flask, request, abort
import os

app = Flask(__name__)
SECRET = os.environ["WEBHOOK_SECRET"]

@app.post("/hooks/transcript")
def transcript_done():
    # 1. Xác thực bằng header riêng mà bạn đã cấu hình khi tạo job
    if request.headers.get("X-Webhook-Secret") != SECRET:
        abort(401)
    event = request.get_json(force=True)
    tid = event.get("transcript_id")
    # 2. Idempotent: bỏ qua nếu ID đã nằm trong hàng đợi hoặc đã xử lý
    if not seen_before(tid):      # ví dụ: INSERT ... ON CONFLICT DO NOTHING
        enqueue_fetch(tid)        # worker lấy transcript và xử lý sau
    # 3. Trả 2xx ngay, trước khi hết 10 giây
    return "", 200
```

Còn với nhóm vẫn phải giữ polling trong lúc chuyển đổi, bản vá tối thiểu là đọc Retry-After rồi chờ đúng khoảng đó, thay vì dùng một khoảng chờ cố định. Song song, hãy xem họ đang dùng key free hay trả phí. Nếu cần nâng concurrency thì kéo Sales vào, vì đây là vai trò liên phòng ban, làm cùng Sales, Support, Product và Engineering.

## Năm bước để tự làm một ca onboarding

Bước đầu là theo dõi tín hiệu usage, không chờ ticket. Một lượng gọi tăng đột ngột, một chuỗi lỗi 429 hay một key free đang chạm trần concurrency đều đáng để bạn viết một tin nhắn ngắn hỏi khách đang làm gì.

Bước hai là xin xem code. AssemblyAI yêu cầu FDE đọc nhanh codebase lạ của khách và cùng kỹ sư của họ ship bản vá chạy được, thường là service Python hoặc JavaScript/Node. Ba mươi phút đọc chỗ code gọi API thường cho bạn biết nhiều hơn một tiếng họp.

Bước ba là sửa đúng lớp đang vỡ. Có ca nằm ở cách lấy kết quả (polling hay webhook), có ca ở giới hạn tài khoản, có ca ở mạng hoặc allowlist. Mỗi lớp cần người khác nhau, nên đừng gửi một danh sách mười việc cần làm.

Bước bốn là kiểm thử trên môi trường staging hoặc test, không đụng vào pipeline production của khách. Gửi trùng một payload, cho handler chậm cố ý quá 10 giây, rồi xem log để thấy việc gửi lại diễn ra thế nào. Bước năm là đưa những gì học được cho Product và Support, để khách kế tiếp không vấp đúng chỗ đó.

## Những lỗi hay gặp

Lỗi phổ biến nhất là xử lý cả công việc nặng ngay trong webhook handler, vượt quá 10 giây, rồi nhận về cùng một sự kiện nhiều lần, đôi khi khiến ghi chú bị tạo trùng. Lỗi thứ hai là coi 429 là lỗi của nhà cung cấp mà không đọc Retry-After.

Lỗi thứ ba là lỗi của chính FDE: cho rằng khách im lặng nghĩa là họ đang ổn. Lỗi thứ tư là gửi tài liệu thay cho bản vá. Khách đang kẹt cần một pull request, không cần thêm một đường link.

## Đem kỹ năng này vào hồ sơ thế nào?

Khi đọc mô tả công việc, hãy tìm các cụm như activation, first API call to production, carry a number. Chúng cho biết vai trò được đo bằng việc khách có chạy production hay không. Tin của AssemblyAI còn yêu cầu hiểu các giao thức real-time và streaming như WebSockets và audio pipeline, nên nếu chưa từng làm, hãy tự dựng một client streaming nhỏ để luyện.

Trong CV, một dòng như "chuyển pipeline của khách từ polling sang webhook idempotent, hết lỗi 429, lên production trong hai tuần" có sức nặng hơn hẳn một danh sách framework. Nếu chưa có khách thật, hãy làm cùng bài đó trên dự án cá nhân và ghi lại số liệu trước và sau.

Với developer ở đầu bài, cơ hội nằm ở ngày thứ Tư, khi đường usage còn đang lên. Đến thứ Sáu, khi họ đã im lặng, việc kéo họ quay lại khó hơn nhiều.

**Thử ngay tuần này:**

- Viết một webhook handler nhỏ chỉ làm ba việc: kiểm tra header bí mật, ghi ID vào hàng đợi, trả 200. Sau đó gửi trùng một payload hai lần để kiểm tra rằng job chỉ chạy một lần.
- Mở một repo mã nguồn mở bằng Python hoặc Node mà bạn chưa đọc bao giờ, đặt giờ 30 phút để tìm chỗ nó gọi API bên ngoài, rồi ghi ra một bản vá bạn sẽ đề xuất.
- Viết lại một dòng trong CV theo dạng kết quả: khách hoặc nhóm nào, từ trạng thái nào lên production, mất bao lâu.

## Nguồn

- [Forward Deployed Engineer, Onboarding (AssemblyAI, via Accel Jobs)](https://jobs.accel.com/companies/assemblyai/jobs/78049975-forward-deployed-engineer-onboarding)

- [Forward Deployed Engineer, Onboarding (AssemblyAI, Built In)](https://builtin.com/job/forward-deployed-engineer-onboarding/9301251)

- [AssemblyAI Docs: Webhooks (pre-recorded audio)](https://www.assemblyai.com/docs/pre-recorded-audio/webhooks.md)

- [AssemblyAI Docs: Concurrency (pre-recorded audio)](https://www.assemblyai.com/docs/pre-recorded-audio/concurrency)
