¶ciel.eval — Evaluación y testing reproducible (Fase 18)
Capa de evaluación offline-safe por defecto: las métricas propias son
deterministas y no requieren red ni extras. DeepEval/RAGAS/TruLens son
opt-in vía el extra eval; si no están instalados, Evaluator degrada a
métricas propias.
¶Componentes
| Símbolo | Tipo | Descripción |
|---|---|---|
EvalCase |
dataclass | Un caso: query, expected, context, gold, metadata. |
Evaluator |
clase | Corre un dataset sobre un agente/callable y acumula KPIs. |
Evaluator.run / arun |
método | Ejecuta (sync/async) y devuelve List[EvalResult]. |
Evaluator.kpis |
método | Agrega pass_rate y medias de cada métrica. |
Evaluator.export |
método | Exporta results.json (kpis + resultados). |
load_dataset |
función | Carga un dataset YAML de casos. |
exact_match, contains, f1_token |
métricas | Coincidencia cerrada. |
faithfulness, context_relevance |
métricas | RAG (tokens comunes respuesta↔contexto; usa Retriever si se pasa). |
answer_relevance |
métrica | Heurística de diagnóstico (no gating por defecto). |
¶Uso mínimo
import asyncio
from ciel.eval import Evaluator, load_dataset
from ciel.providers import MockProvider
from ciel.runtime import ChatRequest, ChatMessage
cases = load_dataset("tests/eval/smoke.yaml")
async def agent(query, **kw):
p = MockProvider(mode="fixed", response="París")
r = await p.complete(ChatRequest(messages=[ChatMessage(role="user", content=query)]))
return r.choice.message.content
ev = Evaluator(agent=agent)
ev.run(cases, threshold=0.8)
print(ev.kpis())
ev.export("results.json")
¶CLI
# Correr un dataset con MockProvider (offline)
ciel evaluate run --dataset tests/eval/smoke.yaml --provider mock --threshold 0.8
# Modo mapa explícito
ciel evaluate run --dataset ds.yaml --provider mock \
--mock-map "capital de Francia=París,2+2=4"
# Regression gate contra un baseline
ciel evaluate regression --baseline results.json --dataset ds.yaml --provider mock
# Red-teaming (prompt injection / fuga de tenant) con MockProvider
ciel evaluate redteam --dataset adversarial.yaml --provider mock
El extra eval habilita métricas de terceros (se degradan a None si no
están instaladas):
¶
ciel.eval
ciel.eval — capa de evaluación y testing reproducible (Fase 18).
Offline-safe por defecto: métricas deterministas propias funcionan sin red ni
extras. DeepEval/RAGAS/TruLens son opt-in vía el extra eval; si no están
instalados, Evaluator degrada a métricas propias (igual que LiteLLM/RAG).
¶
__all__ = ['EvalCase', 'Evaluator', 'EvalResult', 'exact_match', 'contains', 'f1_token', 'faithfulness', 'context_relevance', 'answer_relevance', 'load_dataset']
module-attribute
¶
EvalCase
dataclass
Un caso de evaluación.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
str
|
entrada que se le pasa al agente/evaluable. |
required |
expected
|
Optional[str]
|
respuesta esperada (para métricas cerradas como |
None
|
context
|
Optional[str]
|
contexto RAG recuperado (para |
None
|
gold
|
Optional[str]
|
respuesta "gold" alternativa para |
None
|
metadata
|
Dict[str, Any]
|
metadatos libres (tenant, tags, etc.). |
dict()
|
Source code in src/ciel/eval/eval_case.py
¶
EvalResult
dataclass
Resultado de un caso individual.
Source code in src/ciel/eval/evaluator.py
¶
Evaluator
Evalúa un agente/callable sobre un dataset y acumula KPIs.
Source code in src/ciel/eval/evaluator.py
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | |
¶
export(path: str) -> Dict[str, Any]
Exporta resultados + KPIs a results.json.
Source code in src/ciel/eval/evaluator.py
¶
answer_relevance(answer: str, query: str) -> float
Heurística determinista: la respuesta comparte tokens con la query.
Castiga respuestas vacías o que ignoran por completo la pregunta.
Source code in src/ciel/eval/metrics.py
¶
contains(actual: str, expected: str) -> float
1.0 si la respuesta contiene el substring esperado (case-insensitive).
Source code in src/ciel/eval/metrics.py
¶
context_relevance(query: str, context: Optional[str], *, retriever: Any = None, tenant_id: Optional[str] = None) -> float
Afinación del contexto respecto a la query.
- Si se pasa un
Retrieverdel F17, recupera chunks para la query y mide la superposición de tokens entre la query y los chunks recuperados. - Si no, mide la superposición de tokens entre la query y el
contextprovisto (heurística determinista).
Source code in src/ciel/eval/metrics.py
¶
exact_match(actual: str, expected: str) -> float
1.0 si la respuesta coincide exactamente (trim + lower) con lo esperado.
Source code in src/ciel/eval/metrics.py
¶
f1_token(actual: str, expected: str) -> float
F1 sobre tokens entre la respuesta y la referencia (cerrada).
Source code in src/ciel/eval/metrics.py
¶
faithfulness(answer: str, context: Optional[str]) -> float
¿La respuesta se apoya en el contexto recuperado?
Heurística determinista: proporción de tokens de la respuesta que también aparecen en el contexto. Sin contexto -> 0.0.
Source code in src/ciel/eval/metrics.py
¶
load_dataset(path: str) -> List[EvalCase]
Carga un dataset YAML de casos de evaluación.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
ruta al archivo YAML. Puede ser una lista de dicts o un dict con
una clave |
required |
Returns:
| Type | Description |
|---|---|
List[EvalCase]
|
lista de |