Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

A project gallery of full end-to-end applications built with SIE. Each project lives in its own subdirectory. Clone it, run it, learn from it.

New to SIE? Start with the **[quickstart notebook](./quickstart.ipynb)** [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/superlinked/sie/blob/main/examples/quickstart.ipynb): encode, score, and extract in 5 minutes, then pick a project below.
New to SIE? Start with the **[Python quickstart](./quickstart)** for one
SDK call against local, self-deployed, or managed SIE. Continue with the
**[quickstart notebook](./quickstart.ipynb)** [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/superlinked/sie/blob/main/examples/quickstart.ipynb)
to try encode, score, and extract, then pick a project below.

## Gallery

Expand Down
1 change: 0 additions & 1 deletion examples/contract-review-agent/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
__pycache__/
.env
*.log
uv.lock
.ruff_cache/
# Generated sample artifacts (recreate with `uv run make-sample`)
contract_review_agent/data/generated/
18 changes: 17 additions & 1 deletion examples/contract-review-agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,22 @@ The flow is **two agents**:

> Two agents instead of one: a single structured-output agent tends to emit the schema immediately and skip the tools, sometimes hallucinating the fields. Splitting "gather with tools" from "format the result" keeps the fan-out real and the output grounded.

## Offline synthetic quickstart

Generate and inspect three fictional contracts without downloading a corpus or
calling a model:

```bash
cd examples/contract-review-agent
uv sync --frozen
uv run make-sample
uv run review --list
```

This creates an Acme MSA, an NDA, an SOW, a signature image, and a local SQLite
obligations database. Configure SIE and run `uv run review --contract acme-msa`
when you are ready to execute the model-backed review.

## Run it

You need Python 3.12 and a **GPU-backed SIE deployment**. The generative models run on SIE's generation bundle (CUDA), so the `latest-cpu-default` image can't serve them.
Expand All @@ -59,7 +75,7 @@ docker run --gpus all -p 8080:8080 -v sie-hf-cache:/app/.cache/huggingface \

cd examples/contract-review-agent
cp .env.example .env # edit SIE_CLUSTER_URL / SIE_API_KEY if not localhost
uv sync
uv sync --frozen

# 2. Fetch a handful of real contracts from CUAD (CC BY 4.0). Downloads a ~18 MB archive once.
uv run fetch-contracts # or: uv run make-sample (offline synthetic contracts)
Expand Down
997 changes: 997 additions & 0 deletions examples/contract-review-agent/uv.lock

Large diffs are not rendered by default.

