diff --git a/README.md b/README.md index f45eb28e8..77704265e 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,6 @@ rails: - self check facts - self check hallucination - activefence moderation - - gotitai rag truthcheck config: # Configure the types of entities that should be masked on user input. diff --git a/docs/user-guides/community/gotitai.md b/docs/user-guides/community/gotitai.md deleted file mode 100644 index 7c30ba2a9..000000000 --- a/docs/user-guides/community/gotitai.md +++ /dev/null @@ -1,35 +0,0 @@ -# Got It AI Integration - -```{warning} -**Deprecation Notice:** -The Got It AI integration has been deprecated and will be discontinued on 15th December, 2024. -``` - -NeMo Guardrails integrates with [Got It AI's Hallucination Manager](https://www.app.got-it.ai/hallucination-manager) for hallucination detection in RAG systems. The Hallucination Manager's TruthChecker API is designed to detect and manage hallucinations in AI models, specifically for real-world RAG applications. - -Existing fact-checking methods are not sufficient to detect hallucinations in AI models for real-world RAG applications. The TruthChecker API performs a dual task to determine whether a response is a `hallucination` or not: - -1. Check for the faithfulness of the generated response to the retrieved knowledge chunks. -2. Check for the relevance of the response to the user query and the conversation history. - -The TruthChecker API can be configured to work for open-domain use-case or for a specific domain or knowledge base. By default, the TruthChecker API is configured to work for open-domain and we expect it to deliver strong performance on specific domains. However, for an enhanced experience for a specific domain or knowledge base, you can fine-tuning the model on the knowledge base and unlock benefits like secure on-premise model deployments. - -Please [contact the Got It AI team](https://www.app.got-it.ai/) for more information on how to fine-tune the TruthChecker API for your specific domain or knowledge base. - -To integrate the TruthChecker API with NeMo Guardrails, the `GOTITAI_API_KEY` environment variable needs to be set. - -```yaml -rails: - output: - flows: - - gotitai rag truthcheck -``` - -To trigger the fact-checking rail, you have to set the `$check_facts` context variable to `True` before a bot message that requires fact-checking, e.g.: - -```colang -define flow - user ask about report - $check_facts = True - bot provide report answer -``` diff --git a/docs/user-guides/guardrails-library.md b/docs/user-guides/guardrails-library.md index 14b84fe44..cd65dcd48 100644 --- a/docs/user-guides/guardrails-library.md +++ b/docs/user-guides/guardrails-library.md @@ -624,26 +624,6 @@ rails: For more details, check out the [ActiveFence Integration](./community/active-fence.md) page. -### Got It AI - -```{warning} -**Deprecation Notice:** -The Got It AI integration has been deprecated and will be discontinued on 15th December, 2024. -``` - -NeMo Guardrails integrates with [Got It AI's Hallucination Manager](https://www.app.got-it.ai/hallucination-manager) for hallucination detection in RAG systems. To integrate the TruthChecker API with NeMo Guardrails, the `GOTITAI_API_KEY` environment variable needs to be set. - -#### Example usage - -```yaml -rails: - output: - flows: - - gotitai rag truthcheck -``` - -For more details, check out the [Got It AI Integration](./community/gotitai.md) page. - ### AutoAlign NeMo Guardrails supports using the AutoAlign's guardrails API (you need to have the `AUTOALIGN_API_KEY` environment variable set). diff --git a/examples/sample_config.yml b/examples/sample_config.yml index f137e8d7a..254a8d3fb 100644 --- a/examples/sample_config.yml +++ b/examples/sample_config.yml @@ -37,7 +37,6 @@ rails: - self check hallucination - activefence moderation - check sensitive data - - gotitai rag truthcheck # Execution rails are triggered before and after an action is invoked # TODO diff --git a/nemoguardrails/library/gotitai/__init__.py b/nemoguardrails/library/gotitai/__init__.py deleted file mode 100644 index 9ba9d4310..000000000 --- a/nemoguardrails/library/gotitai/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. diff --git a/nemoguardrails/library/gotitai/actions.py b/nemoguardrails/library/gotitai/actions.py deleted file mode 100644 index a5cba7d1b..000000000 --- a/nemoguardrails/library/gotitai/actions.py +++ /dev/null @@ -1,93 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -import json -import logging -import os -from typing import Optional - -import aiohttp - -from nemoguardrails.actions import action - -log = logging.getLogger(__name__) - - -@action(name="call gotitai truthchecker api", is_system_action=True) -async def call_gotitai_truthchecker_api(context: Optional[dict] = None): - api_key = os.environ.get("GOTITAI_API_KEY") - - if api_key is None: - raise ValueError("GOTITAI_API_KEY environment variable not set.") - - if context is None: - raise ValueError( - "Context is empty. `user_message`, `bot_response` and `relevant_chunks` keys are required to call the GotIt AI Truthchecker api." - ) - - user_message = context.get("user_message", "") - response = context.get("bot_message", "") - knowledge = context.get("relevant_chunks_sep", []) - - retval = {"hallucination": None} # in case the api call is skipped - - if not isinstance(knowledge, list): - log.error( - "Could not run Got It AI Truthchecker. `relevant_chunks_sep` must be a list of knowledge." - ) - return retval - - if not knowledge: - log.error( - "Could not run Got It AI Truthchecker. At least 1 relevant chunk is required." - ) - return retval - - url = "https://api.got-it.ai/api/v1/hallucination-manager/truthchecker" - headers = { - "Content-Type": "application/json", - "Authorization": "Bearer " + api_key, - } - data = { - "knowledge": [ - { - "text": chunk, - } - for chunk in knowledge - ], - "prompt": user_message, - "generated_text": response, - # Messages is empty for now since there is no standard way to get them. - # This should be updated once 0.8.0 is released. - # Reference: https://github.com/NVIDIA/NeMo-Guardrails/issues/246 - "messages": [], - } - - async with aiohttp.ClientSession() as session: - async with session.post( - url=url, - headers=headers, - json=data, - ) as response: - if response.status != 200: - log.error( - f"GotItAI TruthChecking call failed with status code {response.status}.\n" - f"Details: {await response.json()}" - ) - response_json = await response.json() - log.info(json.dumps(response_json, indent=True)) - hallucination = response_json["hallucination"] - retval = {"hallucination": hallucination} - - return retval diff --git a/nemoguardrails/library/gotitai/flows.co b/nemoguardrails/library/gotitai/flows.co deleted file mode 100644 index 24c30c1ae..000000000 --- a/nemoguardrails/library/gotitai/flows.co +++ /dev/null @@ -1,14 +0,0 @@ -flow gotitai rag truthcheck - """Guardrail based on the maximum risk score.""" - if $check_facts == True - global $check_facts - $check_facts = False - - $result = await call gotitai truthchecker api - - if $result.hallucination == "yes" - if $system.config.enable_rails_exceptions - send GotitaiHallucinationRailException(message="Hallucination detected. The previous answer may not be accurate") - else - bot inform answer unknown - abort diff --git a/nemoguardrails/library/gotitai/flows.v1.co b/nemoguardrails/library/gotitai/flows.v1.co deleted file mode 100644 index 81b00428f..000000000 --- a/nemoguardrails/library/gotitai/flows.v1.co +++ /dev/null @@ -1,13 +0,0 @@ -define subflow gotitai rag truthcheck - """Guardrail based on the maximum risk score.""" - if $check_facts == True - $check_facts = False - - $result = execute call gotitai truthchecker api - - if $result.hallucination == "yes" - if $config.enable_rails_exceptions - create event GotitaiHallucinationRailException(message="Hallucination detected. The previous answer may not be accurate") - else - bot inform answer unknown - stop diff --git a/tests/test_configs/gotitai_truthchecker/config.yml b/tests/test_configs/gotitai_truthchecker/config.yml deleted file mode 100644 index fa7b5b4f5..000000000 --- a/tests/test_configs/gotitai_truthchecker/config.yml +++ /dev/null @@ -1,8 +0,0 @@ -models: - - type: main - engine: openai - model: gpt-3.5-turbo-instruct -rails: - output: - flows: - - gotitai rag truthcheck diff --git a/tests/test_configs/gotitai_truthchecker/truthcheck.co b/tests/test_configs/gotitai_truthchecker/truthcheck.co deleted file mode 100644 index 7dc12308f..000000000 --- a/tests/test_configs/gotitai_truthchecker/truthcheck.co +++ /dev/null @@ -1,10 +0,0 @@ -define user ask general question - "Do you ship within 2 days?" - -define flow - user ask general question - $check_facts = True - bot provide answer - -define bot inform answer unknown - "I don't know the answer to that." diff --git a/tests/test_gotitai_output_rail.py b/tests/test_gotitai_output_rail.py deleted file mode 100644 index 483f2abf4..000000000 --- a/tests/test_gotitai_output_rail.py +++ /dev/null @@ -1,115 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os - -import pytest -from aioresponses import aioresponses - -from nemoguardrails import RailsConfig -from nemoguardrails.actions.actions import ActionResult, action -from tests.utils import TestChat - -CONFIGS_FOLDER = os.path.join(os.path.dirname(__file__), ".", "test_configs") - -GOTITAI_API_URL = "https://api.got-it.ai/api/v1/hallucination-manager/truthchecker" - - -@action(is_system_action=True) -async def retrieve_relevant_chunks(): - """Retrieve relevant chunks from the knowledge base and add them to the context.""" - context_updates = {} - context_updates["relevant_chunks_sep"] = ["Shipping takes at least 3 days."] - - return ActionResult( - return_value=context_updates["relevant_chunks_sep"], - context_updates=context_updates, - ) - - -@pytest.mark.asyncio -async def test_hallucination(monkeypatch): - monkeypatch.setenv("GOTITAI_API_KEY", "xxx") - config = RailsConfig.from_path(os.path.join(CONFIGS_FOLDER, "gotitai_truthchecker")) - chat = TestChat( - config, - llm_completions=[ - "user ask general question", # user intent - "Yes, shipping can be done in 2 days.", # bot response that will be intercepted - ], - ) - - with aioresponses() as m: - chat.app.register_action(retrieve_relevant_chunks, "retrieve_relevant_chunks") - m.post( - GOTITAI_API_URL, - payload={ - "hallucination": "yes", - }, - ) - - chat >> "Do you ship within 2 days?" - await chat.bot_async("I don't know the answer to that.") - - -@pytest.mark.asyncio -async def test_not_hallucination(monkeypatch): - monkeypatch.setenv("GOTITAI_API_KEY", "xxx") - config = RailsConfig.from_path(os.path.join(CONFIGS_FOLDER, "gotitai_truthchecker")) - chat = TestChat( - config, - llm_completions=[ - # " express greeting", - "user ask general question", # user intent - "No, shipping takes at least 3 days.", # bot response that will not be intercepted - ], - ) - - with aioresponses() as m: - chat.app.register_action(retrieve_relevant_chunks, "retrieve_relevant_chunks") - m.post( - GOTITAI_API_URL, - payload={ - "hallucination": "no", - }, - ) - - chat >> "Do you ship within 2 days?" - await chat.bot_async("No, shipping takes at least 3 days.") - - -@pytest.mark.asyncio -async def test_no_context(monkeypatch): - monkeypatch.setenv("GOTITAI_API_KEY", "xxx") - config = RailsConfig.from_path(os.path.join(CONFIGS_FOLDER, "gotitai_truthchecker")) - chat = TestChat( - config, - llm_completions=[ - # " express greeting", - "user ask general question", # user intent - "Yes, shipping can be done in 2 days.", # bot response that will not be intercepted - ], - ) - - with aioresponses() as m: - m.post( - GOTITAI_API_URL, - payload={ - "hallucination": None, - }, - ) - - chat >> "Do you ship within 2 days?" - await chat.bot_async("Yes, shipping can be done in 2 days.")