Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Audit chất lượng vòng đời phần mềm khi có AI tham gia

Câu hỏi bài này trả lời: làm sao biết một dự án có AI tham gia đang ở đâu và chất lượng thật tới đâu, khi bản ghi, mã nguồn và môi trường đang chạy có thể nói những điều khác nhau?

Cần biết trước: đã đọc Viết tiêu chí hoàn tất mà AI có thể kiểm chứng và biết git, test, CI ở mức cơ bản. Phần lab chỉ dùng thư viện chuẩn của Python 3, không cài thêm gì.

Bài của Anthropic về harness cho agent chạy dài mô tả một dạng lệch cụ thể: agent ghi trạng thái từng tính năng vào một tệp tiến độ, rồi một phiên sau thấy đã có tiến độ nên tuyên bố xong. Bài cũng ghi nhận agent hay đánh dấu hoàn thành khi chưa kiểm thử đúng cách. Tệp tiến độ là một lời khai. Audit là việc đặt lời khai cạnh hiện vật và môi trường để xem chúng còn khớp nhau không.

Audit khác test và review ở đâu

ViệcCâu hỏiĐối tượngKết quả
TestHành vi này có chạy đúng không?Một hành viĐạt hoặc không đạt
ReviewThay đổi này có nên vào không?Một thay đổiDuyệt, làm lại hoặc leo thang
AuditĐiều được tuyên bố về dự án có khớp với thực tế không?Cả dự án tại một thời điểmDanh sách chỗ lệch kèm bằng chứng

Test và review vẫn cần. Audit bắt loại lỗi mà chúng không thấy: lỗi nằm giữa các nguồn, như bản ghi nói đã xong trong khi bản đang chạy lại là một bản khác.

Ba nguồn sự thật và quy tắc đối chiếu

NguồnGồmAi tạo raĐiểm yếu
Bản ghiKế hoạch, ticket, bảng tiến độ, nhật kýNgười hoặc agent tự cập nhậtKhông ai chạy nó nên có thể đi sau hoặc đi trước thực tế
Hiện vậtMã, test, tài liệu, cấu hình trong kho mã, kết quả CINgười và công cụChỉ nói về bản đã kiểm, chưa chắc là bản đang chạy
Môi trường vận hànhBản đang phục vụ người dùng, hạ tầng đang chạyQuá trình triển khaiKhó đo; cần cách đo từ bên ngoài, không tin khai báo cấu hình

Mỗi cặp nguồn trả lời một câu hỏi riêng:

  • Bản ghi và hiện vật: những việc ghi là xong có test đạt không, và tiến độ ghi có khớp số đếm được không?
  • Hiện vật và môi trường: bản đã kiểm có phải bản đang chạy không, và bản đang chạy có nằm trong danh sách đã duyệt không?
  • Bản ghi và môi trường: kế hoạch nói đã hay chưa triển khai, còn thực tế đang chạy gì?

Ba quy tắc đi kèm:

  1. Hai nguồn lệch nhau là một phát hiện, chưa phải lỗi của ai.
  2. Khi mâu thuẫn, tin nguồn mà công cụ đo được hơn nguồn do người hoặc agent tự khai.
  3. Sửa ở đúng nguồn. Chỉnh bản ghi cho khớp thực tế là hợp lệ khi thực tế là điều đúng; chỉnh bản ghi để báo cáo trông xanh thì không.

Lab: dựng ba nguồn và để script tìm chỗ lệch

Dự án giả lập có bốn việc. Bản ghi (ledger.json) nói ba việc đã xong và tiến độ 80%. Hiện vật (artifacts.json) là kết quả lần chạy test gần nhất trên bản b42. Môi trường (live.json) cho biết bản đang chạy là b43 và chỉ b42 đã được duyệt. Tạo thư mục trống, ví dụ audit-lab, và các file sau. Dữ liệu là giả lập; script chỉ minh hoạ cách đối chiếu, không phải công cụ audit hoàn chỉnh.

{
  "progress_percent": 80,
  "tasks": {
    "login": "done",
    "export": "done",
    "report": "done",
    "billing": "in_progress"
  }
}
{
  "build": "b42",
  "tests": {
    "login": "pass",
    "export": "fail",
    "report": "pass",
    "billing": "pass"
  }
}
{
  "build": "b43",
  "approved_builds": ["b42"]
}

audit.py đọc cả ba nguồn rồi in từng chỗ lệch và kết thúc với exit code 1 nếu có:

import json
import sys


