Case-Studies-Agent / agents.py
abjasrees's picture
Update agents.py
eb9c861 verified
# agents.py
import os, json, textwrap, pathlib
from typing import Dict, Any, Tuple
from openai import OpenAI
from files_process import load_input_text
# ---------- Instructions ----------
def build_case_study_instructions() -> str:
return textwrap.dedent("""\
You are a senior medical writer specializing in AI in healthcare.
Using ONLY the provided INPUT (no fabrication), produce a professional case study in **Markdown**.
STRICT REQUIREMENTS (cite inline in prose, not as links):
- Use established reporting guidance:
β€’ CARE case reports for completeness/transparency (CARE, 2013/2017).
β€’ CONSORT-AI (trial reports) and SPIRIT-AI (protocols) where applicable (2020).
β€’ TRIPOD+AI (2024) for prediction model reporting (discrimination, calibration, validation).
β€’ HIPAA de-identification Safe Harbor: state that 18 identifiers are removed or avoided; avoid re-identification risk.
β€’ FDA AI/ML SaMD perspective: risk controls, monitoring, change management.
- If a section lacks data, write β€œNot specified.”
- Use a neutral, clinical tone (avoid marketing fluff).
- Prefer short paragraphs and tables where appropriate.
MANDATORY SECTIONS (use these exact headings):
# Title
## Executive Summary
- 3–6 bullets
## Clinical Context & Problem
## Patient/Population & Setting
## Data Sources & Governance
- Provenance; access; quality checks; de-identification approach (HIPAA Safe Harbor)
- Security/compliance: HIPAA (and GDPR if applicable)
## AI/ML Approach
- Task definition; target(s)
- Features/data preparation
- Model(s); training/validation split; external validation if any
- Fairness/bias checks
## Evaluation & Metrics if provided
- Classification/regression metrics
- Calibration; confidence estimation
- Clinical outcomes (if available)
- Reference TRIPOD+AI for what to report
## Workflow Integration & Safety
- Human oversight; failure modes; alerting
- Monitoring & model updates (FDA SaMD AI/ML perspective)
## Results & Impact
- Clinical impact; operational efficiency; ROI/costs where applicable
## Ethics & Bias Mitigation
## Regulatory, Privacy & Security
- HIPAA/GDPR; access controls; audit
## Limitations & Generalizability
## Conclusion
LENGTH: aim 4,000–5,800 words.
OUTPUT: Valid Markdown only.
DO NOT include code fences around the Markdown.
""")
def build_manager_instructions() -> str:
return textwrap.dedent("""\
You are the manager reviewing three case study drafts on AI in healthcare.
TASKS:
1) Rate each draft on a 1–10 scale for:
- Clinical completeness (CARE)
- AI reporting rigor (TRIPOD+AI)
- Trial/protocol framing where relevant (CONSORT-AI / SPIRIT-AI)
- Privacy & regulatory correctness (HIPAA Safe Harbor; FDA SaMD)
- Clarity & structure
2) Briefly justify each rating (1–3 sentences).
3) Pick a **single winner** among the three drafts (best overall).
OUTPUT JSON (strict):
{
"scores": [
{"agent": "agent1", "clinical_completeness": int, "ai_rigor": int, "trial_framing": int, "privacy_regulatory": int, "clarity_structure": int, "justification": "..."},
{"agent": "agent2", "clinical_completeness": int, "ai_rigor": int, "trial_framing": int, "privacy_regulatory": int, "clarity_structure": int, "justification": "..."},
{"agent": "agent3", "clinical_completeness": int, "ai_rigor": int, "trial_framing": int, "privacy_regulatory": int, "clarity_structure": int, "justification": "..."}
],
"winner": "agent1|agent2|agent3"
}
IMPORTANT:
- Return only JSON.
""")
# ---------- Agent calls (OpenAI SDK) ----------
def _openai_client() -> OpenAI:
return OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
def call_openai_case_study(input_text: str, model: str = "gpt-4o-mini") -> str:
client = _openai_client()
system = build_case_study_instructions()
prompt = f"INPUT:\n{input_text}\n\nFollow the instructions strictly."
resp = client.responses.create(
model=model,
instructions=system,
input=prompt,
temperature=0.3,
)
return resp.output_text.strip()
def call_gemini_case_study(input_text: str, model: str = "gpt-4.1-nano") -> str:
client = _openai_client()
system = build_case_study_instructions()
prompt = f"INPUT:\n{input_text}\n\nFollow the instructions strictly."
resp = client.responses.create(
model=model,
instructions=system,
input=prompt,
temperature=0.3,
)
return resp.output_text.strip()
def call_deepseek_case_study(input_text: str, model: str = "gpt-4.1-mini") -> str:
client = _openai_client()
system = build_case_study_instructions()
prompt = f"INPUT:\n{input_text}\n\nFollow the instructions strictly."
resp = client.responses.create(
model=model,
instructions=system,
input=prompt,
temperature=0.3,
)
return resp.output_text.strip()
def call_openai_manager(agent1: str, agent2: str, agent3: str,
model: str = "gpt-4o") -> Dict[str, Any]:
client = _openai_client()
manager_instr = build_manager_instructions()
payload = {
"agent1_draft": agent1,
"agent2_draft": agent2,
"agent3_draft": agent3,
}
resp = client.responses.create(
model=model,
instructions=manager_instr,
input=json.dumps(payload),
temperature=0.2,
#response_format={"type": "json_object"},
)
raw = resp.output_text
try:
return json.loads(raw)
except Exception as e:
# Fallback JSON slice
s, e2 = raw.find("{"), raw.rfind("}")
if s != -1 and e2 != -1 and e2 > s:
return json.loads(raw[s:e2+1])
raise RuntimeError(f"Manager returned non-JSON: {raw}") from e
# ---------- Orchestration ----------
def run_pipeline(file: str,
oai_model: str = "gpt-4o-mini",
gem_model: str = "gpt-4.1-nano",
ds_model: str = "gpt-4.1-mini") -> Dict[str, Any]:
"""
- Reads text (string or path) with load_input_text
- Calls three agents
- Saves their drafts as agent1.md / agent2.md / agent3.md
- Calls manager and returns its JSON (scores + winner)
"""
source_text = load_input_text(file)
print("Generating case studies with three agents...")
print("Generating Agent 1 Output...")
a1 = call_openai_case_study(source_text, model=oai_model)
print("Generating Agent 2 Output...")
a2 = call_gemini_case_study(source_text, model=gem_model)
print("Generating Agent 3 Output...")
a3 = call_deepseek_case_study(source_text, model=ds_model)
pathlib.Path("agent1.md").write_text(a1, encoding="utf-8")
pathlib.Path("agent2.md").write_text(a2, encoding="utf-8")
pathlib.Path("agent3.md").write_text(a3, encoding="utf-8")
print("Saved agent outputs to agent1.md, agent2.md, agent3.md")
print("Manager evaluating...")
result = call_openai_manager(a1, a2, a3)
return result