| """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 |
| |
| 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. |
| """ |
| |
| relevant_slugs = select_relevant_articles(client, question, articles, model="claude-haiku-4-5-20251001") |
|
|
| |
| 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 |
|
|