Skip to content

Commit 01ac0c0

Browse files
committed
Harden LLM relevance scoring prompt and evidence gating
1 parent 54a646f commit 01ac0c0

1 file changed

Lines changed: 35 additions & 4 deletions

File tree

app/paper_digest_app.py

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ class Paper:
106106
llm_relevance_text: str = ""
107107
llm_core_point_text: str = ""
108108
llm_usefulness_text: str = ""
109+
llm_evidence_spans: List[str] = field(default_factory=list)
109110

110111

111112
@dataclass
@@ -1772,14 +1773,16 @@ def annotate_papers_with_llm(
17721773
)
17731774

17741775
prompt = (
1775-
"You are a personalized research assistant for a medical-AI PhD researcher.\n"
1776+
"You are a personalized research assistant.\n"
1777+
"Evaluate how relevant each paper is to the user's research projects.\n"
17761778
"Project context:\n"
17771779
f"{project_context}\n\n"
17781780
"For each paper, do the following:\n"
17791781
"1) score relevance from 1 to 10\n"
17801782
f"2) write one short relevance reason in {output_language}\n"
17811783
f"3) write core-point summary in {output_language} using 3-4 short lines\n"
1782-
f"4) write usefulness explanation in {output_language} using 3-4 short lines\n\n"
1784+
f"4) write usefulness explanation in {output_language} using 3-4 short lines\n"
1785+
"5) provide 1-3 evidence spans (exact short phrases copied from title/abstract)\n\n"
17831786
"Return ONLY JSON object:\n"
17841787
"{\n"
17851788
' "items": [\n'
@@ -1788,11 +1791,21 @@ def annotate_papers_with_llm(
17881791
' "relevance_score": 1,\n'
17891792
' "relevance_reason": "...",\n'
17901793
' "core_point": "...",\n'
1791-
' "usefulness": "..."\n'
1794+
' "usefulness": "...",\n'
1795+
' "evidence_spans": ["...", "..."]\n'
17921796
" }\n"
17931797
" ]\n"
17941798
"}\n"
1795-
"Rules:\n"
1799+
"Scoring policy (strict):\n"
1800+
"- Hard-cap A: if 2 or more of these mismatch with project context, score must be <= 5:\n"
1801+
" disease/population, modality/data type, task/clinical objective.\n"
1802+
"- Hard-cap B: if overlap is only generic terms (e.g., 'medical AI', 'foundation model') "
1803+
"without concrete project fit, score must be <= 4.\n"
1804+
"- score >= 7 is allowed only when there is direct overlap in experiment design, dataset, "
1805+
"or clinical context with the user's project.\n"
1806+
"- 9-10 must be rare and reserved for near-direct project matches.\n"
1807+
"- Calibrate to avoid score inflation: unless this batch is unusually strong, most papers "
1808+
"should stay in the mid-range (about 3-6).\n"
17961809
"- score must be integer 1..10\n"
17971810
f"- score >= {min_score:.1f} means pass\n"
17981811
"- do not hallucinate beyond title and abstract\n"
@@ -1813,6 +1826,22 @@ def annotate_papers_with_llm(
18131826
score = float(item.get("relevance_score", 0))
18141827
except (TypeError, ValueError):
18151828
score = 0.0
1829+
evidence_spans: List[str] = []
1830+
evidence_raw = item.get("evidence_spans", [])
1831+
if isinstance(evidence_raw, list):
1832+
for span in evidence_raw[:3]:
1833+
text = clean_text(str(span))
1834+
if text:
1835+
evidence_spans.append(text[:220])
1836+
elif isinstance(evidence_raw, str):
1837+
for span in re.split(r"[\n;]+", evidence_raw):
1838+
text = clean_text(span)
1839+
if text:
1840+
evidence_spans.append(text[:220])
1841+
if len(evidence_spans) >= 3:
1842+
break
1843+
if score >= 7.0 and not evidence_spans:
1844+
score = 6.0
18161845
paper.score = max(0.0, min(10.0, score))
18171846
paper.llm_relevance_text = clean_text(
18181847
str(item.get("relevance_reason", item.get("relevance_reason_ko", "")))
@@ -1823,6 +1852,7 @@ def annotate_papers_with_llm(
18231852
paper.llm_usefulness_text = clean_text(
18241853
str(item.get("usefulness", item.get("usefulness_ko", "")))
18251854
)
1855+
paper.llm_evidence_spans = evidence_spans
18261856
paper.topic = "LLM-Relevance"
18271857

18281858
selected = [paper for paper in papers if paper.score >= min_score]
@@ -2708,6 +2738,7 @@ def run_digest(
27082738
"summary_relevance": paper.llm_relevance_text,
27092739
"summary_core": paper.llm_core_point_text,
27102740
"summary_usefulness": paper.llm_usefulness_text,
2741+
"summary_evidence_spans": paper.llm_evidence_spans,
27112742
}
27122743
for paper in papers
27132744
],

0 commit comments

Comments
 (0)