·

Đo token usage một lần rồi để đó là cách chắc chắn khiến chi phí AI agent âm thầm phình to trở lại chỉ sau vài tuần. Model provider tung bản cập nhật pricing, một teammate thêm vài đoạn "context" vào system prompt cho "chắc ăn", RAG pipeline bắt đầu nhét thêm chunk vì threshold retrieval bị chỉnh sai — và trước khi bạn nhận ra, chi phí token đã tăng 40% mà không ai biết vì sao.

Cách duy nhất để tối ưu hóa token bền vững, không phải là một dự án "làm một lần cho xong", là biến nó thành một feedback loop (vòng lặp phản hồi) — một quy trình lặp đi lặp lại có cấu trúc: đo lường liên tục, phát hiện tín hiệu bất thường, đặt giả thuyết, thử nghiệm có kiểm soát, và institutionalize (thể chế hóa — biến thành quy trình chính thức của team) những gì hiệu quả. Bài này trình bày chi tiết bốn phase của vòng lặp đó, cách vận hành từng phase trong thực tế, và cách tự động hóa để nó không phụ thuộc vào ý chí cá nhân của một kỹ sư nào.

Bốn Phase của Vòng lặp Tối ưu hóa Token

Feedback loop tối ưu hóa token gồm bốn phase nối tiếp nhau, lặp lại theo chu kỳ (thường là hàng tuần hoặc hai tuần một lần đối với team có agent chạy production, tùy vào tốc độ thay đổi của hệ thống):

  1. Phase 1 — Measurement (Đo lường): Thu thập số liệu token usage, chi phí, latency và quality theo thời gian thực hoặc gần thời gian thực, đủ chi tiết để phát hiện bất thường.
  2. Phase 2 — Hypothesis (Giả thuyết): Từ các tín hiệu thu được, hình thành các giả thuyết cụ thể ("nếu ta làm X, token sẽ giảm Y%, quality không đổi") và xếp hạng ưu tiên.
  3. Phase 3 — Experiment (Thử nghiệm): Chạy A/B test hoặc thử nghiệm có kiểm soát để kiểm chứng giả thuyết trước khi rollout toàn bộ.
  4. Phase 4 — Ship & Institutionalize (Triển khai & Thể chế hóa): Đưa thay đổi đã được kiểm chứng vào production theo staged rollout, ghi lại bài học, và biến nó thành kiến thức chung của team.

Điểm quan trọng: vòng lặp này không có điểm kết thúc. Sau khi Phase 4 hoàn tất, hệ thống lại tiếp tục được đo lường ở Phase 1, và chu kỳ lặp lại. Token cost là một moving target — model mới ra mắt, traffic pattern thay đổi, feature mới được thêm vào agent — nên optimization phải là một năng lực thường trực (ongoing capability), không phải một sprint riêng lẻ.

Mẹo: Đừng cố chạy đủ bốn phase cho mọi thay đổi nhỏ. Với các optimization "no-brainer" — rõ ràng có lợi, rủi ro gần như bằng không (ví dụ bật prompt caching) — hãy bỏ qua Phase 3 và ship trực tiếp. Dành ngân sách thử nghiệm A/B cho những giả thuyết mà tác động đến quality thật sự chưa rõ ràng.

Phase 1: Đo lường Hệ thống và Phát hiện Tín hiệu

Phase đo lường là nền tảng của toàn bộ vòng lặp — không có dữ liệu đáng tin cậy, bạn sẽ đặt giả thuyết dựa trên cảm tính, và thử nghiệm dựa trên giả thuyết sai sẽ lãng phí thời gian của cả team.

Một hệ thống đo lường tốt cần theo dõi liên tục các chỉ số sau, tách theo từng agent/task và ideally theo từng phiên bản prompt:

  • Token usage per call: input token, output token, cached token (nếu dùng prompt caching), tách riêng để biết phần nào đang "ăn" chi phí.
  • Cost per call và cost per outcome: chi phí tính bằng tiền thật, quy đổi theo pricing hiện hành của provider — không chỉ số token thô, vì pricing giữa input/output/cached token khác nhau đáng kể.
  • Latency: p50/p95/p99, vì nhiều optimization giảm token cũng gián tiếp giảm latency (và ngược lại — cắt token quá tay có thể làm agent phải retry, làm latency tăng).
  • Quality score: điểm chất lượng output (qua rubric tự động, LLM-as-judge, hoặc feedback từ người dùng), để đảm bảo optimization không "ăn cắp" chất lượng để đổi lấy chi phí thấp.

