File size: 4,940 Bytes
3ebaeb6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
"""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