Fix ai-service Dockerfile: bake in drug_entities.json, override its path
This commit is contained in:
@@ -33,7 +33,14 @@ Quy tắc bắt buộc:
|
||||
[n] ở mọi câu — gắn một lần cho một cụm cùng nguồn là đủ. Không bịa số [n].
|
||||
5. Nếu BẰNG CHỨNG không đủ (thiếu đối tượng được hỏi, thiếu con số, hoặc chỉ nói
|
||||
chung chung), nói rõ là không đủ và đặt evidence_sufficient=false. Đó là câu
|
||||
trả lời hợp lệ. Không suy diễn để lấp chỗ trống.
|
||||
trả lời hợp lệ. Không suy diễn để lấp chỗ trống. TRƯỜNG HỢP NÀY BẮT BUỘC LUÔN
|
||||
điền `clarifying_question` giải thích NGẮN GỌN, CỤ THỂ vì sao — dù đó là vì
|
||||
người dùng chưa nêu đủ dữ kiện (hỏi lại dữ kiện còn thiếu, như quy tắc 7), hay
|
||||
đơn giản là chuyên luận KHÔNG đề cập nội dung này cho đối tượng/đường dùng
|
||||
đang hỏi (nói thẳng điều đó, ví dụ "Dược thư không nêu liều dùng đường nhỏ
|
||||
mắt của thuốc này"). TUYỆT ĐỐI KHÔNG để `clarifying_question`=null khi
|
||||
evidence_sufficient=false — một câu giải thích cụ thể luôn hữu ích hơn cho
|
||||
người đọc so với việc để 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
|
||||
@@ -70,8 +77,11 @@ ANSWER_SCHEMA = {
|
||||
"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."
|
||||
"BẮT BUỘC khi evidence_sufficient=false: 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), HOẶC — nếu vấn đề là "
|
||||
"chuyên luận không có nội dung này — một câu nói thẳng điều đó (vd "
|
||||
"'Dược thư không nêu liều dùng đường nhỏ mắt của thuốc này'). "
|
||||
"null CHỈ khi evidence_sufficient=true."
|
||||
),
|
||||
},
|
||||
},
|
||||
@@ -94,18 +104,32 @@ Quy tắc:
|
||||
- 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}.
|
||||
Trả về DUY NHẤT JSON: {"sufficient": bool, "clarifying_question": string|null,
|
||||
"quick_replies": string[]}.
|
||||
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."""
|
||||
hay giảm đau?"). Nếu đủ: sufficient=true, clarifying_question=null,
|
||||
quick_replies=[].
|
||||
|
||||
quick_replies: 2-4 phương án trả lời NGẮN (dưới ~20 ký tự mỗi phương án) cho
|
||||
CHÍNH câu clarifying_question vừa đặt ra, để người dùng bấm chọn thay vì gõ —
|
||||
CHỈ khi câu hỏi thực sự có vài lựa chọn rời rạc, tự nhiên (vd đối tượng: "Người
|
||||
lớn" / "Trẻ em"; đường dùng: "Uống" / "Tiêm"). Để mảng RỖNG nếu câu hỏi cần một
|
||||
con số cụ thể không có sẵn lựa chọn ngắn (vd hỏi cân nặng chính xác) — không
|
||||
được bịa ra các phương án number-ish giả."""
|
||||
|
||||
SUFFICIENCY_SCHEMA = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"sufficient": {"type": "boolean"},
|
||||
"clarifying_question": {"type": ["string", "null"]},
|
||||
"quick_replies": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"maxItems": 4,
|
||||
},
|
||||
},
|
||||
"required": ["sufficient", "clarifying_question"],
|
||||
"required": ["sufficient", "clarifying_question", "quick_replies"],
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
@@ -180,7 +204,8 @@ def build_entailment_request(claims: list[tuple[str, str]]) -> "GenerationReques
|
||||
|
||||
|
||||
def build_request(
|
||||
question: str, evidence_texts: tuple[str, ...], intro: bool = False
|
||||
question: str, evidence_texts: tuple[str, ...], intro: bool = False,
|
||||
list_mode: bool = False,
|
||||
) -> GenerationRequest:
|
||||
"""The prompt for one question over one ordered evidence list.
|
||||
|
||||
@@ -191,6 +216,14 @@ def build_request(
|
||||
`intro=True` is the "user typed only a drug name" case: instead of restating
|
||||
a section, write a short introduction — what the drug is, its class and its
|
||||
main indication — then invite a specific follow-up. Still evidence-only.
|
||||
|
||||
`list_mode=True` is the symptom_to_drug reverse-lookup case: each evidence
|
||||
block is a DIFFERENT drug's own `chi_dinh`, not alternative phrasings of
|
||||
one drug's section — found live 2026-08-07 that without this the model
|
||||
picked just one drug out of 8 real matches and answered only about that
|
||||
one, silently dropping the rest. Not a treatment ranking — a factual list
|
||||
([[feedback_no_recommendation_gate]] already covers why a "which is best"
|
||||
framing would be wrong for this audience anyway).
|
||||
"""
|
||||
if not evidence_texts:
|
||||
raise ValueError("cannot build a grounded prompt with no evidence")
|
||||
@@ -206,6 +239,16 @@ def build_request(
|
||||
"lượng. Kết thúc bằng một câu mời hỏi tiếp về thuộc tính cụ thể (liều "
|
||||
"dùng, chống chỉ định, thận trọng, tương tác…)."
|
||||
)
|
||||
elif list_mode:
|
||||
task = (
|
||||
f"CÂU HỎI: {question}\n\nMỖI đoạn BẰNG CHỨNG trên là chỉ định của MỘT "
|
||||
"thuốc KHÁC NHAU. Hãy LIỆT KÊ TẤT CẢ các thuốc mà bằng chứng cho thấy "
|
||||
"có chỉ định phù hợp với câu hỏi — không chỉ chọn một thuốc. Mỗi thuốc "
|
||||
"một câu ngắn, gắn đúng số nguồn [n] của thuốc đó. Đây là liệt kê tra "
|
||||
"cứu, KHÔNG phải khuyến cáo thuốc nào tốt hơn — không xếp hạng, không "
|
||||
"chọn thuốc \"phù hợp nhất\". Nếu KHÔNG thuốc nào trong bằng chứng thực "
|
||||
"sự phù hợp với câu hỏi, nói rõ điều đó thay vì liệt kê thuốc không liên quan."
|
||||
)
|
||||
else:
|
||||
task = f"CÂU HỎI: {question}"
|
||||
user = f"BẰNG CHỨNG:\n\n{blocks}\n\n{task}"
|
||||
|
||||
Reference in New Issue
Block a user