nsr51324 commited on
Commit
af77c6e
·
verified ·
1 Parent(s): dac03af

Upload 21 files

Browse files
Files changed (2) hide show
  1. __pycache__/app.cpython-310.pyc +0 -0
  2. app.py +54 -21
__pycache__/app.cpython-310.pyc CHANGED
Binary files a/__pycache__/app.cpython-310.pyc and b/__pycache__/app.cpython-310.pyc differ
 
app.py CHANGED
@@ -1,4 +1,5 @@
1
  import os
 
2
  import time
3
  import json
4
  import difflib
@@ -71,7 +72,47 @@ If and ONLY IF the USER QUESTION itself is in-domain:
71
  - Answer using ONLY the RETRIEVED MEDICAL EVIDENCE.
72
  - Do NOT use pretrained/background medical knowledge.
73
  - Do NOT guess or invent missing details.
74
- - Cite supporting [doc_id] for every medical claim.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
  ==================================================
77
  TYPE 2 — APP / IDENTITY QUESTIONS
@@ -222,7 +263,9 @@ If the evidence is insufficient or irrelevant, give a clear refusal.
222
  temperature=0.1,
223
  max_tokens=800,
224
  )
225
- return response.choices[0].message.content
 
 
226
  except Exception as e:
227
  # Fallback or error handling for Groq API
228
  return f"Error generating answer from LLM: {str(e)}"
@@ -304,18 +347,14 @@ class QueryRequest(BaseModel):
304
  top_k: Optional[int] = Field(default=6, ge=1, le=20)
305
 
306
  class EvidenceItem(BaseModel):
307
- doc_id: int
308
  question: str
309
  answer: str
310
  category: str
311
- similarity: float
312
- rerank_score: float
313
 
314
  class QueryResponse(BaseModel):
315
  status: str
316
  question: str
317
  answer: str
318
- evidence: List[EvidenceItem]
319
  execution_time_sec: float
320
 
321
  # ==========================================
@@ -337,40 +376,34 @@ def health_check():
337
  "model_loaded": "embedder" in rag_resources
338
  }
339
 
340
- @app.post("/predict", response_model=QueryResponse, tags=["RAG Inference"])
341
- @app.post("/query", response_model=QueryResponse, tags=["RAG Inference"])
342
- def predict(payload: QueryRequest):
343
  start_time = time.time()
344
-
345
  try:
346
- # Step 1: Vector Search
347
  candidates = vector_search(payload.question, top_n=RAG_CONFIG.get("retrieve_top_n", 20))
348
-
349
- # Step 2: Cross Encoder Rerank
350
  reranked_df = rerank(payload.question, candidates, top_k=payload.top_k)
351
-
352
- # Step 3: Deduplicate Evidence
353
  evidence = build_evidence(reranked_df)
354
-
355
- # Step 4: Generate LLM Answer
356
  answer = generate_answer(payload.question, payload.user_data or "", evidence)
357
-
358
  elapsed = round(time.time() - start_time, 3)
359
-
360
  return QueryResponse(
361
  status="success",
362
  question=payload.question,
363
  answer=answer,
364
- evidence=[EvidenceItem(**item) for item in evidence],
365
  execution_time_sec=elapsed
366
  )
367
-
368
  except Exception as e:
369
  raise HTTPException(
370
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
371
  detail=f"An error occurred during inference: {str(e)}"
372
  )
373
 
 
 
 
 
 
 
 
 
374
  if __name__ == "__main__":
375
  import uvicorn
376
  uvicorn.run("app:app", host="127.0.0.1", port=8000, reload=True)
 
1
  import os
2
+ import re
3
  import time
4
  import json
5
  import difflib
 
72
  - Answer using ONLY the RETRIEVED MEDICAL EVIDENCE.
73
  - Do NOT use pretrained/background medical knowledge.
74
  - Do NOT guess or invent missing details.