Dữ liệu này nên được đẩy vào một dashboard hoặc data warehouse (ví dụ BigQuery, hoặc một bảng Postgres đơn giản) với timestamp, agent_id, prompt_version, và metadata liên quan, để có thể query theo thời gian và so sánh giữa các phiên bản.

Ba Loại Tín hiệu

Không phải mọi con số bất thường đều đáng để hành động. Trong thực tế, các tín hiệu đáng chú ý rơi vào ba nhóm:

1. Regression (Suy giảm) — token usage hoặc cost tăng lên mà không có lý do rõ ràng, thường là dấu hiệu của technical debt âm thầm tích lũy. Ví dụ điển hình: một kỹ sư thêm một đoạn hướng dẫn mới vào system prompt để xử lý một edge case, nhưng không xóa đoạn cũ đã lỗi thời — kết quả là system prompt phình to dần theo từng lần sửa. Regression thường được phát hiện qua so sánh tuần-với-tuần (week-over-week) hoặc bằng cách đặt alert threshold (ví dụ: cost per call tăng hơn 15% so với baseline 7 ngày trước).

2. Opportunity (Cơ hội) — không có gì "sai", nhưng dữ liệu cho thấy khoảng trống để tối ưu. Ví dụ: một agent luôn trả về output dài 800 token cho một task mà theo yêu cầu nghiệp vụ chỉ cần 150 token là đủ (task chỉ cần trả "yes/no" kèm lý do ngắn, nhưng model đang viết cả đoạn giải thích dài dòng). Opportunity signal thường xuất hiện khi bạn nhìn vào phân phối (distribution) của output length hoặc input token, chứ không phải chỉ nhìn giá trị trung bình.

3. Anomaly (Bất thường đột biến) — một sự thay đổi đột ngột, thường liên quan đến lỗi hệ thống hơn là vấn đề thiết kế prompt. Ví dụ: RAG retrieval bỗng trả về 20 chunk thay vì 5 do một thay đổi config không được review kỹ, hoặc một vòng lặp agent bị stuck và gọi lại tool nhiều lần liên tiếp (retry loop), khiến token usage tăng vọt trong một khoảng thời gian ngắn. Anomaly cần alert gần real-time, vì để lâu có thể gây thiệt hại chi phí lớn trong vài giờ.

Phân loại đúng tín hiệu quan trọng vì nó quyết định mức độ ưu tiên xử lý: anomaly cần xử lý ngay (thường là revert một config), regression cần đưa vào backlog để fix trong sprint gần nhất, còn opportunity có thể xếp vào backlog dài hạn và xử lý khi có capacity.

Mẹo: Thiết lập alert dựa trên thay đổi tương đối (relative change) so với baseline trung bình động (rolling average) 7 hoặc 14 ngày, không dùng ngưỡng tuyệt đối cố định. Traffic pattern theo ngày trong tuần hoặc theo mùa vụ kinh doanh sẽ khiến ngưỡng cố định liên tục báo động giả (false positive) hoặc bỏ lọt vấn đề thật.

Phase 2: Hình thành và Ưu tiên hóa Giả thuyết

Không phải tín hiệu nào cũng đáng được đầu tư thời gian ngang nhau. Sinh giả thuyết (hypothesis generation) vừa là một bài toán sáng tạo, vừa là một bài toán ưu tiên hóa nguồn lực.

Từ mỗi tín hiệu phát hiện ở Phase 1, hãy đặt câu hỏi: "Nếu tôi thay đổi X, tôi kỳ vọng token/cost giảm bao nhiêu, và rủi ro đối với quality là gì?" Một giả thuyết tốt luôn cụ thể, có thể đo lường được, và có thể kiểm chứng bằng thử nghiệm — tránh những giả thuyết mơ hồ như "system prompt có vẻ dài, nên rút ngắn lại".

Backlog Giả thuyết

