·

Tiếng Việt: Continuous feedback, autonomous execution, and regression analysis

Continuous feedback, autonomous execution, and regression analysis

Một pipeline CI/CD chạy test là chưa đủ để gọi là "agentic QA". Cái làm nên khác biệt là vòng lặp phản hồi (feedback loop): kết quả test không chỉ dừng lại ở màn hình đỏ/xanh trên Slack, mà được một agent đọc, diễn giải, phân loại, và — quan trọng nhất — đưa ngược trở lại giai đoạn lập kế hoạch test (test planning) để cải thiện chu kỳ tiếp theo.

Ở các chương trước trong Module 8, bạn đã thấy agent lên kế hoạch test, sinh test case, sinh test automation, và thực hiện exploratory testing. Chương này là mảnh ghép khép vòng: sau khi test chạy xong — thường là tự động, không cần ai bấm nút — điều gì xảy ra tiếp theo? Ai đọc kết quả? Làm sao phân biệt một regression thật với một flaky test vô hại? Và làm sao những gì học được từ 100 lần chạy test tuần này thực sự làm cho tuần sau thông minh hơn, thay vì lặp lại y hệt?

Đây là bài toán vận hành (operational) chứ không phải bài toán công cụ. Bạn có thể có agent xịn nhất, prompt hay nhất, nhưng nếu team vẫn phải tự tay đọc hàng trăm dòng log mỗi sáng, hoặc mỗi PR đều bị block bởi một flaky test đã tồn tại từ ba tháng trước, thì "agentic" chỉ là cái nhãn dán lên một quy trình vẫn thủ công ở phần quan trọng nhất.

Cơ chế thực thi test tự động hoạt động ra sao và kết quả đến với team như thế nào?

Trước khi nói đến AI diễn giải kết quả, cần có một nền tảng thực thi (execution) đáng tin cậy, chạy đúng lịch, đúng phạm vi, và đẩy kết quả tới đúng người — đúng định dạng để đọc trong 30 giây, không phải 30 phút.

Kiến Trúc Thực Thi Tự Động (The Autonomous Execution Architecture)

Một kiến trúc thực thi tự động thường có bốn lớp, độc lập nhau nhưng nối tiếp:

  1. Trigger layer — cái gì khởi động lần chạy: theo lịch (scheduled, ví dụ 2h sáng mỗi ngày), theo sự kiện (event, ví dụ merge vào main, tag release), hoặc theo yêu cầu thủ công (manual dispatch) khi QA lead muốn chạy full regression trước khi release.
  2. Execution layer — nơi test thực sự chạy: runner CI/CD (GitHub Actions, GitLab CI, Jenkins...), có thể chạy song song (parallel/sharded) để một bộ 2.000 test case không mất 4 giờ.
  3. Aggregation layer — thu thập kết quả từ nhiều shard/nhiều môi trường (staging, các browser khác nhau...) thành một bộ dữ liệu thống nhất: JUnit XML, JSON report, coverage report.
  4. Interpretation & delivery layer — đây là lớp mà agent tham gia: đọc dữ liệu thô, diễn giải, sinh báo cáo dễ đọc, và đẩy tới nơi con người thực sự nhìn thấy (Slack channel, email, dashboard nội bộ, comment trên PR).

Điểm agentic hóa nằm ở lớp 4. Ba lớp đầu là hạ tầng CI/CD truyền thống — bạn có thể đã có sẵn. Cái thiếu ở hầu hết team là lớp diễn giải: dữ liệu thô (raw JUnit XML với 2.000 test case) không phải là thứ con người muốn đọc mỗi sáng. Agent đứng ở giữa, biến dữ liệu thô thành nhận định (insight) có thể hành động.

Một nguyên tắc thiết kế đáng nhớ ở lớp này: đừng để agent diễn giải chạy trong cùng job với test execution. Tách thành job riêng (hoặc workflow riêng, trigger bởi workflow_run) nhận input là artifact kết quả test — nếu agent bị lỗi (rate limit, timeout khi gọi model), bạn không muốn nó làm fail luôn cả pipeline test vốn đã tốn 40 phút chạy.

