orbitals 0.0.3__tar.gz → 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- orbitals-0.1.0/.dockerignore +2 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/Dockerfile +11 -10
- {orbitals-0.0.3 → orbitals-0.1.0}/LICENSE +1 -1
- orbitals-0.1.0/PKG-INFO +103 -0
- orbitals-0.1.0/README.md +76 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/README.scope-guard.md +41 -98
- {orbitals-0.0.3 → orbitals-0.1.0}/pyproject.toml +4 -23
- {orbitals-0.0.3 → orbitals-0.1.0}/src/orbitals/scope_guard/guards/base.py +4 -4
- {orbitals-0.0.3 → orbitals-0.1.0}/src/orbitals/scope_guard/guards/hf.py +1 -1
- {orbitals-0.0.3 → orbitals-0.1.0}/src/orbitals/scope_guard/guards/vllm.py +2 -2
- {orbitals-0.0.3 → orbitals-0.1.0}/src/orbitals/types.py +2 -14
- orbitals-0.1.0/src/orbitals/utils.py +45 -0
- orbitals-0.1.0/src/scripts/playground.ipynb +196 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/uv.lock +5 -25
- orbitals-0.0.3/.dockerignore +0 -5
- orbitals-0.0.3/CONTRIBUTING.md +0 -45
- orbitals-0.0.3/PKG-INFO +0 -161
- orbitals-0.0.3/README.md +0 -109
- orbitals-0.0.3/assets/orbitals-banner.png +0 -0
- orbitals-0.0.3/examples/scope-guard/test.py +0 -27
- orbitals-0.0.3/src/orbitals/utils.py +0 -53
- orbitals-0.0.3/src/scripts/playground.ipynb +0 -267
- {orbitals-0.0.3 → orbitals-0.1.0}/.gitignore +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/AGENTS.md +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/assets/orbitals.svg +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/assets/scope-guard.svg +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/examples/scope-guard/api.py +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/examples/scope-guard/async_api.py +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/examples/scope-guard/local.py +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/examples/scope-guard/vllm_serve.py +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/src/hf_pipeline/scope_guard.py +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/src/orbitals/__init__.py +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/src/orbitals/cli/__init__.py +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/src/orbitals/cli/main.py +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/src/orbitals/scope_guard/__init__.py +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/src/orbitals/scope_guard/cli/__init__.py +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/src/orbitals/scope_guard/cli/convert_default_model_name.py +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/src/orbitals/scope_guard/cli/main.py +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/src/orbitals/scope_guard/cli/serve.py +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/src/orbitals/scope_guard/guards/__init__.py +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/src/orbitals/scope_guard/guards/api.py +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/src/orbitals/scope_guard/modeling.py +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/src/orbitals/scope_guard/prompting.py +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/src/orbitals/scope_guard/serving/__init__.py +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/src/orbitals/scope_guard/serving/main.py +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/src/orbitals/scope_guard/serving/vllm_logging_config.json +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/src/scripts/push_hf_pipeline.py +0 -0
- {orbitals-0.0.3 → orbitals-0.1.0}/src/scripts/push_model.py +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
FROM vllm/vllm-openai:v0.
|
|
1
|
+
FROM vllm/vllm-openai:v0.11.2 as builder
|
|
2
2
|
|
|
3
3
|
ARG DEBIAN_FRONTEND=noninteractive
|
|
4
4
|
ARG MODEL
|
|
@@ -17,22 +17,23 @@ COPY pyproject.toml uv.lock README.md /app/
|
|
|
17
17
|
|
|
18
18
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
19
19
|
uv venv -p 3.12 && \
|
|
20
|
-
uv sync --frozen --extra
|
|
21
|
-
|
|
22
|
-
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
23
|
-
hf download ${MODEL}
|
|
20
|
+
uv sync --frozen --extra serve --no-install-project --no-dev
|
|
24
21
|
|
|
25
22
|
COPY src /app/src/
|
|
26
23
|
|
|
27
24
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
28
|
-
uv sync --locked --extra
|
|
25
|
+
uv sync --locked --extra serve --no-editable --no-dev
|
|
26
|
+
|
|
27
|
+
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
28
|
+
--mount=type=secret,id=HF_TOKEN \
|
|
29
|
+
hf auth login --token $(cat /run/secrets/HF_TOKEN) && \
|
|
30
|
+
hf download $(scope-classifier convert-default-model-name ${MODEL}) && \
|
|
31
|
+
rm -rf /root/.huggingface
|
|
29
32
|
|
|
30
33
|
# TODO remove next line
|
|
31
34
|
ENTRYPOINT ["/bin/bash", "-c"]
|
|
32
35
|
|
|
33
|
-
FROM vllm/vllm-openai:v0.
|
|
34
|
-
|
|
35
|
-
ARG MODEL
|
|
36
|
+
FROM vllm/vllm-openai:v0.11.2 as runner
|
|
36
37
|
|
|
37
38
|
WORKDIR /app
|
|
38
39
|
ENV PATH="/app/.venv/bin:$PATH"
|
|
@@ -45,4 +46,4 @@ COPY --from=builder /root/.cache/huggingface/hub /root/.cache/huggingface/hub
|
|
|
45
46
|
EXPOSE 8000
|
|
46
47
|
|
|
47
48
|
ENTRYPOINT ["/bin/bash", "-c"]
|
|
48
|
-
CMD [ "
|
|
49
|
+
CMD [ "scope-classifier", "serve", "${MODEL}", "--backend", "hf", "--port", "8000", "--host", "0.0.0.0" ]
|
|
@@ -186,7 +186,7 @@
|
|
|
186
186
|
same "printed page" as the copyright notice for easier
|
|
187
187
|
identification within third-party archives.
|
|
188
188
|
|
|
189
|
-
Copyright
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
190
|
|
|
191
191
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
192
|
you may not use this file except in compliance with the License.
|
orbitals-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: orbitals
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: LLM Guardrails tailored to your Principles
|
|
5
|
+
Author-email: Luigi Procopio <luigi@principled-intelligence.com>, Edoardo Barba <edoardo@principled-intelligence.com>
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Requires-Dist: aiohttp
|
|
10
|
+
Requires-Dist: pydantic>=2.0.0
|
|
11
|
+
Requires-Dist: requests
|
|
12
|
+
Requires-Dist: typer>=0.12.3
|
|
13
|
+
Provides-Extra: scope-guard-hf
|
|
14
|
+
Requires-Dist: accelerate>=1.11.0; extra == 'scope-guard-hf'
|
|
15
|
+
Requires-Dist: transformers<5.0.0,>=4.47.0; extra == 'scope-guard-hf'
|
|
16
|
+
Provides-Extra: scope-guard-serve
|
|
17
|
+
Requires-Dist: fastapi[standard]>=0.119.1; extra == 'scope-guard-serve'
|
|
18
|
+
Requires-Dist: transformers<5.0.0,>=4.47.0; extra == 'scope-guard-serve'
|
|
19
|
+
Requires-Dist: uvicorn>=0.29.0; extra == 'scope-guard-serve'
|
|
20
|
+
Requires-Dist: vllm>=0.11.0; extra == 'scope-guard-serve'
|
|
21
|
+
Requires-Dist: xgrammar; extra == 'scope-guard-serve'
|
|
22
|
+
Provides-Extra: scope-guard-vllm
|
|
23
|
+
Requires-Dist: transformers<5.0.0,>=4.47.0; extra == 'scope-guard-vllm'
|
|
24
|
+
Requires-Dist: vllm>=0.11.0; extra == 'scope-guard-vllm'
|
|
25
|
+
Requires-Dist: xgrammar; extra == 'scope-guard-vllm'
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
<div align="center">
|
|
29
|
+
<img src="assets/orbitals.svg" width="40%" />
|
|
30
|
+
<h3 align="center">
|
|
31
|
+
<p>
|
|
32
|
+
<b>LLM Guardrails tailored to your Principles</b>
|
|
33
|
+
</p>
|
|
34
|
+
</h4>
|
|
35
|
+
<hr/>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<p align="center">
|
|
39
|
+
<img src="https://img.shields.io/badge/type%20checked-ty-blue.svg?color=green" alt="Type Checked with ty">
|
|
40
|
+
<img src="https://img.shields.io/pypi/v/orbitals?color=green" alt="PyPI Version">
|
|
41
|
+
<img src="https://img.shields.io/github/license/principled-intelligence/orbitals" alt="GitHub License">
|
|
42
|
+
<img src="https://img.shields.io/pypi/pyversions/orbitals" alt="Python Versions">
|
|
43
|
+
<img src="https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2Fprincipled-intelligence%2Forbitals%2Fmain%2Fpyproject.toml" alt="Required Python Version">
|
|
44
|
+
</p>
|
|
45
|
+
|
|
46
|
+
`orbitals` is an ecosystem of LLM guardrails, designed to provide a governance layer tailored to **user-specific principles, requirements and use cases**. Rather than enforcing generic notions of safety, correctness, etc., Orbitals evaluates inputs and outputs against *user-defined specifications*. This makes guardrails explicit, auditable, and aligned with the user's philosophy.
|
|
47
|
+
|
|
48
|
+
Orbitals guardrails fall into two typologies:
|
|
49
|
+
- **Guards** operate on the *input* of a guardrailed LLM, assessing whether a user request is legitimate under the provided specifications.
|
|
50
|
+
- **Supervisors** operate on the *output* of a guardrailed LLM, evaluating the assistant’s response before it is returned.
|
|
51
|
+
|
|
52
|
+
Guardrails may be released under different modality flavors:
|
|
53
|
+
- **Open** (open-source and open-weight), allowing users to run guardrails and underlying models on their own infrastructure.
|
|
54
|
+
- **Hosted**, accessible via simple HTTP calls (API key required).
|
|
55
|
+
|
|
56
|
+
## Available Guardrails
|
|
57
|
+
|
|
58
|
+
| Name | Flavor | Description |
|
|
59
|
+
|-------------|-------------------------|-----------------------------------------------------------------------------|
|
|
60
|
+
| [ScopeGuard](README.scope-guard.md) | Open / Hosted | Validates whether a user request falls within the intended use of an AI service. |
|
|
61
|
+
| RagSupervisor | Coming soon | Ensures LLM responses remain grounded in retrieved context for RAG setups. |
|
|
62
|
+
|
|
63
|
+
<details>
|
|
64
|
+
<summary>ScopeGuard</summary>
|
|
65
|
+
<br>
|
|
66
|
+
|
|
67
|
+
First, we need to install `orbitals` and `scope-guard`:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pip install orbitals[scope-guard-vllm]
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Then:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from orbitals.scope_guard import ScopeGuard
|
|
77
|
+
|
|
78
|
+
scope_guard = ScopeGuard(
|
|
79
|
+
backend="vllm",
|
|
80
|
+
model="small"
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
ai_service_description = """
|
|
84
|
+
You are a virtual assistant for a parcel delivery service.
|
|
85
|
+
You can only answer questions about package tracking.
|
|
86
|
+
Never respond to requests for refunds.
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
user_query = "If the package hasn't arrived by tomorrow, can I get my money back?"
|
|
90
|
+
result = scope_guard.validate(user_query, ai_service_description)
|
|
91
|
+
|
|
92
|
+
print(f"Scope: {result.scope_class.value}")
|
|
93
|
+
if result.evidences:
|
|
94
|
+
print("Evidences:")
|
|
95
|
+
for evidence in result.evidences:
|
|
96
|
+
print(f" - {evidence}")
|
|
97
|
+
|
|
98
|
+
# Scope: Restricted
|
|
99
|
+
# Evidences:
|
|
100
|
+
# - Never respond to requests for refunds.
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
</details>
|
orbitals-0.1.0/README.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="assets/orbitals.svg" width="40%" />
|
|
3
|
+
<h3 align="center">
|
|
4
|
+
<p>
|
|
5
|
+
<b>LLM Guardrails tailored to your Principles</b>
|
|
6
|
+
</p>
|
|
7
|
+
</h4>
|
|
8
|
+
<hr/>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<img src="https://img.shields.io/badge/type%20checked-ty-blue.svg?color=green" alt="Type Checked with ty">
|
|
13
|
+
<img src="https://img.shields.io/pypi/v/orbitals?color=green" alt="PyPI Version">
|
|
14
|
+
<img src="https://img.shields.io/github/license/principled-intelligence/orbitals" alt="GitHub License">
|
|
15
|
+
<img src="https://img.shields.io/pypi/pyversions/orbitals" alt="Python Versions">
|
|
16
|
+
<img src="https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2Fprincipled-intelligence%2Forbitals%2Fmain%2Fpyproject.toml" alt="Required Python Version">
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
`orbitals` is an ecosystem of LLM guardrails, designed to provide a governance layer tailored to **user-specific principles, requirements and use cases**. Rather than enforcing generic notions of safety, correctness, etc., Orbitals evaluates inputs and outputs against *user-defined specifications*. This makes guardrails explicit, auditable, and aligned with the user's philosophy.
|
|
20
|
+
|
|
21
|
+
Orbitals guardrails fall into two typologies:
|
|
22
|
+
- **Guards** operate on the *input* of a guardrailed LLM, assessing whether a user request is legitimate under the provided specifications.
|
|
23
|
+
- **Supervisors** operate on the *output* of a guardrailed LLM, evaluating the assistant’s response before it is returned.
|
|
24
|
+
|
|
25
|
+
Guardrails may be released under different modality flavors:
|
|
26
|
+
- **Open** (open-source and open-weight), allowing users to run guardrails and underlying models on their own infrastructure.
|
|
27
|
+
- **Hosted**, accessible via simple HTTP calls (API key required).
|
|
28
|
+
|
|
29
|
+
## Available Guardrails
|
|
30
|
+
|
|
31
|
+
| Name | Flavor | Description |
|
|
32
|
+
|-------------|-------------------------|-----------------------------------------------------------------------------|
|
|
33
|
+
| [ScopeGuard](README.scope-guard.md) | Open / Hosted | Validates whether a user request falls within the intended use of an AI service. |
|
|
34
|
+
| RagSupervisor | Coming soon | Ensures LLM responses remain grounded in retrieved context for RAG setups. |
|
|
35
|
+
|
|
36
|
+
<details>
|
|
37
|
+
<summary>ScopeGuard</summary>
|
|
38
|
+
<br>
|
|
39
|
+
|
|
40
|
+
First, we need to install `orbitals` and `scope-guard`:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install orbitals[scope-guard-vllm]
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Then:
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from orbitals.scope_guard import ScopeGuard
|
|
50
|
+
|
|
51
|
+
scope_guard = ScopeGuard(
|
|
52
|
+
backend="vllm",
|
|
53
|
+
model="small"
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
ai_service_description = """
|
|
57
|
+
You are a virtual assistant for a parcel delivery service.
|
|
58
|
+
You can only answer questions about package tracking.
|
|
59
|
+
Never respond to requests for refunds.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
user_query = "If the package hasn't arrived by tomorrow, can I get my money back?"
|
|
63
|
+
result = scope_guard.validate(user_query, ai_service_description)
|
|
64
|
+
|
|
65
|
+
print(f"Scope: {result.scope_class.value}")
|
|
66
|
+
if result.evidences:
|
|
67
|
+
print("Evidences:")
|
|
68
|
+
for evidence in result.evidences:
|
|
69
|
+
print(f" - {evidence}")
|
|
70
|
+
|
|
71
|
+
# Scope: Restricted
|
|
72
|
+
# Evidences:
|
|
73
|
+
# - Never respond to requests for refunds.
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
</details>
|
|
@@ -16,28 +16,27 @@
|
|
|
16
16
|
</div>
|
|
17
17
|
|
|
18
18
|
Given the specifications of an AI assistant and a user query, `scope-guard` maps the user query to one of the following five classes:
|
|
19
|
-
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* **Chit Chat**: The query is a social interaction not related to the assistant's function.
|
|
19
|
+
* **Directly Supported**: The query is clearly within the assistant's capabilities.
|
|
20
|
+
* **Potentially Supported**: The query could plausibly be handled by the assistant.
|
|
21
|
+
* **Out of Scope**: The query is outside the assistant's defined role.
|
|
22
|
+
* **Restricted**: The query cannot be handled due to a specific constraint.
|
|
23
|
+
* **Chit Chat**: The query is a social interaction not related to the assistant's function.
|
|
25
24
|
|
|
26
25
|
<p align="center">
|
|
27
26
|
<img src="assets/scope-guard.svg" width="80%" />
|
|
28
27
|
</p>
|
|
29
28
|
|
|
30
|
-
To do this, `scope-guard` leverages specialized language models trained to evaluate whether a user query falls within an assistant’s intended scope. Different models are available, released with different
|
|
29
|
+
To do this, `scope-guard` leverages specialized language models trained to evaluate whether a user query falls within an assistant’s intended scope. Different models are available, released with different modality flavors:
|
|
31
30
|
|
|
32
|
-
|
|
|
33
|
-
| :--- | :--- | :--- | :--- | :--- | :--- |
|
|
34
|
-
|
|
|
35
|
-
| scope-guard-4B-g-2601 | 4B | Self-hosted | 90.1 | 78.0 | 88.0 | T4, L4, L40S, 4090, 5090 |
|
|
36
|
-
| scope-guard-pro | ~ | Cloud-only | 91.9 | 81.8 | 92.0 | ~ |
|
|
31
|
+
| Flavor | Model | Parameters | Description | Accuracy | Required VRAM |
|
|
32
|
+
| :--- | :--- | :--- | :--- | :--- | :--- |
|
|
33
|
+
| Open | `small` | 1.7B | A compact and fast model for general use. | 85.3 | 8GB |
|
|
37
34
|
|
|
38
|
-
## Quickstart
|
|
35
|
+
## Quickstart
|
|
39
36
|
|
|
40
|
-
|
|
37
|
+
<details open>
|
|
38
|
+
<summary>Open Flavor</summary>
|
|
39
|
+
<br>
|
|
41
40
|
|
|
42
41
|
First, we need to install `orbitals` and `scope-guard`:
|
|
43
42
|
|
|
@@ -52,10 +51,9 @@ Then:
|
|
|
52
51
|
```python
|
|
53
52
|
from orbitals.scope_guard import ScopeGuard
|
|
54
53
|
|
|
55
|
-
|
|
54
|
+
scope_guard = ScopeGuard(
|
|
56
55
|
backend="vllm",
|
|
57
|
-
model="
|
|
58
|
-
# model="scope-guard-g", # for the Gemma-family model
|
|
56
|
+
model="small"
|
|
59
57
|
)
|
|
60
58
|
|
|
61
59
|
ai_service_description = """
|
|
@@ -65,7 +63,7 @@ Never respond to requests for refunds.
|
|
|
65
63
|
"""
|
|
66
64
|
|
|
67
65
|
user_query = "If the package hasn't arrived by tomorrow, can I get my money back?"
|
|
68
|
-
result =
|
|
66
|
+
result = scope_guard.validate(user_query, ai_service_description)
|
|
69
67
|
|
|
70
68
|
print(f"Scope: {result.scope_class.value}")
|
|
71
69
|
if result.evidences:
|
|
@@ -78,12 +76,11 @@ if result.evidences:
|
|
|
78
76
|
# - Never respond to requests for refunds.
|
|
79
77
|
```
|
|
80
78
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
ScopeGuard Pro is our most advanced model, available via API through our managed cloud hosting (get in touch with us if you are interested in on-premise deployment). It achieves best-in-class performance on scope classification tasks, including custom safety evaluations based on user-defined policies.
|
|
79
|
+
</details>
|
|
84
80
|
|
|
85
|
-
>
|
|
86
|
-
>
|
|
81
|
+
<details>
|
|
82
|
+
<summary>Hosted Flavor</summary>
|
|
83
|
+
<br>
|
|
87
84
|
|
|
88
85
|
First, we need to install `orbitals` and `scope-guard`. In this case, plain `orbitals` is all we need:
|
|
89
86
|
|
|
@@ -96,9 +93,9 @@ Then:
|
|
|
96
93
|
```python
|
|
97
94
|
from orbitals.scope_guard import ScopeGuard
|
|
98
95
|
|
|
99
|
-
|
|
96
|
+
scope_guard = ScopeGuard(
|
|
100
97
|
backend="api",
|
|
101
|
-
api_key="principled_1234",
|
|
98
|
+
api_key="principled_1234",
|
|
102
99
|
)
|
|
103
100
|
|
|
104
101
|
ai_service_description = """
|
|
@@ -108,7 +105,7 @@ Never respond to requests for refunds.
|
|
|
108
105
|
"""
|
|
109
106
|
|
|
110
107
|
user_query = "If the package hasn't arrived by tomorrow, can I get my money back?"
|
|
111
|
-
result =
|
|
108
|
+
result = scope_guard.validate(user_query, ai_service_description)
|
|
112
109
|
|
|
113
110
|
print(f"Scope: {result.scope_class.value}")
|
|
114
111
|
if result.evidences:
|
|
@@ -121,61 +118,9 @@ if result.evidences:
|
|
|
121
118
|
# - Never respond to requests for refunds.
|
|
122
119
|
```
|
|
123
120
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
### Initialization
|
|
127
|
-
|
|
128
|
-
Initialize the `ScopeGuard` object by specifying the backend and model you want to use.
|
|
129
|
-
|
|
130
|
-
If you are using the self-hosted models, you can choose between the `vllm` and `huggingface` backends:
|
|
131
|
-
|
|
132
|
-
```python
|
|
133
|
-
from orbitals.scope_guard import ScopeGuard
|
|
134
|
-
|
|
135
|
-
sg = ScopeGuard(
|
|
136
|
-
model="scope-guard-q", # for the Qwen-family model
|
|
137
|
-
# model="scope-guard-g", # for the Gemma-family model
|
|
138
|
-
backend="vllm", # or "huggingface"
|
|
139
|
-
)
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
If you are using the hosted models, use the `api` backend and provide your API key:
|
|
143
|
-
|
|
144
|
-
```python
|
|
145
|
-
from orbitals.scope_guard import ScopeGuard
|
|
146
|
-
|
|
147
|
-
sg = ScopeGuard(
|
|
148
|
-
backend="api",
|
|
149
|
-
api_key="principled_1234", # replace with your actual API key
|
|
150
|
-
)
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### Scope Classes
|
|
154
|
-
|
|
155
|
-
The possible scope classes returned by `scope-guard` are:
|
|
156
|
-
|
|
157
|
-
```python
|
|
158
|
-
from orbitals.scope_guard import ScopeClass
|
|
159
|
-
print(ScopeClass.DIRECTLY_SUPPORTED.value) # "Directly Supported"
|
|
160
|
-
print(ScopeClass.POTENTIALLY_SUPPORTED.value) # "Potentially Supported"
|
|
161
|
-
print(ScopeClass.OUT_OF_SCOPE.value) # "Out of Scope"
|
|
162
|
-
print(ScopeClass.RESTRICTED.value) # "Restricted"
|
|
163
|
-
print(ScopeClass.CHIT_CHAT.value) # "Chit Chat"
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
For example, you can check the scope class of a validation result as follows:
|
|
167
|
-
|
|
168
|
-
```python
|
|
169
|
-
result = sg.validate(user_query, ai_service_description)
|
|
170
|
-
|
|
171
|
-
# Using the Enum member:
|
|
172
|
-
if result.scope_class == ScopeClass.RESTRICTED:
|
|
173
|
-
print("The user query is restricted.")
|
|
121
|
+
</details>
|
|
174
122
|
|
|
175
|
-
|
|
176
|
-
if result.scope_class.value == "Restricted":
|
|
177
|
-
print("The user query is restricted.")
|
|
178
|
-
```
|
|
123
|
+
## Usage
|
|
179
124
|
|
|
180
125
|
### Input Formats
|
|
181
126
|
|
|
@@ -184,7 +129,7 @@ The `validate` method is flexible and accepts various input formats for the conv
|
|
|
184
129
|
#### User query as a string
|
|
185
130
|
|
|
186
131
|
```python
|
|
187
|
-
result =
|
|
132
|
+
result = scope_guard.validate(
|
|
188
133
|
"When is my package scheduled to arrive?",
|
|
189
134
|
ai_service_description
|
|
190
135
|
)
|
|
@@ -192,8 +137,9 @@ result = sg.validate(
|
|
|
192
137
|
|
|
193
138
|
#### User query as a dictionary (OpenAI's API Message)
|
|
194
139
|
|
|
140
|
+
|
|
195
141
|
```python
|
|
196
|
-
result =
|
|
142
|
+
result = scope_guard.validate(
|
|
197
143
|
{
|
|
198
144
|
"role": "user",
|
|
199
145
|
"content": "When is my package scheduled to arrive?"
|
|
@@ -202,10 +148,10 @@ result = sg.validate(
|
|
|
202
148
|
)
|
|
203
149
|
```
|
|
204
150
|
|
|
205
|
-
#### Conversation as a list of dictionaries
|
|
151
|
+
#### Conversation as a list of dictionaries
|
|
206
152
|
|
|
207
153
|
```python
|
|
208
|
-
result =
|
|
154
|
+
result = scope_guard.validate(
|
|
209
155
|
[
|
|
210
156
|
{
|
|
211
157
|
"role": "user",
|
|
@@ -245,7 +191,7 @@ queries = [
|
|
|
245
191
|
"When is the package expected to be delivered?"
|
|
246
192
|
]
|
|
247
193
|
|
|
248
|
-
result =
|
|
194
|
+
result = scope_guard.batch_validate(
|
|
249
195
|
queries,
|
|
250
196
|
ai_service_description=ai_service_description
|
|
251
197
|
)
|
|
@@ -259,31 +205,28 @@ ai_service_descriptions = [
|
|
|
259
205
|
"You are a virtual assistant for a Courier. You answer questions about package tracking. Never respond to refund requests."
|
|
260
206
|
]
|
|
261
207
|
|
|
262
|
-
result =
|
|
208
|
+
result = scope_guard.batch_validate(
|
|
263
209
|
queries,
|
|
264
210
|
ai_service_descriptions=ai_service_descriptions
|
|
265
211
|
)
|
|
266
212
|
```
|
|
267
213
|
|
|
268
|
-
## Serving
|
|
214
|
+
## Serving
|
|
269
215
|
|
|
270
216
|
`scope-guard` comes with built-in support for serving. For better performance, it consists of two components:
|
|
271
|
-
|
|
272
217
|
1. A **vLLM serving engine** that runs the model
|
|
273
218
|
2. A **FastAPI server** that provides the end-to-end API interface, mapping input data to prompts, invoking the vLLM serving engine and returning the response to the user
|
|
274
219
|
|
|
275
220
|
All of this is configured via the `orbitals scope-guard serve` command:
|
|
276
|
-
|
|
277
221
|
```bash
|
|
278
222
|
# install the necessary packages
|
|
279
223
|
pip install orbitals[scope-guard-serve]
|
|
280
224
|
|
|
281
225
|
# start everything
|
|
282
|
-
orbitals scope-guard serve
|
|
226
|
+
orbitals scope-guard serve serve small --port 8000
|
|
283
227
|
```
|
|
284
228
|
|
|
285
229
|
Alternatively, we also release a pre-built Docker image:
|
|
286
|
-
|
|
287
230
|
```bash
|
|
288
231
|
docker run --runtime nvidia --gpus all \
|
|
289
232
|
-p 8000:8000 \
|
|
@@ -317,7 +260,7 @@ Response:
|
|
|
317
260
|
],
|
|
318
261
|
"scope_class": "Restricted",
|
|
319
262
|
"time_taken": 0.23,
|
|
320
|
-
"model": "
|
|
263
|
+
"model": "small"
|
|
321
264
|
}
|
|
322
265
|
```
|
|
323
266
|
|
|
@@ -328,14 +271,14 @@ Response:
|
|
|
328
271
|
**Synchronous API client:**
|
|
329
272
|
|
|
330
273
|
```python
|
|
331
|
-
from orbitals.
|
|
274
|
+
from orbitals.guard import ScopeGuard
|
|
332
275
|
|
|
333
|
-
|
|
276
|
+
scope_guard = ScopeGuard(
|
|
334
277
|
backend="api",
|
|
335
278
|
api_url="http://localhost:8000"
|
|
336
279
|
)
|
|
337
280
|
|
|
338
|
-
result =
|
|
281
|
+
result = scope_guard.validate(
|
|
339
282
|
"If the package doesn't arrive by tomorrow, can I get my money back?",
|
|
340
283
|
"You are a virtual assistant for a parcel delivery service. You can only answer questions about package tracking. Never respond to requests for refunds."
|
|
341
284
|
)
|
|
@@ -344,14 +287,14 @@ result = sg.validate(
|
|
|
344
287
|
**Asynchronous API client:**
|
|
345
288
|
|
|
346
289
|
```python
|
|
347
|
-
from orbitals.
|
|
290
|
+
from orbitals.guard import AsyncScopeGuard
|
|
348
291
|
|
|
349
|
-
|
|
292
|
+
scope_guard = AsyncScopeGuard(
|
|
350
293
|
backend="api",
|
|
351
294
|
api_url="http://localhost:8000"
|
|
352
295
|
)
|
|
353
296
|
|
|
354
|
-
result = await
|
|
297
|
+
result = await scope_guard.validate(
|
|
355
298
|
"If the package doesn't arrive by tomorrow, can I get my money back?",
|
|
356
299
|
"You are a virtual assistant for a parcel delivery service. You can only answer questions about package tracking. Never respond to requests for refunds."
|
|
357
300
|
)
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "orbitals"
|
|
7
|
-
version = "0.0
|
|
7
|
+
version = "0.1.0"
|
|
8
8
|
description = "LLM Guardrails tailored to your Principles"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
|
|
@@ -17,38 +17,19 @@ authors = [
|
|
|
17
17
|
]
|
|
18
18
|
|
|
19
19
|
keywords = []
|
|
20
|
-
classifiers = [
|
|
21
|
-
"Programming Language :: Python :: 3 :: Only",
|
|
22
|
-
"Programming Language :: Python :: 3.10",
|
|
23
|
-
"Programming Language :: Python :: 3.11",
|
|
24
|
-
"Programming Language :: Python :: 3.12",
|
|
25
|
-
"Programming Language :: Python :: 3.13",
|
|
26
|
-
"Programming Language :: Python :: 3.14",
|
|
27
|
-
]
|
|
20
|
+
classifiers = []
|
|
28
21
|
|
|
29
22
|
dependencies = ["pydantic>=2.0.0", "typer>=0.12.3", "requests", "aiohttp"]
|
|
30
23
|
|
|
31
24
|
[project.optional-dependencies]
|
|
32
|
-
scope-guard-hf = ["transformers>=4.47.0,<5.0.0", "accelerate>=1.11.0"
|
|
33
|
-
scope-guard-vllm = [
|
|
34
|
-
"transformers>=4.47.0,<5.0.0",
|
|
35
|
-
"vllm>=0.11.0",
|
|
36
|
-
"xgrammar",
|
|
37
|
-
"pynvml",
|
|
38
|
-
]
|
|
25
|
+
scope-guard-hf = ["transformers>=4.47.0,<5.0.0", "accelerate>=1.11.0"]
|
|
26
|
+
scope-guard-vllm = ["transformers>=4.47.0,<5.0.0", "vllm>=0.11.0", "xgrammar"]
|
|
39
27
|
scope-guard-serve = [
|
|
40
28
|
"orbitals[scope-guard-vllm]",
|
|
41
29
|
"fastapi[standard]>=0.119.1",
|
|
42
30
|
"uvicorn>=0.29.0",
|
|
43
31
|
"vllm>=0.11.0",
|
|
44
32
|
]
|
|
45
|
-
scope-guard-all = [
|
|
46
|
-
"orbitals[scope-guard-vllm]",
|
|
47
|
-
"orbitals[scope-guard-hf]",
|
|
48
|
-
"orbitals[scope-guard-serve]",
|
|
49
|
-
]
|
|
50
|
-
|
|
51
|
-
all = ["orbitals[scope-guard-all]"]
|
|
52
33
|
|
|
53
34
|
[project.scripts]
|
|
54
35
|
orbitals = "orbitals.cli.main:app"
|
|
@@ -17,7 +17,7 @@ from ..modeling import (
|
|
|
17
17
|
ScopeGuardOutput,
|
|
18
18
|
)
|
|
19
19
|
|
|
20
|
-
DefaultModel = Literal["
|
|
20
|
+
DefaultModel = Literal["small"]
|
|
21
21
|
|
|
22
22
|
MODEL_MAPPING = {
|
|
23
23
|
"scope-guard": "principled-intelligence/scope-guard-4B-q-2601",
|
|
@@ -137,7 +137,7 @@ class ScopeGuard(BaseScopeGuard):
|
|
|
137
137
|
def __new__(
|
|
138
138
|
cls,
|
|
139
139
|
backend: Literal["hf"] = "hf",
|
|
140
|
-
model: DefaultModel | str = "
|
|
140
|
+
model: DefaultModel | str = "small",
|
|
141
141
|
skip_evidences: bool = False,
|
|
142
142
|
max_new_tokens: int = 10_000,
|
|
143
143
|
do_sample: bool = False,
|
|
@@ -148,7 +148,7 @@ class ScopeGuard(BaseScopeGuard):
|
|
|
148
148
|
def __new__(
|
|
149
149
|
cls,
|
|
150
150
|
backend: Literal["vllm"],
|
|
151
|
-
model: DefaultModel | str = "
|
|
151
|
+
model: DefaultModel | str = "small",
|
|
152
152
|
skip_evidences: bool = False,
|
|
153
153
|
temperature: float = 0.0,
|
|
154
154
|
max_tokens: int = 10_000,
|
|
@@ -223,7 +223,7 @@ class AsyncScopeGuard(BaseScopeGuard):
|
|
|
223
223
|
def __new__(
|
|
224
224
|
cls,
|
|
225
225
|
backend: Literal["vllm-api"],
|
|
226
|
-
model: DefaultModel | str = "
|
|
226
|
+
model: DefaultModel | str = "small",
|
|
227
227
|
skip_evidences: bool = False,
|
|
228
228
|
vllm_serving_url: str = "http://localhost:8000",
|
|
229
229
|
temperature: float = 0.0,
|
|
@@ -21,7 +21,7 @@ class HuggingFaceScopeGuard(ScopeGuard):
|
|
|
21
21
|
def __init__(
|
|
22
22
|
self,
|
|
23
23
|
backend: Literal["hf"] = "hf",
|
|
24
|
-
model: DefaultModel | str = "
|
|
24
|
+
model: DefaultModel | str = "small",
|
|
25
25
|
skip_evidences: bool = False,
|
|
26
26
|
max_new_tokens: int = 10_000,
|
|
27
27
|
do_sample: bool = False,
|
|
@@ -23,7 +23,7 @@ class VLLMScopeGuard(ScopeGuard):
|
|
|
23
23
|
def __init__(
|
|
24
24
|
self,
|
|
25
25
|
backend: Literal["vllm"] = "vllm",
|
|
26
|
-
model: DefaultModel | str = "
|
|
26
|
+
model: DefaultModel | str = "small",
|
|
27
27
|
skip_evidences: bool = False,
|
|
28
28
|
temperature: float = 0.0,
|
|
29
29
|
max_tokens: int = 10_000,
|
|
@@ -127,7 +127,7 @@ class AsyncVLLMApiScopeGuard(AsyncScopeGuard):
|
|
|
127
127
|
def __init__(
|
|
128
128
|
self,
|
|
129
129
|
backend: Literal["vllm-api", "vllm-async-api"] = "vllm-api",
|
|
130
|
-
model: DefaultModel | str = "
|
|
130
|
+
model: DefaultModel | str = "small",
|
|
131
131
|
skip_evidences: bool = False,
|
|
132
132
|
vllm_serving_url: str = "http://localhost:8000",
|
|
133
133
|
temperature: float = 0.0,
|