Duy trì một hypothesis backlog — danh sách có cấu trúc các ý tưởng tối ưu hóa, đủ chi tiết để có thể hành động ngay khi đến lượt ưu tiên. Mỗi item trong backlog nên có đầy đủ các trường thông tin sau, viết dưới dạng một "hồ sơ giả thuyết" chuẩn hóa:

  • Loại tín hiệu: Regression / Opportunity / Anomaly (theo phân loại ở Phase 1).
  • Ngày phát hiệnagent liên quan.
  • Quan sát: mô tả cụ thể bằng số liệu (ví dụ: "system prompt tăng từ 650 lên 1.240 token sau bản cập nhật security guideline tháng 3, chi phí tuần tăng thêm $280").
  • Giả thuyết: hành động cụ thể dự kiến thực hiện và kết quả kỳ vọng (ví dụ: "loại bỏ đoạn văn mở đầu thừa và chuyển checklist bảo mật từ văn xuôi sang dạng bullet gọn sẽ giảm token system prompt từ 1.240 xuống còn khoảng 600, không làm giảm quality").
  • Tác động kỳ vọng: ước tính % token giảm, số lượng call mỗi tuần, và số tiền tiết kiệm mỗi tuần.
  • Rủi ro về quality: đánh giá Thấp/Trung bình/Cao, kèm lý giải ngắn.
  • Thiết kế thử nghiệm dự kiến: kích thước mẫu, thời gian chạy A/B test.
  • Ngưỡng bảo vệ quality (quality guard): điểm quality tối thiểu phải giữ được.
  • Điểm ưu tiên: High / Medium / Low / Critical.

Một hồ sơ giả thuyết mẫu, viết dưới dạng ghi chú backlog, trông như sau:

Giả thuyết: Rút gọn System Prompt của PR Review Agent

- Loại tín hiệu: Regression
- Ngày phát hiện: 2026-05-03
- Agent: pr_review_agent
- Quan sát: System prompt tăng từ 650 token lên 1.240 token sau bản cập
  nhật security guideline tháng 3. Chi phí tuần tăng thêm $280.
- Giả thuyết: Loại bỏ các đoạn "context-setting" trùng lặp và chuyển
  checklist bảo mật từ văn xuôi sang dạng bullet gọn sẽ giảm token
  system prompt từ 1.240 xuống ~600 mà không làm giảm chất lượng review
  (điểm quality hiện tại: 4.3/5.0).
- Tác động kỳ vọng: giảm ~50% token system prompt (640 token/call),
  ~8.500 call/tuần, tiết kiệm ~$95/tuần theo pricing hiện tại.
- Rủi ro quality: Thấp — nội dung bảo mật vẫn được giữ đầy đủ, chỉ
  trình bày gọn hơn.
- Thiết kế thử nghiệm: A/B test, 400 sample/variant, chạy 7 ngày.
- Quality guard: điểm quality >= 4.0/5.0 (hiện tại: 4.3/5.0).
- Điểm ưu tiên: High (tiết kiệm lớn, rủi ro thấp, dễ triển khai).

Ma trận Ưu tiên hóa

Chấm điểm mỗi giả thuyết theo hai chiều: Impact Score (mức tiết kiệm token/chi phí kỳ vọng) và Risk Score (khả năng gây suy giảm quality, điểm thấp hơn = an toàn hơn):

Giả thuyết Impact Score (1-5) Risk Score (1-5, thấp=an toàn) Ưu tiên
Rút gọn system prompt 4 1 High
Bật prompt caching 5 1 Critical
Giảm số chunk RAG từ 8 xuống 5 3 3 Medium
Chuyển từ GPT-4o sang Claude Haiku cho task classification 5 4 Medium
Bỏ few-shot example trong prompt code gen 3 4 Low
Thêm giới hạn độ dài output cho prompt tóm tắt 4 2 High

Hãy xử lý phần đầu ma trận trước. Những giả thuyết impact cao, risk thấp (như bật prompt caching cho system prompt tĩnh) nên được ship ngay, không cần A/B test — vì rủi ro gần như bằng không và lợi ích rõ ràng.

Mẹo: Tách bạch rõ hai nhóm: "tối ưu hóa hiển nhiên" (no-brainer) và "cần thử nghiệm" (needs testing). Bật prompt caching, xóa context trùng lặp, và sửa các lỗi verbosity (dài dòng) rõ ràng trong prompt nên được ship trực tiếp như một cải tiến thông thường. Dành ngân sách A/B testing cho những giả thuyết mà tác động đến quality thực sự chưa chắc chắn.

Phase 3: Chạy Thử nghiệm Tối ưu hóa

Phase thử nghiệm áp dụng phương pháp A/B testing đã trình bày ở bài trước trong module này, nhưng trong bối cảnh feedback loop, tốc độ (velocity) và tính chặt chẽ (rigor) đều quan trọng ngang nhau — không thể chỉ chọn một trong hai.

