|
| 1 | +# Architecture & Design |
| 2 | + |
| 3 | +This document describes the architectural logic and data flow of **CAS Evals**. |
| 4 | + |
| 5 | +## Core Logic |
| 6 | + |
| 7 | +CAS Evals is built around a deterministic evaluation pipeline that evaluates LLM-generated responses against expected baselines. It supports two distinct execution paths: |
| 8 | + |
| 9 | +1. **Offline Mode (Default):** Evaluates pre-recorded fixture data directly. It is completely offline, ensuring maximum reproducibility. |
| 10 | +2. **Live Reference Product Mode:** Opt-in mode using the `--reference-product-url` flag. It posts a `PromptEnvelope` to a live, local HTTP endpoint (`cas-reference-product`), extracts the dynamic output, and runs it through the same deterministic evaluation pipeline. |
| 11 | + |
| 12 | +### Evaluation Criteria |
| 13 | + |
| 14 | +For each case, CAS Evals enforces strict gating rules: |
| 15 | +- **Quality:** Fraction of expected keyword concepts present in the response versus a configured minimum threshold. |
| 16 | +- **Safety:** Absence of prohibited unsafe content (requires a 100% pass rate). |
| 17 | +- **Cost:** Cost in USD validated against a configured maximum threshold. |
| 18 | +- **Latency:** Duration in milliseconds validated against a configured maximum threshold. |
| 19 | + |
| 20 | +Any threshold violation fails the case, resulting in a failed suite. |
| 21 | + |
| 22 | +### Schema Contracts and Evidence |
| 23 | + |
| 24 | +Every per-case result generates an `EvaluationResult` conforming to the pinned `cas-contracts` version. The evidence payload includes: |
| 25 | +- SHA-256 fixture digests to guarantee immutability. |
| 26 | +- Strict lifecycle metadata (e.g., `correlationId`, `traceContext`) that must be preserved by live reference products. |
| 27 | +- Granular metric results (`value`, `threshold`, `passed`, `details`). |
| 28 | + |
| 29 | +## System Architecture Diagram |
| 30 | + |
| 31 | +The following Mermaid diagram visualizes the evaluation pipeline across both offline and live modes. |
| 32 | + |
| 33 | +```mermaid |
| 34 | +flowchart TD |
| 35 | + %% CLI and Input |
| 36 | + CLI[cas_evals.cli] |
| 37 | + FixtureJSON[("Fixture JSON\n(e.g., golden.json)")] |
| 38 | +
|
| 39 | + CLI -->|Parses| FixtureJSON |
| 40 | + FixtureJSON -->|Yields Suite & Cases| Router{Live Mode\nEnabled?} |
| 41 | +
|
| 42 | + %% Branch: Offline vs Live |
| 43 | + Router -- "No (--output)" --> OfflineEv[Offline Evaluator\nevaluator.py] |
| 44 | + Router -- "Yes (--reference-product-url)" --> LiveRef[Reference Product Adapter\nreference_product.py] |
| 45 | +
|
| 46 | + %% Live Reference Product Flow |
| 47 | + subgraph Live Reference Product Adapter |
| 48 | + LiveRef --> BuildEnv[Build PromptEnvelope] |
| 49 | + BuildEnv --> HTTPPost[HTTP POST\n/api/v1/workflows] |
| 50 | + HTTPPost --> HTTPResp[Extract Response & Events] |
| 51 | + HTTPResp --> ValidateMeta{Validate Lifecycle\nEvents/Metadata} |
| 52 | + ValidateMeta -- Invalid --> RefError((ReferenceProductError)) |
| 53 | + ValidateMeta -- Valid --> LiveCase[Inject live 'output'\nas 'response'] |
| 54 | + end |
| 55 | + |
| 56 | + LiveCase --> SharedEval |
| 57 | +
|
| 58 | + %% Offline Flow |
| 59 | + OfflineEv --> SharedEval[Shared Core Evaluator\n_evaluate_case_with_evidence] |
| 60 | +
|
| 61 | + %% Core Evaluation Logic |
| 62 | + subgraph Evaluation Pipeline |
| 63 | + SharedEval --> MetricQ[Calculate Quality\n(expected keywords)] |
| 64 | + SharedEval --> MetricS[Calculate Safety\n(prohibited words)] |
| 65 | + SharedEval --> MetricC[Extract Cost\n(observed USD vs limits)] |
| 66 | + SharedEval --> MetricL[Extract Latency\n(observed ms vs limits)] |
| 67 | + |
| 68 | + MetricQ --> Agg[Aggregate Evidence] |
| 69 | + MetricS --> Agg |
| 70 | + MetricC --> Agg |
| 71 | + MetricL --> Agg |
| 72 | + |
| 73 | + Agg --> ValidateContract[Validate EvaluationResult Schema] |
| 74 | + end |
| 75 | +
|
| 76 | + %% Output |
| 77 | + ValidateContract --> PassFail{Passed\nAll Metrics?} |
| 78 | + PassFail -- Yes --> Success((Suite Pass)) |
| 79 | + PassFail -- No --> Fail((Suite Fail)) |
| 80 | +
|
| 81 | + %% Contract references |
| 82 | + casContracts[("cas-contracts\nvendor/cas-contracts/")] -.-> ValidateContract |
| 83 | +
|
| 84 | + classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px; |
| 85 | + classDef error fill:#ffe6e6,stroke:#cc0000; |
| 86 | + classDef success fill:#e6ffe6,stroke:#006600; |
| 87 | + class RefError,Fail error; |
| 88 | + class Success success; |
| 89 | +``` |
| 90 | + |
| 91 | +## Module Responsibilities |
| 92 | + |
| 93 | +- **`cli.py`:** Parses arguments, loads the fixture suite, handles top-level error formatting, and writes JSON results to `stdout` and/or the `--output` file. |
| 94 | +- **`evaluator.py`:** Contains the pure evaluation kernel (`_evaluate_case_with_evidence`), responsible for scoring quality, safety, and validating cost/latency against thresholds. Forms the standard `EvaluationResult`. |
| 95 | +- **`reference_product.py`:** Contains the HTTP transport and metadata validation logic for live endpoint evaluations. It wraps the core evaluator by providing it with dynamic responses instead of fixture responses. |
| 96 | +- **`contracts.py`:** Integrates the pinned `cas-contracts` JSON schemas from `vendor/cas-contracts/` to ensure offline validation of all evidence. |
0 commit comments