75
+
76
+ ==================================================
77
+ DOSAGE & TREATMENT SAFETY — MANDATORY RULES
78
+ ==================================================
79
+ These rules OVERRIDE everything else for any answer involving medications,
80
+ insulin, doses, units, quantities, or treatment amounts:
81
+
82
+ 1. NEVER extract a numeric dosage from a retrieved document that describes
83
+ a SPECIFIC PATIENT CASE and present it as a general recommendation.
84
+
85
+ 2. A dosage found in evidence is ONLY valid for the exact clinical scenario
86
+ described in that document (e.g., specific blood glucose level, patient
87
+ weight, insulin type, diabetes type, age, medical history).
88
+
89
+ 3. If the user's question is GENERAL (e.g., "How much insulin should I take?")
90
+ and the evidence only contains case-specific dosages, you MUST NOT quote
91
+ those numbers as a general answer.
92
+
93
+ 4. For ANY medication dosage question where the evidence is:
94
+ - Case-specific (belongs to a specific patient scenario), OR
95
+ - Contradicted by other evidence, OR
96
+ - Insufficient to determine a safe dose for the user's exact situation:
97
+ → Explicitly state that the dose CANNOT be determined from the available
98
+ information without individual physician assessment.
99
+ → Always direct the user to consult their treating physician.
100
+
101
+ 5. Do NOT present partial evidence (one document saying "4-8 units") as a
102
+ complete answer when other evidence clearly states that doses are
103
+ patient-specific and require physician supervision.
104
+
105
+ EXAMPLE — WRONG (do not do this):
106
+ User: "How much insulin should I take?"
107
+ Evidence has: "If sugar > 300, inject 4-8 units"
108
+ WRONG answer: "You may need 4-8 units of insulin."
109
+
110
+ EXAMPLE — CORRECT:
111
+ User: "How much insulin should I take?"
112
+ CORRECT answer: "Insulin doses cannot be determined from general guidelines.
113
+ They depend on your blood sugar level, weight, type of diabetes, insulin type,
114
+ and medical history. You must consult your treating physician to determine the
115
+ appropriate dose for your specific situation."
116
 
117
  ==================================================
118
  TYPE 2 — APP / IDENTITY QUESTIONS
 
263
  temperature=0.1,
264
  max_tokens=800,
265
  )
266
+ answer = response.choices[0].message.content
267
+ answer = re.sub(r'\[\d+\]', '', answer)
268
+ return answer
269
  except Exception as e:
270
  # Fallback or error handling for Groq API
271
  return f"Error generating answer from LLM: {str(e)}"
 
347
  top_k: Optional[int] = Field(default=6, ge=1, le=20)
348
 
349
  class EvidenceItem(BaseModel):
 
350
  question: str
351
  answer: str
352
  category: str
 
 
353
 
354
  class QueryResponse(BaseModel):
355
  status: str
356
  question: str
357
  answer: str
 
358
  execution_time_sec: float
359
 
360
  # ==========================================
 
376
  "model_loaded": "embedder" in rag_resources
377
  }
378
 
379
+ def _run_rag(payload: QueryRequest) -> QueryResponse:
 
 
380
  start_time = time.time()
 
381
  try:
 
382
  candidates = vector_search(payload.question, top_n=RAG_CONFIG.get("retrieve_top_n", 20))
 
 
383
  reranked_df = rerank(payload.question, candidates, top_k=payload.top_k)
 
 
384
  evidence = build_evidence(reranked_df)
 
 
385
  answer = generate_answer(payload.question, payload.user_data or "", evidence)
 
386
  elapsed = round(time.time() - start_time, 3)
 
387
  return QueryResponse(
388
  status="success",
389
  question=payload.question,
390
  answer=answer,
 
391
  execution_time_sec=elapsed
392
  )
 
393
  except Exception as e:
394
  raise HTTPException(
395
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
396
  detail=f"An error occurred during inference: {str(e)}"
397
  )
398
 
399
+ @app.post("/query", response_model=QueryResponse, tags=["RAG Inference"])
400
+ def query(payload: QueryRequest):
401
+ return _run_rag(payload)
402
+
403
+ @app.post("/predict", response_model=QueryResponse, tags=["RAG Inference"])
404
+ def predict(payload: QueryRequest):
405
+ return _run_rag(payload)
406
+
407
  if __name__ == "__main__":
408
  import uvicorn
409
  uvicorn.run("app:app", host="127.0.0.1", port=8000, reload=True)