Đánh đổi giữa Velocity và Rigor trong Thử nghiệm

Một thử nghiệm càng chặt chẽ (mẫu lớn, thời gian chạy dài, nhiều biến kiểm soát) thì càng đáng tin cậy, nhưng cũng càng chậm. Nếu team chỉ chạy 2-3 thử nghiệm mỗi quý vì mỗi thử nghiệm kéo dài ba tuần, backlog giả thuyết sẽ tồn đọng và giá trị tối ưu hóa sẽ đến rất chậm so với tốc độ thay đổi của hệ thống.

Cách thực tế để cân bằng: phân loại thử nghiệm theo mức độ rủi ro của giả thuyết.

  • Rủi ro thấp, impact rõ (ví dụ rút gọn một đoạn văn thừa trong system prompt): chạy thử nghiệm "nhanh" — mẫu nhỏ (100-200 request/variant), thời gian ngắn (2-3 ngày), miễn là đủ để phát hiện suy giảm quality nghiêm trọng.
  • Rủi ro trung bình đến cao (ví dụ đổi model, thay đổi cấu trúc retrieval RAG): chạy thử nghiệm đầy đủ — mẫu đủ lớn để đạt statistical significance (ý nghĩa thống kê), thời gian chạy 7-14 ngày để bắt được biến động theo ngày trong tuần.

Nguyên tắc chung: velocity cao dành cho thay đổi nhỏ, rigor cao dành cho thay đổi có khả năng ảnh hưởng sâu đến trải nghiệm người dùng hoặc độ chính xác nghiệp vụ.

Theo dõi Thử nghiệm trong Feedback Loop

Để feedback loop hoạt động trơn tru, mọi thử nghiệm cần được ghi log tập trung — không chỉ trong đầu người thực hiện hoặc rải rác trong Slack. Một module Python đơn giản để track thử nghiệm có thể trông như sau:

"""
Module theo dõi các thử nghiệm tối ưu hóa token trong feedback loop.
Lưu metadata thử nghiệm, kết quả, và quyết định cuối cùng vào một
data store tập trung (ở đây minh họa bằng SQLite cho gọn).
"""

import sqlite3
import json
import datetime
from dataclasses import dataclass, asdict
from typing import Optional


@dataclass
class ExperimentResult:
    experiment_id: str
    hypothesis: str
    agent_name: str
    variant_a_tokens_avg: float
    variant_b_tokens_avg: float
    variant_a_quality_avg: float
    variant_b_quality_avg: float
    sample_size_a: int
    sample_size_b: int
    started_at: str
    ended_at: Optional[str]
    status: str  # "running" | "shipped" | "rejected" | "inconclusive"
    quality_guard_threshold: float


class ExperimentTracker:
    def __init__(self, db_path: str = "token_experiments.db"):
        self.conn = sqlite3.connect(db_path)
        self._init_schema()

    def _init_schema(self):
        self.conn.execute("""
            CREATE TABLE IF NOT EXISTS experiments (
                experiment_id TEXT PRIMARY KEY,
                payload TEXT NOT NULL,
                status TEXT NOT NULL,
                updated_at TEXT NOT NULL
            )
        """)
        self.conn.commit()

    def start_experiment(self, result: ExperimentResult) -> None:
        self.conn.execute(
            "INSERT INTO experiments (experiment_id, payload, status, updated_at) "
            "VALUES (?, ?, ?, ?)",
            (
                result.experiment_id,
                json.dumps(asdict(result)),
                result.status,
                datetime.datetime.utcnow().isoformat(),
            ),
        )
        self.conn.commit()

    def evaluate_and_close(self, experiment_id: str) -> str:
        """
        Đánh giá kết quả thử nghiệm dựa trên token savings và quality guard.
        Trả về quyết định cuối cùng: "shipped", "rejected", hoặc "inconclusive".
        """
        row = self.conn.execute(
            "SELECT payload FROM experiments WHERE experiment_id = ?",
            (experiment_id,),
        ).fetchone()
        if row is None:
            raise ValueError(f"Experiment {experiment_id} not found")

        data = json.loads(row[0])
        token_reduction_pct = (
            (data["variant_a_tokens_avg"] - data["variant_b_tokens_avg"])
            / data["variant_a_tokens_avg"]
        ) * 100

        quality_ok = data["variant_b_quality_avg"] >= data["quality_guard_threshold"]
        sample_ok = min(data["sample_size_a"], data["sample_size_b"]) >= 100

        if not sample_ok:
            decision = "inconclusive"
        elif quality_ok and token_reduction_pct > 5:
            decision = "shipped"
        else:
            decision = "rejected"

        data["status"] = decision
        data["ended_at"] = datetime.datetime.utcnow().isoformat()
        self.conn.execute(
            "UPDATE experiments SET payload = ?, status = ?, updated_at = ? "
            "WHERE experiment_id = ?",
            (json.dumps(data), decision, data["ended_at"], experiment_id),
        )
        self.conn.commit()
        return decision


