orbitals 0.0.1__tar.gz → 0.0.3__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.0.3/.dockerignore +5 -0
- orbitals-0.0.3/CONTRIBUTING.md +45 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/Dockerfile +10 -11
- {orbitals-0.0.1 → orbitals-0.0.3}/LICENSE +1 -1
- orbitals-0.0.3/PKG-INFO +161 -0
- orbitals-0.0.3/README.md +109 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/README.scope-guard.md +96 -41
- orbitals-0.0.3/examples/scope-guard/test.py +27 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/pyproject.toml +23 -4
- {orbitals-0.0.1 → orbitals-0.0.3}/src/orbitals/types.py +14 -2
- orbitals-0.0.3/src/orbitals/utils.py +53 -0
- orbitals-0.0.3/src/scripts/playground.ipynb +267 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/uv.lock +25 -5
- orbitals-0.0.1/.dockerignore +0 -2
- orbitals-0.0.1/PKG-INFO +0 -103
- orbitals-0.0.1/README.md +0 -76
- orbitals-0.0.1/src/orbitals/utils.py +0 -45
- orbitals-0.0.1/src/scripts/playground.ipynb +0 -196
- {orbitals-0.0.1 → orbitals-0.0.3}/.gitignore +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/AGENTS.md +0 -0
- /orbitals-0.0.1/assets/Orbitals Banner.png → /orbitals-0.0.3/assets/orbitals-banner.png +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/assets/orbitals.svg +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/assets/scope-guard.svg +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/examples/scope-guard/api.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/examples/scope-guard/async_api.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/examples/scope-guard/local.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/examples/scope-guard/vllm_serve.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/hf_pipeline/scope_guard.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/orbitals/__init__.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/orbitals/cli/__init__.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/orbitals/cli/main.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/orbitals/scope_guard/__init__.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/orbitals/scope_guard/cli/__init__.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/orbitals/scope_guard/cli/convert_default_model_name.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/orbitals/scope_guard/cli/main.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/orbitals/scope_guard/cli/serve.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/orbitals/scope_guard/guards/__init__.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/orbitals/scope_guard/guards/api.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/orbitals/scope_guard/guards/base.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/orbitals/scope_guard/guards/hf.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/orbitals/scope_guard/guards/vllm.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/orbitals/scope_guard/modeling.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/orbitals/scope_guard/prompting.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/orbitals/scope_guard/serving/__init__.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/orbitals/scope_guard/serving/main.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/orbitals/scope_guard/serving/vllm_logging_config.json +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/scripts/push_hf_pipeline.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.3}/src/scripts/push_model.py +0 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Contributing to Orbitals
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to `orbitals`! We welcome contributions from the community.
|
|
4
|
+
|
|
5
|
+
## Getting Started
|
|
6
|
+
|
|
7
|
+
1. **Fork the repository** and clone it locally
|
|
8
|
+
2. **Install dependencies** using `uv`:
|
|
9
|
+
```bash
|
|
10
|
+
uv sync
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Development Workflow
|
|
14
|
+
|
|
15
|
+
1. Create a new branch for your feature or fix:
|
|
16
|
+
```bash
|
|
17
|
+
git checkout -b feature/your-feature-name
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
2. Make your changes and ensure they follow the project's coding conventions
|
|
21
|
+
|
|
22
|
+
3. Test your changes thoroughly
|
|
23
|
+
|
|
24
|
+
4. Commit your changes with a clear, descriptive message
|
|
25
|
+
|
|
26
|
+
5. Push to your fork and submit a pull request
|
|
27
|
+
|
|
28
|
+
## Coding Conventions
|
|
29
|
+
|
|
30
|
+
- Use **Google-style docstrings** for all documentation
|
|
31
|
+
- Follow PEP 8 style guidelines
|
|
32
|
+
- Keep code modular and well-organized
|
|
33
|
+
|
|
34
|
+
## Reporting Issues
|
|
35
|
+
|
|
36
|
+
When reporting issues, please include:
|
|
37
|
+
|
|
38
|
+
- A clear description of the problem
|
|
39
|
+
- Steps to reproduce the issue
|
|
40
|
+
- Expected vs actual behavior
|
|
41
|
+
- Your environment details (Python version, OS, etc.)
|
|
42
|
+
|
|
43
|
+
## Questions?
|
|
44
|
+
|
|
45
|
+
Feel free to open an issue for any questions or discussions about contributing.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
FROM vllm/vllm-openai:v0.
|
|
1
|
+
FROM vllm/vllm-openai:v0.14.1 as builder
|
|
2
2
|
|
|
3
3
|
ARG DEBIAN_FRONTEND=noninteractive
|
|
4
4
|
ARG MODEL
|
|
@@ -17,23 +17,22 @@ 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 serve --no-install-project --no-dev
|
|
21
|
-
|
|
22
|
-
COPY src /app/src/
|
|
20
|
+
uv sync --frozen --extra scope-guard-serve --no-install-project --no-dev
|
|
23
21
|
|
|
24
22
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
25
|
-
|
|
23
|
+
hf download ${MODEL}
|
|
24
|
+
|
|
25
|
+
COPY src /app/src/
|
|
26
26
|
|
|
27
27
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
28
|
-
--
|
|
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
|
|
28
|
+
uv sync --locked --extra scope-guard-serve --no-editable --no-dev
|
|
32
29
|
|
|
33
30
|
# TODO remove next line
|
|
34
31
|
ENTRYPOINT ["/bin/bash", "-c"]
|
|
35
32
|
|
|
36
|
-
FROM vllm/vllm-openai:v0.
|
|
33
|
+
FROM vllm/vllm-openai:v0.14.1 as runner
|
|
34
|
+
|
|
35
|
+
ARG MODEL
|
|
37
36
|
|
|
38
37
|
WORKDIR /app
|
|
39
38
|
ENV PATH="/app/.venv/bin:$PATH"
|
|
@@ -46,4 +45,4 @@ COPY --from=builder /root/.cache/huggingface/hub /root/.cache/huggingface/hub
|
|
|
46
45
|
EXPOSE 8000
|
|
47
46
|
|
|
48
47
|
ENTRYPOINT ["/bin/bash", "-c"]
|
|
49
|
-
CMD [ "scope-
|
|
48
|
+
CMD [ "orbitals", "scope-guard", "serve", "principled-intelligence/${MODEL}", "--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 2026 Principled Intelligence s.r.l.
|
|
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.0.3/PKG-INFO
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: orbitals
|
|
3
|
+
Version: 0.0.3
|
|
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
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Requires-Dist: aiohttp
|
|
16
|
+
Requires-Dist: pydantic>=2.0.0
|
|
17
|
+
Requires-Dist: requests
|
|
18
|
+
Requires-Dist: typer>=0.12.3
|
|
19
|
+
Provides-Extra: all
|
|
20
|
+
Requires-Dist: accelerate>=1.11.0; extra == 'all'
|
|
21
|
+
Requires-Dist: fastapi[standard]>=0.119.1; extra == 'all'
|
|
22
|
+
Requires-Dist: pynvml; extra == 'all'
|
|
23
|
+
Requires-Dist: transformers<5.0.0,>=4.47.0; extra == 'all'
|
|
24
|
+
Requires-Dist: uvicorn>=0.29.0; extra == 'all'
|
|
25
|
+
Requires-Dist: vllm>=0.11.0; extra == 'all'
|
|
26
|
+
Requires-Dist: xgrammar; extra == 'all'
|
|
27
|
+
Provides-Extra: scope-guard-all
|
|
28
|
+
Requires-Dist: accelerate>=1.11.0; extra == 'scope-guard-all'
|
|
29
|
+
Requires-Dist: fastapi[standard]>=0.119.1; extra == 'scope-guard-all'
|
|
30
|
+
Requires-Dist: pynvml; extra == 'scope-guard-all'
|
|
31
|
+
Requires-Dist: transformers<5.0.0,>=4.47.0; extra == 'scope-guard-all'
|
|
32
|
+
Requires-Dist: uvicorn>=0.29.0; extra == 'scope-guard-all'
|
|
33
|
+
Requires-Dist: vllm>=0.11.0; extra == 'scope-guard-all'
|
|
34
|
+
Requires-Dist: xgrammar; extra == 'scope-guard-all'
|
|
35
|
+
Provides-Extra: scope-guard-hf
|
|
36
|
+
Requires-Dist: accelerate>=1.11.0; extra == 'scope-guard-hf'
|
|
37
|
+
Requires-Dist: pynvml; extra == 'scope-guard-hf'
|
|
38
|
+
Requires-Dist: transformers<5.0.0,>=4.47.0; extra == 'scope-guard-hf'
|
|
39
|
+
Provides-Extra: scope-guard-serve
|
|
40
|
+
Requires-Dist: fastapi[standard]>=0.119.1; extra == 'scope-guard-serve'
|
|
41
|
+
Requires-Dist: pynvml; extra == 'scope-guard-serve'
|
|
42
|
+
Requires-Dist: transformers<5.0.0,>=4.47.0; extra == 'scope-guard-serve'
|
|
43
|
+
Requires-Dist: uvicorn>=0.29.0; extra == 'scope-guard-serve'
|
|
44
|
+
Requires-Dist: vllm>=0.11.0; extra == 'scope-guard-serve'
|
|
45
|
+
Requires-Dist: xgrammar; extra == 'scope-guard-serve'
|
|
46
|
+
Provides-Extra: scope-guard-vllm
|
|
47
|
+
Requires-Dist: pynvml; extra == 'scope-guard-vllm'
|
|
48
|
+
Requires-Dist: transformers<5.0.0,>=4.47.0; extra == 'scope-guard-vllm'
|
|
49
|
+
Requires-Dist: vllm>=0.11.0; extra == 'scope-guard-vllm'
|
|
50
|
+
Requires-Dist: xgrammar; extra == 'scope-guard-vllm'
|
|
51
|
+
Description-Content-Type: text/markdown
|
|
52
|
+
|
|
53
|
+
<div align="center">
|
|
54
|
+
<img src="assets/orbitals-banner.png" width="70%" />
|
|
55
|
+
<h3 align="center">
|
|
56
|
+
<p>
|
|
57
|
+
<b>LLM Guardrails tailored to your Principles</b>
|
|
58
|
+
</p>
|
|
59
|
+
</h4>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<p align="center">
|
|
63
|
+
<img src="https://img.shields.io/pypi/v/orbitals?color=green" alt="PyPI Version">
|
|
64
|
+
<!-- <img src="https://img.shields.io/badge/type%20checked-ty-blue.svg?color=green" alt="Type Checked with ty"> -->
|
|
65
|
+
<img src="https://img.shields.io/pypi/pyversions/orbitals" alt="Python Versions">
|
|
66
|
+
<img src="https://img.shields.io/github/license/principled-intelligence/orbitals" alt="GitHub License">
|
|
67
|
+
</p>
|
|
68
|
+
|
|
69
|
+
## Overview
|
|
70
|
+
|
|
71
|
+
**Orbitals** is a lightweight Python library for adding LLM guardrails in just a few lines of code. With Orbitals, you can add a governance layer tailored to **user-specific principles**. Rather than enforcing generic notions of safety, compliance, and correctness, Orbitals validates inputs (e.g., user requests) and outputs (e.g., assistant responses) against user-defined specifications and custom policies. This makes guardrails explicit, auditable, and aligned with the user's philosophy.
|
|
72
|
+
|
|
73
|
+
### Key Features
|
|
74
|
+
|
|
75
|
+
- **User-defined specifications** — Guardrails that match your use case and your custom policies, not generic safety rules
|
|
76
|
+
- **Simple integration** — Add guardrails with minimal code changes
|
|
77
|
+
- **Open framework, open models** — Orbitals is open-source and is a simple interface for our open models
|
|
78
|
+
|
|
79
|
+
## Getting started
|
|
80
|
+
|
|
81
|
+
### Installation
|
|
82
|
+
|
|
83
|
+
You can install Orbitals via pip:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pip install orbitals[all]
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Basic Usage
|
|
90
|
+
|
|
91
|
+
Here's a quick example to get you started with Orbitals, in which we use the ScopeGuard module to guard an AI service (for example, a customer support chatbot) from user requests that violate specified principles or fall outside of the scope of the core task of the assistant.
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from orbitals.scope_guard import ScopeGuard
|
|
95
|
+
|
|
96
|
+
ai_service_description = "You are a helpful assistant for ..."
|
|
97
|
+
user_message = "Can I buy ..."
|
|
98
|
+
|
|
99
|
+
guardrail = ScopeGuard()
|
|
100
|
+
result = guardrail.validate(user_message, ai_service_description)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The result of a guardrail validation will indicate whether the input or output passed the guardrail checks, along with details on any violations. You can then handle violations as needed, such as by rejecting the input or modifying the output. For example:
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
if result.scope_class.value == "Restricted" or result.scope_class.value == "Out of Scope":
|
|
107
|
+
print("Request violates guardrail:", result.evidences)
|
|
108
|
+
else:
|
|
109
|
+
# The user request is safe!
|
|
110
|
+
# We can now pass it to the AI assistant for processing.
|
|
111
|
+
...
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Available Guardrails
|
|
115
|
+
|
|
116
|
+
Orbitals currently provides the following guardrail modules:
|
|
117
|
+
|
|
118
|
+
| Guardrail | Description | Hosting Options |
|
|
119
|
+
|:----------|:------------|:----------------|
|
|
120
|
+
| **[ScopeGuard](README.scope-guard.md)** | Classifies user queries against AI assistant specifications to detect out-of-scope requests, policy violations, and chit-chat | Self-hosted / Cloud hosting |
|
|
121
|
+
| 🚀 *Coming Soon* | More guardrails are on the way — stay tuned for updates! | — |
|
|
122
|
+
|
|
123
|
+
#### Hosting Options
|
|
124
|
+
|
|
125
|
+
- **Self-hosted**: Use open-weight models that you can deploy on your own infrastructure, ensuring data privacy and control.
|
|
126
|
+
- **Cloud hosting**: (Coming soon) Managed hosting options for ease of use and scalability
|
|
127
|
+
|
|
128
|
+
### Documentation
|
|
129
|
+
|
|
130
|
+
For detailed documentation, including installation instructions, usage guides, and API references, please visit the Orbitals Documentation.
|
|
131
|
+
|
|
132
|
+
- [ScopeGuard Documentation](README.scope-guard.md)
|
|
133
|
+
|
|
134
|
+
### FAQ
|
|
135
|
+
|
|
136
|
+
- **Can I use Orbitals for commercial applications?**
|
|
137
|
+
Yes, Orbitals is designed to be used in both research and commercial applications. It is licensed under the Apache 2.0 License, which allows for commercial use.
|
|
138
|
+
- **Other questions?**
|
|
139
|
+
Feel free to reach out to us at [orbitals@principled-intelligence.com](mailto:orbitals@principled-intelligence.com)!
|
|
140
|
+
|
|
141
|
+
### Contributing
|
|
142
|
+
|
|
143
|
+
We welcome contributions from the community! If you'd like to contribute to Orbitals, please check out our [Contributing Guide](CONTRIBUTING.md) for guidelines on how to get started.
|
|
144
|
+
|
|
145
|
+
### License
|
|
146
|
+
|
|
147
|
+
This project is licensed under the Apache 2.0 License. See the [LICENSE](LICENSE) file for details.
|
|
148
|
+
|
|
149
|
+
### Contact
|
|
150
|
+
|
|
151
|
+
For questions, feedback, or support, please reach out to us at [orbitals@principled-intelligence.com](mailto:orbitals@principled-intelligence.com).
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
<div align="center">
|
|
156
|
+
<p>
|
|
157
|
+
<b>Built with ❤️ by <a href="https://principled-intelligence.com">Principled Intelligence</a></b>
|
|
158
|
+
<br />
|
|
159
|
+
Follow us on <a href="https://www.linkedin.com/company/principled-ai/">LinkedIn</a> for the latest updates.
|
|
160
|
+
</p>
|
|
161
|
+
</div>
|
orbitals-0.0.3/README.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="assets/orbitals-banner.png" width="70%" />
|
|
3
|
+
<h3 align="center">
|
|
4
|
+
<p>
|
|
5
|
+
<b>LLM Guardrails tailored to your Principles</b>
|
|
6
|
+
</p>
|
|
7
|
+
</h4>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<p align="center">
|
|
11
|
+
<img src="https://img.shields.io/pypi/v/orbitals?color=green" alt="PyPI Version">
|
|
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/pyversions/orbitals" alt="Python Versions">
|
|
14
|
+
<img src="https://img.shields.io/github/license/principled-intelligence/orbitals" alt="GitHub License">
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
## Overview
|
|
18
|
+
|
|
19
|
+
**Orbitals** is a lightweight Python library for adding LLM guardrails in just a few lines of code. With Orbitals, you can add a governance layer tailored to **user-specific principles**. Rather than enforcing generic notions of safety, compliance, and correctness, Orbitals validates inputs (e.g., user requests) and outputs (e.g., assistant responses) against user-defined specifications and custom policies. This makes guardrails explicit, auditable, and aligned with the user's philosophy.
|
|
20
|
+
|
|
21
|
+
### Key Features
|
|
22
|
+
|
|
23
|
+
- **User-defined specifications** — Guardrails that match your use case and your custom policies, not generic safety rules
|
|
24
|
+
- **Simple integration** — Add guardrails with minimal code changes
|
|
25
|
+
- **Open framework, open models** — Orbitals is open-source and is a simple interface for our open models
|
|
26
|
+
|
|
27
|
+
## Getting started
|
|
28
|
+
|
|
29
|
+
### Installation
|
|
30
|
+
|
|
31
|
+
You can install Orbitals via pip:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install orbitals[all]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Basic Usage
|
|
38
|
+
|
|
39
|
+
Here's a quick example to get you started with Orbitals, in which we use the ScopeGuard module to guard an AI service (for example, a customer support chatbot) from user requests that violate specified principles or fall outside of the scope of the core task of the assistant.
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from orbitals.scope_guard import ScopeGuard
|
|
43
|
+
|
|
44
|
+
ai_service_description = "You are a helpful assistant for ..."
|
|
45
|
+
user_message = "Can I buy ..."
|
|
46
|
+
|
|
47
|
+
guardrail = ScopeGuard()
|
|
48
|
+
result = guardrail.validate(user_message, ai_service_description)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The result of a guardrail validation will indicate whether the input or output passed the guardrail checks, along with details on any violations. You can then handle violations as needed, such as by rejecting the input or modifying the output. For example:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
if result.scope_class.value == "Restricted" or result.scope_class.value == "Out of Scope":
|
|
55
|
+
print("Request violates guardrail:", result.evidences)
|
|
56
|
+
else:
|
|
57
|
+
# The user request is safe!
|
|
58
|
+
# We can now pass it to the AI assistant for processing.
|
|
59
|
+
...
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Available Guardrails
|
|
63
|
+
|
|
64
|
+
Orbitals currently provides the following guardrail modules:
|
|
65
|
+
|
|
66
|
+
| Guardrail | Description | Hosting Options |
|
|
67
|
+
|:----------|:------------|:----------------|
|
|
68
|
+
| **[ScopeGuard](README.scope-guard.md)** | Classifies user queries against AI assistant specifications to detect out-of-scope requests, policy violations, and chit-chat | Self-hosted / Cloud hosting |
|
|
69
|
+
| 🚀 *Coming Soon* | More guardrails are on the way — stay tuned for updates! | — |
|
|
70
|
+
|
|
71
|
+
#### Hosting Options
|
|
72
|
+
|
|
73
|
+
- **Self-hosted**: Use open-weight models that you can deploy on your own infrastructure, ensuring data privacy and control.
|
|
74
|
+
- **Cloud hosting**: (Coming soon) Managed hosting options for ease of use and scalability
|
|
75
|
+
|
|
76
|
+
### Documentation
|
|
77
|
+
|
|
78
|
+
For detailed documentation, including installation instructions, usage guides, and API references, please visit the Orbitals Documentation.
|
|
79
|
+
|
|
80
|
+
- [ScopeGuard Documentation](README.scope-guard.md)
|
|
81
|
+
|
|
82
|
+
### FAQ
|
|
83
|
+
|
|
84
|
+
- **Can I use Orbitals for commercial applications?**
|
|
85
|
+
Yes, Orbitals is designed to be used in both research and commercial applications. It is licensed under the Apache 2.0 License, which allows for commercial use.
|
|
86
|
+
- **Other questions?**
|
|
87
|
+
Feel free to reach out to us at [orbitals@principled-intelligence.com](mailto:orbitals@principled-intelligence.com)!
|
|
88
|
+
|
|
89
|
+
### Contributing
|
|
90
|
+
|
|
91
|
+
We welcome contributions from the community! If you'd like to contribute to Orbitals, please check out our [Contributing Guide](CONTRIBUTING.md) for guidelines on how to get started.
|
|
92
|
+
|
|
93
|
+
### License
|
|
94
|
+
|
|
95
|
+
This project is licensed under the Apache 2.0 License. See the [LICENSE](LICENSE) file for details.
|
|
96
|
+
|
|
97
|
+
### Contact
|
|
98
|
+
|
|
99
|
+
For questions, feedback, or support, please reach out to us at [orbitals@principled-intelligence.com](mailto:orbitals@principled-intelligence.com).
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
<div align="center">
|
|
104
|
+
<p>
|
|
105
|
+
<b>Built with ❤️ by <a href="https://principled-intelligence.com">Principled Intelligence</a></b>
|
|
106
|
+
<br />
|
|
107
|
+
Follow us on <a href="https://www.linkedin.com/company/principled-ai/">LinkedIn</a> for the latest updates.
|
|
108
|
+
</p>
|
|
109
|
+
</div>
|
|
@@ -16,29 +16,28 @@
|
|
|
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
|
-
*
|
|
19
|
+
|
|
20
|
+
* **Directly Supported**: The query is clearly within the assistant's capabilities.
|
|
21
|
+
* **Potentially Supported**: The query could plausibly be handled by the assistant.
|
|
22
|
+
* **Out of Scope**: The query is outside the assistant's defined role.
|
|
23
|
+
* **Restricted**: The query cannot be handled due to a specific constraint.
|
|
24
|
+
* **Chit Chat**: The query is a social interaction not related to the assistant's function.
|
|
24
25
|
|
|
25
26
|
<p align="center">
|
|
26
27
|
<img src="assets/scope-guard.svg" width="80%" />
|
|
27
28
|
</p>
|
|
28
29
|
|
|
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
|
|
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 deployment options:
|
|
30
31
|
|
|
31
|
-
|
|
|
32
|
+
| Model | Parameters | Hosting Options | Scope Classification | Custom Safety | Vanilla Safety | Tested GPUs |
|
|
32
33
|
| :--- | :--- | :--- | :--- | :--- | :--- | :--- |
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
|
|
|
34
|
+
| scope-guard-4B-q-2601 | 4B | Self-hosted | 89.1 | 79.1 | 90.3 | T4, L4, L40S, 4090, 5090 |
|
|
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 | ~ |
|
|
36
37
|
|
|
37
|
-
## Quickstart
|
|
38
|
+
## Quickstart with our open models
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
<summary>Open Flavor</summary>
|
|
41
|
-
<br>
|
|
40
|
+
The easiest way to get started with ScopeGuard is to use our open models, which you can self-host on consumer-grade GPUs (e.g., Nvidia RTX series) and use via the `vllm` or `huggingface` backends. `scope-guard-4B-q-2601` and `scope-guard-4B-g-2601` are both 4B-parameter models so they can run even on a free instance on Google Colab with a T4 GPU.
|
|
42
41
|
|
|
43
42
|
First, we need to install `orbitals` and `scope-guard`:
|
|
44
43
|
|
|
@@ -53,9 +52,10 @@ Then:
|
|
|
53
52
|
```python
|
|
54
53
|
from orbitals.scope_guard import ScopeGuard
|
|
55
54
|
|
|
56
|
-
|
|
55
|
+
sg = ScopeGuard(
|
|
57
56
|
backend="vllm",
|
|
58
|
-
model="scope-guard"
|
|
57
|
+
model="scope-guard-q", # for the Qwen-family model
|
|
58
|
+
# model="scope-guard-g", # for the Gemma-family model
|
|
59
59
|
)
|
|
60
60
|
|
|
61
61
|
ai_service_description = """
|
|
@@ -65,7 +65,7 @@ Never respond to requests for refunds.
|
|
|
65
65
|
"""
|
|
66
66
|
|
|
67
67
|
user_query = "If the package hasn't arrived by tomorrow, can I get my money back?"
|
|
68
|
-
result =
|
|
68
|
+
result = sg.validate(user_query, ai_service_description)
|
|
69
69
|
|
|
70
70
|
print(f"Scope: {result.scope_class.value}")
|
|
71
71
|
if result.evidences:
|
|
@@ -78,11 +78,12 @@ if result.evidences:
|
|
|
78
78
|
# - Never respond to requests for refunds.
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
## Quickstart with our hosted models
|
|
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.
|
|
82
84
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
<br>
|
|
85
|
+
> Open access to the hosted models is coming soon.
|
|
86
|
+
> Need access earlier? Contact us at [orbitals@principled-intelligence.com](mailto:orbitals@principled-intelligence.com).
|
|
86
87
|
|
|
87
88
|
First, we need to install `orbitals` and `scope-guard`. In this case, plain `orbitals` is all we need:
|
|
88
89
|
|
|
@@ -95,9 +96,9 @@ Then:
|
|
|
95
96
|
```python
|
|
96
97
|
from orbitals.scope_guard import ScopeGuard
|
|
97
98
|
|
|
98
|
-
|
|
99
|
+
sg = ScopeGuard(
|
|
99
100
|
backend="api",
|
|
100
|
-
api_key="principled_1234",
|
|
101
|
+
api_key="principled_1234", # replace with your actual API key
|
|
101
102
|
)
|
|
102
103
|
|
|
103
104
|
ai_service_description = """
|
|
@@ -107,7 +108,7 @@ Never respond to requests for refunds.
|
|
|
107
108
|
"""
|
|
108
109
|
|
|
109
110
|
user_query = "If the package hasn't arrived by tomorrow, can I get my money back?"
|
|
110
|
-
result =
|
|
111
|
+
result = sg.validate(user_query, ai_service_description)
|
|
111
112
|
|
|
112
113
|
print(f"Scope: {result.scope_class.value}")
|
|
113
114
|
if result.evidences:
|
|
@@ -120,10 +121,62 @@ if result.evidences:
|
|
|
120
121
|
# - Never respond to requests for refunds.
|
|
121
122
|
```
|
|
122
123
|
|
|
123
|
-
</details>
|
|
124
|
-
|
|
125
124
|
## Usage
|
|
126
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.")
|
|
174
|
+
|
|
175
|
+
# Or using the string value:
|
|
176
|
+
if result.scope_class.value == "Restricted":
|
|
177
|
+
print("The user query is restricted.")
|
|
178
|
+
```
|
|
179
|
+
|
|
127
180
|
### Input Formats
|
|
128
181
|
|
|
129
182
|
The `validate` method is flexible and accepts various input formats for the conversation.
|
|
@@ -131,7 +184,7 @@ The `validate` method is flexible and accepts various input formats for the conv
|
|
|
131
184
|
#### User query as a string
|
|
132
185
|
|
|
133
186
|
```python
|
|
134
|
-
result =
|
|
187
|
+
result = sg.validate(
|
|
135
188
|
"When is my package scheduled to arrive?",
|
|
136
189
|
ai_service_description
|
|
137
190
|
)
|
|
@@ -139,9 +192,8 @@ result = scope_guard.validate(
|
|
|
139
192
|
|
|
140
193
|
#### User query as a dictionary (OpenAI's API Message)
|
|
141
194
|
|
|
142
|
-
|
|
143
195
|
```python
|
|
144
|
-
result =
|
|
196
|
+
result = sg.validate(
|
|
145
197
|
{
|
|
146
198
|
"role": "user",
|
|
147
199
|
"content": "When is my package scheduled to arrive?"
|
|
@@ -150,10 +202,10 @@ result = scope_guard.validate(
|
|
|
150
202
|
)
|
|
151
203
|
```
|
|
152
204
|
|
|
153
|
-
#### Conversation as a list of dictionaries
|
|
205
|
+
#### Conversation as a list of dictionaries
|
|
154
206
|
|
|
155
207
|
```python
|
|
156
|
-
result =
|
|
208
|
+
result = sg.validate(
|
|
157
209
|
[
|
|
158
210
|
{
|
|
159
211
|
"role": "user",
|
|
@@ -193,7 +245,7 @@ queries = [
|
|
|
193
245
|
"When is the package expected to be delivered?"
|
|
194
246
|
]
|
|
195
247
|
|
|
196
|
-
result =
|
|
248
|
+
result = sg.batch_validate(
|
|
197
249
|
queries,
|
|
198
250
|
ai_service_description=ai_service_description
|
|
199
251
|
)
|
|
@@ -207,28 +259,31 @@ ai_service_descriptions = [
|
|
|
207
259
|
"You are a virtual assistant for a Courier. You answer questions about package tracking. Never respond to refund requests."
|
|
208
260
|
]
|
|
209
261
|
|
|
210
|
-
result =
|
|
262
|
+
result = sg.batch_validate(
|
|
211
263
|
queries,
|
|
212
264
|
ai_service_descriptions=ai_service_descriptions
|
|
213
265
|
)
|
|
214
266
|
```
|
|
215
267
|
|
|
216
|
-
## Serving
|
|
268
|
+
## Serving ScopeGuard on-premise or on your infrastructure
|
|
217
269
|
|
|
218
270
|
`scope-guard` comes with built-in support for serving. For better performance, it consists of two components:
|
|
271
|
+
|
|
219
272
|
1. A **vLLM serving engine** that runs the model
|
|
220
273
|
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
|
|
221
274
|
|
|
222
275
|
All of this is configured via the `orbitals scope-guard serve` command:
|
|
276
|
+
|
|
223
277
|
```bash
|
|
224
278
|
# install the necessary packages
|
|
225
279
|
pip install orbitals[scope-guard-serve]
|
|
226
280
|
|
|
227
281
|
# start everything
|
|
228
|
-
orbitals scope-guard serve
|
|
282
|
+
orbitals scope-guard serve scope-guard --port 8000
|
|
229
283
|
```
|
|
230
284
|
|
|
231
285
|
Alternatively, we also release a pre-built Docker image:
|
|
286
|
+
|
|
232
287
|
```bash
|
|
233
288
|
docker run --runtime nvidia --gpus all \
|
|
234
289
|
-p 8000:8000 \
|
|
@@ -273,14 +328,14 @@ Response:
|
|
|
273
328
|
**Synchronous API client:**
|
|
274
329
|
|
|
275
330
|
```python
|
|
276
|
-
from orbitals.
|
|
331
|
+
from orbitals.scope_guard import ScopeGuard
|
|
277
332
|
|
|
278
|
-
|
|
333
|
+
sg = ScopeGuard(
|
|
279
334
|
backend="api",
|
|
280
335
|
api_url="http://localhost:8000"
|
|
281
336
|
)
|
|
282
337
|
|
|
283
|
-
result =
|
|
338
|
+
result = sg.validate(
|
|
284
339
|
"If the package doesn't arrive by tomorrow, can I get my money back?",
|
|
285
340
|
"You are a virtual assistant for a parcel delivery service. You can only answer questions about package tracking. Never respond to requests for refunds."
|
|
286
341
|
)
|
|
@@ -289,14 +344,14 @@ result = scope_guard.validate(
|
|
|
289
344
|
**Asynchronous API client:**
|
|
290
345
|
|
|
291
346
|
```python
|
|
292
|
-
from orbitals.
|
|
347
|
+
from orbitals.scope_guard import AsyncScopeGuard
|
|
293
348
|
|
|
294
|
-
|
|
349
|
+
sg = AsyncScopeGuard(
|
|
295
350
|
backend="api",
|
|
296
351
|
api_url="http://localhost:8000"
|
|
297
352
|
)
|
|
298
353
|
|
|
299
|
-
result = await
|
|
354
|
+
result = await sg.validate(
|
|
300
355
|
"If the package doesn't arrive by tomorrow, can I get my money back?",
|
|
301
356
|
"You are a virtual assistant for a parcel delivery service. You can only answer questions about package tracking. Never respond to requests for refunds."
|
|
302
357
|
)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
def main():
|
|
2
|
+
from orbitals.scope_guard import ScopeGuard
|
|
3
|
+
|
|
4
|
+
sg = ScopeGuard(
|
|
5
|
+
backend="vllm",
|
|
6
|
+
model="scope-guard-q", # for the Qwen-family model
|
|
7
|
+
# model="scope-guard-g", # for the Gemma-family model
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
ai_service_description = """
|
|
11
|
+
You are a virtual assistant for a parcel delivery service.
|
|
12
|
+
You can only answer questions about package tracking.
|
|
13
|
+
Never respond to requests for refunds.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
user_query = "If the package hasn't arrived by tomorrow, can I get my money back?"
|
|
17
|
+
result = sg.validate(user_query, ai_service_description)
|
|
18
|
+
|
|
19
|
+
print(f"Scope: {result.scope_class.value}")
|
|
20
|
+
if result.evidences:
|
|
21
|
+
print("Evidences:")
|
|
22
|
+
for evidence in result.evidences:
|
|
23
|
+
print(f" - {evidence}")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
if __name__ == "__main__":
|
|
27
|
+
main()
|