Skip to content

Commit 95afc6b

Browse files
authored
Merge pull request #40 from KRLabsOrg/feat/taxonomy
Feat/taxonomy
2 parents 9a68e12 + 0289368 commit 95afc6b

10 files changed

Lines changed: 1354 additions & 69 deletions

File tree

‎.gitignore‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,6 @@ temp/
182182

183183
# cache/
184184
lettucedetect/cache/
185-
testing/
185+
testing/
186+
187+
CLAUDE.md

‎docs/guide/detection-methods.md‎

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,78 @@ detector = HallucinationDetector(method="llm", model_path="gpt-4o-mini")
2929

3030
**When to use:** Quick prototyping, or when you want the LLM to explain *why* something is hallucinated.
3131

32+
### Backends
33+
34+
Beyond OpenAI-compatible APIs, the detector now ships an `LLMClient` abstraction with an AWS Bedrock backend. Select it with `provider`, or pass your own `client` for a custom backend:
35+
36+
```python
37+
detector = HallucinationDetector(
38+
method="llm",
39+
provider="bedrock",
40+
model="anthropic.claude-3-5-sonnet-20240620-v1:0",
41+
region_name="us-east-1",
42+
)
43+
```
44+
45+
The OpenAI backend uses strict JSON-schema structured output; Bedrock obtains the same structured output through a forced tool call.
46+
47+
### Reasoning and confidence
48+
49+
Set `include_reasoning=True` to make the model reason before it judges. The response opens with a claim-by-claim `analysis` scratchpad, and each span carries a short `reasoning`, a `confidence` score (0–1), and an `is_hallucination` verdict. Spans the model talks itself out of (verdict `false`) are discarded automatically, and the `confidence`/`reasoning` keys are added to the returned spans.
50+
51+
```python
52+
detector = HallucinationDetector(
53+
method="llm",
54+
model="gpt-4.1-mini",
55+
include_reasoning=True,
56+
min_confidence=0.7, # drop low-confidence spans
57+
)
58+
```
59+
60+
`min_confidence` filters out spans scored below the threshold (only meaningful together with `include_reasoning`).
61+
62+
### Taxonomy classification
63+
64+
Set `include_taxonomy=True` to classify each hallucination into one of the unified taxonomy categories, or pass a list of category names to use a custom set. The chosen label is returned under a `category` key on each span.
65+
66+
```python
67+
detector = HallucinationDetector(method="llm", model="gpt-4.1-mini", include_taxonomy=True)
68+
```
69+
70+
With `include_taxonomy=True` the unified taxonomy is used, with these categories:
71+
72+
| Category | Definition |
73+
|---|---|
74+
| `contradiction` | The span directly conflicts with the context: the context states one thing and the answer asserts a different, incompatible thing. |
75+
| `unsupported_addition` | The span asserts something the context neither states nor implies — plausible, but not derivable from the context. |
76+
| `fabricated_reference` | The span references a named element (identifier, section, file, entity, attribute) that does not appear anywhere in the context. |
77+
78+
Pass a `{category: description}` dict instead of `True` to classify against your own taxonomy. The descriptions are injected into the prompt so the model knows what each label means:
79+
80+
```python
81+
detector = HallucinationDetector(
82+
method="llm",
83+
model="gpt-4.1-mini",
84+
include_taxonomy={
85+
"unsupported_claim": "a statement not backed by anything in the source",
86+
"contradiction": "directly contradicts the source",
87+
"wrong_entity": "right relation but the wrong name, place, or number",
88+
},
89+
)
90+
```
91+
92+
You can also pass a plain list of names; definitions are reused from the built-in taxonomy where the name matches and omitted otherwise.
93+
94+
### Verification pass
95+
96+
Set `verify=True` to run a second, deliberately strict pass that re-judges each flagged span against the source and drops the ones it cannot confirm. Spans the verifier does not return are kept, so a malformed verdict never silently discards confirmed detections.
97+
98+
```python
99+
detector = HallucinationDetector(method="llm", model="gpt-4.1-mini", verify=True)
100+
```
101+
102+
These options compose freely and are all cached, so repeated runs over the same inputs avoid redundant API calls.
103+
32104
## RAG Fact Checker
33105

34106
Triplet-based fact checking that breaks the answer into structured claims and verifies each one.

‎lettucedetect/detectors/cache.py‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,10 @@ def set(self, key: str, value: Any) -> None: # noqa: ANN401
3838
with self._lock:
3939
self._data[key] = value
4040
self.path.write_text(json.dumps(self._data, ensure_ascii=False), encoding="utf-8")
41+
42+
def delete(self, key: str) -> None:
43+
"""Remove a key from the cache and persist to disk."""
44+
with self._lock:
45+
if key in self._data:
46+
del self._data[key]
47+
self.path.write_text(json.dumps(self._data, ensure_ascii=False), encoding="utf-8")

0 commit comments

Comments
 (0)