if __name__ == "__main__":
    tracker = ExperimentTracker()
    result = ExperimentResult(
        experiment_id="exp-2026-05-07-pr-review-compress",
        hypothesis="Compress PR review system prompt from 1240 to ~600 tokens",
        agent_name="pr_review_agent",
        variant_a_tokens_avg=1240,
        variant_b_tokens_avg=610,
        variant_a_quality_avg=4.3,
        variant_b_quality_avg=4.25,
        sample_size_a=412,
        sample_size_b=408,
        started_at=datetime.datetime.utcnow().isoformat(),
        ended_at=None,
        status="running",
        quality_guard_threshold=4.0,
    )
    tracker.start_experiment(result)
    decision = tracker.evaluate_and_close(result.experiment_id)
    print(f"Experiment decision: {decision}")

Với một tracker như trên, bất kỳ ai trong team đều có thể query lịch sử thử nghiệm, tránh việc lặp lại cùng một giả thuyết đã bị test và reject trước đó (một tình huống rất phổ biến khi kiến thức chỉ nằm trong đầu một vài người).

Mẹo: Luôn lưu lại cả những thử nghiệm bị "rejected" hoặc "inconclusive", không chỉ những thử nghiệm thành công. Biết được điều gì KHÔNG hiệu quả (và tại sao) có giá trị ngang với biết điều gì hiệu quả — nó ngăn team lãng phí thời gian thử lại một hướng đã được chứng minh là không khả thi.

Phase 4: Triển khai, Ghi lại Bài học, và Thể chế hóa

Một thử nghiệm thắng lợi trong A/B test không có nghĩa là công việc đã hoàn tất. Phase cuối cùng của vòng lặp đảm bảo optimization được đưa vào production một cách an toàn, và kiến thức thu được không biến mất sau khi người thực hiện chuyển sang task khác.

Checklist trước khi Ship

Trước khi merge một thay đổi tối ưu hóa token vào production, hãy đi qua checklist sau:

  • [ ] Thử nghiệm A/B đã đạt statistical significance (hoặc đủ mẫu theo tiêu chí đã định trong Phase 3).
  • [ ] Quality guard được thỏa mãn — điểm quality của variant mới không thấp hơn ngưỡng tối thiểu đã đặt ra.
  • [ ] Đã kiểm tra các edge case đặc biệt (input rất dài, input rất ngắn, input đa ngôn ngữ nếu áp dụng) không bị ảnh hưởng tiêu cực.
  • [ ] Có kế hoạch rollback rõ ràng — biết chính xác cách revert nếu có vấn đề phát sinh sau khi ship.
  • [ ] Đã thông báo cho các bên liên quan (stakeholder) nếu thay đổi ảnh hưởng đến hành vi hiển thị với người dùng cuối.
  • [ ] Dashboard đo lường (Phase 1) đã được cập nhật để theo dõi metric mới sau khi rollout.

Triển khai Staged Rollout

Đừng bao giờ đẩy một optimization đã test thành công ra 100% traffic ngay lập tức. Staged rollout (triển khai theo từng giai đoạn) — tăng dần tỷ lệ traffic nhận thay đổi mới, đồng thời theo dõi chặt các chỉ số — giúp giảm thiểu thiệt hại nếu có vấn đề mà A/B test chưa phát hiện ra (ví dụ một edge case hiếm chỉ xuất hiện ở quy mô lớn).

Một cấu hình staged rollout điển hình: 5% traffic ngày đầu, 25% sau 24 giờ nếu không có cảnh báo, 100% sau 72 giờ. Đoạn code sau minh họa logic giám sát trong khi staged rollout đang chạy:

