Hert4/avabench

Agentic benchmark for MISA's AVA assistant, AutomationBench-style stateful world. Public 27-task set; leaderboard over the full 100.

★ 0Forks 0PythonGitHub ↗Compare

README

AVABench

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.

Vì sao không dùng thẳng scope/

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.

Cách chạy

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 4

Kế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.

Chấm điểm

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.

So số theo kiểu Việt

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.

Task hỏng vì khung thì bị loại, không đội lốt model kém

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.

Thế giới

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.

Nguồn khó của task

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.

Nhiễu

--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.

Bộ task hiện có

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".

Tách bộ công khai và bộ giữ kín

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.py và oracle.py chỉ chứa 27 task công khai. Chạy --validate-only hay selftest ra 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.

Bẫy trong domain sale là bẫy có thật

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

Thêm task mới

  1. Viết hàm dựng task trong avabench/domains/<domain>/tasks.py, lấy base_company() rồi merge() thêm bản ghi riêng.
  2. Thêm assertion. Assertion mang nghĩa "không được đụng vào" thì gắn "negative": True.
  3. Viết lời giải mẫu trong avabench/oracle.py.
  4. Viết thêm một lời giải SAI cố ý trong ANTI_ORACLES nếu task có chỗ dễ chấm lỏng.
  5. Chạy python -m avabench.selftest và --validate-only. Validator bắt: tool chưa đăng ký, assertion trỏ bảng không có, initial_state sai kiểu, task đã đúng sẵn ngay trên state gốc, key assertion gõ sai (body_contain thiếu s), trường where không có trong schema, và toán tử lạ (equal thay vì eq). Ba lỗi cuối trước đây làm assertion thành luôn đúng mà không ai biết.

Contributors

Hert4

Issues