Benchmark agentic cho trợ lý AVA của MISA, dựng theo kiến trúc AutomationBench (Zapier) nhưng thay thế giới SaaS bằng thế giới nghiệp vụ MISA.
Mỗi task nạp một trạng thái công ty mô phỏng, thả model chạy nhiều bước với bộ công cụ thật có tác dụng phụ, rồi chấm trạng thái cuối của thế giới bằng assertion, không chấm chuỗi hội thoại.
scope/eval_inference.py + eval_accuracy.py đo bài toán khác: một lượt gọi
duy nhất, chấm bằng cách so tập tên tool với nhãn, bỏ qua arguments và không có
trạng thái. Nó trả lời câu "supervisor route đúng skill chưa". AVABench trả lời
câu "agent có làm xong việc không". Dữ liệu scope/ đóng góp phần khung: danh
mục 144 skill, phân bố domain (Kế toán/CRM, AMIS, Tuyển dụng, Mail, Others) và
văn phong yêu cầu tiếng Việt của người dùng thật.
uv venv --python 3.13 .venv
uv pip install --python .venv/bin/python pydantic openai httpx
# kiểm tra bộ task, không tốn tiền gọi model
.venv/bin/python -m avabench.cli --validate-only
.venv/bin/python -m avabench.cli --list-tasks
# hai chốt chặn: lời giải mẫu phải đạt 1.0, lời giải sai cố ý phải trượt
.venv/bin/python -m avabench.selftest # thêm số để bật nhiễu: selftest 8
# so nhiều lần chạy, và chấm lại kết quả cũ khi sửa assertion (không gọi model)
.venv/bin/python -m avabench.report
.venv/bin/python -m avabench.rescore
# chạy model
AVABENCH_SSL_VERIFY=0 .venv/bin/python -m avabench.cli \
--model misa-qwen3.8-27b \
--base-url https://runai.misaonline.vpnlocal/prod-llm/misa-qwen38-27b-api/v1 \
--api-key "$RUNAI_KEY" \
--reasoning-effort none --noise 8 --max-concurrent 4Kết quả ghi ra results/<model-alias>.json: điểm tổng, điểm theo domain, và với
mỗi task là toàn bộ trace công cụ, từng assertion đạt/trượt, và trạng thái cuối
của world.
Mỗi task cho hai số:
partial_credit(0.0–1.0): tỉ lệ assertion đạt. Tín hiệu dày để so model hoặc làm reward cho RL.task_completed_correctly(0/1): chỉ bằng 1 khi mọi assertion được chấm đều đạt. Trung bình con số này chính là pass rate của benchmark.
Assertion đã đúng sẵn trên trạng thái ban đầu không vào mẫu số. Nó là assertion "giữ nguyên": agent ngồi im không ăn được điểm nào từ nó, nhưng phá vỡ nó thì bị tính trượt. Đây là luật của code gốc AutomationBench.
Lưu ý: bench này từng chạy luật khác, chép theo docstring của AutomationBench ("phủ định chỉ được điểm khi mọi khẳng định đạt"). Đọc code gốc thì họ không hề chạy luật đó, và luật đó làm partial credit nhảy bậc: trượt một khẳng định nhỏ là mất sạch điểm của mọi phủ định. Đã bỏ.
Chống bắn vãi vẫn còn nguyên, do chính các assertion record_not_exists,
record_count, mail_not_sent đảm nhiệm.
Assertion so số theo giá trị, không so chuỗi. 1.5 khớp 1,5 ngày,
60000000 khớp cả 60.000.000đ lẫn 60 triệu, 200000 khớp 200k. Ngược
lại 60 KHÔNG còn khớp bừa vào 160.000.000 như kiểu so chuỗi. Trước khi có
bước này, ba model viết đúng chuẩn tiếng Việt đã bị chấm trượt oan.
Lỗi hạ tầng, và trường hợp model bị cắt ở max_tokens khi chưa kịp gọi tool
nào, được đánh dấu invalid: loại khỏi mẫu số và đếm riêng ở cột Bỏ. Trước
khi có nó, một model thinking bị cắt giữa chừng bị chấm 0 trong im lặng và tụt
15 điểm phần trăm vì lỗi của khung.
WorldState gồm bảy phân hệ, tất cả là pydantic model nên seed sai kiểu là báo
lỗi ngay lúc validate chứ không âm thầm:
| Phân hệ | Nội dung |
|---|---|
crm |
khách hàng, nhà cung cấp, hàng hoá, đơn hàng, báo giá, hoá đơn, hoạt động, mục tiêu doanh số, trình duyệt |
hrm |
nhân viên, đơn nghỉ phép, chấm công, ca làm, bảng lương, phòng họp, đặt phòng |
mail |
hộp thư AVA Mail |
tuyendung |
tin tuyển dụng, ứng viên, CV, phỏng vấn, mẫu email |
helpdesk |
ticket nội bộ, tài liệu quy định, bảng tin |
workspace |
memory dài hạn, biểu đồ, báo cáo đã lưu, tin nhắn và human handoff |
83 công cụ, 42 trong số đó có tác dụng phụ lên world. Tên công cụ bám theo danh
mục skill thật trong scope/ (amismail_write_mail, ava_approval,
recruitment_skill_sumarize_cv, document_qa, edit_memory…) nhưng có schema
tham số cụ thể để thao tác được lên dữ liệu.
Task không khó vì câu chữ, mà vì phải bắc cầu nhiều chặng:
- Tra quy định trước khi làm. Đáp án đúng nằm trong
helpdesk.documents, ví dụ hết phép thì phải tách thành hai đơn annual/unpaid và mở thêm ticket. - Rẽ nhánh theo dữ liệu. Cùng một yêu cầu, người còn đủ phép thì duyệt, người không đủ thì từ chối và phải báo lại đúng số dư.
- Bắc cầu nhiều bảng. Khách hàng → người phụ trách → quản lý của người đó mới ra địa chỉ email cần gửi.
- Ghép hai quy định. Chọn phòng phỏng vấn phải thoả cả quy trình tuyển dụng (tối thiểu 6 chỗ) lẫn quy định đặt phòng (chọn phòng nhỏ nhất còn trống).
- Cấm làm dư. Không được đụng vào đơn của phòng khác, không gửi công nợ ra ngoài công ty, không đổi trạng thái hoá đơn chưa tới hạn.
--noise N bơm N bản ghi nhiễu vào mỗi bảng an toàn: nhân viên trùng họ, công
ty tên na ná, hoá đơn chưa tới hạn, ticket đã đóng, thư nội bộ chưa đọc. Luật an
toàn được thi hành tự động: không bơm vào bảng nào mà assertion của chính task
đó có đụng tới, và không bao giờ bơm vào bảng tra cứu cố định (tài liệu quy
định, danh mục hàng hoá, phòng họp, ca làm, mẫu email). selftest phải vẫn đạt
đủ điểm khi bật nhiễu; nếu tụt thì nhiễu đã phá đáp án.
100 task, 5 phân hệ × 20. Chia hai lớp theo cách AutomationBench làm (họ tách 54 task khó khỏi 523 task thao tác đơn lẻ): mỗi phân hệ 8 task khó + 12 task cơ bản, tổng 505 assertion.
| Phân hệ | Task | Nguồn gốc |
|---|---|---|
sale |
20 | Bám tool thật của AgentWork Sale trong MISA.AgentworkPlatform.AIChat/src/agent/tools/agentworksale/: tên tool, tên tham số và ràng buộc nghiệp vụ lấy từ đó |
crm, hrm, tuyendung, helpdesk |
80 | Tổng hợp, bám danh mục skill và phân bố phân hệ của scope/ nhưng schema tham số do bench tự đặt |
Chỉ sale mới trả lời được câu "agent bán hàng của MISA làm xong việc chưa".
Bốn phân hệ còn lại đo hẹp hơn: "model nền có kỷ luật tra cứu trước khi ghi không".
Bản trên GitHub chỉ mang 27 task — đúng mẫu --sample 27 --sample-seed 0,
chia đều theo phân hệ. 73 task còn lại giữ kín để bảng xếp hạng không bị
học thuộc: model nào tối ưu riêng cho bộ công khai sẽ lộ ra ngay ở chênh lệch
giữa hai bộ.
Vì thế trong repo này:
avabench/domains/*/tasks.pyvàoracle.pychỉ chứa 27 task công khai. Chạy--validate-onlyhayselftestra 27, không phải 100.results/public27/có trace đầy đủ của 27 task đó: từng bước gọi tool, từng assertion đạt/trượt, trạng thái cuối của world. Đủ để kiểm chứng lại điểm mà không cần gọi model.results/full100/chỉ có số tổng và điểm theo phân hệ trên đủ 100 task. Không kèm tên, đề bài hay trace của task nào, kể cả task công khai.
Bảng xếp hạng trong RESULTS.md là bảng của bộ 100 task. Điểm trên bộ 27 công
khai luôn cao hơn vài chục phần trăm vì mẫu đó rơi nhiều vào lớp cơ bản, đừng
đem hai con số ra so thẳng.
Lấy nguyên từ mô tả tham số của tool thật, không phải nghĩ ra:
- SKU đặt hàng phải lấy từ kết quả
search_product, tự chế mã là tool báo lỗi - thiếu tên người nhận, số điện thoại hoặc địa chỉ thì phải hỏi lại, cấm tự điền
- tên người nhận không được là danh xưng chung (bạn, mình, anh, chị, shop)
- mã
DRAFT-...không dùng để chốt đơn hay tạo QR - sửa hoặc huỷ đơn phải kèm số điện thoại khớp đơn
- combo có biến thể: số SKU chọn cho mỗi thành phần phải đúng bằng số lượng
- đơn đã thanh toán thì không tự huỷ, phải chuyển người thật
- địa chỉ ngoài bảng phí thì không được tự ước lượng phí ship
- Viết hàm dựng task trong
avabench/domains/<domain>/tasks.py, lấybase_company()rồimerge()thêm bản ghi riêng. - Thêm assertion. Assertion mang nghĩa "không được đụng vào" thì gắn
"negative": True. - Viết lời giải mẫu trong
avabench/oracle.py. - Viết thêm một lời giải SAI cố ý trong
ANTI_ORACLESnếu task có chỗ dễ chấm lỏng. - Chạy
python -m avabench.selftestvà--validate-only. Validator bắt: tool chưa đăng ký, assertion trỏ bảng không có,initial_statesai kiểu, task đã đúng sẵn ngay trên state gốc, key assertion gõ sai (body_containthiếu s), trườngwherekhông có trong schema, và toán tử lạ (equalthay vìeq). Ba lỗi cuối trước đây làm assertion thành luôn đúng mà không ai biết.