Send patient context once per session, not on every turn

This commit is contained in:
2026-08-25 14:05:27 +07:00
parent 04b1bb734f
commit 692a9c99b5
+21 -6
View File
@@ -156,6 +156,15 @@ export function ChatPanel({
// Fetched once; `getPatientProfile()` itself returns null on a 401, so an
// anonymous visitor never even attempts an authenticated call more than once.
const patientProfileRef = useRef<PatientProfile | null>(null);
// Which sessionId has already had the patient-context clause sent. Prepending
// on every single turn (the original design) adds "Bệnh nhân X tuổi, Y kg."
// noise to queries that have nothing to do with dosing/patient-specific
// context — measured live: it pushed a plain ADR-listing question
// (unrelated to age/weight) from a correct answerable answer into
// evidence_insufficient. `rag/understanding.py`'s multi-turn merge already
// carries a stated fact forward, so sending it once per conversation is
// enough — this only resets when `sessionId` itself changes.
const patientContextSentForSessionRef = useRef<string | null>(null);
useEffect(() => {
getPatientProfile()
@@ -202,16 +211,22 @@ export function ChatPanel({
}, 1000);
try {
patientContextSentForSessionRef.current = sessionId;
const res = await fetch("/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
// Prepends saved patient context (age/weight/renal/hepatic/allergy)
// to what's actually sent, never to what's shown in the chat
// bubble above — the LLM understanding step already extracts these
// fields from free text every turn (see rag/understanding.py), so
// this reuses that exact path instead of adding a second one.
content: withPatientContext(userText, patientProfileRef.current),
// Prepends saved patient context on the first turn of this session
// only — never to what's shown in the chat bubble above. The LLM
// understanding step extracts these fields from free text and
// carries them across the conversation (rag/understanding.py), so
// repeating them on every later turn only adds noise to queries
// that aren't patient-specific (measured: it broke a plain ADR
// lookup). See patientContextSentForSessionRef above.
content:
patientContextSentForSessionRef.current === sessionId
? userText
: withPatientContext(userText, patientProfileRef.current),
conversationId: sessionId,
responseMode,
}),