Skip to content

Commit 039ab03

Browse files
pjoshi30Preetam Joshi
andauthored
Added support for new hallucination detector. (#6)
* Added support for new hallucination detector. Includes a few other minor fixes. * Incrementing version --------- Co-authored-by: Preetam Joshi <info@aimon.ai>
1 parent ad51e39 commit 039ab03

File tree

5 files changed

+49
-23
lines changed

5 files changed

+49
-23
lines changed

aimon/client.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
from .utils.http import get_request, post_request, post_form_request
22
from .utils import AIMON_SDK_BACKEND_URL
3+
from .utils.retry import retry, RetryableError
34
from .models import MLModel, Application
45
from .dataset import Dataset, DatasetCollection
56
from .evaluation import Evaluation, Run
67
from .simple_client import SimpleAimonRelyClient
8+
from .metrics_config import Config
79
from typing import List, Dict, Any
10+
import requests
811

912

1013
class InvalidAPIKeyError(Exception):
@@ -17,6 +20,8 @@ class ApplicationStage:
1720

1821
class Client(object):
1922

23+
DETECTION_API_URL = "https://api.aimon.ai/v2/inference"
24+
2025
def __init__(self, api_key, email):
2126
self.api_key = api_key
2227
self.check_api_key()
@@ -129,11 +134,14 @@ def analyze(self, application, dataset_record, model_output, eval_run=None):
129134
data["evaluation_run_id"] = eval_run.id
130135
return post_request('{}/v1/save-compute-metrics'.format(AIMON_SDK_BACKEND_URL), headers=headers, data=[data])
131136

132-
def detect(self, data_to_send: List[Dict[str, Any]]):
137+
@retry(RetryableError)
138+
def detect(self, data_to_send: List[Dict[str, Any]], config=Config()):
133139
"""
134140
A synchronous API to detect quality metrics in the response of a language model.
135141
:param data_to_send: An array of dict objects where each dict contains a "context", a "generated_text" and
136142
optionally a "config" object
143+
:param config: The detector configuration that will be applied to every single request.
144+
137145
:return: A JSON object containing the following fields (if applicable):
138146
"hallucination": Indicates whether the response consisted of intrinsic or extrinsic hallucinations.
139147
"is_hallucinated": top level string indicating if hallucinated or not,
@@ -158,7 +166,26 @@ def detect(self, data_to_send: List[Dict[str, Any]]):
158166
"severe_toxic", "toxic": The response did not fall into the above 4 labels but is still considered
159167
either severely toxic or generally toxic content.
160168
"""
161-
return self._inline_client.detect(data_to_send)
169+
headers = {
170+
"Authorization": f"Bearer {self.api_key}",
171+
'Content-Type': 'application/json'
172+
}
173+
payload = []
174+
for item in data_to_send:
175+
if 'config' not in item:
176+
item['config'] = config.detectors
177+
payload.append(item)
178+
response = requests.post(self.DETECTION_API_URL, json=payload, headers=headers, timeout=30)
179+
if response.status_code in [503, 504]:
180+
raise RetryableError("Status code: {} received".format(response.status_code))
181+
if response.status_code == 401:
182+
raise InvalidAPIKeyError("Use a valid Aimon API key. Request it at info@aimon.ai or on Discord.")
183+
if response.status_code != 200:
184+
raise Exception(f"Error, bad response: {response}")
185+
if len(response.json()) == 0 or 'error' in response.json() or 'error' in response.json()[0]:
186+
raise Exception(
187+
f"Received an error in the response: {response if len(response.json()) == 0 else response.json()}")
188+
return response.json()
162189

163190
def get_dataset(self, name):
164191
headers = self.create_auth_header()

aimon/metrics_config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
class Config:
55
SUPPORTED_DETECTORS = {'hallucination': 'default', 'toxicity': 'default', 'conciseness': 'default',
66
'completeness': 'default'}
7-
SUPPORTED_VALUES = {'default'}
7+
SUPPORTED_VALUES = {'default', 'hall_v2'}
88

99
def __init__(self, detectors: Dict[str, str] = None):
1010
"""

examples/langchain_summarization_app.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from langchain.llms.openai import OpenAI
1010
from langchain.chains.summarize import load_summarize_chain
1111

12-
from aimon import SimpleAimonRelyClient, Config, InvalidAPIKeyError
12+
from aimon import Client, Config, InvalidAPIKeyError
1313

1414
# Streamlit app
1515
st.title('LangChain Text Summarizer')
@@ -26,8 +26,7 @@
2626
st.write(f"Please complete the missing fields.")
2727
else:
2828
try:
29-
aimon_rely_client = SimpleAimonRelyClient(aimon_api_key, config=Config(
30-
{'hallucination': 'default', 'conciseness': 'default', 'completeness': 'default'}))
29+
aimon_rely_client = Client(aimon_api_key, "preetam@aimon.ai")
3130
# Split the source text
3231
text_splitter = CharacterTextSplitter()
3332
texts = text_splitter.split_text(source_text)
@@ -50,8 +49,8 @@
5049
"context": source_text,
5150
"generated_text": summary
5251
}
53-
])
54-
# You could perform any action based on this reponse here
52+
], config=Config({'hallucination': 'default', 'conciseness': 'default', 'completeness': 'default'}))
53+
# You could perform any action based on this response here
5554
# ....
5655

5756
# Display the Aimon Rely response

examples/notebooks/aimon_sdk_langchain_summarization.ipynb

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"source": [
3030
"# Create the AIMon client. You would need an API Key (that can be retrieved from the UI in your user profile). \n",
3131
"# Your user email is also needed to track ownership of components such as datasets and applications.\n",
32-
"aimon_client = Client(api_key=\"YOUR AIMon API KEY HERE\", email=\"YOUR EMAIL ID HERE\")"
32+
"aimon_client = Client(api_key=\"YOUR API KEY HERE\", email=\"YOUR EMAIL HERE\")"
3333
]
3434
},
3535
{
@@ -100,7 +100,7 @@
100100
"from aimon import ApplicationStage\n",
101101
"# Using the AIMon client, create or get an existing application\n",
102102
"new_app = aimon_client.application(\n",
103-
" \"my_llm_summarization_app\", \n",
103+
" \"app_jun18_2024\", \n",
104104
" my_model, \n",
105105
" stage=ApplicationStage.EVALUATION, \n",
106106
" app_type=\"summarization\", \n",
@@ -120,17 +120,17 @@
120120
},
121121
{
122122
"cell_type": "code",
123-
"execution_count": null,
123+
"execution_count": 6,
124124
"id": "11e5fc3a-da44-4fda-b29a-a691569487d5",
125125
"metadata": {},
126126
"outputs": [],
127127
"source": [
128-
"openai_api_key = \"YOUR API KEY HERE\""
128+
"openai_api_key = \"YOUR OPEN AI KEY HERE\""
129129
]
130130
},
131131
{
132132
"cell_type": "code",
133-
"execution_count": 6,
133+
"execution_count": 8,
134134
"id": "af98abfc-c04d-4cc7-ba3c-62f550de0c99",
135135
"metadata": {},
136136
"outputs": [],
@@ -187,7 +187,7 @@
187187
},
188188
{
189189
"cell_type": "code",
190-
"execution_count": 7,
190+
"execution_count": 9,
191191
"id": "34881793-3778-4114-8066-7c41cfb6d462",
192192
"metadata": {},
193193
"outputs": [],
@@ -199,7 +199,7 @@
199199
},
200200
{
201201
"cell_type": "code",
202-
"execution_count": 8,
202+
"execution_count": 10,
203203
"id": "c7cc2795-6010-479a-90c0-bd275589f0cf",
204204
"metadata": {},
205205
"outputs": [],
@@ -220,7 +220,7 @@
220220
},
221221
{
222222
"cell_type": "code",
223-
"execution_count": 9,
223+
"execution_count": 11,
224224
"id": "0dbceabd-a6a2-4671-959d-ca15025841b1",
225225
"metadata": {},
226226
"outputs": [],
@@ -245,7 +245,7 @@
245245
},
246246
{
247247
"cell_type": "code",
248-
"execution_count": 10,
248+
"execution_count": 12,
249249
"id": "0f7991bf-a7b5-42f6-9a45-08c66c98d41c",
250250
"metadata": {},
251251
"outputs": [],
@@ -269,7 +269,7 @@
269269
},
270270
{
271271
"cell_type": "code",
272-
"execution_count": 11,
272+
"execution_count": 13,
273273
"id": "7b76a493-8738-40ba-a722-e22425c37e1f",
274274
"metadata": {},
275275
"outputs": [],
@@ -284,17 +284,17 @@
284284
},
285285
{
286286
"cell_type": "code",
287-
"execution_count": 12,
287+
"execution_count": 14,
288288
"id": "c2706102-672d-4e11-b77b-c1110a31772f",
289289
"metadata": {},
290290
"outputs": [
291291
{
292292
"name": "stderr",
293293
"output_type": "stream",
294294
"text": [
295-
"/Users/preetamjoshi/projects/aimon/aimon-rely/artry/lib/python3.9/site-packages/langchain_core/_api/deprecation.py:119: LangChainDeprecationWarning: The class `OpenAI` was deprecated in LangChain 0.0.10 and will be removed in 0.3.0. An updated version of the class exists in the langchain-openai package and should be used instead. To use it run `pip install -U langchain-openai` and import as `from langchain_openai import OpenAI`.\n",
295+
"/Users/preetamjoshi/projects/aimon/aimon-rely/artry3/lib/python3.10/site-packages/langchain_core/_api/deprecation.py:139: LangChainDeprecationWarning: The class `OpenAI` was deprecated in LangChain 0.0.10 and will be removed in 0.3.0. An updated version of the class exists in the langchain-openai package and should be used instead. To use it run `pip install -U langchain-openai` and import as `from langchain_openai import OpenAI`.\n",
296296
" warn_deprecated(\n",
297-
"/Users/preetamjoshi/projects/aimon/aimon-rely/artry/lib/python3.9/site-packages/langchain_core/_api/deprecation.py:119: LangChainDeprecationWarning: The method `Chain.run` was deprecated in langchain 0.1.0 and will be removed in 0.3.0. Use invoke instead.\n",
297+
"/Users/preetamjoshi/projects/aimon/aimon-rely/artry3/lib/python3.10/site-packages/langchain_core/_api/deprecation.py:139: LangChainDeprecationWarning: The method `Chain.run` was deprecated in langchain 0.1.0 and will be removed in 0.3.0. Use invoke instead.\n",
298298
" warn_deprecated(\n"
299299
]
300300
},
@@ -404,7 +404,7 @@
404404
"name": "python",
405405
"nbconvert_exporter": "python",
406406
"pygments_lexer": "ipython3",
407-
"version": "3.9.0"
407+
"version": "3.10.13"
408408
}
409409
},
410410
"nbformat": 4,

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
name='aimon',
55
python_requires='>3.8.0',
66
packages=find_packages(),
7-
version="0.2.0",
7+
version="0.3.0",
88
install_requires=[
99
"requests"
1010
],

0 commit comments

Comments
 (0)