Checkpoint frontend UI/UX overhaul and ingestion embed benchmark work
This commit is contained in:
@@ -36,6 +36,19 @@ Quy tắc bắt buộc:
|
||||
trả lời hợp lệ. Không suy diễn để lấp chỗ trống.
|
||||
6. Giữ nguyên thuật ngữ chuyên môn của sách. Không diễn giải cho người
|
||||
không chuyên.
|
||||
7. HỎI LẠI khi thiếu dữ kiện — ĐÂY LÀ QUY TẮC QUAN TRỌNG NHẤT, ưu tiên hơn việc
|
||||
trả lời. TUYỆT ĐỐI KHÔNG liệt kê nhiều mức liều rồi để người đọc tự chọn.
|
||||
Nếu là câu hỏi LIỀU/CÁCH DÙNG và bằng chứng phân mức theo điều kiện (tuổi,
|
||||
cân nặng, chức năng thận/gan, chỉ định/bệnh, đường dùng, mức độ nặng…) mà
|
||||
người dùng CHƯA nêu đủ (các) điều kiện để chọn ĐÚNG MỘT mức, thì BẮT BUỘC:
|
||||
để `answer`="", `evidence_sufficient`=false, và đặt `clarifying_question`
|
||||
hỏi NGẮN GỌN tất cả dữ kiện còn thiếu.
|
||||
- "trẻ em" hay "cho trẻ" nói chung là CHƯA đủ (liều trẻ em thay đổi theo
|
||||
tuổi/cân nặng) → phải hỏi lại, KHÔNG được liệt kê các nhóm tuổi.
|
||||
- "người lớn" thường là đủ cho liều người lớn tiêu chuẩn → trả lời được.
|
||||
Ví dụ clarifying_question: "Bé mấy tuổi, cân nặng bao nhiêu kg, dùng đường
|
||||
nào (uống/đặt hậu môn/tiêm) và để hạ sốt hay giảm đau?".
|
||||
Nếu đã đủ dữ kiện thì trả lời bình thường, `clarifying_question`=null.
|
||||
|
||||
Viết gọn. Trả lời đúng điều được hỏi, không mở rộng phạm vi."""
|
||||
|
||||
@@ -54,12 +67,59 @@ ANSWER_SCHEMA = {
|
||||
"type": "boolean",
|
||||
"description": "false nếu bằng chứng không đủ để trả lời câu hỏi.",
|
||||
},
|
||||
"clarifying_question": {
|
||||
"type": ["string", "null"],
|
||||
"description": (
|
||||
"Câu hỏi lại khi người dùng chưa nêu đủ dữ kiện (vd tuổi/cân nặng "
|
||||
"cho câu hỏi liều có nhiều mức). null nếu đã đủ dữ kiện để trả lời."
|
||||
),
|
||||
},
|
||||
},
|
||||
"required": ["answer", "evidence_sufficient"],
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
|
||||
SUFFICIENCY_SYSTEM = """\
|
||||
Bạn là bộ KIỂM TRA ĐỦ DỮ KIỆN cho tra cứu Dược thư, chạy TRƯỚC khi trả lời.
|
||||
Cho CÂU HỎI của người dùng và BẰNG CHỨNG, xác định câu hỏi đã đủ dữ kiện để đưa
|
||||
ra ĐÚNG MỘT câu trả lời cụ thể hay chưa.
|
||||
|
||||
Quy tắc:
|
||||
- Nếu là câu hỏi về LIỀU/CÁCH DÙNG và BẰNG CHỨNG có NHIỀU mức khác nhau theo điều
|
||||
kiện (tuổi, cân nặng, chức năng thận/gan, chỉ định/bệnh, đường dùng, mức độ
|
||||
nặng) mà CÂU HỎI chưa nêu đủ (các) điều kiện để chọn đúng MỘT mức → CHƯA đủ.
|
||||
- "trẻ em" / "cho trẻ" / "cho bé" nói chung là CHƯA đủ (liều trẻ thay đổi theo
|
||||
tuổi và cân nặng). "người lớn" thường ĐỦ cho liều người lớn tiêu chuẩn.
|
||||
- Câu hỏi KHÔNG về liều (chống chỉ định, tương tác, tác dụng phụ, giới thiệu
|
||||
thuốc…) thì thường ĐỦ.
|
||||
|
||||
Trả về DUY NHẤT JSON: {"sufficient": bool, "clarifying_question": string|null}.
|
||||
Nếu CHƯA đủ: sufficient=false và clarifying_question hỏi NGẮN GỌN tất cả dữ kiện
|
||||
còn thiếu (vd: "Bé mấy tuổi, cân nặng bao nhiêu kg, dùng đường nào và để hạ sốt
|
||||
hay giảm đau?"). Nếu đủ: sufficient=true, clarifying_question=null."""
|
||||
|
||||
SUFFICIENCY_SCHEMA = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"sufficient": {"type": "boolean"},
|
||||
"clarifying_question": {"type": ["string", "null"]},
|
||||
},
|
||||
"required": ["sufficient", "clarifying_question"],
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
|
||||
def build_sufficiency_request(
|
||||
question: str, evidence_texts: tuple[str, ...]
|
||||
) -> "GenerationRequest":
|
||||
blocks = "\n\n".join(
|
||||
f"[{index}] {text}" for index, text in enumerate(evidence_texts, start=1)
|
||||
)
|
||||
user = f"BẰNG CHỨNG:\n\n{blocks}\n\nCÂU HỎI: {question}"
|
||||
return GenerationRequest(system=SUFFICIENCY_SYSTEM, user=user, schema=SUFFICIENCY_SCHEMA)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class GenerationRequest:
|
||||
system: str
|
||||
@@ -67,6 +127,58 @@ class GenerationRequest:
|
||||
schema: dict
|
||||
|
||||
|
||||
ENTAILMENT_SYSTEM = """\
|
||||
Bạn là bộ KIỂM TRA ĐỘ CHÍNH XÁC, chạy SAU khi một câu trả lời đã được sinh ra.
|
||||
|
||||
Với mỗi CÂU dưới đây, so sánh nó với ĐÚNG đoạn BẰNG CHỨNG ĐƯỢC TRÍCH đi kèm câu
|
||||
đó (câu đã được gắn số nguồn [n] trỏ tới đúng đoạn này). Việc DUY NHẤT cần làm:
|
||||
nội dung của CÂU có được đoạn BẰNG CHỨNG ĐƯỢC TRÍCH đó — và CHỈ đoạn đó — nói
|
||||
tới hay không. KHÔNG dùng kiến thức y khoa của bạn, KHÔNG suy luận thêm, KHÔNG
|
||||
tự hỏi liệu câu đó có hợp lý về mặt y khoa hay không.
|
||||
|
||||
Một CÂU là KHÔNG được chứng thực nếu nó nêu chỉ định, chống chỉ định, cơ chế,
|
||||
tương tác, đối tượng áp dụng, hoặc bất kỳ quan hệ nào mà đoạn BẰNG CHỨNG ĐƯỢC
|
||||
TRÍCH của nó KHÔNG nói tới — kể cả khi câu đó đúng về mặt y khoa, và kể cả khi
|
||||
đúng tên thuốc nhưng sai ý (ví dụ bằng chứng nói "điều trị đái tháo đường" mà
|
||||
câu nói "chữa ung thư").
|
||||
|
||||
LƯU Ý QUAN TRỌNG: bằng chứng trong lĩnh vực dược thường liệt kê nhiều tên
|
||||
thuốc trong một câu/danh sách dài, phân cách bởi dấu phẩy (ví dụ: "Tác dụng
|
||||
của warfarin có thể tăng lên khi dùng với: acetaminophen, allopurinol, ...,
|
||||
aspirin, kháng sinh, ..."). Hãy ĐỌC KỸ TOÀN BỘ danh sách trước khi kết luận —
|
||||
nếu tên thuốc trong CÂU xuất hiện ở bất kỳ đâu trong danh sách đó với đúng
|
||||
quan hệ đang nói (vd "làm tăng tác dụng của X"), đó LÀ được chứng thực, dù
|
||||
tên thuốc chỉ là một mục nhỏ giữa danh sách dài.
|
||||
|
||||
Trả về DUY NHẤT JSON: {"entailed": bool, "unsupported": [danh sách số thứ tự
|
||||
1-based của các CÂU KHÔNG được chứng thực; rỗng nếu tất cả đều được chứng
|
||||
thực]}. entailed=true chỉ khi unsupported rỗng."""
|
||||
|
||||
ENTAILMENT_SCHEMA = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"entailed": {"type": "boolean"},
|
||||
"unsupported": {"type": "array", "items": {"type": "integer"}},
|
||||
},
|
||||
"required": ["entailed", "unsupported"],
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
|
||||
def build_entailment_request(claims: list[tuple[str, str]]) -> "GenerationRequest":
|
||||
"""`claims` is a list of (claim_text, cited_evidence_text) pairs — already
|
||||
filtered by the caller to the claims worth checking (substantive content,
|
||||
a validly-cited evidence block to check it against)."""
|
||||
if not claims:
|
||||
raise ValueError("cannot build an entailment request with no claims")
|
||||
blocks = "\n\n".join(
|
||||
f"CÂU {index}: {claim}\nBẰNG CHỨNG ĐƯỢC TRÍCH: {evidence}"
|
||||
for index, (claim, evidence) in enumerate(claims, start=1)
|
||||
)
|
||||
user = f"{blocks}\n\nKiểm tra từng CÂU theo đúng BẰNG CHỨNG ĐƯỢC TRÍCH của nó."
|
||||
return GenerationRequest(system=ENTAILMENT_SYSTEM, user=user, schema=ENTAILMENT_SCHEMA)
|
||||
|
||||
|
||||
def build_request(
|
||||
question: str, evidence_texts: tuple[str, ...], intro: bool = False
|
||||
) -> GenerationRequest:
|
||||
|
||||
Reference in New Issue
Block a user