Hóa đơn OpenAI cho biết bạn đã chi 4.237 đô la tháng trước. Nó không cho biết 3.100 đô la đến từ một endpoint tóm tắt chạy quá mức, 700 đô la đến từ một khách hàng chỉ trả 50 đô la/tháng, và 437 đô la đến từ một tính năng không ai dùng. Muốn ra quyết định về giá, hạn mức hoặc roadmap, bạn cần phân bổ chi phí theo từng request.
Bài viết này hướng dẫn cách triển khai phân bổ chi phí API OpenAI: gắn metadata cho mỗi request, log usage/token/cost, tổng hợp theo feature/route/customer, đặt budget limit theo key, và kiểm thử wrapper bằng Apidog trước khi đưa lên production.
💡 Apidog giúp bạn kiểm thử request ở cấp kịch bản để xác minh wrapper theo dõi chi phí hoạt động đúng trước khi deploy. Bạn có thể phát lại request đã gắn tag, assert schema log và xác thực mỗi call đều mang metadata mà data warehouse cần.
TL;DR
- Gắn tag mọi OpenAI API call bằng metadata có cấu trúc:
feature,route,customer_id,environment. - Ghi một JSON log cho mỗi request, gồm token usage và
cost_usd. - Tính chi phí tại thời điểm ghi log, không tính lại khi query.
- Tổng hợp dữ liệu trong BigQuery, ClickHouse, Snowflake hoặc Postgres.
- Đặt budget limit theo project key trong OpenAI dashboard.
- Cảnh báo bất thường theo giờ từ data warehouse.
- Kiểm thử wrapper end-to-end bằng Apidog trước khi tin vào dashboard.
Vấn đề: OpenAI dashboard không đủ để phân bổ chi phí
OpenAI billing dashboard cho bạn biết tổng chi tiêu theo ngày và theo model. Nhưng khi chạy LLM trong production, bạn thường cần trả lời các câu hỏi khác:
- Feature nào đang tiêu nhiều tiền nhất?
- Endpoint nào tạo spike?
- Customer nào đang làm giảm gross margin?
- Chi phí staging/dev có bị trộn vào production không?
- Background job nào đang chạy quá mức?
- Một retry có bị tính hai lần không?
Dashboard gốc không có các chiều phân tích như feature, route, customer_id hoặc environment. OpenAI usage API hữu ích cho đối soát tổng hợp, nhưng không thay thế được attribution ở cấp request.
Nếu bạn cần bối cảnh về giá, xem thêm phân tích chi tiết giá GPT-5.5. Với bài toán billing tương tự trong công cụ dev, xem thanh toán sử dụng GitHub Copilot cho các nhóm API. Tài liệu gốc của OpenAI nằm tại OpenAI API reference.
Mô hình dữ liệu phân bổ chi phí
Đơn vị phân tích nên là một event cho mỗi OpenAI request.
Schema tối thiểu:
| Cột | Kiểu | Ví dụ | Mục đích |
|---|---|---|---|
request_id |
uuid | 7a91... |
Dedup, retry, trace |
timestamp |
timestamptz | 2026-05-06T14:23:01Z |
Time-series query |
feature |
text | support-chat |
Feature gọi LLM |
route |
text | /api/v1/chat/answer |
HTTP route hoặc background job |
customer_id |
text | cust_4291 |
Chi phí theo khách hàng |
environment |
text | prod |
Tách prod/staging/dev |
model |
text | gpt-5.5 |
Tính giá theo model |
prompt_tokens |
int | 15234 |
Token đầu vào |
completion_tokens |
int | 812 |
Token đầu ra |
reasoning_tokens |
int | 4500 |
Token suy luận, tính theo output |
cached_tokens |
int | 12000 |
Token cache, thường rẻ hơn input thường |
latency_ms |
int | 2341 |
Correlate cost với UX |
cost_usd |
numeric | 0.045672 |
Chi phí đã tính tại thời điểm request |
prompt_cache_key |
text | system-v3 |
Theo dõi cache hit |
error_code |
text | 429 |
Debug retry/error |
Tính chi phí tại thời điểm ghi log
Đừng chỉ lưu token rồi tính chi phí sau. Giá có thể thay đổi. Hãy lưu cost_usd ngay khi request hoàn tất để dữ liệu lịch sử phản ánh đúng mức giá tại thời điểm đó.
Ví dụ Python:
PRICING = { # USD per 1M tokens, as of May 2026
"gpt-5.5": {"input": 5.00, "cached": 2.50, "output": 30.00},
"gpt-5.5-pro": {"input": 30.00, "cached": 15.00, "output": 180.00},
"gpt-5.4": {"input": 2.50, "cached": 1.25, "output": 15.00},
"gpt-5.4-mini": {"input": 0.25, "cached": 0.125, "output": 2.00},
}
def compute_cost_usd(
model,
prompt_tokens,
cached_tokens,
completion_tokens,
reasoning_tokens
):
rates = PRICING[model]
uncached_tokens = max(0, prompt_tokens - cached_tokens)
input_cost = (uncached_tokens * rates["input"]) / 1_000_000
cache_cost = (cached_tokens * rates["cached"]) / 1_000_000
# Reasoning tokens are billed as output.
output_tokens = completion_tokens + reasoning_tokens
output_cost = (output_tokens * rates["output"]) / 1_000_000
return round(input_cost + cache_cost + output_cost, 6)
Token suy luận được OpenAI trả về trong:
usage.completion_tokens_details.reasoning_tokens
Chúng phải được cộng vào output cost, không phải input cost. Nếu bỏ qua phần này, bạn sẽ tính thiếu chi phí cho các chế độ reasoning/thinking.
Bọc OpenAI client bằng attribution wrapper
Mọi call đến OpenAI nên đi qua một wrapper duy nhất. Wrapper nhận metadata, gọi API, đọc response.usage, tính chi phí và ghi log có cấu trúc.
import time
import uuid
import json
import logging
from openai import OpenAI
client = OpenAI()
logger = logging.getLogger("llm.cost")
def call_with_attribution(
*,
feature,
route,
customer_id,
environment,
model,
messages,
request_id=None,
**openai_kwargs
):
request_id = request_id or str(uuid.uuid4())
started = time.time()
error_code = None
response = None
try:
response = client.chat.completions.create(
model=model,
messages=messages,
**openai_kwargs
)
return response
except Exception as e:
error_code = getattr(e, "code", "unknown_error")
raise
finally:
latency_ms = int((time.time() - started) * 1000)
usage = response.usage if response else None
prompt_tokens = getattr(usage, "prompt_tokens", 0)
completion_tokens = getattr(usage, "completion_tokens", 0)
cached_tokens = (
getattr(
getattr(usage, "prompt_tokens_details", None),
"cached_tokens",
0
) or 0
)
reasoning_tokens = (
getattr(
getattr(usage, "completion_tokens_details", None),
"reasoning_tokens",
0
) or 0
)
cost_usd = compute_cost_usd(
model=model,
prompt_tokens=prompt_tokens,
cached_tokens=cached_tokens,
completion_tokens=completion_tokens,
reasoning_tokens=reasoning_tokens,
)
logger.info(json.dumps({
"event": "openai.request",
"request_id": request_id,
"timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
"feature": feature,
"route": route,
"customer_id": customer_id,
"environment": environment,
"model": model,
"prompt_tokens": prompt_tokens,
"completion_tokens": completion_tokens,
"reasoning_tokens": reasoning_tokens,
"cached_tokens": cached_tokens,
"latency_ms": latency_ms,
"cost_usd": cost_usd,
"error_code": error_code,
}))
Cách dùng:
response = call_with_attribution(
feature="support-chat",
route="/api/v1/chat/answer",
customer_id="cust_4291",
environment="prod",
model="gpt-5.5",
messages=[
{"role": "system", "content": "Bạn là trợ lý hỗ trợ kỹ thuật."},
{"role": "user", "content": "Làm sao reset API key?"}
],
)
Nguyên tắc triển khai:
- Không cho phép
feature,route,customer_id,environmentmặc định là"unknown". - Với retry idempotent, truyền lại cùng
request_id. - Ghi log mọi request, không sampling.
- Với background job, dùng
routedạngcron:nightly-summaryhoặcqueue:document-indexing.
Với Node.js, pattern tương tự: wrap SDK, nhận metadata, đọc response.usage, tính cost_usd, ghi một JSON event. Nếu hệ thống đã có Kafka, NATS hoặc Pub/Sub, publish event vào bus thay vì stdout.
Đưa log vào data warehouse
Bạn không cần một pipeline riêng cho LLM nếu đã có logging stack.
Có thể dùng:
- Vector
- Fluent Bit
- Logstash
- OTLP collector
- Datadog/CloudWatch export
- Kafka consumer
- Custom ingestion job
Đích đến có thể là:
- BigQuery
- ClickHouse
- Snowflake
- Postgres
- Redshift
Ví dụ query chi phí theo feature:
SELECT
feature,
DATE_TRUNC(timestamp, DAY) AS day,
COUNT(*) AS requests,
SUM(cost_usd) AS spend_usd,
SUM(prompt_tokens + completion_tokens + reasoning_tokens) AS total_tokens,
AVG(latency_ms) AS avg_latency_ms,
SUM(cached_tokens) / NULLIF(SUM(prompt_tokens), 0) AS cache_hit_rate
FROM openai_events
WHERE environment = 'prod'
AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY feature, day
ORDER BY day DESC, spend_usd DESC;
Chi phí theo customer:
SELECT
customer_id,
COUNT(*) AS requests,
SUM(cost_usd) AS spend_usd,
AVG(cost_usd) AS avg_cost_per_request
FROM openai_events
WHERE environment = 'prod'
AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY customer_id
ORDER BY spend_usd DESC
LIMIT 50;
Top route tiêu tiền hôm qua:
SELECT
route,
feature,
COUNT(*) AS requests,
SUM(cost_usd) AS spend_usd
FROM openai_events
WHERE environment = 'prod'
AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 DAY)
GROUP BY route, feature
ORDER BY spend_usd DESC
LIMIT 20;
Kiểm thử wrapper bằng Apidog
Sau khi có wrapper, hãy kiểm thử nó như một contract. Nếu schema log sai, dashboard và alert của bạn sẽ sai âm thầm.
Dùng Apidog để chạy end-to-end test:
- Tạo request đến endpoint AI của bạn.
- Truyền
customer_id,featurehoặc dữ liệu đầu vào có thể xác định được. - Gọi service qua môi trường staging.
- Kiểm tra response.
- Kiểm tra log side-channel hoặc log endpoint nội bộ.
- Assert các field bắt buộc tồn tại:
request_idfeatureroutecustomer_idenvironmentmodelprompt_tokenscompletion_tokenscost_usd
- Assert giá trị hợp lệ:
cost_usd > 0prompt_tokens > 0environment = "staging"
- Phát lại request để kiểm tra retry không bị tính trùng nếu dùng cùng
request_id.
Ví dụ assertion logic:
pm.test("cost attribution log is valid", function () {
const log = pm.response.json().debug.cost_event;
pm.expect(log.feature).to.eql("support-chat");
pm.expect(log.route).to.eql("/api/v1/chat/answer");
pm.expect(log.customer_id).to.eql("cust_test_001");
pm.expect(log.prompt_tokens).to.be.above(0);
pm.expect(log.cost_usd).to.be.above(0);
});
Để mở rộng kiểm thử API, xem công cụ kiểm thử API cho kỹ sư QA. Nếu bạn muốn áp dụng contract-first cho cả API và cost attribution, xem phát triển API theo hợp đồng trước.
Đặt budget limit và alert
OpenAI project key giúp bạn chia tách một phần chi phí. Hãy tạo key theo môi trường hoặc feature:
prod-support-chatprod-summarizationprod-agent-workflowsstaging-alldev-all
Sau đó:
- Đặt hard budget limit trong OpenAI dashboard.
- Dùng key riêng cho từng service/feature quan trọng.
- Không dùng chung key production cho staging.
- Thêm alert từ data warehouse để phát hiện spike nhanh hơn dashboard.
Ví dụ alert SQL chạy mỗi 10 phút:
WITH hourly_spend AS (
SELECT
feature,
TIMESTAMP_TRUNC(timestamp, HOUR) AS hour,
SUM(cost_usd) AS spend_usd
FROM openai_events
WHERE environment = 'prod'
AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
GROUP BY feature, hour
),
baseline AS (
SELECT
feature,
AVG(spend_usd) AS avg_hourly_spend
FROM hourly_spend
WHERE hour < TIMESTAMP_TRUNC(CURRENT_TIMESTAMP(), HOUR)
GROUP BY feature
),
current_hour AS (
SELECT
feature,
SUM(cost_usd) AS current_spend
FROM openai_events
WHERE environment = 'prod'
AND timestamp >= TIMESTAMP_TRUNC(CURRENT_TIMESTAMP(), HOUR)
GROUP BY feature
)
SELECT
c.feature,
c.current_spend,
b.avg_hourly_spend
FROM current_hour c
JOIN baseline b USING (feature)
WHERE c.current_spend > b.avg_hourly_spend * 3;
Gửi kết quả đến Slack, PagerDuty hoặc Opsgenie.
Tối ưu chi phí sau khi đã đo đúng
1. Prompt caching
Nếu model hỗ trợ prompt caching, hãy giữ system prompt và context ổn định ở phần đầu prompt, đặt dữ liệu biến đổi ở cuối.
Theo dõi:
SELECT
feature,
SUM(cached_tokens) / NULLIF(SUM(prompt_tokens), 0) AS cache_hit_rate
FROM openai_events
WHERE environment = 'prod'
GROUP BY feature
ORDER BY cache_hit_rate ASC;
Xem thêm tài liệu prompt caching của OpenAI.
2. Batch API cho tác vụ offline
Các job không cần response đồng bộ nên dùng Batch API nếu phù hợp:
- Tóm tắt hàng đêm
- Eval run
- Re-index tài liệu
- Backfill embedding
- Xử lý lại dữ liệu cũ
Vẫn gắn tag như request thường, thêm batch_job_id để phân bổ chi phí về job nguồn.
3. Điều chỉnh reasoning effort
Nếu feature đang dùng reasoning ở mức cao, hãy đo lại chất lượng và chi phí ở mức thấp hơn.
Ví dụ test matrix:
| Feature | Effort | Quality score | Avg cost/request |
|---|---|---|---|
| support-chat | low | 0.86 | 0.012 |
| support-chat | medium | 0.88 | 0.031 |
| support-chat | high | 0.89 | 0.074 |
Nếu low đạt chất lượng đủ tốt, bạn không cần trả tiền cho high.
Xem thêm cách sử dụng API GPT-5.5.
4. Kiểm soát context window
Prompt dài là nguồn chi phí phổ biến nhất.
Theo dõi token đầu vào theo feature:
SELECT
feature,
AVG(prompt_tokens) AS avg_prompt_tokens,
APPROX_QUANTILES(prompt_tokens, 100)[OFFSET(95)] AS p95_prompt_tokens
FROM openai_events
WHERE environment = 'prod'
GROUP BY feature
ORDER BY p95_prompt_tokens DESC;
Nếu prompt_tokens tăng đều mỗi tuần mà không có thay đổi sản phẩm tương ứng, prompt hoặc RAG retrieval của bạn đang phình ra.
5. Cảnh báo request gần ngưỡng context lớn
Nếu pricing có multiplier cho request vượt ngưỡng token lớn, thêm guardrail trong wrapper:
if prompt_tokens > 250_000:
logger.warning(json.dumps({
"event": "openai.large_context_warning",
"request_id": request_id,
"feature": feature,
"route": route,
"customer_id": customer_id,
"prompt_tokens": prompt_tokens,
}))
Xem thêm bài viết về giá GPT-5.5.
6. Giới hạn theo customer
Với B2B SaaS, bạn nên kiểm tra quota trước mỗi LLM call.
Pseudo-code:
def ensure_customer_ai_quota(customer_id):
monthly_spend = get_monthly_llm_spend(customer_id)
monthly_limit = get_customer_ai_limit(customer_id)
if monthly_spend >= monthly_limit:
raise AiQuotaExceeded(
"Quota AI hàng tháng đã vượt quá. Vui lòng nâng cấp gói."
)
Chi phí LLM nên là một phần của unit economics, không phải khoản chi chung không kiểm soát.
Lỗi phổ biến cần tránh
- Gắn tag ở cấp SDK thay vì tại điểm gọi.
- Để
customer_id = null. - Không gắn tag background job.
- Bỏ qua
reasoning_tokens. - Tính
reasoning_tokenstheo input price thay vì output price. - Dùng OpenAI dashboard cho alert thời gian thực.
- Sampling log request.
- Không dedup retry bằng
request_id. - Trộn staging/dev vào production.
- Không cố định bảng giá theo thời điểm request.
Có nên tự xây hay dùng công cụ?
| Phương pháp | Ưu điểm | Chi phí | Khi nên dùng |
|---|---|---|---|
| OpenAI usage API | Native, không cần setup, khớp billing | Miễn phí | Một project, ít feature, không cần customer attribution |
| Helicone | Proxy nhanh, dashboard, cache, cost per user | Có free tier; trả phí từ khoảng 20 đô la/tháng | Muốn dashboard nhanh và chấp nhận proxy |
| Langfuse | Open-source, tracing + cost | Self-host miễn phí; cloud từ khoảng 29 đô la/tháng | Muốn trace và cost trong cùng hệ thống |
| LangSmith | Tích hợp tốt với LangChain, eval + cost | Trả phí từ khoảng 39 đô la/user/tháng | Đã dùng LangChain |
| Custom warehouse | Kiểm soát hoàn toàn, không proxy, tích hợp data stack | Thời gian kỹ thuật | Scale lớn, cần dimension tùy chỉnh, yêu cầu dữ liệu nghiêm ngặt |
Tham khảo thêm:
- Hướng dẫn của Helicone về theo dõi chi phí LLM
- Tài liệu Langfuse về model usage và cost
- Nền tảng API cho kiến trúc microservices
Use case thực tế
SaaS B2B
Một sản phẩm sales intelligence dùng GPT-5.5 để tạo tóm tắt. Trước attribution, công ty chỉ biết tổng chi OpenAI là 80.000 đô la/tháng. Sau khi phân bổ theo customer_id, họ thấy 12% khách hàng tạo ra 71% chi phí.
Hành động:
- Thêm tier pricing.
- Đặt soft quota cho gói thấp.
- Tính overage cho usage cao.
- Theo dõi gross margin theo customer.
Kết quả: feature AI chuyển từ rủi ro margin thành sản phẩm có thể định giá.
Công cụ nội bộ cho developer
Một tổ chức cấp trợ lý GPT riêng cho developer. Khi dùng customer_id = dev_email, platform team phát hiện 3 developer tạo 50% chi phí. Hai người đang chạy agent loop bị quên tắt. Tắt loop tiết kiệm 1.800 đô la/tháng.
Dự báo chi phí feature mới
Trước khi launch feature tóm tắt, product team dùng dữ liệu lịch sử để ước tính:
cost/user/day =
avg_calls_per_user_per_day
* avg_cost_per_call
Nếu kết quả là 0,04 đô la/user/ngày, tức khoảng 1,20 đô la/user/tháng, pricing team có cơ sở để định giá feature ở mức 5 đô la/user/tháng.
Checklist triển khai
- [ ] Tạo wrapper duy nhất cho OpenAI client.
- [ ] Bắt buộc truyền
feature,route,customer_id,environment. - [ ] Đọc
response.usage. - [ ] Tính
cost_usdtại thời điểm request. - [ ] Ghi JSON log cho mọi request.
- [ ] Dedup retry bằng
request_id. - [ ] Đưa log vào data warehouse.
- [ ] Tạo dashboard theo feature, route, customer.
- [ ] Tạo alert spike theo giờ.
- [ ] Tạo project key theo môi trường/feature.
- [ ] Đặt budget limit trong OpenAI dashboard.
- [ ] Kiểm thử wrapper bằng Apidog.
Kết luận
OpenAI billing dashboard trả lời câu hỏi “đã chi bao nhiêu”. Đội sản phẩm và kỹ thuật cần trả lời câu hỏi “chi phí đến từ đâu”.
Cách triển khai thực tế:
- Bọc mọi OpenAI call bằng attribution wrapper.
- Gắn tag ở điểm gọi.
- Ghi usage và cost thành event có cấu trúc.
- Tổng hợp trong data warehouse.
- Đặt budget limit theo key.
- Cảnh báo bất thường theo feature/customer/route.
- Kiểm thử schema log bằng Apidog trước khi production.
Tải Apidog và dùng nó để xác minh wrapper phân bổ chi phí từ đầu đến cuối: gửi request đã gắn tag, assert payload log và phát lại kịch bản trên nhiều môi trường.
Đọc thêm:
Câu hỏi thường gặp
Token suy luận được tính là input hay output?
Output. OpenAI trả về token suy luận trong usage.completion_tokens_details.reasoning_tokens. Khi tính chi phí, cộng chúng vào output tokens. Xem thêm phân tích giá GPT-5.5.
response.usage có khớp OpenAI dashboard không?
Token count trong response.usage nên khớp với billing usage. Sai lệch thường đến từ việc bạn dùng bảng giá cũ. Hãy version bảng giá theo ngày hiệu lực.
Chỉ dùng OpenAI project key có đủ không?
Không nếu bạn cần phân bổ theo feature, customer hoặc route. Project key chỉ cho bạn một chiều phân bổ. Metadata cấp ứng dụng vẫn cần thiết.
Retry có làm tính trùng chi phí không?
Có thể. Nếu request thành công rồi app retry, bạn có thể log hai lần. Với retry idempotent, truyền lại cùng request_id và dedup khi ghi hoặc khi ingest.
OpenAI usage API nhanh đến mức nào?
Có độ trễ từ vài chục phút đến vài giờ. Dùng nó cho đối soát, không dùng cho alert thời gian thực.
Có nên sampling log không?
Không. Một JSON line cho mỗi request là rất nhỏ. Sampling làm hỏng phân bổ theo customer và route.
Cách này dùng được cho provider khác không?
Có. Thêm cột provider, ví dụ openai, anthropic, google, deepseek, và bảng giá riêng cho từng provider. Schema và dashboard có thể dùng chung. Xem thêm giá API DeepSeek V4.
Embeddings và image generation thì sao?
Dùng cùng pattern, nhưng công thức cost khác. Thêm cột endpoint, ví dụ chat, embeddings, image, rồi branch logic tính chi phí theo loại endpoint.
Top comments (0)