Cấu Hình Lịch Thực Thi Tự Động (Configuring the Autonomous Execution Schedule)

Việc chọn lịch chạy là một quyết định có đánh đổi thật, không phải chi tiết kỹ thuật vụn vặt. Chạy quá thường xuyên (mỗi commit) thì tốn chi phí compute và chi phí gọi model để diễn giải; chạy quá thưa (mỗi tuần) thì khi phát hiện regression, thủ phạm có thể là một trong 40 commit đã merge — thông tin gần như vô dụng, không còn biết bắt đầu điều tra từ đâu.

Cấu hình phổ biến và hợp lý cho nhiều team: full regression suite chạy theo lịch qua đêm (nightly), còn smoke test / test liên quan trực tiếp tới thay đổi chạy trên mỗi PR.

name: Nightly Regression Suite

on:
  schedule:
    - cron: "0 19 * * *"  # 2:00 AM Vietnam time (UTC+7)
  workflow_dispatch:       # allow manual trigger when needed

jobs:
  run-regression:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        shard: [1, 2, 3, 4]
    steps:
      - uses: actions/checkout@v4
      - name: Run test shard
        run: npx playwright test --shard=${{ matrix.shard }}/4
      - uses: actions/upload-artifact@v4
        with:
          name: test-results-${{ matrix.shard }}
          path: test-results/

  interpret-results:
    needs: run-regression
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@v4
      - name: Run AI interpretation agent
        run: node scripts/interpret-and-report.js
      - name: Post report to Slack
        run: node scripts/post-to-slack.js

Chọn giờ chạy cũng đáng suy nghĩ: 2h sáng theo giờ Việt Nam nghĩa là báo cáo đã sẵn sàng khi team bắt đầu ngày làm việc — không ai phải chờ, và không ai chạy vào giờ tải cao của hạ tầng staging/shared environment.

Team Nhìn Thấy Gì: Thiết Kế Báo Cáo (What the Team Sees: Report Design)

Đây là phần dễ bị đánh giá thấp nhất — và cũng là phần quyết định liệu cả hệ thống có được tin dùng hay không. Một báo cáo tốt phải trả lời được câu hỏi "tôi có cần làm gì ngay bây giờ không?" trong vòng vài giây đầu, trước khi người đọc phải cuộn xuống chi tiết.

Cấu trúc báo cáo nên đi từ tổng quan xuống chi tiết, với một chỉ số sức khỏe (health status) rõ ràng ngay đầu:

Daily Regression Report — 2024-01-15
Health Status: AMBER

Failures Requiring Action (2)
- checkout.spec.ts › applies promo code before payment
  → Likely cause: promo validation endpoint returns 500 for codes >10 chars
  → Introduced in: PR #4821 (merged 14:32 yesterday)
- payment.spec.ts › retries on gateway timeout
  → Likely cause: mock gateway timeout threshold changed, real assertion now flaky-looking
  → Introduced in: PR #4819

Flaky Tests (Investigate, Not Urgent) (3)
- search.spec.ts › returns results within 2s
  → Failed 2/10 runs this week, consistent with known infra latency on staging DB
- notifications.spec.ts › shows toast on save
  → Failed 1/10 runs, race condition suspected (animation timing)

No Action Needed (1,847 passed, 6 skipped by design)

Next Steps
1. Assign checkout.spec.ts failure to owner of PR #4821 (@minh.tran)
2. Confirm payment.spec.ts is a real regression or timeout config drift
3. Flaky tests logged to known-issues.md — no blocking action this cycle

Chỉ số Health Status (GREEN / AMBER / RED) là chi tiết nhỏ nhưng có tác dụng lớn về mặt tâm lý vận hành: một QA lead bận rộn, mở báo cáo lúc 8h sáng, cần biết trong 2 giây liệu hôm nay có "cháy nhà" hay không, trước khi quyết định có đọc tiếp hay không. AMBER nghĩa là "có việc cần xem, nhưng chưa cần dừng mọi thứ" — khác hẳn RED ("có regression chặn release") và GREEN ("mọi thứ ổn, lướt qua báo cáo trong 10 giây rồi làm việc khác").

