diff --git a/docs/examples/intrinsics/answer_relevance.py b/docs/examples/intrinsics/answer_relevance.py new file mode 100644 index 00000000..1be2b368 --- /dev/null +++ b/docs/examples/intrinsics/answer_relevance.py @@ -0,0 +1,26 @@ +""" +Example usage of the answer relevance intrinsic for RAG applications. + +To run this script from the root of the Mellea source tree, use the command: +``` +uv run python docs/examples/intrinsics/answer_relevance.py +``` +""" + +from mellea.backends.huggingface import LocalHFBackend +from mellea.stdlib.base import ChatContext, Document +from mellea.stdlib.chat import Message +from mellea.stdlib.intrinsics import rag + + +backend = LocalHFBackend(model_id="ibm-granite/granite-3.3-2b-instruct") +context = ChatContext().add(Message("user", "Who attended the meeting?")) +documents = [ + Document("Meeting attendees: Alice, Bob, Carol."), + Document("Meeting time: 9:00 am to 11:00 am."), +] +original_result = "Many people attended the meeting." + +print(f"Result before relevance intrinsic: {original_result}") +result = rag.rewrite_answer_for_relevance(original_result, documents, context, backend) +print(f"Result after relevance intrinsic: {result}") diff --git a/docs/examples/intrinsics/answerability.py b/docs/examples/intrinsics/answerability.py new file mode 100644 index 00000000..a3d20bc4 --- /dev/null +++ b/docs/examples/intrinsics/answerability.py @@ -0,0 +1,28 @@ +""" +Example usage of the answerability intrinsic for RAG applications. + +To run this script from the root of the Mellea source tree, use the command: +``` +uv run python docs/examples/intrinsics/answerability.py +``` +""" + +from mellea.backends.huggingface import LocalHFBackend +from mellea.stdlib.base import ChatContext, Document +from mellea.stdlib.chat import Message +from mellea.stdlib.intrinsics import rag + + +backend = LocalHFBackend(model_id="ibm-granite/granite-3.3-2b-instruct") +context = ChatContext().add(Message("assistant", "Hello there, how can I help you?")) +next_user_turn = "What is the square root of 4?" +documents_answerable = [Document("The square root of 4 is 2.")] +documents_unanswerable = [Document("The square root of 8 is not 2.")] + +result = rag.check_answerability(next_user_turn, documents_answerable, context, backend) +print(f"Result of answerability check when answer is in documents: {result}") + +result = rag.check_answerability( + next_user_turn, documents_unanswerable, context, backend +) +print(f"Result of answerability check when answer is not in documents: {result}") diff --git a/docs/examples/intrinsics/citations.py b/docs/examples/intrinsics/citations.py new file mode 100644 index 00000000..aa27ed00 --- /dev/null +++ b/docs/examples/intrinsics/citations.py @@ -0,0 +1,77 @@ +""" +Example usage of the citations intrinsic for RAG applications. + +To run this script from the root of the Mellea source tree, use the command: +``` +uv run python docs/examples/intrinsics/citations.py +``` +""" + +from mellea.backends.huggingface import LocalHFBackend +from mellea.stdlib.base import ChatContext, Document +from mellea.stdlib.chat import Message +from mellea.stdlib.intrinsics import rag +import json + + +backend = LocalHFBackend(model_id="ibm-granite/granite-3.3-2b-instruct") +context = ChatContext().add( + Message( + "user", + "How does Murdoch's expansion in Australia compare to his expansion " + "in New Zealand?", + ) +) +assistant_response = ( + "Murdoch expanded in Australia and New Zealand by acquiring and expanding local " + "newspapers. I do not have information about his expansion in New Zealand after " + "purchasing The Dominion." +) +documents = [ + Document( + doc_id="1", + text="Keith Rupert Murdoch was born on 11 March 1931 in Melbourne, Australia, " + "the son of Sir Keith Murdoch (1885-1952) and Dame Elisabeth Murdoch (nee " + "Greene; 1909-2012). He is of English, Irish, and Scottish ancestry. Murdoch's " + "parents were also born in Melbourne. Keith Murdoch was a war correspondent " + "and later a regional newspaper magnate owning two newspapers in Adelaide, " + "South Australia, and a radio station in a faraway mining town. Following his " + "father's death, when he was 21, Murdoch returned from Oxford to take charge " + "of the family business News Limited, which had been established in 1923. " + "Rupert Murdoch turned its Adelaide newspaper, The News, its main asset, into " + "a major success. He began to direct his attention to acquisition and " + "expansion, buying the troubled Sunday Times in Perth, Western Australia " + "(1956) and over the next few years acquiring suburban and provincial " + "newspapers in New South Wales, Queensland, Victoria and the Northern " + "Territory, including the Sydney afternoon tabloid, The Daily Mirror (1960). " + 'The Economist describes Murdoch as "inventing the modern tabloid", as he ' + "developed a pattern for his newspapers, increasing sports and scandal " + "coverage and adopting eye-catching headlines. Murdoch's first foray outside " + "Australia involved the purchase of a controlling interest in the New Zealand " + "daily The Dominion. In January 1964, while touring New Zealand with friends " + "in a rented Morris Minor after sailing across the Tasman, Murdoch read of a " + "takeover bid for the Wellington paper by the British-based Canadian newspaper " + "magnate, Lord Thomson of Fleet. On the spur of the moment, he launched a " + "counter-bid. A four-way battle for control ensued in which the 32-year-old " + "Murdoch was ultimately successful. Later in 1964, Murdoch launched The " + "Australian, Australia's first national daily newspaper, which was based " + "first in Canberra and later in Sydney. In 1972, Murdoch acquired the Sydney " + "morning tabloid The Daily Telegraph from Australian media mogul Sir Frank " + "Packer, who later regretted selling it to him. In 1984, Murdoch was appointed " + "Companion of the Order of Australia (AC) for services to publishing. In 1999, " + "Murdoch significantly expanded his music holdings in Australia by acquiring " + "the controlling share in a leading Australian independent label, Michael " + "Gudinski's Mushroom Records; he merged that with Festival Records, and the " + "result was Festival Mushroom Records (FMR). Both Festival and FMR were " + "managed by Murdoch's son James Murdoch for several years.", + ), + Document( + doc_id="2", + text="This document has nothing to do with Rupert Murdoch. This document is " + "two sentences long.", + ), +] + + +result = rag.find_citations(assistant_response, documents, context, backend) +print(f"Result of citations intrinsic:\n{json.dumps(result, indent=2)}") diff --git a/docs/examples/intrinsics/context_relevance.py b/docs/examples/intrinsics/context_relevance.py new file mode 100644 index 00000000..dcf24062 --- /dev/null +++ b/docs/examples/intrinsics/context_relevance.py @@ -0,0 +1,31 @@ +""" +Example usage of the context relevance intrinsic for RAG applications. + +To run this script from the root of the Mellea source tree, use the command: +``` +uv run python docs/examples/intrinsics/context_relevance.py +``` +""" + +from mellea.backends.huggingface import LocalHFBackend +from mellea.stdlib.base import ChatContext, Document +from mellea.stdlib.chat import Message +from mellea.stdlib.intrinsics import rag + + +backend = LocalHFBackend(model_id="ibm-granite/granite-3.3-2b-instruct") +context = ChatContext() +question = "Who is the CEO of Microsoft?" +document = Document( + # Document text does not say who is the CEO. + "Microsoft Corporation is an American multinational corporation and technology " + "conglomerate headquartered in Redmond, Washington.[2] Founded in 1975, the " + "company became influential in the rise of personal computers through software " + "like Windows, and the company has since expanded to Internet services, cloud " + "computing, video gaming and other fields. Microsoft is the largest software " + "maker, one of the most valuable public U.S. companies,[a] and one of the most " + "valuable brands globally." +) + +result = rag.check_context_relevance(question, document, context, backend) +print(f"Result of context relevance check: {result}") diff --git a/docs/examples/intrinsics/hallucination_detection.py b/docs/examples/intrinsics/hallucination_detection.py new file mode 100644 index 00000000..74ab966e --- /dev/null +++ b/docs/examples/intrinsics/hallucination_detection.py @@ -0,0 +1,34 @@ +""" +Example usage of the hallucination detection intrinsic for RAG applications. + +To run this script from the root of the Mellea source tree, use the command: +``` +uv run python docs/examples/intrinsics/hallucination_detection.py +``` +""" + +from mellea.backends.huggingface import LocalHFBackend +from mellea.stdlib.base import ChatContext, Document +from mellea.stdlib.chat import Message +from mellea.stdlib.intrinsics import rag +import json + + +backend = LocalHFBackend(model_id="ibm-granite/granite-3.3-2b-instruct") +context = ( + ChatContext() + .add(Message("assistant", "Hello there, how can I help you?")) + .add(Message("user", "Tell me about some yellow fish.")) +) + +assistant_response = "Purple bumble fish are yellow. Green bumble fish are also yellow." + +documents = [ + Document( + doc_id="1", + text="The only type of fish that is yellow is the purple bumble fish.", + ) +] + +result = rag.flag_hallucinated_content(assistant_response, documents, context, backend) +print(f"Result of hallucination check: {json.dumps(result, indent=2)}") diff --git a/docs/examples/intrinsics/query_rewrite.py b/docs/examples/intrinsics/query_rewrite.py new file mode 100644 index 00000000..e0ef32a1 --- /dev/null +++ b/docs/examples/intrinsics/query_rewrite.py @@ -0,0 +1,41 @@ +""" +Example usage of the query rewrite intrinsic for RAG applications. + +To run this script from the root of the Mellea source tree, use the command: +``` +uv run python docs/examples/intrinsics/query_rewrite.py +``` +""" + +from mellea.backends.huggingface import LocalHFBackend +from mellea.stdlib.base import ChatContext +from mellea.stdlib.chat import Message +from mellea.stdlib.intrinsics import rag + + +backend = LocalHFBackend(model_id="ibm-granite/granite-3.3-2b-instruct") +context = ( + ChatContext() + .add(Message("assistant", "Welcome to pet questions!")) + .add(Message("user", "I have two pets, a dog named Rex and a cat named Lucy.")) + .add( + Message( + "assistant", + "Rex spends a lot of time in the backyard and outdoors, " + "and Luna is always inside.", + ) + ) + .add( + Message( + "user", + "Sounds good! Rex must love exploring outside, while Lucy " + "probably enjoys her cozy indoor life.", + ) + ) +) +next_user_turn = "But is he more likely to get fleas because of that?" + +print(f"Original user question: {next_user_turn}") + +result = rag.rewrite_question(next_user_turn, context, backend) +print(f"Rewritten user question: {result}")