Skip to content

Commit ae1bb60

Browse files
authored
Add TypeSafe integration page (#623)
* Add TypeSafe integration page * Add TypeSafe logo
1 parent 13eda2b commit ae1bb60

2 files changed

Lines changed: 182 additions & 0 deletions

File tree

‎integrations/typesafe.md‎

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
---
2+
layout: integration
3+
name: TypeSafe
4+
description: Classify documents and route text with TypeSafe's System One decision models, such as Jev, in Haystack pipelines.
5+
authors:
6+
- name: deepset
7+
socials:
8+
github: deepset-ai
9+
twitter: deepset_ai
10+
linkedin: https://www.linkedin.com/company/deepset-ai/
11+
pypi: https://pypi.org/project/typesafe-haystack
12+
repo: https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/typesafe
13+
type: Model Provider
14+
report_issue: https://github.com/deepset-ai/haystack-core-integrations/issues
15+
logo: /logos/typesafe.png
16+
version: Haystack 2.0
17+
toc: true
18+
---
19+
20+
### **Table of Contents**
21+
- [Overview](#overview)
22+
- [Installation](#installation)
23+
- [Usage](#usage)
24+
- [License](#license)
25+
26+
## Overview
27+
28+
[TypeSafe](https://typesafe.ai) builds System One models, such as Jev, which make fast, structured decisions for software. Instead of generating text, a System One model answers typed questions about a text in a single request and returns calibrated probabilities:
29+
30+
- `choice`: picks one label from a set of options.
31+
- `score`: rates the text on ordered levels.
32+
- `noul`: returns the probability that a yes/no question is true.
33+
34+
The `typesafe-haystack` package brings these models to Haystack through two components:
35+
36+
- `TypeSafeDocumentClassifier` answers typed questions about each document and stores the answers in its metadata.
37+
- `TypeSafeTextRouter` routes a text to the output of the label the model picks for it, with an optional `low_confidence` output for uncertain answers.
38+
39+
Both components also work with servers that implement the TypeSafe API, such as [Ollaya](https://ollaya.dev), which runs open decision models on your own machine.
40+
41+
To use TypeSafe's hosted models, you'll need an API key from the [TypeSafe console](https://console.typesafe.ai). Add it as an environment variable, `TYPESAFE_API_KEY`. For more information, see [the TypeSafe docs](https://docs.typesafe.ai).
42+
43+
## Installation
44+
45+
```bash
46+
pip install typesafe-haystack
47+
```
48+
49+
## Usage
50+
51+
### Classify documents
52+
53+
`TypeSafeDocumentClassifier` sends each document to the model and stores the answers under `meta["typesafe"]`, keyed by question ID. Documents that can't be classified are returned in `failed_documents`.
54+
55+
```python
56+
from haystack import Document
57+
from haystack_integrations.components.classifiers.typesafe import TypeSafeDocumentClassifier
58+
59+
classifier = TypeSafeDocumentClassifier(
60+
questions={
61+
"department": {
62+
"type": "choice",
63+
"instructions": "Which department should handle this ticket?",
64+
"criteria": {"billing": None, "technical": None, "sales": None},
65+
},
66+
"urgency": {
67+
"type": "score",
68+
"instructions": "How urgent is this ticket?",
69+
"criteria": ["can wait", "this week", "today"],
70+
},
71+
"refund": {"type": "noul", "instructions": "Is the customer asking for a refund?"},
72+
},
73+
)
74+
75+
result = classifier.run(documents=[Document(content="I was charged twice, please refund me today.")])
76+
print(result["documents"][0].meta["typesafe"])
77+
# {'department': {'type': 'choice', 'choice': 'billing', 'confidence': 0.9516,
78+
# 'probabilities': {'billing': 0.9677, 'technical': 0.0221, 'sales': 0.0102}},
79+
# 'urgency': {'type': 'score', 'score': 1.948, 'confidence': 0.9389,
80+
# 'legend': {'0': 'can wait', '1': 'this week', '2': 'today'},
81+
# 'probabilities': {'0': 0.0113, '1': 0.0295, '2': 0.9593}},
82+
# 'refund': {'type': 'noul', 'noul': 0.9498}}
83+
```
84+
85+
To send each document down a different branch of a pipeline based on its answers, connect the classifier to a `MetadataRouter`:
86+
87+
```python
88+
from haystack import Document, Pipeline
89+
from haystack.components.routers import MetadataRouter
90+
from haystack_integrations.components.classifiers.typesafe import TypeSafeDocumentClassifier
91+
92+
labels = ["billing", "technical"]
93+
94+
pipeline = Pipeline()
95+
pipeline.add_component(
96+
"classifier",
97+
TypeSafeDocumentClassifier(
98+
questions={
99+
"department": {
100+
"type": "choice",
101+
"instructions": "Which department should handle this ticket?",
102+
"criteria": dict.fromkeys(labels),
103+
}
104+
},
105+
),
106+
)
107+
pipeline.add_component(
108+
"router",
109+
MetadataRouter(
110+
rules={
111+
label: {"field": "meta.typesafe.department.choice", "operator": "==", "value": label}
112+
for label in labels
113+
}
114+
),
115+
)
116+
pipeline.connect("classifier.documents", "router.documents")
117+
118+
result = pipeline.run(
119+
{
120+
"classifier": {
121+
"documents": [
122+
Document(content="I was charged twice for my subscription."),
123+
Document(content="The app crashes every time I open the settings page."),
124+
]
125+
}
126+
}
127+
)
128+
print({output: [document.content for document in documents] for output, documents in result["router"].items()})
129+
# {'billing': ['I was charged twice for my subscription.'],
130+
# 'technical': ['The app crashes every time I open the settings page.'],
131+
# 'unmatched': []}
132+
```
133+
134+
### Route text
135+
136+
`TypeSafeTextRouter` has one output per label. With `min_confidence` set, texts whose answer is less confident than the threshold go to the `low_confidence` output instead, so you can send them to a fallback such as an LLM or a human.
137+
138+
```python
139+
from haystack_integrations.components.routers.typesafe import TypeSafeTextRouter
140+
141+
router = TypeSafeTextRouter(
142+
labels={
143+
"billing": "Payments, invoices, refunds and charges",
144+
"technical": "Bugs, crashes and errors in the product",
145+
},
146+
instructions="Which team should handle this support request?",
147+
min_confidence=0.6,
148+
)
149+
150+
print(router.run(text="I was charged twice for my subscription."))
151+
# {'billing': 'I was charged twice for my subscription.'}
152+
```
153+
154+
### Run open models locally with Ollaya
155+
156+
[Ollaya](https://ollaya.dev) serves open decision models through the TypeSafe API. Start it and pull a model:
157+
158+
```bash
159+
docker run -d --name ollaya -p 11435:11435 -v ollaya:/home/ollaya/.ollaya ghcr.io/ollaya-dev/ollaya
160+
docker exec ollaya ollaya pull laya:en
161+
```
162+
163+
Then point either component at the server with `api_base_url` and pick one of its models. Ollaya accepts any non-empty API key unless it is configured with one:
164+
165+
```python
166+
from haystack.utils import Secret
167+
from haystack_integrations.components.routers.typesafe import TypeSafeTextRouter
168+
169+
router = TypeSafeTextRouter(
170+
labels=["billing", "technical"],
171+
model="laya:en",
172+
api_key=Secret.from_token("local"),
173+
api_base_url="http://localhost:11435",
174+
)
175+
176+
print(router.run(text="The app crashes every time I open the settings page."))
177+
# {'technical': 'The app crashes every time I open the settings page.'}
178+
```
179+
180+
### License
181+
182+
`typesafe-haystack` is distributed under the terms of the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) license.

‎logos/typesafe.png‎

7.24 KB
Loading

0 commit comments

Comments
 (0)