Mẹo: Đặt "Next Steps" ở cuối báo cáo, không phải ở đầu — con người cần thấy dữ liệu (bao nhiêu fail, fail gì) trước khi tin vào kết luận của agent. Nếu "Next Steps" xuất hiện ngay đầu mà không có evidence phía trên, người đọc sẽ hoài nghi và bỏ qua toàn bộ agent output — kể cả những lần nó đúng.

Làm sao dùng AI để diễn giải kết quả test — failure, flakiness, và coverage delta?

Diễn giải kết quả không phải là "đưa log cho AI, AI tóm tắt". Diễn giải đúng nghĩa nghĩa là phân loại failure theo nguyên nhân, phát hiện được test nào không đáng tin (flaky), và hiểu coverage đã thay đổi ra sao sau một thay đổi code — ba việc khác nhau, cần ba cách tiếp cận khác nhau.

Diễn Giải Failure: Phân Loại Nguyên Nhân Gốc (Failure Interpretation: Root Cause Classification)

Khi một test fail, câu hỏi đầu tiên không phải "test này pass hay fail" — bạn đã biết nó fail — mà là "fail vì cái gì". Có ít nhất 5 nhóm nguyên nhân gốc (root cause) khác nhau, và mỗi nhóm cần hành động khác nhau:

  • Regression thật — code thay đổi làm hỏng hành vi đúng đắn. Cần block PR / báo bug ngay.
  • Test lỗi thời (outdated test) — hành vi mới là chủ đích (feature thay đổi có chủ ý), nhưng test chưa được cập nhật. Cần sửa test, không sửa code.
  • Vấn đề môi trường/hạ tầng — DB staging chậm, service phụ thuộc down, rate limit của third-party API. Không liên quan gì đến code.
  • Flaky do race condition/timing — test tự thân không ổn định, fail ngẫu nhiên không phụ thuộc code thay đổi.
  • Lỗi test data — dữ liệu seed bị người khác sửa, hoặc test phụ thuộc vào state để lại từ lần chạy trước.

Prompt diễn giải hiệu quả cho agent cần cung cấp đủ ngữ cảnh để phân loại được nhóm này, không chỉ đưa error message:

You are analyzing a failed test. Classify the root cause into one of:
REGRESSION, OUTDATED_TEST, ENVIRONMENT_ISSUE, FLAKY_TIMING, TEST_DATA_ISSUE.