"""
Giám sát các chỉ số quality và cost trong khi một optimization đang
được staged rollout. Tự động tạm dừng rollout (pause) và gửi cảnh báo
nếu quality guard bị vi phạm.
"""

import time
import logging
from dataclasses import dataclass

logger = logging.getLogger("staged_rollout_monitor")

ROLLOUT_STAGES = [
    {"stage": 1, "traffic_pct": 5, "min_duration_hours": 24},
    {"stage": 2, "traffic_pct": 25, "min_duration_hours": 24},
    {"stage": 3, "traffic_pct": 100, "min_duration_hours": 0},
]


@dataclass
class StageMetrics:
    quality_avg: float
    error_rate: float
    cost_per_call_avg: float


def check_stage_health(
    metrics: StageMetrics,
    quality_guard: float,
    max_error_rate: float = 0.02,
) -> tuple[bool, str]:
    """Trả về (is_healthy, reason)."""
    if metrics.quality_avg < quality_guard:
        return False, (
            f"Quality {metrics.quality_avg:.2f} dưới ngưỡng "
            f"{quality_guard:.2f} — pause rollout"
        )
    if metrics.error_rate > max_error_rate:
        return False, (
            f"Error rate {metrics.error_rate:.2%} vượt ngưỡng "
            f"{max_error_rate:.2%} — pause rollout"
        )
    return True, "OK"


def advance_rollout(current_stage: int, metrics: StageMetrics, quality_guard: float):
    is_healthy, reason = check_stage_health(metrics, quality_guard)
    if not is_healthy:
        logger.error(
            "Rollout stage %s FAILED health check: %s. Rolling back to 0%%.",
            current_stage,
            reason,
        )
        # Gọi vào feature-flag service để set traffic_pct = 0 ngay lập tức
        return {"action": "rollback", "reason": reason}

    next_stage = current_stage + 1
    if next_stage > len(ROLLOUT_STAGES):
        logger.info("Rollout completed successfully at 100%% traffic.")
        return {"action": "complete"}

    logger.info(
        "Stage %s healthy. Advancing to stage %s (%s%% traffic).",
        current_stage,
        next_stage,
        ROLLOUT_STAGES[next_stage - 1]["traffic_pct"],
    )
    return {"action": "advance", "next_stage": next_stage}

Điểm quan trọng cần nhớ: staged rollout không chỉ để "an toàn hơn về mặt kỹ thuật" — nó còn cho phép bạn phát hiện các vấn đề về quality mà chỉ xuất hiện với volume traffic lớn hơn những gì A/B test ban đầu có thể mô phỏng.

Ghi lại Bài học

Sau khi một optimization được ship thành công (hoặc bị reject), hãy ghi lại bài học vào một nơi mà cả team có thể tra cứu sau này — không chỉ trong commit message hay Slack thread sẽ bị trôi mất. Nội dung ghi lại nên bao gồm: giả thuyết ban đầu, kết quả thử nghiệm thực tế (có khớp với kỳ vọng không, sai lệch bao nhiêu và tại sao), và — quan trọng nhất — bài học tổng quát có thể áp dụng cho các agent hoặc prompt khác trong hệ thống.

Mẹo: Việc ghi lại bài học có giá trị nhất khi nó trả lời được câu hỏi "lần sau gặp tình huống tương tự, ta nên làm gì khác đi?" — không chỉ mô tả lại những gì đã xảy ra. Một dòng "chúng tôi giảm 50% system prompt và không mất quality" kém giá trị hơn nhiều so với "loại bỏ đoạn văn giải thích lặp lại là an toàn ở mọi agent dùng cùng base prompt template, nhưng compress checklist thành bullet chỉ an toàn khi checklist có dưới 10 item — với checklist dài hơn, quality giảm đáng kể vì model bỏ sót item".

Các Tối ưu hóa Đã được Chứng minh (Cập nhật: 2026-05-10)

Sau nhiều vòng lặp feedback loop chạy trên các agent production khác nhau, một số pattern tối ưu hóa đã được kiểm chứng lặp lại nhiều lần với kết quả nhất quán, đến mức có thể coi là "mặc định nên áp dụng" thay vì phải test lại từ đầu mỗi lần.

Kiểm soát Verbosity của Output