47 changes: 24 additions & 23 deletions examples/quickstart.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@
"source": [
"# SIE Quickstart\n",
"\n",
"Three functions - `encode`, `score`, `extract` - running on your laptop or a free Colab GPU.\n",
"Three functions - `encode`, `score`, `extract` - using the same SDK against local, self-deployed, or managed SIE.\n",
"\n",
"This notebook installs the SIE server, starts it in the background, and walks through the full API."
"By default this notebook starts SIE locally. To use an existing deployment instead, set `SIE_CLUSTER_URL` and, when required, `SIE_API_KEY` before running it."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. Install and start the server\n",
"## 1. Install and connect\n",
"\n",
"Works on your laptop (Mac or Linux, CPU is fine) or a free Colab GPU. The `[local]` extra pins the transformers version the embedding and reranking models need.\n",
"Works on your laptop (Mac or Linux, CPU is fine), a free Colab GPU, a self-deployed SIE gateway, or managed SIE. The `[local]` extra is only used when this notebook starts the server itself.\n",
"\n",
"On Colab, expect a few minutes: SIE pins torch 2.9, so pip replaces Colab's preinstalled PyTorch. First output lands about two minutes after that; the optional showcase model adds a few more minutes of downloads.\n",
"\n",
Expand All @@ -39,30 +39,31 @@
"metadata": {},
"outputs": [],
"source": [
"import subprocess, time, urllib.request, logging\n",
"import logging, os, subprocess, time, urllib.request\n",
"\n",
"# Show the SDK's wait/retry messages while a model downloads server-side\n",
"logging.basicConfig(level=logging.INFO, format=\"%(message)s\")\n",
"logging.getLogger(\"sie_sdk\").setLevel(logging.INFO)\n",
"\n",
"# Start the server in the background (defaults: host 0.0.0.0, port 8080).\n",
"# Download progress goes to the log - check it any time with: !tail -n 5 /tmp/sie-server.log\n",
"proc = subprocess.Popen(\n",
" [\"sie-server\", \"serve\", \"--port\", \"8080\"],\n",
" stdout=open(\"/tmp/sie-server.log\", \"w\"),\n",
" stderr=subprocess.STDOUT,\n",
")\n",
"\n",
"# Wait for the server to be ready (/healthz answers before any model loads)\n",
"for i in range(120):\n",
" try:\n",
" urllib.request.urlopen(\"http://localhost:8080/healthz\")\n",
" print(f\"Server ready (took ~{i}s)\")\n",
" break\n",
" except Exception:\n",
" time.sleep(1)\n",
"cluster_url = os.getenv(\"SIE_CLUSTER_URL\", \"http://localhost:8080\")\n",
"api_key = os.getenv(\"SIE_API_KEY\")\n",
"\n",
"if cluster_url == \"http://localhost:8080\":\n",
" # Download progress goes to /tmp/sie-server.log.\n",
" proc = subprocess.Popen(\n",
" [\"sie-server\", \"serve\", \"--port\", \"8080\"],\n",
" stdout=open(\"/tmp/sie-server.log\", \"w\"),\n",
" stderr=subprocess.STDOUT,\n",
" )\n",
" for i in range(120):\n",
" try:\n",
" urllib.request.urlopen(f\"{cluster_url}/healthz\")\n",
" print(f\"Local SIE ready (took ~{i}s)\")\n",
" break\n",
" except Exception:\n",
" time.sleep(1)\n",
"else:\n",
" print(\"Server did not start - check /tmp/sie-server.log\")"
" print(f\"Using SIE at {cluster_url}\")"
]
},
{
Expand All @@ -83,7 +84,7 @@
"from sie_sdk import SIEClient\n",
"from sie_sdk.types import Item\n",
"\n",
"client = SIEClient(\"http://localhost:8080\")\n",
"client = SIEClient(cluster_url, api_key=api_key)\n",
"\n",
"result = client.encode(\"sentence-transformers/all-MiniLM-L6-v2\", Item(text=\"Hello world\"))\n",
"print(f\"Shape: {result['dense'].shape}\") # (384,)\n",
Expand Down
53 changes: 53 additions & 0 deletions examples/quickstart/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# SIE Python quickstart

This example uses the SIE SDK to create one text embedding. The code is the
same whether SIE runs on your laptop, in your Kubernetes cluster, or as a
managed service.

## Run it

Install the SDK:

```bash
pip install sie-sdk
cd examples/quickstart
```

For a local SIE server on `http://localhost:8080`, no configuration is needed:

```bash
python quickstart.py
```

For self-deployed SIE, point the SDK at your gateway:

```bash
export SIE_CLUSTER_URL="https://sie.example.com"
python quickstart.py
```

For managed SIE, also provide your API key:

```bash
export SIE_CLUSTER_URL="<your SIE endpoint>"
export SIE_API_KEY="<your API key>"
python quickstart.py
```

`SIE_MODEL` optionally selects a different embedding model:

```bash
export SIE_MODEL="BAAI/bge-m3"
```

Keep API keys in environment variables or your normal secrets manager, never
in source files.

The [quickstart notebook](../quickstart.ipynb) continues with scoring and
extraction.

## Test

```bash
PYTHONPATH=. python -m unittest test_quickstart.py
```
22 changes: 22 additions & 0 deletions examples/quickstart/quickstart.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# ruff: noqa: INP001

import os

from sie_sdk import SIEClient


def main() -> None:
with SIEClient(
os.getenv("SIE_CLUSTER_URL", "http://localhost:8080"),
api_key=os.getenv("SIE_API_KEY"),
) as client:
result = client.encode(
os.getenv("SIE_MODEL", "BAAI/bge-m3"),
{"text": "Embeddings make meaning searchable."},
)

print(f"Created a {len(result['dense'])}-dimensional embedding.")


if __name__ == "__main__":
main()
42 changes: 42 additions & 0 deletions examples/quickstart/test_quickstart.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# ruff: noqa: INP001

import os
import unittest
from unittest.mock import MagicMock, patch

import quickstart


class QuickStartTest(unittest.TestCase):
@patch.dict(
os.environ,
{
"SIE_CLUSTER_URL": "https://sie.example.com",
"SIE_API_KEY": "test-key",
"SIE_MODEL": "example/model",
},
clear=True,
)
@patch("quickstart.SIEClient")
def test_uses_configured_sie_deployment(self, client_type: MagicMock) -> None:
client = client_type.return_value.__enter__.return_value
client.encode.return_value = {"dense": [0.1, 0.2, 0.3]}

with patch("builtins.print") as print_output:
quickstart.main()

client_type.assert_called_once_with(
"https://sie.example.com",
api_key="test-key",
)
client.encode.assert_called_once_with(
"example/model",
{"text": "Embeddings make meaning searchable."},
)
print_output.assert_called_once_with(
"Created a 3-dimensional embedding.",
)


if __name__ == "__main__":
unittest.main()
9 changes: 9 additions & 0 deletions examples/retrieval-ablation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,22 @@ uv sync
# Validate config (no GPU needed)
uv run python benchmark_ablation.py --dry-run

# Run the same pipeline on the checked-in sample (12 documents, 6 queries)
uv run python benchmark_ablation.py --sample --gpu l4-spot

# Run the production pipeline end-to-end (all 7 models, all 1,854 queries)
uv run python benchmark_ablation.py --gpu l4-spot

# Or run just the winning combination (skip baselines and alternatives)
uv run python benchmark_ablation.py --gpu l4-spot --skip-conditions 1,2,3
```

`--sample` uses fictional, redistributable passages and the canonical
NDCG@10, MRR@10, and Recall@10 evaluator. It still requires SIE and
Turbopuffer because it runs the same retrieval conditions as the full
benchmark. Its index, cache, and result file are isolated from full
benchmark runs.

All expensive operations (encoding, search) cache to `cache/ablation/`. Re-runs skip completed steps. Cross-encoder reranking checkpoints every 100 queries for crash recovery.

## Evidence
Expand Down
Loading