def load(path):
    with open(path, encoding="utf-8") as handle:
        return json.load(handle)


ledger = load("ledger.json")
artifacts = load("artifacts.json")
live = load("live.json")
findings = []

tasks = ledger["tasks"]
tests = artifacts["tests"]
for name, status in tasks.items():
    result = tests.get(name, "missing")
    if status == "done" and result != "pass":
        findings.append(f"ghi 'done' nhưng test {result}: {name}")
    if status != "done" and result == "pass":
        findings.append(f"test pass nhưng bản ghi '{status}': {name}")

done = sum(1 for status in tasks.values() if status == "done")
counted = round(100 * done / len(tasks))
if counted != ledger["progress_percent"]:
    findings.append(
        f"tiến độ ghi {ledger['progress_percent']}% nhưng đếm được {counted}%"
    )

if live["build"] != artifacts["build"]:
    findings.append(
        f"môi trường chạy {live['build']}, bản đã kiểm là {artifacts['build']}"
    )
if live["build"] not in live["approved_builds"]:
    findings.append(f"bản {live['build']} đang chạy chưa nằm trong danh sách đã duyệt")

for line in findings:
    print("LỆCH:", line)
print(f"tổng: {len(findings)} chỗ lệch")
sys.exit(1 if findings else 0)

Chạy lần đầu. Script kết thúc với exit code 1:

python3 audit.py
LỆCH: ghi 'done' nhưng test fail: export
LỆCH: test pass nhưng bản ghi 'in_progress': billing
LỆCH: tiến độ ghi 80% nhưng đếm được 75%
LỆCH: môi trường chạy b43, bản đã kiểm là b42
LỆCH: bản b43 đang chạy chưa nằm trong danh sách đã duyệt
tổng: 5 chỗ lệch

Năm chỗ lệch thuộc ba loại. Hai dòng đầu là bản ghi so với hiện vật: một việc ghi xong nhưng test fail, một việc test đạt nhưng bản ghi chưa cập nhật. Dòng thứ ba là bản ghi tự mâu thuẫn với số đếm của chính nó. Hai dòng cuối là hiện vật so với môi trường: thứ đang chạy không phải thứ đã kiểm và chưa được duyệt. Bộ test của dự án này vẫn có thể xanh trên bản b42; không dòng nào ở trên làm test đỏ.

Sửa đúng nguồn. Việc export còn fail thì bản ghi phải nói in_progress; việc billing đã đạt thì ghi done; môi trường quay về bản đã duyệt. Trong dự án thật, việc cuối là một lần triển khai có người duyệt, không phải sửa file. Ghi đè hai file:

{
  "progress_percent": 75,
  "tasks": {
    "login": "done",
    "export": "in_progress",
    "report": "done",
    "billing": "done"
  }
}
{
  "build": "b42",
  "approved_builds": ["b42"]
}

Chạy lại. Lần này script kết thúc với exit code 0:

python3 audit.py
tổng: 0 chỗ lệch

Audit xanh không có nghĩa là hết lỗi: export vẫn fail. Khác biệt là bản ghi giờ nói đúng điều đó. Audit tìm chỗ lệch giữa các nguồn, không thay cho việc sửa lỗi.

Môi trường đã chạy: macOS trên Apple silicon, Python 3.14. Chưa thử: Linux và Windows.

Các lớp kiểm và cổng duyệt đi kèm

Audit không thay review, nhưng cần biết lớp kiểm nào đang có mặt và cổng nào đang áp, vì thiếu lớp là một loại phát hiện. Cách review từng thay đổi nằm ở Review code do AI sinh ra; phần này chỉ là bản đồ.

  • Lớp máy chạy trước khi người đọc: build, lint, kiểm kiểu, test, quét secret, và xác nhận thư viện được gọi có thật.
  • Tầng 1, đúng logic: đối chiếu từng tiêu chí chấp nhận với diff thật, thử các ca biên, soi chỗ nuốt lỗi và mã thừa.
  • Tầng 2, hợp kiến trúc: đúng ranh giới module, không tạo bản sao của thứ đã có.
  • Tầng 3, đủ hiệu năng: truy vấn trong vòng lặp, kéo cả tập dữ liệu vào bộ nhớ, độ phức tạp trên kích thước dữ liệu thật.
  • Tầng 4, an toàn khi đồng thời: chạy hai lần không hỏng dữ liệu, ranh giới transaction, retry và timeout.
  • Bảo mật xuyên các tầng: đầu vào đi tới đâu, phân quyền, thư viện và công cụ của agent có thật và đáng tin, secret, dữ liệu cá nhân.