Yêu cầu rõ ràng về format và độ dài mong muốn trong system prompt (ví dụ: "trả lời trong tối đa 3 câu", "chỉ trả JSON theo schema, không giải thích thêm") gần như luôn giảm được 30-60% output token mà không ảnh hưởng đến chất lượng thông tin truyền tải, với điều kiện là schema/format được định nghĩa đủ rõ để model không "bù" bằng cách viết dài ở phần khác. Đây là optimization có risk/reward tốt nhất trong toàn bộ danh sách — rủi ro gần bằng không, lợi ích lớn, và áp dụng được cho hầu hết agent.

Rút gọn System Prompt

System prompt có xu hướng phình to theo thời gian do "context creep" — mỗi lần sửa lỗi hoặc thêm yêu cầu mới, ai đó thêm một đoạn hướng dẫn mà không xóa đoạn cũ đã lỗi thời. Rà soát và rút gọn system prompt định kỳ (khuyến nghị mỗi quý) thường thu hồi được 20-40% token của system prompt mà không giảm quality, vì phần lớn nội dung dư thừa là các đoạn trùng lặp hoặc hướng dẫn đã không còn áp dụng.

Quản lý Context của RAG

Nhiều pipeline RAG (Retrieval-Augmented Generation) retrieve nhiều chunk hơn mức cần thiết "cho chắc" — retrieve top-10 hoặc top-15 chunk trong khi top-5 đã đủ thông tin cho hầu hết câu hỏi. Giảm số chunk retrieve, kết hợp với re-ranking (xếp hạng lại) để đảm bảo các chunk quan trọng nhất được giữ, thường giảm 30-50% token context mà chất lượng câu trả lời không đổi hoặc thậm chí cải thiện (vì loại bỏ được nhiễu — noise — từ các chunk ít liên quan gây phân tán cho model).

Mẹo: Ba pattern trên nên là điểm khởi đầu mặc định cho bất kỳ agent mới nào, không cần chờ tín hiệu regression mới áp dụng — hãy audit output verbosity, system prompt, và RAG chunk count ngay khi agent chuyển sang production, trước khi vòng lặp feedback loop chính thức bắt đầu.

Tự động hóa Feedback Loop

Feedback loop chạy thủ công (một kỹ sư tự tay chạy query, tự đọc dashboard mỗi tuần) sẽ dần bị bỏ quên khi công việc khác bận rộn hơn. Để vòng lặp bền vững, cần tự động hóa tối đa các bước phát hiện tín hiệu và kiểm tra regression.

Phát hiện Regression và Cảnh báo Tự động

Một script chạy định kỳ, so sánh metric hiện tại với baseline trung bình động, và gửi cảnh báo khi phát hiện lệch bất thường, giúp Phase 1 của vòng lặp hoạt động mà không cần ai chủ động kiểm tra:

"""
Script chạy hàng ngày (qua cron hoặc scheduled job) để phát hiện
regression về token usage/cost so với baseline 14 ngày gần nhất.
Gửi cảnh báo qua webhook (ví dụ Slack) khi phát hiện lệch bất thường.
"""

import requests
import statistics
from dataclasses import dataclass

SLACK_WEBHOOK_URL = "https://hooks.slack.com/services/REPLACE/WITH/YOUR_WEBHOOK"
REGRESSION_THRESHOLD_PCT = 15  # % tăng so với baseline được coi là regression


@dataclass
class DailyMetric:
    agent_name: str
    date: str
    avg_cost_per_call: float


def fetch_last_n_days(agent_name: str, days: int = 15) -> list[DailyMetric]:
    """
    Trong hệ thống thực tế, hàm này query từ data warehouse
    (BigQuery, Snowflake, hoặc Postgres). Ở đây minh họa với dữ liệu giả.
    """
    # TODO: thay bằng query thực tế tới observability store
    raise NotImplementedError("Kết nối tới data warehouse tại đây")


def check_regression(metrics: list[DailyMetric]) -> dict | None:
    if len(metrics) < 8:
        return None  # chưa đủ dữ liệu để so sánh đáng tin cậy

    *baseline_days, today = metrics
    baseline_avg = statistics.mean(m.avg_cost_per_call for m in baseline_days)
    change_pct = ((today.avg_cost_per_call - baseline_avg) / baseline_avg) * 100

    if change_pct > REGRESSION_THRESHOLD_PCT:
        return {
            "agent_name": today.agent_name,
            "baseline_avg": round(baseline_avg, 4),
            "today_avg": round(today.avg_cost_per_call, 4),
            "change_pct": round(change_pct, 1),
        }
    return None


