alignmenter 0.2.0__tar.gz → 0.3.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.
- alignmenter-0.3.0/MANIFEST.in +8 -0
- alignmenter-0.3.0/PKG-INFO +553 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/README.md +80 -92
- alignmenter-0.3.0/configs/run-grounded.yaml +36 -0
- alignmenter-0.3.0/datasets/README.md +615 -0
- alignmenter-0.3.0/datasets/grounded_demo.jsonl +6 -0
- alignmenter-0.3.0/datasets/wendys_twitter.jsonl +235 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/pyproject.toml +13 -7
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/__init__.py +2 -2
- alignmenter-0.3.0/src/alignmenter/_version.py +3 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/cli.py +300 -7
- alignmenter-0.3.0/src/alignmenter/data/configs/demo_config.yaml +15 -0
- alignmenter-0.3.0/src/alignmenter/data/configs/judges/safety_prompt.txt +2 -0
- alignmenter-0.3.0/src/alignmenter/data/configs/persona/default.yaml +64 -0
- alignmenter-0.3.0/src/alignmenter/data/configs/run-grounded.yaml +36 -0
- alignmenter-0.3.0/src/alignmenter/data/configs/run.yaml +12 -0
- alignmenter-0.3.0/src/alignmenter/data/configs/safety_keywords.yaml +7 -0
- alignmenter-0.3.0/src/alignmenter/data/datasets/demo_conversations.jsonl +60 -0
- alignmenter-0.3.0/src/alignmenter/data/datasets/grounded_demo.jsonl +6 -0
- alignmenter-0.3.0/src/alignmenter/evaluators/__init__.py +1 -0
- alignmenter-0.3.0/src/alignmenter/evaluators/custom.py +68 -0
- alignmenter-0.3.0/src/alignmenter/evaluators/evidence.py +37 -0
- alignmenter-0.3.0/src/alignmenter/evaluators/faithfulness.py +35 -0
- alignmenter-0.3.0/src/alignmenter/evaluators/grounding.py +119 -0
- alignmenter-0.3.0/src/alignmenter/evaluators/metrics.py +76 -0
- alignmenter-0.3.0/src/alignmenter/examples/__init__.py +1 -0
- alignmenter-0.3.0/src/alignmenter/examples/resource_task.py +58 -0
- alignmenter-0.3.0/src/alignmenter/execution/__init__.py +1 -0
- alignmenter-0.3.0/src/alignmenter/execution/archive.py +111 -0
- alignmenter-0.3.0/src/alignmenter/execution/artifacts.py +26 -0
- alignmenter-0.3.0/src/alignmenter/execution/comparison.py +140 -0
- alignmenter-0.3.0/src/alignmenter/execution/evaluation.py +358 -0
- alignmenter-0.3.0/src/alignmenter/execution/gates.py +71 -0
- alignmenter-0.3.0/src/alignmenter/execution/leases.py +45 -0
- alignmenter-0.3.0/src/alignmenter/execution/legacy.py +151 -0
- alignmenter-0.3.0/src/alignmenter/execution/recovery.py +223 -0
- alignmenter-0.3.0/src/alignmenter/execution/review.py +139 -0
- alignmenter-0.3.0/src/alignmenter/execution/suite.py +118 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/judges/prompts.py +77 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/providers/base.py +6 -2
- alignmenter-0.3.0/src/alignmenter/providers/callable.py +51 -0
- alignmenter-0.3.0/src/alignmenter/providers/durable_judge.py +73 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/providers/judges.py +42 -0
- alignmenter-0.3.0/src/alignmenter/release_cli.py +169 -0
- alignmenter-0.3.0/src/alignmenter/reporting/durable.py +171 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/reporting/html.py +62 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/run_config.py +40 -1
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/runner.py +184 -62
- alignmenter-0.3.0/src/alignmenter/schemas/__init__.py +1 -0
- alignmenter-0.3.0/src/alignmenter/schemas/evaluation.py +239 -0
- alignmenter-0.3.0/src/alignmenter/schemas/execution.py +214 -0
- alignmenter-0.3.0/src/alignmenter/schemas/gates.py +38 -0
- alignmenter-0.3.0/src/alignmenter/schemas/metrics.py +65 -0
- alignmenter-0.3.0/src/alignmenter/schemas/review.py +47 -0
- alignmenter-0.3.0/src/alignmenter/schemas/scoring.py +130 -0
- alignmenter-0.3.0/src/alignmenter/schemas/suite.py +41 -0
- alignmenter-0.3.0/src/alignmenter/scorers/__init__.py +48 -0
- alignmenter-0.3.0/src/alignmenter/scorers/faithfulness.py +278 -0
- alignmenter-0.3.0/src/alignmenter/scorers/grounding.py +267 -0
- alignmenter-0.3.0/src/alignmenter/sdk.py +53 -0
- alignmenter-0.3.0/src/alignmenter/storage/__init__.py +5 -0
- alignmenter-0.3.0/src/alignmenter/storage/evaluations.py +312 -0
- alignmenter-0.3.0/src/alignmenter/storage/reviews.py +53 -0
- alignmenter-0.3.0/src/alignmenter/storage/runs.py +473 -0
- alignmenter-0.3.0/src/alignmenter.egg-info/PKG-INFO +553 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter.egg-info/SOURCES.txt +72 -1
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter.egg-info/requires.txt +13 -2
- alignmenter-0.3.0/tests/__init__.py +1 -0
- alignmenter-0.3.0/tests/conftest.py +11 -0
- alignmenter-0.3.0/tests/data/durable_evaluation_judge.py +51 -0
- alignmenter-0.3.0/tests/data/durable_evaluation_worker.py +32 -0
- alignmenter-0.3.0/tests/data/durable_recovery_target.py +51 -0
- alignmenter-0.3.0/tests/data/durable_recovery_worker.py +28 -0
- alignmenter-0.3.0/tests/data/durable_run_worker.py +66 -0
- alignmenter-0.3.0/tests/data/mini_cli_dataset.jsonl +4 -0
- alignmenter-0.3.0/tests/test_builtin_evaluations.py +324 -0
- alignmenter-0.3.0/tests/test_capture_recovery.py +380 -0
- alignmenter-0.3.0/tests/test_cli_grounded.py +91 -0
- alignmenter-0.3.0/tests/test_durable_evaluations.py +473 -0
- alignmenter-0.3.0/tests/test_durable_execution.py +443 -0
- alignmenter-0.3.0/tests/test_faithfulness.py +199 -0
- alignmenter-0.3.0/tests/test_grounding.py +112 -0
- alignmenter-0.3.0/tests/test_release_workflow.py +206 -0
- alignmenter-0.3.0/tests/test_review_workflow.py +152 -0
- alignmenter-0.3.0/tests/test_run_config_grounded.py +67 -0
- alignmenter-0.3.0/tests/test_suite_archive.py +181 -0
- alignmenter-0.2.0/PKG-INFO +0 -757
- alignmenter-0.2.0/src/alignmenter/scorers/__init__.py +0 -7
- alignmenter-0.2.0/src/alignmenter.egg-info/PKG-INFO +0 -757
- {alignmenter-0.2.0 → alignmenter-0.3.0}/LICENSE +0 -0
- {alignmenter-0.2.0/src/alignmenter/data → alignmenter-0.3.0}/configs/demo_config.yaml +0 -0
- {alignmenter-0.2.0/src/alignmenter/data → alignmenter-0.3.0}/configs/judges/safety_prompt.txt +0 -0
- {alignmenter-0.2.0/src/alignmenter/data → alignmenter-0.3.0}/configs/persona/default.yaml +0 -0
- {alignmenter-0.2.0/src/alignmenter/data → alignmenter-0.3.0}/configs/run.yaml +0 -0
- {alignmenter-0.2.0/src/alignmenter/data → alignmenter-0.3.0}/configs/safety_keywords.yaml +0 -0
- {alignmenter-0.2.0/src/alignmenter/data → alignmenter-0.3.0}/datasets/demo_conversations.jsonl +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/setup.cfg +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/calibration/__init__.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/calibration/analyze.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/calibration/bounds.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/calibration/diagnose.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/calibration/generate.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/calibration/label.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/calibration/optimize.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/calibration/sampling.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/calibration/validate.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/config.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/judges/__init__.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/judges/authenticity_judge.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/providers/__init__.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/providers/anthropic.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/providers/classifiers.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/providers/embeddings.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/providers/local.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/providers/openai.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/reporting/__init__.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/reporting/json_out.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/scorers/authenticity.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/scorers/safety.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/scorers/stability.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/scripts/__init__.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/scripts/bootstrap_dataset.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/scripts/calibrate_persona.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/scripts/run_openai_demo.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/scripts/sanitize_dataset.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/utils/__init__.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/utils/io.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/utils/optional.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/utils/tokens.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter/utils/yaml.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter.egg-info/dependency_links.txt +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter.egg-info/entry_points.txt +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/src/alignmenter.egg-info/top_level.txt +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_authenticity_judge.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_calibrate_persona.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_cli_errors.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_cli_helpers.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_cli_import.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_cli_init.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_cli_run_config.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_config.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_html_report.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_judge_providers.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_offline_safety.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_persona_gpt.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_provider_local.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_provider_openai.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_providers.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_run_config_loader.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_run_openai_demo.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_runner.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_sampling.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_scorers.py +0 -0
- {alignmenter-0.2.0 → alignmenter-0.3.0}/tests/test_smoke.py +0 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
include LICENSE README.md
|
|
2
|
+
recursive-include tests *.py *.json *.jsonl *.yaml *.yml *.txt *.csv
|
|
3
|
+
recursive-include configs *.yaml *.yml *.json *.txt
|
|
4
|
+
recursive-include datasets *.jsonl *.md
|
|
5
|
+
recursive-include src/alignmenter/data *.yaml *.yml *.jsonl *.txt
|
|
6
|
+
prune build
|
|
7
|
+
prune dist
|
|
8
|
+
prune reports
|
|
@@ -0,0 +1,553 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: alignmenter
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Durable application alignment evaluations, evidence review, saved comparisons, and CI gates.
|
|
5
|
+
Author: Alignmenter
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://alignmenter.com
|
|
8
|
+
Project-URL: Repository, https://github.com/justinGrosvenor/alignmenter
|
|
9
|
+
Project-URL: Documentation, https://github.com/justinGrosvenor/alignmenter
|
|
10
|
+
Project-URL: Bug Tracker, https://github.com/justinGrosvenor/alignmenter/issues
|
|
11
|
+
Keywords: llm,evaluation,alignment,persona,safety,llm-judge
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: Information Technology
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
16
|
+
Classifier: Programming Language :: Python
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: typer<1,>=0.12
|
|
27
|
+
Requires-Dist: pydantic<3,>=2.5
|
|
28
|
+
Requires-Dist: pydantic-settings<3,>=2
|
|
29
|
+
Requires-Dist: openai<3,>=1.40
|
|
30
|
+
Requires-Dist: anthropic<1,>=0.40
|
|
31
|
+
Requires-Dist: pyyaml<7,>=6
|
|
32
|
+
Requires-Dist: tiktoken<1,>=0.7
|
|
33
|
+
Requires-Dist: requests<3,>=2.32
|
|
34
|
+
Provides-Extra: ml
|
|
35
|
+
Requires-Dist: torch<3,>=2; extra == "ml"
|
|
36
|
+
Requires-Dist: sentence-transformers<6,>=3; extra == "ml"
|
|
37
|
+
Requires-Dist: transformers<6,>=4.40; extra == "ml"
|
|
38
|
+
Provides-Extra: calibrate
|
|
39
|
+
Requires-Dist: scikit-learn<2,>=1.3; extra == "calibrate"
|
|
40
|
+
Requires-Dist: numpy<3,>=1.24; extra == "calibrate"
|
|
41
|
+
Provides-Extra: safety
|
|
42
|
+
Requires-Dist: alignmenter[ml]; extra == "safety"
|
|
43
|
+
Provides-Extra: all
|
|
44
|
+
Requires-Dist: alignmenter[calibrate,ml]; extra == "all"
|
|
45
|
+
Provides-Extra: dev
|
|
46
|
+
Requires-Dist: alignmenter[calibrate,ml]; extra == "dev"
|
|
47
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
48
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
49
|
+
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
50
|
+
Requires-Dist: build; extra == "dev"
|
|
51
|
+
Requires-Dist: twine; extra == "dev"
|
|
52
|
+
Provides-Extra: test
|
|
53
|
+
Requires-Dist: pytest>=8; extra == "test"
|
|
54
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
55
|
+
Requires-Dist: ruff>=0.6; extra == "test"
|
|
56
|
+
Requires-Dist: build; extra == "test"
|
|
57
|
+
Requires-Dist: twine; extra == "test"
|
|
58
|
+
Provides-Extra: docs
|
|
59
|
+
Requires-Dist: mkdocs<2,>=1.6; extra == "docs"
|
|
60
|
+
Requires-Dist: mkdocs-material<10,>=9; extra == "docs"
|
|
61
|
+
Dynamic: license-file
|
|
62
|
+
|
|
63
|
+
# Alignmenter
|
|
64
|
+
|
|
65
|
+
Application alignment evaluations with saved evidence, repeatable release checks,
|
|
66
|
+
and a lightweight Python SDK and CLI.
|
|
67
|
+
|
|
68
|
+
## Overview
|
|
69
|
+
|
|
70
|
+
Alignmenter 0.3 checks whether an assistant meets the commitments of its application:
|
|
71
|
+
uses the resources the user has, respects constraints, supports claims with supplied
|
|
72
|
+
evidence, and avoids dangerous advice. Capture answers once, evaluate them under
|
|
73
|
+
versioned criteria, compare a candidate with a baseline, and preserve human review.
|
|
74
|
+
|
|
75
|
+
- **Durable execution:** SQLite observations, frozen inputs, explicit recovery, and
|
|
76
|
+
shared judge reservations preserve partial work across interruptions.
|
|
77
|
+
- **Application-owned checks:** deterministic evaluator factories and typed metrics
|
|
78
|
+
work with the same grouping, reports, comparisons, and gates as builtins.
|
|
79
|
+
- **Evidence evaluation:** offline quantity traceability/citation checks and strict
|
|
80
|
+
judged faithfulness retain the claims and source quotes behind each outcome.
|
|
81
|
+
- **Release decisions:** matched case comparisons, explicit coverage, absolute and
|
|
82
|
+
regression gates, and consistent CLI/HTML/JSON/Markdown/JUnit results.
|
|
83
|
+
- **Human review:** append-only JSONL annotation exchange, adjudication, evaluator
|
|
84
|
+
agreement reports, and regression promotion with case lineage and split groups.
|
|
85
|
+
- **Local inspection:** offline HTML and portable read-only run archives; the core
|
|
86
|
+
install does not require torch or scikit-learn.
|
|
87
|
+
|
|
88
|
+
Missing work cannot produce a green release check. A draft specification cannot pass.
|
|
89
|
+
The legacy persona, authenticity, safety, stability, and calibration tools remain
|
|
90
|
+
available; new release integrations should use the durable workflow.
|
|
91
|
+
|
|
92
|
+
## Quickstart
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
pip install alignmenter
|
|
96
|
+
alignmenter --version
|
|
97
|
+
alignmenter init-suite --out evals/resource-task
|
|
98
|
+
alignmenter run-suite evals/resource-task/suite.yaml --out reports
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The installed example uses a local target and a deterministic resource constraint.
|
|
102
|
+
It needs no API key. The command prints the run directory, evaluation UUID, decision,
|
|
103
|
+
and artifact directory. Open its `index.html` to inspect evidence. Exit codes are
|
|
104
|
+
**0 pass, 2 fail, 3 inconclusive**. Exercise a deliberate failure with:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
ALIGNMENTER_DEMO_VARIANT=bad alignmenter run-suite evals/resource-task/suite.yaml --out reports
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
To work from this checkout, including a release candidate before publication:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
python -m venv .venv
|
|
114
|
+
source .venv/bin/activate
|
|
115
|
+
pip install -e 'alignmenter[test,docs]'
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Python 3.10–3.14 are supported for the core package. Durable execution uses a local
|
|
119
|
+
POSIX coordinator; Windows and multi-host/network-filesystem execution are not
|
|
120
|
+
supported in 0.3. Optional `[ml]` and `[calibrate]` extras retain their upstream
|
|
121
|
+
platform requirements.
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
from alignmenter.sdk import run_suite, evaluation_summary
|
|
125
|
+
|
|
126
|
+
result = run_suite("evals/resource-task/suite.yaml", out_dir="reports")
|
|
127
|
+
summary = evaluation_summary(result["run_dir"], details=True)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
See the [release workflow](https://docs.alignmenter.com/guides/release-workflow/),
|
|
131
|
+
[SDK reference](https://docs.alignmenter.com/reference/sdk/), and
|
|
132
|
+
[0.3 migration guide](https://docs.alignmenter.com/guides/migration-0.3/).
|
|
133
|
+
In the repository, these sources are under `docs/guides/` and `docs/reference/`.
|
|
134
|
+
|
|
135
|
+
The example is an engineering fixture, not evidence of model quality. Atlas integration
|
|
136
|
+
fixtures preserve real failures, with product rubrics still marked draft. Actual judge
|
|
137
|
+
qualification needs independent human references and saved model outputs. AverCare
|
|
138
|
+
qualification awaits a selected application workflow. Hosted review, physical-device
|
|
139
|
+
replay, distributed budgets, and automatic optimization remain roadmap work.
|
|
140
|
+
|
|
141
|
+
## Legacy persona documentation
|
|
142
|
+
|
|
143
|
+
The sections below describe the retained persona/scorer APIs. Their older scores,
|
|
144
|
+
reports, and scorer-local budgets do not use the new durable contracts. See the
|
|
145
|
+
linked migration guide when integrating them into release checks.
|
|
146
|
+
|
|
147
|
+
## Legacy persona features
|
|
148
|
+
|
|
149
|
+
### 🎯 Three-Dimensional Scoring
|
|
150
|
+
|
|
151
|
+
#### Authenticity
|
|
152
|
+
- **Embedding similarity**: Measures semantic alignment with persona examples
|
|
153
|
+
- **Trait model**: Logistic regression on linguistic features (trained via calibration)
|
|
154
|
+
- **Lexicon matching**: Enforces preferred/avoided vocabulary
|
|
155
|
+
- **Bootstrap CI**: Statistical confidence intervals for reliability
|
|
156
|
+
|
|
157
|
+
#### Safety
|
|
158
|
+
- **Keyword classifier**: Fast pattern matching for common violations
|
|
159
|
+
- **LLM judge**: GPT-4 as a safety oracle with budget controls
|
|
160
|
+
- **Offline classifier**: ProtectAI's distilled-safety-roberta (no API calls)
|
|
161
|
+
- **Fused scoring**: Weighted ensemble of rule-based + model-based signals
|
|
162
|
+
- **Adversarial testing**: Built-in safety traps in demo datasets
|
|
163
|
+
|
|
164
|
+
#### Stability
|
|
165
|
+
- **Cosine variance**: Detects semantic drift across conversation turns
|
|
166
|
+
- **Session clustering**: Identifies divergent response patterns
|
|
167
|
+
- **Temporal analysis**: Tracks consistency over time
|
|
168
|
+
|
|
169
|
+
### 📊 Rich Reporting
|
|
170
|
+
|
|
171
|
+
- **Interactive HTML**: Grade-based report cards with charts (Chart.js)
|
|
172
|
+
- **JSON export**: Machine-readable results for CI/CD pipelines
|
|
173
|
+
- **CSV downloads**: Per-metric exports for spreadsheet analysis
|
|
174
|
+
- **Turn-level explorer**: Drill down into individual responses
|
|
175
|
+
|
|
176
|
+
### 🔧 Production-Ready
|
|
177
|
+
|
|
178
|
+
- **Multi-provider support**: OpenAI, Anthropic, local (vLLM, Ollama)
|
|
179
|
+
- **Budget guardrails**: Halt runs at 90% of judge API budget
|
|
180
|
+
- **Cost projection**: Estimate expenses before execution
|
|
181
|
+
- **Reproducibility**: Logs Python version, model, seed, timestamps
|
|
182
|
+
- **PII sanitization**: Built-in scrubbing for production data
|
|
183
|
+
|
|
184
|
+
### 🚀 Developer Experience
|
|
185
|
+
|
|
186
|
+
- **CLI-first**: Simple commands for evaluation, calibration, reporting
|
|
187
|
+
- **YAML configuration**: Declarative persona packs and run configs
|
|
188
|
+
- **Python API**: Programmatic access for custom workflows
|
|
189
|
+
- **Comprehensive tests**: 69+ unit tests with pytest
|
|
190
|
+
- **Type safety**: Full type hints throughout
|
|
191
|
+
|
|
192
|
+
## Architecture
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
196
|
+
│ Alignmenter CLI │
|
|
197
|
+
│ alignmenter run / report / calibrate / bootstrap / sanitize │
|
|
198
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
199
|
+
│
|
|
200
|
+
▼
|
|
201
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
202
|
+
│ Runner │
|
|
203
|
+
│ Orchestrates evaluation: load data → score → report │
|
|
204
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
205
|
+
│
|
|
206
|
+
┌───────────────────┼───────────────────┐
|
|
207
|
+
▼ ▼ ▼
|
|
208
|
+
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
209
|
+
│ Authenticity │ │ Safety │ │ Stability │
|
|
210
|
+
│ Scorer │ │ Scorer │ │ Scorer │
|
|
211
|
+
└──────────────┘ └──────────────┘ └──────────────┘
|
|
212
|
+
│ │ │
|
|
213
|
+
│ │ │
|
|
214
|
+
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
215
|
+
│ Embeddings │ │ LLM Judge │ │ Cosine │
|
|
216
|
+
│ Trait Model │ │ Keywords │ │ Variance │
|
|
217
|
+
│ Lexicon │ │ Fusion │ │ Clustering │
|
|
218
|
+
└──────────────┘ └──────────────┘ └──────────────┘
|
|
219
|
+
│
|
|
220
|
+
▼
|
|
221
|
+
┌───────────────────────────────────────┐
|
|
222
|
+
│ Reporting Layer │
|
|
223
|
+
│ HTML / JSON / CSV / Interactive UI │
|
|
224
|
+
└───────────────────────────────────────┘
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Key Components
|
|
228
|
+
|
|
229
|
+
| Component | Purpose | Key Files |
|
|
230
|
+
|-----------|---------|-----------|
|
|
231
|
+
| **CLI** | Command-line interface | `src/alignmenter/cli.py` |
|
|
232
|
+
| **Runner** | Orchestration engine | `src/alignmenter/runner.py` |
|
|
233
|
+
| **Scorers** | Metric computation | `src/alignmenter/scorers/` |
|
|
234
|
+
| **Providers** | LLM/embedding backends | `src/alignmenter/providers/` |
|
|
235
|
+
| **Reporters** | Output generation | `src/alignmenter/reporting/` |
|
|
236
|
+
| **Datasets** | JSONL conversation data | `datasets/` |
|
|
237
|
+
| **Personas** | Brand voice definitions | `configs/persona/` |
|
|
238
|
+
|
|
239
|
+
## 📚 Documentation
|
|
240
|
+
|
|
241
|
+
**Full documentation available at [docs.alignmenter.com](https://docs.alignmenter.com)**
|
|
242
|
+
|
|
243
|
+
Quick links:
|
|
244
|
+
- **[Quick Start Guide](https://docs.alignmenter.com/getting-started/quickstart/)** - Get started in 5 minutes
|
|
245
|
+
- **[Installation](https://docs.alignmenter.com/getting-started/installation/)** - Install and setup
|
|
246
|
+
- **[CLI Reference](https://docs.alignmenter.com/reference/cli/)** - Complete command reference
|
|
247
|
+
- **[Persona Guide](https://docs.alignmenter.com/guides/persona/)** - Configure your brand voice
|
|
248
|
+
- **[Calibration Guide](https://docs.alignmenter.com/guides/calibration/)** - Advanced calibration workflow
|
|
249
|
+
- **[Safety Guide](https://docs.alignmenter.com/guides/safety/)** - Offline safety classifier
|
|
250
|
+
- **[LLM Judges](https://docs.alignmenter.com/guides/llm-judges/)** - Qualitative analysis
|
|
251
|
+
- **[Contributing](https://docs.alignmenter.com/contributing/)** - How to contribute
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## Case Studies
|
|
256
|
+
|
|
257
|
+
- **[Wendy's Twitter Voice](../docs/case-studies/wendys-twitter.md)** - End-to-end calibration example using the included case-study assets. *(Available when running from the source repo; not included in the PyPI wheel.)*
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Usage Examples
|
|
262
|
+
|
|
263
|
+
### Evaluate Multiple Models
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
# Compare GPT-4 vs Claude
|
|
267
|
+
alignmenter run \
|
|
268
|
+
--model openai:gpt-4 \
|
|
269
|
+
--compare anthropic:claude-3-5-sonnet-20241022 \
|
|
270
|
+
--dataset datasets/demo_conversations.jsonl \
|
|
271
|
+
--persona configs/persona/default.yaml
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Custom Judge and Embeddings
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
# Use Claude as safety judge, local embeddings
|
|
278
|
+
alignmenter run \
|
|
279
|
+
--model openai:gpt-4o-mini \
|
|
280
|
+
--judge anthropic:claude-3-5-sonnet-20241022 \
|
|
281
|
+
--embedding sentence-transformer:all-MiniLM-L6-v2 \
|
|
282
|
+
--dataset datasets/demo_conversations.jsonl \
|
|
283
|
+
--persona configs/persona/default.yaml
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Bootstrap Synthetic Dataset
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
# Generate 50 conversations with adversarial traps
|
|
290
|
+
alignmenter bootstrap-dataset \
|
|
291
|
+
--out datasets/my_test.jsonl \
|
|
292
|
+
--sessions 50 \
|
|
293
|
+
--safety-trap-ratio 0.15 \
|
|
294
|
+
--brand-trap-ratio 0.20 \
|
|
295
|
+
--seed 42
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Calibrate Persona Traits
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
# Train trait model from labeled data
|
|
302
|
+
alignmenter calibrate-persona \
|
|
303
|
+
--persona-path configs/persona/mybot.yaml \
|
|
304
|
+
--dataset annotations.jsonl \
|
|
305
|
+
--out configs/persona/mybot.traits.json \
|
|
306
|
+
--epochs 300
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Sanitize Production Data
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
# Remove PII before evaluation
|
|
313
|
+
alignmenter dataset sanitize prod_logs.jsonl \
|
|
314
|
+
--out datasets/sanitized.jsonl \
|
|
315
|
+
--no-use-hashing
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
## Persona Configuration
|
|
319
|
+
|
|
320
|
+
Define your brand voice in YAML:
|
|
321
|
+
|
|
322
|
+
```yaml
|
|
323
|
+
# configs/persona/mybot.yaml
|
|
324
|
+
id: mybot
|
|
325
|
+
name: "MyBot Assistant"
|
|
326
|
+
description: "Professional, evidence-driven, technical"
|
|
327
|
+
|
|
328
|
+
voice:
|
|
329
|
+
tone: ["professional", "precise", "measured"]
|
|
330
|
+
formality: "business_casual"
|
|
331
|
+
|
|
332
|
+
# Preferred vocabulary
|
|
333
|
+
lexicon:
|
|
334
|
+
preferred:
|
|
335
|
+
- "baseline"
|
|
336
|
+
- "signal"
|
|
337
|
+
- "alignment"
|
|
338
|
+
- "evidence-based"
|
|
339
|
+
avoided:
|
|
340
|
+
- "lol"
|
|
341
|
+
- "bro"
|
|
342
|
+
- "hype"
|
|
343
|
+
- "vibes"
|
|
344
|
+
|
|
345
|
+
# Example on-brand responses (for embedding similarity)
|
|
346
|
+
examples:
|
|
347
|
+
- "Our baseline analysis indicates a 15% improvement in alignment metrics."
|
|
348
|
+
- "The signal-to-noise ratio suggests this approach is viable."
|
|
349
|
+
- "Let's establish a clear baseline before proceeding."
|
|
350
|
+
|
|
351
|
+
# Trait model weights (generated by calibration)
|
|
352
|
+
traits:
|
|
353
|
+
weights: [0.12, -0.34, 0.08, ...] # Learned from annotations
|
|
354
|
+
vocabulary: ["baseline", "signal", ...]
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## Legacy API usage
|
|
358
|
+
|
|
359
|
+
`Runner` coordinates transcript preparation, scoring, and report generation.
|
|
360
|
+
It takes a `RunConfig` plus a list of scorers, and `execute()` returns the
|
|
361
|
+
path to the timestamped report directory (JSON + HTML are written for you).
|
|
362
|
+
|
|
363
|
+
Runs now persist source snapshots and each captured answer before scoring. If execution
|
|
364
|
+
fails, `runner.run_dir` identifies the saved work. Use `alignmenter status RUN_DIRECTORY`
|
|
365
|
+
and `alignmenter export-transcripts RUN_DIRECTORY --out recovered.jsonl` to inspect and
|
|
366
|
+
recover committed records. `runner.capture()` and `alignmenter capture` save answers
|
|
367
|
+
without scoring; `alignmenter resume` continues compatible capture with explicit adapter
|
|
368
|
+
recovery contracts. See the [durable run guide](../docs/guides/durable-runs.md) and
|
|
369
|
+
[capture/recovery guide](../docs/guides/capture-recovery.md) for the contracts and limits.
|
|
370
|
+
|
|
371
|
+
`alignmenter evaluate RUN_DIRECTORY --spec rubrics.yaml --judge-factory module:factory
|
|
372
|
+
--max-judge-calls 20` evaluates saved answers with versioned behavior criteria, a shared
|
|
373
|
+
durable judge budget, and reusable replies/verdicts. `alignmenter evaluation-status
|
|
374
|
+
RUN_DIRECTORY --details` exports the saved evidence and decisions without more judge
|
|
375
|
+
calls. This path also supports [grounding and faithfulness](../docs/guides/grounding-faithfulness.md)
|
|
376
|
+
with typed evidence, explicit missing-data states, and saved metrics. A grounding-only
|
|
377
|
+
spec needs no judge factory or budget. Existing `run` scorers retain their legacy behavior;
|
|
378
|
+
see [durable evaluations](../docs/guides/durable-evaluations.md) for the accounting boundary.
|
|
379
|
+
|
|
380
|
+
```python
|
|
381
|
+
import json
|
|
382
|
+
from pathlib import Path
|
|
383
|
+
|
|
384
|
+
from alignmenter.runner import RunConfig, Runner
|
|
385
|
+
from alignmenter.scorers.authenticity import AuthenticityScorer
|
|
386
|
+
from alignmenter.scorers.safety import SafetyScorer
|
|
387
|
+
from alignmenter.scorers.stability import StabilityScorer
|
|
388
|
+
|
|
389
|
+
config = RunConfig(
|
|
390
|
+
model="openai:gpt-4o-mini",
|
|
391
|
+
dataset_path=Path("datasets/demo_conversations.jsonl"),
|
|
392
|
+
persona_path=Path("configs/persona/default.yaml"),
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
# Pass a judge to AuthenticityScorer/SafetyScorer to blend LLM judgment in;
|
|
396
|
+
# omit it (as here) for a fully offline, deterministic run.
|
|
397
|
+
scorers = [
|
|
398
|
+
AuthenticityScorer(persona_path=config.persona_path, embedding="hashed"),
|
|
399
|
+
SafetyScorer(keyword_path=Path("configs/safety_keywords.yaml")),
|
|
400
|
+
StabilityScorer(embedding="hashed"),
|
|
401
|
+
]
|
|
402
|
+
|
|
403
|
+
# generate_transcripts=False reuses recorded transcripts (no provider calls).
|
|
404
|
+
runner = Runner(config, scorers, generate_transcripts=False)
|
|
405
|
+
run_dir = runner.execute() # -> Path to reports/<timestamp>_<run_id>/
|
|
406
|
+
|
|
407
|
+
results = json.loads((run_dir / "results.json").read_text())
|
|
408
|
+
primary = results["scores"]["primary"]
|
|
409
|
+
auth = primary["authenticity"]
|
|
410
|
+
print(f"Authenticity: {auth['mean']:.3f} (basis: {auth['basis']})")
|
|
411
|
+
print(f"Safety: {primary['safety']['score']:.3f}")
|
|
412
|
+
print(f"Stability: {primary['stability']['stability']:.3f}")
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
## Legacy CI integration
|
|
416
|
+
|
|
417
|
+
```yaml
|
|
418
|
+
# .github/workflows/eval.yml
|
|
419
|
+
name: Persona Evaluation
|
|
420
|
+
|
|
421
|
+
on: [push, pull_request]
|
|
422
|
+
|
|
423
|
+
jobs:
|
|
424
|
+
evaluate:
|
|
425
|
+
runs-on: ubuntu-latest
|
|
426
|
+
steps:
|
|
427
|
+
- uses: actions/checkout@v3
|
|
428
|
+
- uses: actions/setup-python@v4
|
|
429
|
+
with:
|
|
430
|
+
python-version: '3.11'
|
|
431
|
+
|
|
432
|
+
- name: Install Alignmenter
|
|
433
|
+
run: pip install alignmenter
|
|
434
|
+
|
|
435
|
+
- name: Run Evaluation
|
|
436
|
+
env:
|
|
437
|
+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
438
|
+
run: |
|
|
439
|
+
alignmenter run \
|
|
440
|
+
--model openai:gpt-4o-mini \
|
|
441
|
+
--dataset datasets/ci_test.jsonl \
|
|
442
|
+
--persona configs/persona/default.yaml \
|
|
443
|
+
--judge-budget 100
|
|
444
|
+
|
|
445
|
+
- name: Upload Report
|
|
446
|
+
uses: actions/upload-artifact@v3
|
|
447
|
+
with:
|
|
448
|
+
name: evaluation-report
|
|
449
|
+
path: reports/
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
## Development
|
|
453
|
+
|
|
454
|
+
### Running Tests
|
|
455
|
+
|
|
456
|
+
```bash
|
|
457
|
+
# All tests
|
|
458
|
+
pytest
|
|
459
|
+
|
|
460
|
+
# With coverage
|
|
461
|
+
pytest --cov=src/alignmenter --cov-report=html
|
|
462
|
+
|
|
463
|
+
# Specific test file
|
|
464
|
+
pytest tests/test_scorers.py -v
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### Code Quality
|
|
468
|
+
|
|
469
|
+
```bash
|
|
470
|
+
# Type checking
|
|
471
|
+
mypy src/
|
|
472
|
+
|
|
473
|
+
# Linting
|
|
474
|
+
ruff check src/
|
|
475
|
+
|
|
476
|
+
# Formatting
|
|
477
|
+
black src/ tests/
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### Local Development
|
|
481
|
+
|
|
482
|
+
```bash
|
|
483
|
+
# Install in editable mode with dev dependencies
|
|
484
|
+
pip install -e .[dev]
|
|
485
|
+
|
|
486
|
+
# Run from source
|
|
487
|
+
python -m alignmenter.cli run --help
|
|
488
|
+
|
|
489
|
+
# Generate report from last run
|
|
490
|
+
make report-last
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
## Earlier persona roadmap
|
|
494
|
+
|
|
495
|
+
### Completed ✅
|
|
496
|
+
- Three-dimensional scoring (authenticity, safety, stability)
|
|
497
|
+
- Multi-provider support (OpenAI, Anthropic, local models)
|
|
498
|
+
- HTML report cards with interactive charts
|
|
499
|
+
- Offline safety classifier (distilled-safety-roberta)
|
|
500
|
+
- LLM judges for qualitative analysis
|
|
501
|
+
- Budget guardrails and cost tracking
|
|
502
|
+
- PII sanitization tools
|
|
503
|
+
- Calibration workflow and diagnostics
|
|
504
|
+
|
|
505
|
+
### In Progress 🚧
|
|
506
|
+
- Multi-language support (non-English personas)
|
|
507
|
+
- Batch processing optimizations
|
|
508
|
+
- Additional embedding providers
|
|
509
|
+
|
|
510
|
+
### Future Considerations 💭
|
|
511
|
+
- Synthetic test case generation
|
|
512
|
+
- Custom metric plugins
|
|
513
|
+
- Advanced trait models (neural networks)
|
|
514
|
+
|
|
515
|
+
## Contributing
|
|
516
|
+
|
|
517
|
+
We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
518
|
+
|
|
519
|
+
**Areas we'd love help with:**
|
|
520
|
+
- Additional persona packs (different brand voices)
|
|
521
|
+
- Language support beyond English
|
|
522
|
+
- Integration with other LLM providers
|
|
523
|
+
- Performance optimizations for large datasets
|
|
524
|
+
|
|
525
|
+
## License
|
|
526
|
+
|
|
527
|
+
Apache License 2.0 - see [LICENSE](LICENSE) for details.
|
|
528
|
+
|
|
529
|
+
## Citation
|
|
530
|
+
|
|
531
|
+
If you use Alignmenter in research, please cite:
|
|
532
|
+
|
|
533
|
+
```bibtex
|
|
534
|
+
@software{alignmenter2024,
|
|
535
|
+
title={Alignmenter: A Framework for Persona-Aligned Conversational AI Evaluation},
|
|
536
|
+
author={Alignmenter Contributors},
|
|
537
|
+
year={2025},
|
|
538
|
+
url={https://github.com/justinGrosvenor/alignmenter},
|
|
539
|
+
license={Apache-2.0}
|
|
540
|
+
}
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
## Support
|
|
544
|
+
|
|
545
|
+
- **Documentation**: [docs.alignmenter.com](https://docs.alignmenter.com)
|
|
546
|
+
- **Issues**: [GitHub Issues](https://github.com/justinGrosvenor/alignmenter/issues)
|
|
547
|
+
- **Discussions**: [GitHub Discussions](https://github.com/justinGrosvenor/alignmenter/discussions)
|
|
548
|
+
|
|
549
|
+
---
|
|
550
|
+
|
|
551
|
+
<p align="center">
|
|
552
|
+
Made with ❤️ by the Alignmenter team
|
|
553
|
+
</p>
|