Tầng 2 đến 4 và phần bảo mật chỉ bật khi thay đổi chạm ngưỡng, như thay đổi lớn, module lõi, giao diện công khai hoặc job nền, để một thay đổi cỡ vừa vẫn rà xong trong khoảng nửa giờ.

  • Tự trị: nhánh thử nghiệm, sinh test, nháp tài liệu, đọc và giải thích mã. Điều kiện là lớp máy chạy tự động.
  • Duyệt sau, trước khi lan: nhánh dùng chung, cấu hình không phải production, migration trên môi trường phát triển.
  • Duyệt trước, cổng cứng: production, dữ liệu thật, tiền, xác thực và phân quyền, secret, thư viện mới, API công bố ra ngoài.

Dừng và báo khi đầu ra chứa secret hoặc dữ liệu cá nhân chưa che, khi xuất hiện thư viện hoặc công cụ không giải thích được, hoặc khi nghi sự cố production. Cần có đường ngoại lệ hợp pháp ghi ai duyệt, phá mục nào, vì sao và đến khi nào; ngoại lệ tập trung ở đâu thì quy tắc ở đó đang sai. Cách dựng cổng và vòng đời task nằm ở Dựng harness để AI agent làm việc đáng tin.

Một kết luận chỉ có giá trị khi kiểm chứng được

Mỗi phát hiện của audit cần đứng được trên bằng chứng người khác chạy lại được: lệnh, kết quả, thời điểm và nơi lưu. Không chắc thì mục đó chưa đạt, và hỏi. Người hoặc môi trường chấm phải độc lập với bên tạo ra kết quả, nên agent không tự audit đầu ra của chính nó. Máy chạy phép kiểm; con người quyết định điều gì đáng kiểm. Cách viết tiêu chí và kiểm chính verifier nằm ở Viết tiêu chí hoàn tất mà AI có thể kiểm chứng.

Báo cáo audit

Một báo cáo audit gồm bốn phần: phạm vi và thời điểm đo; bảng phát hiện; kết luận đạt, làm lại hoặc leo thang; và phần chưa đo được. Phần chưa đo được phải ghi rõ để không bị đọc thành “đạt”.

Mô tảNguồn lệchMức độBằng chứngNgười xử lýHạn
Bản b43 đang chạy nhưng chưa được duyệtHiện vật và môi trườngChặnLệnh đo và kết quả, kèm thời điểmTên hoặc vai tròNgày cụ thể
Tiến độ ghi 80%, đếm được 75%Bản ghi và số đếmSửa trong sprintKết quả audit.pyTên hoặc vai tròNgày cụ thể

Mức độ nên có định nghĩa rõ từ đầu, ví dụ chặn là không phát hành khi còn tồn tại, sửa trong sprint là có hạn, theo dõi là chưa cần hành động. Mỗi dòng có đúng một người chịu trách nhiệm.

Đo và chu kỳ

  • Đo baseline trước khi bắt đầu; không có baseline thì sau này không so được.
  • Đo hằng tuần: tỷ lệ thay đổi đủ bằng chứng, thời gian rà soát trung vị, lỗi bắt được và lỗi lọt sau khi gộp, số ngoại lệ.
  • Mỗi quý đọc sâu vài thay đổi đã đạt để đếm lỗi lọt theo tầng. Lỗi lọt lặp lại thì thêm mục kiểm; mục lâu không bắt được gì và không phải rào an toàn thì cân nhắc cắt.
  • Bộ quy tắc không được nhắc tới trong một quý là bộ quy tắc đang chết; rà lại cùng nhóm.

Giới hạn và lỗi thường gặp

  • Audit không chứng minh phần mềm đúng về ngữ nghĩa. Nó chỉ chứng minh những điều đã được viết ra thành phép kiểm khớp nhau.
  • Nguồn thứ ba không đo được thì ghi “không đo được”, đừng suy từ khai báo cấu hình. Khai báo nói điều muốn có, không nói điều đã áp dụng.
  • Biến audit thành điểm số rồi tối ưu điểm số làm mất ý nghĩa của phép đo. Giữ báo cáo ở dạng phát hiện kèm bằng chứng.
  • Đo quá nhiều thì không ai đọc. Bắt đầu với ba cặp đối chiếu ở trên.
  • Số đo trên một dự án không suy ra được cho dự án khác.

Học tiếp

Nguồn tham khảo