Skip to content

Commit 13a0fd9

Browse files
add public async methods for Get Explanations API (#118)
* add public async methods for Get Explanations API * prepare for release
1 parent e6469df commit 13a0fd9

File tree

4 files changed

+143
-14
lines changed

4 files changed

+143
-14
lines changed

CHANGELOG.md

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.1.31] - 2025-09-18
11+
12+
### Added
13+
14+
- Add `get_explanation_async()` API for TLM and TrustworthyRAG
15+
1016
## [1.1.30] - 2025-09-09
1117

1218
### Added
@@ -60,8 +66,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6066
### Changed
6167

6268
- Updated `TLMOptions` to support `disable_trustworthiness` parameter
63-
- Skips trustworthiness scoring when `disable_trustworthiness` is True, assuming either custom evaluation criteria (TLM) or RAG Evals (TrustworthyRAG) are provided
64-
69+
- Skips trustworthiness scoring when `disable_trustworthiness` is True, assuming either custom evaluation criteria (TLM) or RAG Evals (TrustworthyRAG) are provided
6570

6671
## [1.1.22] - 2025-07-29
6772

@@ -87,55 +92,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8792

8893
- Add `get_model_name()` method to `TrustworthyRAG`, `TLMChatCompletion`
8994

90-
9195
## [1.1.18] - 2025-07-25
9296

9397
### Fixed
9498

9599
- Properly pass quality preset in `TLMChatCompletion`
96100

97-
98101
## [1.1.17] - 2025-07-18
99102

100103
### Changed
101104

102105
- Enabled `TLMChatCompletion.score()`to evaluate structured outputs in `ChatCompletion` objects
103106

104-
105107
## [1.1.16] - 2025-07-15
106108

107109
### Changed
108110

109111
- Add internal setting to bypass model validation check (for custom/VPC models)
110112

111-
112113
## [1.1.15] - 2025-07-14
113114

114115
### Changed
115116

116117
- Enabled `TLMChatCompletion.score()`to evaluate tool calls in `ChatCompletion` objects
117118

118-
119119
## [1.1.14] - 2025-07-08
120120

121121
### Added
122122

123123
- New TLMOption `num_self_reflections`
124124
- Support for `best` and `high` preset in `TrustworthyRAG`
125125

126-
### Changed
126+
### Changed
127127

128128
- Deprecate `use_self_reflection`
129129
- Documentation updates for new default configurations
130130

131-
132131
## [1.1.13] - 2025-06-26
133132

134133
### Added
135134

136135
- Added `form_response_string_chat_completions_api` in `chat.py`
137136

138-
139137
## [1.1.12] - 2025-06-23
140138

141139
### Fixed
@@ -153,7 +151,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
153151
- Bug fix in `chat.py` for empty tool list still using tools prompt
154152
- Bug fix in `chat.py` for handling empty strings args
155153

156-
157154
## [1.1.10] - 2025-06-20
158155

159156
### Added
@@ -346,8 +343,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
346343

347344
- Release of the Cleanlab TLM Python client.
348345

349-
350-
[Unreleased]: https://github.com/cleanlab/cleanlab-tlm/compare/v1.1.30...HEAD
346+
[Unreleased]: https://github.com/cleanlab/cleanlab-tlm/compare/v1.1.31...HEAD
347+
[1.1.31]: https://github.com/cleanlab/cleanlab-tlm/compare/v1.1.30...v1.1.31
351348
[1.1.30]: https://github.com/cleanlab/cleanlab-tlm/compare/v1.1.29...v1.1.30
352349
[1.1.29]: https://github.com/cleanlab/cleanlab-tlm/compare/v1.1.28...v1.1.29
353350
[1.1.28]: https://github.com/cleanlab/cleanlab-tlm/compare/v1.1.27...v1.1.28

src/cleanlab_tlm/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# SPDX-License-Identifier: MIT
2-
__version__ = "1.1.30"
2+
__version__ = "1.1.31"

src/cleanlab_tlm/tlm.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,59 @@ def get_explanation(
588588
)
589589
)
590590

591+
async def get_explanation_async(
592+
self,
593+
*,
594+
prompt: Union[str, Sequence[str]],
595+
response: Optional[Union[str, Sequence[str]]] = None,
596+
tlm_result: Union[TLMResponse, TLMScore, Sequence[TLMResponse], Sequence[TLMScore]],
597+
) -> Union[str, list[str]]:
598+
"""Asynchronously gets explanations for a given prompt-response pair with a given score.
599+
600+
This method provides detailed explanations from TLM about why a particular response
601+
received its trustworthiness score.
602+
603+
The `tlm_result` object will be mutated to include the explanation in its log.
604+
605+
Args:
606+
prompt (str | Sequence[str]): The original prompt(s) that were used to generate
607+
the response(s) or that were evaluated for trustworthiness scoring.
608+
response (str | Sequence[str], optional): The response(s) that were evaluated.
609+
Required when `tlm_result` contains a `TLMScore` object, as the response text is
610+
not included there. Should not be provided when `tlm_result` contains a `TLMResponse`
611+
object, as the response text is already included there.
612+
tlm_result (TLMResponse | TLMScore | Sequence[TLMResponse] | Sequence[TLMScore]):
613+
The result object(s) from a previous TLM call (either `prompt()` or
614+
`get_trustworthiness_score()`).
615+
616+
Returns:
617+
str | list[str]: Explanation(s) for why TLM assigned the given trustworthiness
618+
score(s) to the response(s).
619+
If a single prompt/result pair was provided, returns a single explanation string.
620+
If a list of prompt/results was provided, returns a list of explanation strings matching the input order.
621+
"""
622+
formatted_tlm_result = tlm_explanation_format_tlm_result(tlm_result, response)
623+
624+
async with aiohttp.ClientSession() as session:
625+
if isinstance(prompt, str) and isinstance(tlm_result, dict) and isinstance(formatted_tlm_result, dict):
626+
return await self._get_explanation_async(
627+
prompt,
628+
tlm_result,
629+
formatted_tlm_result,
630+
session,
631+
timeout=self._timeout,
632+
)
633+
634+
assert isinstance(prompt, Sequence)
635+
assert isinstance(tlm_result, Sequence)
636+
assert isinstance(formatted_tlm_result, Sequence)
637+
638+
return await self._batch_get_explanation(
639+
prompts=prompt,
640+
tlm_results=tlm_result,
641+
formatted_tlm_results=formatted_tlm_result,
642+
)
643+
591644
async def _batch_get_explanation(
592645
self,
593646
prompts: Sequence[str],

src/cleanlab_tlm/utils/rag.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,85 @@ def get_explanation(
426426
)
427427
)
428428

