"""Q&A module — answers nursing questions from the wiki using Claude.""" import anthropic QA_SYSTEM_PROMPT = """You are a nursing knowledge assistant for the Nursing Citizen Development Organisation. You answer questions by drawing on a curated nursing knowledge wiki aligned with NMC Standards of Proficiency (2018) and UK clinical practice. When answering: 1. Read the provided wiki articles carefully 2. Give a clear, accurate, clinically appropriate answer 3. Cite specific wiki articles you used (e.g. [[The NMC Code]]) 4. Suggest related articles the student might want to explore 5. Flag any clinical safety considerations prominently 6. Use UK clinical terminology and references (NICE, NMC, NHS, BNF) 7. Map your answer to NMC Proficiency platforms where relevant Always end with: "This tool supports but does not replace clinical judgment." Format your response in clean markdown with: - A direct answer paragraph - Key points as a bulleted list (if appropriate) - **NMC Proficiency**: which platforms are relevant - **Sources used**: list of wiki articles cited - **Explore further**: 2-3 related articles to read next """ ARTICLE_SELECTION_PROMPT = """You are selecting which wiki articles are most relevant to answer a nursing question. Given the question and a list of available articles, return the slugs of the 5-8 most relevant articles. Return only a JSON array of slugs, nothing else. Example: ["nmc_code", "abcde_assessment", "news2"] """ def select_relevant_articles(client: anthropic.Anthropic, question: str, article_index: dict, model: str = "claude-haiku-4-5-20251001") -> list[str]: """Use Claude Haiku to quickly identify the most relevant articles for a question.""" article_list = "\n".join([ f"- {slug}: {art['title']} ({art['category']}) — {', '.join(art.get('tags', []))}" for slug, art in article_index.items() ]) prompt = f"""Question: {question} Available wiki articles: {article_list} Return a JSON array of the 5-8 most relevant article slugs.""" response = client.messages.create( model=model, max_tokens=256, system=ARTICLE_SELECTION_PROMPT, messages=[{"role": "user", "content": prompt}], ) raw = response.content[0].text.strip() if raw.startswith("["): import json try: return json.loads(raw) except Exception: pass # Fallback: return all article slugs (up to 8) return list(article_index.keys())[:8] def answer_question(client: anthropic.Anthropic, question: str, articles: dict, model: str = "claude-sonnet-4-6") -> str: """ Answer a nursing question using the wiki. Returns a markdown-formatted answer with citations. """ # Select relevant articles relevant_slugs = select_relevant_articles(client, question, articles, model="claude-haiku-4-5-20251001") # Build context from selected articles context_parts = [] for slug in relevant_slugs: if slug in articles: art = articles[slug] context_parts.append(f"## {art['title']}\n{art['content']}\n") wiki_context = "\n---\n".join(context_parts) user_prompt = f"""## Nursing Question {question} ## Relevant Wiki Articles {wiki_context[:10000]} Please answer the question using the wiki content above.""" response = client.messages.create( model=model, max_tokens=2048, system=QA_SYSTEM_PROMPT, messages=[{"role": "user", "content": user_prompt}], ) return response.content[0].text.strip() def file_answer_to_wiki(client: anthropic.Anthropic, question: str, answer: str, model: str = "claude-haiku-4-5-20251001") -> dict: """ Convert a Q&A exchange into a wiki article for filing back. Returns article dict or None if not worth filing. """ import datetime prompt = f"""This Q&A exchange from a nursing knowledge base may be worth filing as a new wiki article. Question: {question} Answer: {answer} If this answer contains substantial reusable nursing knowledge not easily found in a single article, create a new wiki article. If not, return null. Return JSON: {{ "should_file": true/false, "slug": "article_slug", "title": "Article Title", "category": "category_name", "tags": ["tag1", "tag2"], "content": "Full markdown article content" }}""" response = client.messages.create( model=model, max_tokens=2048, messages=[{"role": "user", "content": prompt}], ) raw = response.content[0].text.strip() if raw.startswith("```"): raw = raw.split("\n", 1)[1].rsplit("```", 1)[0] import json result = json.loads(raw) if result.get("should_file"): result["last_updated"] = datetime.date.today().isoformat() result["sources"] = ["Q&A session"] return result return None