Test: checkout.spec.ts › applies promo code before payment
Error: Expected status 200, received 500
Stack trace: [...]
Test file diff (last 30 days): [no changes]
Application code diff (last 24h) touching related paths: [PR #4821 diff]
Historical pass rate (last 20 runs): 20/20 passed before this run

Output: classification + one-sentence justification + confidence (high/medium/low).

Việc đưa vào historical pass rate và application diff gần nhất là mấu chốt — không có hai dữ liệu này, agent chỉ đang đoán dựa trên error message, độ chính xác sẽ thấp hơn nhiều so với việc con người tự đọc.

Phát Hiện và Phân Tích Flakiness (Flakiness Detection and Analysis)

Flaky test — test mà cùng một code, chạy nhiều lần, cho kết quả khác nhau — là kẻ thù âm thầm phá hoại niềm tin vào pipeline. Một khi team quen với việc "à, cái đó chắc flaky thôi, chạy lại xem", thì ngày một regression thật xảy ra và trông giống flaky, không ai còn phản ứng kịp.

Cách phát hiện flakiness đáng tin cậy nhất không phải hỏi AI "test này có flaky không" dựa trên một lần chạy — mà là thu thập dữ liệu từ nhiều lần chạy liên tiếp (thường 3 lần trở lên trên cùng một commit) rồi mới đưa cho agent phân tích pattern:

Analyze the following test results across 3 consecutive runs on the same commit (abc1234):

Run 1: search.spec.ts › returns results within 2s → FAIL (timeout at 2.4s)
Run 2: search.spec.ts › returns results within 2s → PASS (1.1s)
Run 3: search.spec.ts › returns results within 2s → FAIL (timeout at 2.6s)

Run 1: checkout.spec.ts › applies promo code → FAIL
Run 2: checkout.spec.ts › applies promo code → FAIL
Run 3: checkout.spec.ts › applies promo code → FAIL

For each test, classify as FLAKY (inconsistent results, same code) or
CONSISTENT_FAILURE (same code, always fails — likely real regression).
Include the failure rate and suspected cause pattern (e.g. timing threshold,
resource contention) for FLAKY tests.

Nguyên tắc vàng: test fail 3/3 lần trên cùng một commit gần như chắc chắn không phải flaky — nó là consistent failure (lỗi tái diễn đều, không phải flaky), cần điều tra như regression thật. Test fail 1-2/3 lần mới là ứng viên flaky thực sự. Đây là lý do tại sao chạy 1 lần rồi kết luận "flaky" là một antipattern (thói làm sai phổ biến) nguy hiểm — rất dễ dùng nhãn "flaky" để né tránh một regression thật.

Phân Tích Coverage Delta (Coverage Delta Analysis)

Coverage delta — sự thay đổi độ phủ test trước và sau một thay đổi code — thường bị bỏ qua vì con số coverage tổng (ví dụ "82% → 81.8%") không nói lên điều gì hữu ích. Cái đáng quan tâm là coverage delta ở mức file/function, đặc biệt là những dòng code mới thêm vào mà không có test nào chạm tới.

Quy trình thực tế: capture coverage report trước khi merge PR (từ branch main) và sau khi merge (từ branch mới), rồi diff hai báo cáo ở cấp độ dòng code:

Compare coverage reports:
- Baseline (main, before PR #4821): coverage-baseline.json
- Current (after PR #4821): coverage-current.json

Identify:
1. New code (added lines) with 0% coverage — list file + line ranges
2. Existing covered code that lost coverage (test removed or path unreachable now)
3. Overall delta by module, not just repo-wide percentage

Flag as HIGH_RISK any uncovered new code in: payment/, checkout/, auth/

Việc chỉ định rõ những thư mục "HIGH_RISK" (payment, checkout, auth) trong prompt là quan trọng — coverage delta ở một hàm helper hiển thị UI không đáng lo bằng coverage delta ở logic xử lý thanh toán. Agent cần biết đâu là vùng rủi ro cao của hệ thống bạn, không phải một quy tắc coverage chung chung.

Mẹo: Khi báo cáo coverage delta cho team, đừng bao giờ chỉ đưa con số phần trăm tổng. Một PR thêm 500 dòng test cho một module ít rủi ro có thể làm coverage tổng tăng đẹp mắt, trong khi 20 dòng logic thanh toán mới hoàn toàn không có test lại bị con số tổng che khuất. Luôn báo theo module, ưu tiên hiển thị vùng rủi ro cao trước.

Làm sao dùng AI để phân biệt failure mới với vấn đề đã tồn tại từ trước?

Đây có thể là năng lực agentic quan trọng nhất trong toàn chương, vì nó giải quyết trực tiếp một trong những nguyên nhân hàng đầu khiến team mất niềm tin vào pipeline: PR bị block bởi một test đã fail từ ba tuần trước, không liên quan gì tới thay đổi hiện tại.

Yêu Cầu Dữ Liệu Để Phân Loại (The Classification Data Requirements)

Để agent phân loại đúng "failure này có phải do PR này gây ra không", nó cần ba loại dữ liệu, thiếu một trong ba là phân loại sẽ sai:

  1. Baseline — trạng thái pass/fail của toàn bộ test suite trên main, ngay trước khi PR được mở (hoặc lần chạy gần nhất trên main).
  2. Kết quả hiện tại — trạng thái pass/fail trên branch của PR, sau khi áp thay đổi.
  3. Lịch sử test đó — test này đã từng fail trên main bao lâu rồi, có phải "known issue" đã được ghi nhận chưa.

Không có baseline, mọi failure trông giống nhau — agent (và con người) không có cách nào biết PR có "gây ra" failure đó hay không, chỉ biết nó đang fail.

Xây Dựng Baseline Record (Building the Baseline Record)

Baseline cần được duy trì như một nguồn dữ liệu sống, cập nhật tự động mỗi khi có thay đổi trên main — không phải một file tĩnh viết tay một lần rồi bỏ quên.

name: Update Test Baseline

on:
  push:
    branches: [main]

jobs:
  update-baseline:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run full test suite
        run: npx playwright test --reporter=json > results.json
      - name: Update baseline record
        run: node scripts/update-baseline.js results.json
      - name: Commit baseline
        run: |
          git add baseline/test-status.json
          git commit -m "chore: update test baseline [skip ci]"
          git push

Baseline record nên lưu tối thiểu: tên test, trạng thái (pass/fail), số lần fail liên tiếp trên main, và ngày fail đầu tiên được ghi nhận — đủ để agent trả lời "test này đã fail trên main từ bao lâu rồi, có phải mới hôm nay không".

Prompt Phân Loại Failure Mới vs. Đã Tồn Tại (The New-vs-Pre-Existing Classification Prompt)

Với baseline đã có, prompt phân loại trở nên khá trực tiếp — về bản chất là một phép so sánh tập hợp (set comparison), nhưng vẫn cần AI để diễn giải các trường hợp không rõ ràng (ví dụ test fail với lỗi khác trên PR so với trên baseline, dù cùng tên test):

Compare test results:
- Baseline (main, as of commit def5678): baseline/test-status.json
- PR branch results (PR #4821, commit abc1234): pr-results.json

For every failing test on the PR branch:
1. If it also fails on baseline with the SAME error signature → PRE_EXISTING
2. If it passes on baseline but fails on PR branch → NEW
3. If it fails on baseline but with a DIFFERENT error on PR branch →
   flag as NEW (the failure mode changed, needs investigation even if the
   test was already flaky)

Output a Failure Classification Report with a blocking recommendation.

Kết quả mong đợi là một báo cáo có thể đưa trực tiếp vào comment trên PR:

Failure Classification Report — PR #4821

New Failures (introduced by this PR) — 1
- checkout.spec.ts › applies promo code before payment
  Baseline: PASS → PR branch: FAIL (500 error)
  → Recommendation: BLOCK MERGE, requires fix or explicit override

Pre-Existing Failures (not caused by this PR) — 2
- search.spec.ts › returns results within 2s (known flaky, tracked in known-issues.md#SEARCH-042)
- reports.spec.ts › exports PDF within 5s (failing on main since 2024-01-08, JIRA-2291)
  → Recommendation: Does not block this PR, already tracked

Blocking Recommendation: BLOCK — 1 new failure requires resolution before merge.

Chú ý quy tắc số 3 trong prompt: nếu một test vốn đã biết flaky nhưng lần này fail với error signature khác hẳn (ví dụ trước là timeout, giờ là 500 error), agent vẫn phải flag là NEW. Đây là chỗ nhiều hệ thống phân loại đơn giản (chỉ so tên test) mắc lỗi — chúng coi mọi lần fail của một "known flaky test" là an toàn để bỏ qua, kể cả khi bản chất lỗi đã đổi.

Mẹo: Luôn yêu cầu agent so khớp theo error signature (loại lỗi + stack trace pattern), không chỉ theo tên test. Một test "known issue" có thể đang che giấu một regression thật hoàn toàn khác, chỉ vì nó tình cờ trùng tên với vấn đề cũ.

Làm sao khép vòng lặp agentic bằng cách đưa kết quả CI ngược lại giai đoạn lập kế hoạch?

Đây là bước mà hầu hết team dừng lại — họ có báo cáo đẹp, có phân loại chính xác, nhưng dữ liệu đó chỉ nằm im trong Slack channel, không bao giờ chảy ngược về nơi quyết định test gì, ưu tiên gì cho chu kỳ tiếp theo. Khép vòng lặp nghĩa là biến mọi kết quả CI thành input cho agent lập kế hoạch test ở chương 2 của module này.

Dữ Liệu Phản Hồi Khép Vòng Lặp (The Feedback Data That Closes the Loop)

Không phải mọi dữ liệu CI đều đáng đưa vào planning — cần chọn lọc những gì thực sự thay đổi cách bạn đánh giá rủi ro:

  • Tần suất và vị trí regression thật trong N chu kỳ gần nhất — module nào liên tục sinh ra bug dù đã có test?
  • Danh sách flaky test và nguyên nhân gốc đã xác định — để tránh lặp lại việc "phát hiện lại" cùng một flaky test mỗi tuần.
  • Vùng coverage yếu lặp lại — module nào liên tục có coverage delta thấp mỗi khi có PR chạm vào?
  • Độ chính xác của risk model (mô hình đánh giá rủi ro) trước đó — những rủi ro agent đánh giá "HIGH" ở vòng lập kế hoạch trước có thực sự là nơi bug xuất hiện không, hay bug lại nằm ở nơi được đánh giá "LOW"?

Prompt Tích Hợp Phản Hồi (The Feedback Integration Prompt)

Analyze the last 4 weeks of CI feedback data (attached: regression log,
flaky test log, coverage deltas, and the risk model used for test planning
during this period).

Produce a report with four sections:
1. Risk Model Calibration — where did actual regressions occur vs. where
   the risk model predicted HIGH risk? Identify miscalibrations.
2. Coverage Pattern Analysis — which modules repeatedly show coverage gaps
   after changes, despite prior recommendations?
3. Persistent Context Updates Needed — specific, concrete edits to
   CLAUDE.md risk weights or test strategy notes.
4. Process Improvements — changes to the execution/reporting process
   itself (schedule, thresholds, escalation rules).

Ví dụ output thực tế cho phần 1 và 3, sau khi phát hiện risk model đã đánh giá thấp rủi ro của luồng thanh toán:

1. Risk Model Calibration
   - Payment flow changes were rated HIGH risk in test planning, but 3 of 4
     regressions this cycle involved payment flow edge cases (promo codes,
     partial refunds, currency rounding) that HIGH-risk test plans did not
     specifically target.
   - Address validation changes were rated LOW/MEDIUM risk, but 2 regressions
     traced back to address format changes affecting payment tax calculation.

3. Persistent Context Updates Needed
   - CLAUDE.md: escalate "Payment flow changes: always HIGH risk" to
     "always CRITICAL risk — requires manual QA review before merge"
   - CLAUDE.md: add new rule "Address validation changes: HIGH risk —
     adjacent to payment flow, verify tax/shipping calculation paths"

Áp Dụng Các Cập Nhật (Applying the Updates)

Một nguyên tắc vận hành quan trọng: agent đề xuất, con người xét duyệt và áp dụng thủ công — ít nhất là ở giai đoạn đầu triển khai hệ thống này. Đừng để agent tự sửa CLAUDE.md hoặc risk weight (trọng số rủi ro) mà không có review, vì đây là những file định hình hành vi của mọi agent khác trong hệ thống — sai một dòng ở đây là sai lan rộng.

Ví dụ diff thực tế trong CLAUDE.md, sau khi phần feedback integration ở trên chỉ ra rủi ro luồng thanh toán bị đánh giá thấp:

## Risk Weights for Test Planning

- Payment flow changes: always HIGH risk
+ Payment flow changes: always CRITICAL risk — requires manual QA review before merge
+ Address validation changes: HIGH risk — adjacent to payment flow, verify
+   tax/shipping calculation paths are re-tested
  Read-only display changes: LOW risk
  Third-party API integration changes: HIGH risk

Song song, known-issues.md cần được cập nhật với những pre-existing issue mới được xác nhận trong chu kỳ này — để lần phân loại failure tiếp theo (ở phần trước của chương) có dữ liệu đầy đủ hơn, thay vì agent phải suy luận lại từ đầu:

## Known Issues

  ### SEARCH-042: Search latency intermittent on staging
  Status: Open since 2024-01-02
  Symptom: search.spec.ts fails ~15% of runs, timeout at 2s threshold
  Root cause: staging DB shared resource contention during nightly batch jobs
  Action: Not blocking — tracked, revisit if failure rate exceeds 30%

+ ### CHECKOUT-118: Promo code validation timeout on codes >10 chars
+ Status: Open since 2024-01-15 (confirmed via PR #4821 classification)
+ Symptom: checkout.spec.ts fails when promo code length exceeds 10 characters
+ Root cause: validation regex backtracking on long input strings
+ Action: Blocking for payment-adjacent PRs — filed as JIRA-2318

Mẹo: Khi review đề xuất cập nhật CLAUDE.md từ agent, luôn hỏi "cập nhật này có làm risk model chính xác hơn ở PR tiếp theo không, hay chỉ đang phản ứng với một sự cố đơn lẻ (overfitting vào một lần fail)?" Một quy tắc risk weight tốt phải tổng quát hóa được từ pattern lặp lại (ví dụ 3/4 regression liên quan payment), không phải suy ra từ một lần fail ngẫu nhiên.

Giá Trị Tích Lũy Theo Thời Gian (The Compounding Value Over Time)

Giá trị thật của vòng lặp continuous feedback không nằm ở một chu kỳ — nó nằm ở đường cong tích lũy qua nhiều chu kỳ. Chu kỳ đầu tiên, risk model của bạn có thể còn thô: đánh giá payment flow "HIGH" thay vì "CRITICAL", chưa biết address validation là vùng rủi ro liên đới. Sau 5-6 chu kỳ với feedback loop hoạt động đều đặn, CLAUDE.md của bạn đã tích lũy được kiến thức cụ thể của chính hệ thống bạn — không phải kiến thức QA chung chung từ sách vở, mà là "ở hệ thống này, address validation ảnh hưởng payment, search có flaky rate 15% do shared staging DB, module X luôn thiếu coverage sau mỗi lần đổi API".

Đây chính là lý do một hệ thống agentic QA vận hành tốt sau 6 tháng sẽ có chất lượng chẩn đoán vượt xa một hệ thống mới thiết lập, dù dùng cùng model, cùng prompt template. Sự khác biệt không nằm ở AI thông minh hơn — nằm ở lượng ngữ cảnh vận hành thực tế đã được tích lũy vào persistent context.

Ba cái bẫy (pitfall) phổ biến nhất phá vỡ đường cong tích lũy này, đáng ghi nhớ như checklist vận hành:

  • Nhầm flaky test thành regression thật (hoặc ngược lại) liên tục — mỗi lần nhầm làm xói mòn niềm tin vào cả hệ thống. Một khi team không còn tin báo cáo của agent, họ quay lại thói quen tự đọc log thủ công — và toàn bộ đầu tư vào continuous feedback coi như mất giá trị.
  • Không duy trì baseline — baseline lỗi thời (không cập nhật sau mỗi merge vào main) khiến mọi PR trông như đang phá vỡ hàng loạt test không liên quan, dẫn đến team mất khả năng phân biệt PR nào thực sự có vấn đề.
  • Để dữ liệu feedback chất đống mà không bao giờ cập nhật CLAUDE.md/risk weight — đây là lỗi âm thầm nhất vì không gây crash, không gây báo động, chỉ đơn giản là vòng lặp không bao giờ khép lại. Team vẫn chạy nightly regression, vẫn có báo cáo đẹp mỗi sáng, nhưng risk model ở chương "lập kế hoạch test" mãi mãi dừng ở phiên bản ngày đầu triển khai — không hề thông minh hơn sau một năm vận hành.

Điều thực sự phân biệt một agentic QA workflow trưởng thành với một agentic QA workflow mới cài đặt không phải là công cụ nó dùng, mà là việc liệu vòng lặp giữa "thực thi → diễn giải → phân loại → phản hồi vào planning" có thực sự đóng kín và lặp lại đều đặn hay không.