429+
async def get_explanation_async(
430+
self,
431+
*,
432+
response: Optional[Union[str, Sequence[str]]] = None,
433+
query: Union[str, Sequence[str]],
434+
context: Union[str, Sequence[str]],
435+
tlm_result: Union[
436+
TrustworthyRAGResponse,
437+
Sequence[TrustworthyRAGResponse],
438+
TrustworthyRAGScore,
439+
Sequence[TrustworthyRAGScore],
440+
],
441+
prompt: Optional[Union[str, Sequence[str]]] = None,
442+
form_prompt: Optional[Callable[[str, str], str]] = None,
443+
) -> Union[str, list[str]]:
444+
"""Asynchronously gets explanations for a response with a given trustworthiness score.
445+
446+
This method provides detailed explanations from TrustworthyRAG about why a particular response
447+
received its trustworthiness score.
448+
449+
The `tlm_result` object will be mutated to include the explanation in its log,
450+
adding an "explanation" key to the log dictionary.
451+
452+
Args:
453+
response (str | Sequence[str], optional): The response(s) that were evaluated.
454+
Required when `tlm_result` contains a `TrustworthyRAGScore` object, as the response text is
455+
not included there. Should not be provided when `tlm_result` contains a `TrustworthyRAGResponse`
456+
object, as the response text is already included there.
457+
query (str | Sequence[str]): The user query (or list of multiple queries) that was used to generate the response.
458+
context (str | Sequence[str]): The context (or list of multiple contexts) that was retrieved from the RAG Knowledge Base and used to generate the response.
459+
tlm_result (TrustworthyRAGResponse | Sequence[TrustworthyRAGResponse] | TrustworthyRAGScore | Sequence[TrustworthyRAGScore]): The result object(s) from a previous TrustworthyRAG call (either `generate()` or `score()`).
460+
prompt (str | Sequence[str], optional): Optional prompt (or list of multiple prompts) representing the actual inputs (combining query, context, and system instructions into one string) to the LLM that generated the response.
461+
form_prompt (Callable[[str, str], str], optional): Optional function to format the prompt based on query and context. Cannot be provided together with prompt, provide one or the other.
462+
This function should take query and context as parameters and return a formatted prompt string.
463+
If not provided, a default prompt formatter will be used.
464+
To include a system prompt or any other special instructions for your LLM,
465+
incorporate them directly in your custom `form_prompt()` function definition.
466+
467+
Returns:
468+
str | list[str]: Explanation(s) for why TrustworthyRAG assigned the given trustworthiness score to the response(s).
469+
If a single prompt/result pair was provided, returns a single explanation string.
470+
If a list of prompt/results was provided, returns a list of explanation strings matching the input order.
471+
472+
"""
473+
if prompt is None and form_prompt is None:
474+
form_prompt = TrustworthyRAG._default_prompt_formatter
475+
476+
formatted_prompt = validate_rag_inputs(
477+
query=query,
478+
context=context,
479+
response=response,
480+
prompt=prompt,
481+
form_prompt=form_prompt,
482+
evals=self._evals,
483+
is_generate=response is None,
484+
)
485+
486+
formatted_tlm_result = tlm_explanation_format_trustworthy_rag_result(tlm_result, response)
487+
488+
if isinstance(formatted_prompt, str) and isinstance(formatted_tlm_result, dict):
489+
assert isinstance(tlm_result, dict)
490+
491+
return await self._get_explanation_async(
492+
prompt=formatted_prompt,
493+
tlm_result=tlm_result,
494+
formatted_tlm_result=formatted_tlm_result,
495+
timeout=self._timeout,
496+
)
497+
498+
assert isinstance(formatted_prompt, Sequence)
499+
assert isinstance(tlm_result, Sequence)
500+
assert isinstance(formatted_tlm_result, Sequence)
501+
502+
return await self._batch_get_explanation(
503+
prompts=formatted_prompt,
504+
tlm_results=tlm_result,
505+
formatted_tlm_results=formatted_tlm_result,
506+
)
507+
429508
async def _batch_get_explanation(
430509
self,
431510
prompts: Sequence[str],

0 commit comments

Comments
 (0)