def send_slack_alert(regression: dict) -> None:
    message = (
        f":rotating_light: *Token cost regression detected*\n"
        f"Agent: `{regression['agent_name']}`\n"
        f"Baseline (14-day avg): ${regression['baseline_avg']}/call\n"
        f"Today: ${regression['today_avg']}/call "
        f"(+{regression['change_pct']}%)\n"
        f"Action: add to hypothesis backlog for review this sprint."
    )
    requests.post(SLACK_WEBHOOK_URL, json={"text": message}, timeout=10)


def main():
    agents = ["pr_review_agent", "support_triage_agent", "code_gen_agent"]
    for agent_name in agents:
        metrics = fetch_last_n_days(agent_name)
        regression = check_regression(metrics)
        if regression:
            send_slack_alert(regression)


if __name__ == "__main__":
    main()

Đặt script này chạy hàng ngày qua cron (0 7 * * * python detect_token_regressions.py) hoặc qua scheduled job trên nền tảng CI/CD, để Phase 1 diễn ra tự động mỗi ngày, còn con người chỉ cần xử lý khi có cảnh báo thực sự.

Tích hợp với CI/CD: Phát hiện Thay đổi Prompt

Một nguồn regression phổ biến là thay đổi prompt được merge vào production mà không ai đánh giá tác động đến token budget (ngân sách token đã định trước cho từng agent). Tích hợp một bước kiểm tra vào CI/CD pipeline giúp bắt được vấn đề này ngay tại pull request, trước khi code chạm production:

name: Token Budget Check

on:
  pull_request:
    paths:
      - "prompts/**"
      - "agents/**/system_prompt.md"

jobs:
  check-token-budget:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Install dependencies
        run: pip install tiktoken pyyaml

      - name: Compare token count against baseline
        run: |
          python .github/scripts/check_token_budget.py \
            --base-ref "${{ github.event.pull_request.base.sha }}" \
            --head-ref "${{ github.event.pull_request.head.sha }}" \
            --budget-config token_budgets.yml \
            --fail-on-exceed

      - name: Post PR comment with token diff
        if: always()
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const report = fs.readFileSync('token_diff_report.md', 'utf8');
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: report,
            });

File token_budgets.yml được tham chiếu ở trên định nghĩa ngân sách token tối đa cho phép mỗi agent (ví dụ pr_review_agent: 900), và script check_token_budget.py sẽ tính token count của prompt mới (dùng tiktoken hoặc tokenizer tương ứng với model đang dùng), so sánh với ngân sách, và fail CI nếu vượt ngưỡng — buộc tác giả PR phải xem xét lại hoặc xin approval rõ ràng nếu việc tăng token là có chủ đích.

Mẹo: Đừng để bước CI check này fail cứng ngay từ ngày đầu triển khai — hãy chạy ở mode "warning only" (chỉ comment vào PR, không block merge) trong 2-3 tuần đầu để team làm quen và điều chỉnh ngân sách token cho hợp lý, trước khi chuyển sang mode "fail-on-exceed" bắt buộc.

Tổng kết

Tối ưu hóa token không phải là một dự án có điểm kết thúc, mà là một năng lực vận hành liên tục, giống như monitoring hiệu năng hệ thống hay quản lý bảo mật. Bốn phase của vòng lặp — đo lường có hệ thống, sinh và ưu tiên hóa giả thuyết, thử nghiệm có kiểm soát, và triển khai kèm ghi lại bài học — tạo thành một quy trình lặp lại được, không phụ thuộc vào trí nhớ hay sự chủ động của một cá nhân riêng lẻ.

Ba nhóm optimization đã được chứng minh hiệu quả nhất quán — kiểm soát verbosity output, rút gọn system prompt, và quản lý context RAG — nên là điểm khởi đầu mặc định cho mọi agent mới, thay vì chờ đến khi phát hiện regression mới xử lý. Và quan trọng không kém: tự động hóa việc phát hiện regression và tích hợp kiểm tra token budget vào CI/CD giúp vòng lặp này tồn tại bền vững qua thời gian, thay vì phai nhạt dần sau vài tháng khi áp lực công việc khác tăng lên.

Một team vận hành feedback loop này nghiêm túc sẽ không chỉ giảm chi phí AI agent một lần, mà xây dựng được một hệ thống miễn nhiễm với "token creep" — khả năng chi phí âm thầm phình to theo thời gian mà không ai chủ động nhận ra, cho đến khi hóa đơn cuối tháng gây bất ngờ.