Bối Cảnh và Tầm Quan Trọng của Việc Kiểm thử
Trong quy trình phát triển ứng dụng sử dụng ngôn ngữ tự nhiên, việc duy trì tính dự đoán được của đầu ra là một thách thức lớn. Guidance cung cấp cơ sở hạ tầng kiểm thử chuyên biệt giúp các nhà phát triển xác minh chất lượng đầu ra trong điều kiện ràng buộc chặt chẽ. Công cụ này hỗ trợ kiểm tra tính chính xác của cú pháp JSON, áp đặt các giới hạn bằng biểu thức chính quy, và validate tính logic trong luồng hội thoại nhiều bước.
- Ràng buộc định dạng: Đảm bảo dữ liệu xuất ra tuân thủ chuẩn cấu trúc như Schema.
- Đánh giá ngữ nghĩa: Xác minh việc sử dụng đúng ngữ cảnh và văn bản mẫu.
- Lập trình đối tác (Conversation): Theo dõi chuỗi tương tác giữa hệ thống và người dùng.
- Giám sát hiệu năng: Đo lường chi phí token và thời gian phản hồi.
Cấu Trúc Kiến Trúc Kiểm thử
Khung kiểm thử được thiết kế theo mô hình phân tầng, tối ưu hóa tốc độ và độ tin cậy:
1. Phân lớp Đơn vị (Unit Layer)
Tọa lạc trong tests/unit/, nhóm này hoạt động độc lập với dịch vụ LLM thực tế, thay vào đó sử dụng công cụ giả lập để tăng tốc độ chạy:
- Cú pháp & Parser:
test_grammar.pyxác nhận bộ phân tích ngôn ngữ. - Sinh dữ liệu JSON: Thư mục
library/json/kiểm chứng các rule phức tạp. - Cơ chế capture:
test_capture.py đảm bảo trích xuất biến đúng yêu cầu.
2. Phân lớp Tích hợp (Integration Layer)
Nằm tại tests/model_integration/, đây là nơi kiểm tra khả năng tương thích với các backend khác nhau thông qua fixture selected_model:
- Core Engine:
test_engine.py. - Tokenizer:
test_tokenizers.py. - API Interface:
test_model.py.
3. Phân lớp Đặc thù (Specific Layer)
Thư mục tests/model_specific/ chứa các bài test tùy biến cho từng nền tảng phần cứng hoặc thư viện cụ thể:
- Llama.cpp Backend:
llama_cpp_tests/. - HuggingFace Transformers:
test_transformers.py.
Cài Đặt Môi Trường Phát Triển
Để khởi động bộ khung kiểm thử, hãy đảm bảo đã cài đặt đầy đủ các gói mở rộng liên quan:
pip install "guidance[test-unit]"
Ví Dụ Minh Họa Thực Tế
Dưới đây là cách xây dựng các trường kiểm thử cơ bản sử dụng Python và Pytest:
1. Kiểm Tra Cơ Chế Chọn Lựa
Mô phỏng một hàm lựa chọn chuỗi từ tập hợp các giá trị có sẵn mà không cần gọi API ngoài:
import pytest
from guidance import select
from guidance.models import Mock
def verify_selection_logic():
"""Xác minh chức năng lựa chọn đầu ra"""
client = Mock()
client += f"This result {select(options=['valid', 'invalid', 'neutral'])}"
result_str = str(client)
allowed_outputs = [
"This result valid",
"This result invalid",
"This result neutral"
]
assert result_str in allowed_outputs
2. Kiểm Tra Sinh JSON theo Schema
Sử dụng Pydantic để định nghĩa cấu trúc dữ liệu bắt buộc, sau đó kiểm chứng quá trình tạo mẫu:
from pydantic import BaseModel
from guidance import json as gen_json
from guidance.models import Mock
class ProductSchema(BaseModel):
item_id: int
status: str
def test_structured_generation():
"""Kiểm tra sinh dữ liệu tuân thủ Schema"""
target_data = b'{\"item_id\": 99, \"status\": \"active\"}'
session = Mock(target_data)
with system_context():
session += "Create a product record"
with assistant_context():
session += gen_json(name="product_info", schema=ProductSchema)
generated_data = session.get("product_info")
assert generated_data == target_data.decode()
Kỹ Thuật Nâng Cao
1. Giả Lập Ngữ Pháp Offline
Dùng Mock để kiểm tra các regex phức tạp mà không tốn chi phí mạng:
from guidance.models import Mock
def validate_expression_parsing():
pattern = "calc=" + gen(regex=r"[0-9]+([+*/][0-9]+)*", name="result")
# Kiểm tra cú pháp đúng/sai
assert pattern.match("calc=10*5") is not None
assert pattern.match("calc=++10") is None
# Chạy simulation
simulator = Mock(b"<s>calc=10*5")
simulator += pattern
final_output = simulator["result"]
assert final_output == "10*5"
2. Đa dạng hóa Kịch Bản (Parametrization)
Test bao phủ nhiều trạng thái đầu vào cùng lúc bằng pytest.mark.parametrize:
@pytest.mark.parametrize("text_input, expected_result", [
("Hello AI", "Hello"),
("World Update", "World"),
("System Check", "System"),
])
def test_extract_leading_word(text_input, expected_result):
engine = Mock(f"<s>{text_input}".encode())
engine += gen(name="prefix", regex=r"\w+")
assert engine["prefix"] == expected_result
Tối Ưu Hóa Vận Hành
Để quản lý quy trình tích hợp liên tục (CI/CD) hiệu quả, cần cấu hình rõ ràng về mô hình và chiến lược chạy test:
Lựa Chọn Backend
Sử dụng cờ dòng lệnh để chỉ định môi trường chạy cho các test tích hợp:
# Chạy trên GPU CPU GPT-2
python -m pytest --selected_model transformers_gpt2_cpu ./tests/model_integration/
# Hoặc thiết lập biến môi trường
export GUIDANCE_SELECTED_MODEL="transformers_llama_cpu"
python -m pytest ./tests/
Chiến Lược Tổ Chức
- Ưu tiên đơn vị: Luôn viết test ở
unittrước để loại bỏ lỗi logic sớm. - Bổ sung tích hợp: Thêm test
model_integrationkhi tính năng đã ổn định. - Thuộc tính đặc thù: Dùng
model_specificcho các bug chỉ xảy ra trên một số phiên bản backend.
Gán Nhãn Hiệu Suất
Phân loại test nặng để tránh làm chậm quy trình build hàng ngày:
@pytest.mark.resource_heavy
def test_massive_gen_stream():
pass
@pytest.mark.unit_quick
def test_syntax_validation():
pass
Xử Lý Lỗi Thường Gặp
Khi gặp vấn đề trong quá trình test, hãy rà soát các điểm sau:
- Định tuyến mô hình: Xác nhận tham số
--selected_modelkhớp với tên gói đã tải. - Tiện ích mở rộng: Thiếu thư viện phụ sẽ gây lỗi import, hãy chạy
pip install -U guidance[all]. - Tương thích Grammar: Sử dụng Mock để debug regex trước khi đưa vào production.