Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ New here? Start with a 5-minute notebook and work your way up:
| Notebook | What you'll build | Time | |
|---|---|---|---|
| [Hello Mellea](https://colab.research.google.com/github/generative-computing/granite-switch/blob/main/tutorials/notebooks/hello_mellea.ipynb) | Call adapters through a clean Python API | 5 min | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/generative-computing/granite-switch/blob/main/tutorials/notebooks/hello_mellea.ipynb) |
| [RAG Pipeline](https://colab.research.google.com/github/generative-computing/granite-switch/blob/main/tutorials/notebooks/rag_full_pipeline.ipynb) | Query rewrite + answerability + citations in one model | 30 min | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/generative-computing/granite-switch/blob/main/tutorials/notebooks/rag_full_pipeline.ipynb) |
| [RAG Flow](https://colab.research.google.com/github/generative-computing/granite-switch/blob/main/tutorials/notebooks/rag_flow.ipynb) | Query rewrite + answerability + citations in one model | 30 min | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/generative-computing/granite-switch/blob/main/tutorials/notebooks/rag_flow.ipynb) |
| [Compose Your Own](https://colab.research.google.com/github/generative-computing/granite-switch/blob/main/tutorials/notebooks/compose_granite_switch.ipynb) | Build a custom checkpoint from adapter function libraries | 15 min | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/generative-computing/granite-switch/blob/main/tutorials/notebooks/compose_granite_switch.ipynb) |

All notebooks run on Colab. See [tutorials/README.md](tutorials/README.md) for the full list and guided learning paths.
Expand Down
150 changes: 6 additions & 144 deletions src/granite_switch/tutorials/rag_display.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
"""Display helpers for the govt RAG pipeline tutorials (03_01, 03_02).
"""Display helpers for the govt RAG flow tutorial.

Formatting / pretty-printing only. Each tutorial uses a different
`show_intermediates` variant to match its pipeline shape:

- `show_intermediates_simple` - 03_01 (no guardian, no retries)
- `show_intermediates_sequential` - 03_02 (harm + scope guardian, no retries)

`show_answer` and `show_history` work for both pipelines
(blocked-state branches are no-ops when `r["blocked"]` is absent).
Formatting / pretty-printing only. Blocked-state branches in
`show_answer` are no-ops when `r["blocked"]` is absent.
"""

import json
Expand All @@ -22,7 +16,7 @@ def _is_clear(clarification):


def show_answer(r):
"""Pretty-print a single pipeline result. Handles all four terminal states."""
"""Pretty-print a single flow result. Handles all four terminal states."""
lines = [f"**Q:** {r['query']}", "---"]
if r.get("blocked"):
lines.append(f"⛔ **BLOCKED** — {r['block_reason']}")
Expand Down Expand Up @@ -53,54 +47,8 @@ def show_history(ctx):
display(Markdown("\n\n".join(md)))


def show_intermediates_simple(r, top_k):
"""03_01 simple pipeline: rewrite -> retrieve -> answerability -> clarify -> answer -> citations."""
md = ["---", f"### Intermediates — *{r['query']}*", "---"]

md.append(f"**[1] Query Rewrite**\n\n"
f"| | |\n|---|---|\n"
f"| original | {r['query']} |\n"
f"| rewritten | {r.get('rewritten_query')} |")

docs = r.get("documents", [])
md.append(f"\n**[2] ChromaDB Retrieval** — {len(docs)} doc(s) (top {top_k}, cosine sim)")
if docs:
md.append(f"\n<details><summary>Show all {len(docs)} documents</summary>\n")
for i, d in enumerate(docs):
md.append(f"<details><summary>Document {i+1}</summary>\n\n```\n{d}\n```\n\n</details>\n")
md.append("</details>")

answerability = r.get("answerability")
if answerability is not None:
badge = "answerable" if not r.get("unanswerable") else "unanswerable"
md.append(f"\n**[3] Answerability** — {badge} &nbsp;&nbsp; `verdict={answerability}`")
if r.get("unanswerable"):
display(Markdown("\n\n".join(md)))
return

clar = r.get("clarification", "")
badge = "CLEAR" if _is_clear(clar) else "needs clarification"
md.append(f"\n**[4] Clarification** — {badge}")
if r.get("needs_clarification"):
md.append(f"\n> {clar}")
display(Markdown("\n\n".join(md)))
return

ans = r.get("answer", "")
md.append(f"\n**[5] Answer** — {len(ans)} chars\n\n> {ans}")

citations = r.get("citations", [])
md.append(f"\n**[6] Citations** — {len(citations)} found")
if citations:
md.append(f"\n<details><summary>Show citations JSON</summary>\n\n```json\n{json.dumps(citations, indent=2)}\n```\n\n</details>")
else:
md.append("\n*(none)*")

display(Markdown("\n\n".join(md)))


def show_intermediates_sequential(r, top_k):
"""03_02 sequential pipeline: harm + scope guardian -> rewrite -> retrieve -> answerability -> clarify -> answer -> citations."""
def show_intermediates(r, top_k):
"""Flow: harm + scope guardian -> rewrite -> retrieve -> answerability -> clarify -> answer -> citations."""
md = ["---", f"### Intermediates - *{r['query']}*", "---"]

harm_score = r.get("guardian_harm_score", 0)
Expand Down Expand Up @@ -163,89 +111,3 @@ def show_intermediates_sequential(r, top_k):
display(Markdown("\n\n".join(md)))


def show_intermediates_loops(r, top_k):
"""03_03 loops pipeline: harm guardian -> scope retry loop -> rewrite -> answerability retry loop -> clarify -> answer -> citations."""
md = ["---", f"### Intermediates — *{r['query']}*", "---"]

# [1] Harm
harm_score = r.get("guardian_harm_score", 0)
harm_badge = "safe" if harm_score < 0.5 else "harmful"
md.append(f"**[1] Guardian — Harm** — {harm_badge} &nbsp;&nbsp; `score={harm_score:.3f}`")

if r.get("blocked") and "Harmful" in r.get("block_reason", ""):
md.append(f"\n> BLOCKED: {r['block_reason']}")
display(Markdown("\n\n".join(md)))
return

# [2] Scope retry loop
scope_attempts = r.get("scope_attempts", [])
if scope_attempts:
n = len(scope_attempts)
last = scope_attempts[-1]
passed = last["score"] >= 0.5
badge = "in-scope" if passed else "out-of-scope"
md.append(f"\n**[2] Scope retry loop** — {badge} &nbsp;&nbsp; ({n} attempt(s))")
md.append("\n| Attempt | Query | Score | Result |")
md.append("|---------|-------|-------|--------|")
for i, att in enumerate(scope_attempts):
result = "in-scope" if att["score"] >= 0.5 else "out-of-scope"
md.append(f"| {i+1} | {att['query'][:60]}{'...' if len(att['query'])>60 else ''} | {att['score']:.3f} | {result} |")

if r.get("blocked"):
md.append(f"\n> BLOCKED: {r['block_reason']}")
display(Markdown("\n\n".join(md)))
return

# [3] Query Rewrite
md.append(f"\n**[3] Query Rewrite**\n\n"
f"| | |\n|---|---|\n"
f"| original | {r['query']} |\n"
f"| rewritten | {r.get('rewritten_query')} |")

# [4] Answerability retry loop
ans_attempts = r.get("answerability_attempts", [])
if ans_attempts:
n = len(ans_attempts)
last = ans_attempts[-1]
passed = last["verdict"] != "unanswerable"
badge = "answerable" if passed else "unanswerable"
md.append(f"\n**[4] Answerability retry loop** — {badge} &nbsp;&nbsp; ({n} attempt(s))")
md.append("\n| Attempt | Query | Verdict |")
md.append("|---------|-------|---------|")
for i, att in enumerate(ans_attempts):
md.append(f"| {i+1} | {att['query'][:60]}{'...' if len(att['query'])>60 else ''} | {att['verdict']} |")

if r.get("unanswerable"):
display(Markdown("\n\n".join(md)))
return

docs = r.get("documents", [])
md.append(f"\n**Retrieval** — {len(docs)} doc(s) (top {top_k}, cosine sim)")
if docs:
md.append(f"\n<details><summary>Show all {len(docs)} documents</summary>\n")
for i, d in enumerate(docs):
md.append(f"<details><summary>Document {i+1}</summary>\n\n```\n{d}\n```\n\n</details>\n")
md.append("</details>")

# [5] Clarification
clar = r.get("clarification", "")
badge = "CLEAR" if _is_clear(clar) else "needs clarification"
md.append(f"\n**[5] Clarification** — {badge}")
if r.get("needs_clarification"):
md.append(f"\n> {clar}")
display(Markdown("\n\n".join(md)))
return

# [6] Answer
ans = r.get("answer", "")
md.append(f"\n**[6] Answer** — {len(ans)} chars\n\n> {ans}")

# [7] Citations
citations = r.get("citations", [])
md.append(f"\n**[7] Citations** — {len(citations)} found")
if citations:
md.append(f"\n<details><summary>Show citations JSON</summary>\n\n```json\n{json.dumps(citations, indent=2)}\n```\n\n</details>")
else:
md.append("\n*(none)*")

display(Markdown("\n\n".join(md)))
8 changes: 4 additions & 4 deletions tutorials/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Step-by-step walkthroughs covering adapter function invocation, pipeline constru
|----------|--------|----------|-------|
| [hello_mellea.ipynb](notebooks/hello_mellea.ipynb) | Mellea adapter functions intro with vLLM | 5 min | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/generative-computing/granite-switch/blob/main/tutorials/notebooks/hello_mellea.ipynb) |
| [rag_101.ipynb](notebooks/rag_101.ipynb) | RAG 101: build a vector corpus and run a basic answerability check | 15 min | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/generative-computing/granite-switch/blob/main/tutorials/notebooks/rag_101.ipynb) |
| [rag_full_flow.ipynb](notebooks/rag_full_flow.ipynb) | Full RAG pipeline with guardian checks (harm + scope) | 30 min | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/generative-computing/granite-switch/blob/main/tutorials/notebooks/rag_full_flow.ipynb) |
| [rag_flow.ipynb](notebooks/rag_flow.ipynb) | Full RAG flow with guardian checks (harm + scope) | 30 min | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/generative-computing/granite-switch/blob/main/tutorials/notebooks/rag_flow.ipynb) |
| [compose_granite_switch.ipynb](notebooks/compose_granite_switch.ipynb) | Compose a checkpoint from adapter libraries | 15 min | |
| [alora_vs_lora_race.ipynb](notebooks/alora_vs_lora_race.ipynb) | ALORA vs LoRA race: side-by-side throughput comparison on a multi-step RAG pipeline | 20 min | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/generative-computing/granite-switch/blob/main/tutorials/notebooks/alora_vs_lora_race.ipynb) |
| [hello_adapter.ipynb](notebooks/hello_adapter.ipynb) | Minimal adapter function invocation with HuggingFace | 5 min | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/generative-computing/granite-switch/blob/main/tutorials/notebooks/hello_adapter.ipynb) |
Expand Down Expand Up @@ -51,7 +51,7 @@ support coming soon.
Best for: Seeing how adapter functions compose into multi-step applications

1. [RAG 101](notebooks/rag_101.ipynb) - corpus build + answerability check, the smallest end-to-end RAG demo [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/generative-computing/granite-switch/blob/main/tutorials/notebooks/rag_101.ipynb)
2. [Full RAG Pipeline with Guardians](notebooks/rag_full_flow.ipynb) - rewrite, answerability, citations, harm + scope checks [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/generative-computing/granite-switch/blob/main/tutorials/notebooks/rag_full_flow.ipynb)
2. [Full RAG Flow with Guardians](notebooks/rag_flow.ipynb) - rewrite, answerability, citations, harm + scope checks [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/generative-computing/granite-switch/blob/main/tutorials/notebooks/rag_flow.ipynb)



Expand Down Expand Up @@ -94,8 +94,8 @@ Granite Switch checkpoints embed adapters drawn from IBM's granitelib libraries.
| Adapter | Purpose | Where used in tutorials | HF repo |
|---------|---------|-------------------------|---------|
| Core | Foundational post-generation adapter functions: certainty scoring, requirement checking, and response attribution. | [granite_switch_with_hf](notebooks/granite_switch_with_hf.ipynb), [compose_granite_switch](notebooks/compose_granite_switch.ipynb) | [ibm-granite/granitelib-core-r1.0](https://huggingface.co/ibm-granite/granitelib-core-r1.0) |
| RAG | Retrieval-augmented generation adapter functions: query rewrite, answerability, hallucination detection, and citation generation. | [hello_mellea](notebooks/hello_mellea.ipynb), [rag_101](notebooks/rag_101.ipynb), [rag_full_flow](notebooks/rag_full_flow.ipynb), [compose_granite_switch](notebooks/compose_granite_switch.ipynb) | [ibm-granite/granitelib-rag-r1.0](https://huggingface.co/ibm-granite/granitelib-rag-r1.0) |
| Guardian | Safety and risk detection: harm, social bias, jailbreaking, factuality, and policy compliance checks. | [hello_adapter](notebooks/hello_adapter.ipynb), [hello_mellea](notebooks/hello_mellea.ipynb), [granite_switch_with_hf](notebooks/granite_switch_with_hf.ipynb), [rag_full_flow](notebooks/rag_full_flow.ipynb), [compose_granite_switch](notebooks/compose_granite_switch.ipynb) | [ibm-granite/granitelib-guardian-r1.0](https://huggingface.co/ibm-granite/granitelib-guardian-r1.0) |
| RAG | Retrieval-augmented generation adapter functions: query rewrite, answerability, hallucination detection, and citation generation. | [hello_mellea](notebooks/hello_mellea.ipynb), [rag_101](notebooks/rag_101.ipynb), [rag_flow](notebooks/rag_flow.ipynb), [compose_granite_switch](notebooks/compose_granite_switch.ipynb) | [ibm-granite/granitelib-rag-r1.0](https://huggingface.co/ibm-granite/granitelib-rag-r1.0) |
| Guardian | Safety and risk detection: harm, social bias, jailbreaking, factuality, and policy compliance checks. | [hello_adapter](notebooks/hello_adapter.ipynb), [hello_mellea](notebooks/hello_mellea.ipynb), [granite_switch_with_hf](notebooks/granite_switch_with_hf.ipynb), [rag_flow](notebooks/rag_flow.ipynb), [compose_granite_switch](notebooks/compose_granite_switch.ipynb) | [ibm-granite/granitelib-guardian-r1.0](https://huggingface.co/ibm-granite/granitelib-guardian-r1.0) |

## External Resources

Expand Down
Loading