Pular para o conteúdo

Guias

Referência do SDK

Todo nome que os pacotes oloproof e oloproof.evaluators exportam, com a sua assinatura, se é síncrono ou assíncrono, e o que retorna. Para uma introdução guiada leia primeiro A API Python.

Só esses dois pacotes são a superfície pública. Qualquer coisa importada de oloproof_core é parte interna do engine e pode mudar sem aviso. Toda função abaixo roda localmente sobre o store do projeto; nenhuma delas envia dados a lugar algum, a menos que um avaliador que você passe chame um provedor de modelos.

Executando uma avaliação

evaluate e aevaluate

def evaluate(*, system, dataset, evaluators, policy=None, **kwargs) -> EvaluationResult
async def aevaluate(*, system, dataset, evaluators, policy=None, **kwargs) -> EvaluationResult
ArgumentoTipoO que é
systemuma função @system, uma classe ou instância @rag_system, ou um callableO sistema em teste.
datasetcaminhoUma suíte JSONL. Veja Suítes.
evaluatorslistaInstâncias de oloproof.evaluators, ou funções @evaluator.
policycaminho de um release.yaml, uma ReleasePolicy, ou NoneA política de lançamento. None não executa gate: result.gate é None e nada é decidido.
concurrencyConcurrencyConfig ou um mapeamento como {"system": 8, "judge": 4}Chamadas em andamento ao mesmo tempo.
sliceslista de stringsSegmentos exploratórios, como em oloproof.yaml.
min_slice_supportinteiroAbaixo deste número de casos elegíveis um segmento não tem intervalo. Padrão 30.
replicatesinteiroMede cada caso este número de vezes. Padrão 1.

evaluate é síncrona. Chamada sem nenhum event loop rodando, usa asyncio.run; chamada de dentro de um loop em execução (um notebook, um teste assíncrono), executa a avaliação em uma thread separada e bloqueia até terminar, então é segura nos dois lugares. aevaluate é a corrotina; use await nela a partir de código assíncrono.

Os demais argumentos nomeados (metrics, store, predictive, event_sink, retry_policy, traffic_draw_id) recebem tipos do engine de oloproof_core e não fazem parte da superfície estável.

from oloproof import evaluate, system, current_case
from oloproof.evaluators import ExactMatch, evaluator

@system(name="support-bot", version="1")
def answer(case):
    current_case().usage(input_tokens=12, output_tokens=3)
    return {"label": "refund" if "refund" in case["question"].lower() else "other"}

@evaluator(criterion="short_label")
def short_label(case):
    return len(case.output["label"]) <= 6

result = evaluate(
    system=answer,
    dataset="cases.jsonl",
    evaluators=[ExactMatch(criterion="correct_label", field="label"), short_label],
)
for metric in result.metrics:
    print(metric.metric, metric.estimate, metric.interval, metric.n_observed, metric.n_missing)

Executado em uma suíte de dois casos sem política, isto imprimiu:

correct_label 1.0 lower=0.15811388300841903 upper=1.0 2 0
short_label 1.0 lower=0.15811388300841903 upper=1.0 2 0

EvaluationResult

MembroTipoO que é
runregistro da execuçãoA execução armazenada, com o seu id, status e completude.
suite, system, evaluatorsregistros de versãoAs versões exatas que esta execução mediu.
metricstupla de resultados de métricaUm por critério e métrica declarada: metric, estimate, interval, n_total, n_eligible, n_observed, n_missing, exclusions, method.
gateresultado do gate ou NoneCom uma política: release_action, exit_code, decisions e reasons.
decisionstuplaAs decisões do gate, ou vazia sem política.
cases()listaTodo caso com a sua execução e os seus julgamentos.
failures()listaCasos que não terminaram, deram erro ou reprovaram em pelo menos um avaliador.
print(stderr=False)nenhumO relatório de terminal que oloproof run imprime.
to_bundle(path)caminhoGrava um bundle portável, como oloproof export faz.

O que os estados, os códigos de motivo e as contagens significam está em Resultados e execução.

evaluate_comparison e aevaluate_comparison

def evaluate_comparison(*, candidate_system, baseline_system, dataset, evaluators, policy, **kwargs) -> ComparisonEvaluationResult
async def aevaluate_comparison(*, candidate_system, baseline_system, dataset, evaluators, policy, **kwargs) -> ComparisonEvaluationResult

Executa os dois sistemas na mesma suíte em uma única ordem com seed e decide as regras de comparação da política. policy é obrigatória e deve conter pelo menos uma regra superiority, non_inferiority ou equivalence, senão a chamada lança um erro de configuração. Argumentos nomeados extras: concurrency, replicates, e metrics, store e retry_policy com tipos do engine. O comportamento síncrono e assíncrono é como em evaluate.

ComparisonEvaluationResult tem candidate e baseline (cada um um EvaluationResult) e comparison, que traz as diferenças pareadas e as suas decisões. Veja Comparando duas versões.

Declarando um sistema

@system

def system(func=None, *, name=None, version=None, config=None, timeout_s=None, records=())

Pode ser usado sem argumentos (@system) ou com argumentos (@system(name=..., version=...)), ou chamado sobre um objeto (system(model.answer, version="v2")). A função recebe o objeto input do caso, não o caso inteiro, e retorna a saída que os avaliadores leem. Pode ser def ou async def; uma função síncrona roda em uma thread de trabalho.

ArgumentoPadrãoO que é
nameo nome da funçãoParte da identidade da versão.
versionausenteObrigatório para um método vinculado ou um objeto callable, porque o comportamento deles depende de um estado que o Oloproof não vê.
configvazioConfigurações registradas com a versão.
timeout_s120Limite por chamada. Uma chamada que o excede é registrada como execução com timeout.
recordsvazioTipos de artefato que o sistema registra, como retrieval/v1. Um avaliador que exige um tipo que o sistema não declara é recusado antes de a execução começar.

O código-fonte do próprio módulo da função entra no digest da versão, então editá-lo invalida as execuções em cache. Veja a Referência de configuração para o que mais invalida e o que não.

current_case

def current_case() -> CaseRecorder

Disponível apenas enquanto o Oloproof está chamando o seu sistema; em qualquer outro lugar lança RuntimeError. Os métodos do gravador:

MétodoRegistra
usage(*, input_tokens=None, output_tokens=None, cost_usd=None)Tokens e custo de uma chamada a um modelo. Um valor omitido fica sem registro, não zero.
artifact(kind, data)Qualquer valor JSON ou modelo Pydantic sob um tipo como trace ou conversation/v1.
retrieval(retrieval)Os candidatos ordenados que um retriever retornou (retrieval/v1).
context(context)O contexto montado para a geração (context/v1).
citations(ids)Os ids que uma resposta cita, como doc_id ou doc_id#chunk_id (citations/v1).
agent_trajectory(trajectory)Os passos de um agente, as chamadas de ferramentas e os resultados, e os checkpoints (agent_trajectory/v1).

Cada um retorna um ArtifactRef (exceto usage, que não retorna nada). Os payloads tipados são exportados para montar esses registros: Retrieval, Passage, Context, ContextItem, DroppedItem, Citations, StageTimings, AgentTrajectory, AgentStep, AgentCheckpoint, AgentConstraintCheck, e o nome de tipo CONVERSATION (conversation/v1).

@rag_system

def rag_system(*, name, depth, top_k, token_budget=None, index_version=None, version=None, config=None, citations_path="citations")

Um decorador de classe. A classe fornece retrieve(input, depth) e generate(input, context), mais count_tokens(passage) quando define um token_budget. context é a lista de objetos Passage que sobreviveram a top_k e ao orçamento, na ordem de ranking. O Oloproof registra por conta própria retrieval/v1, context/v1, citations/v1 e stage_timings/v1, e coloca cada estágio em cache separadamente. citations_path nomeia o campo da saída que contém os ids citados pela resposta. Veja RAG.

Avaliadores

Todas as classes estão em oloproof.evaluators. O criterion de cada uma nomeia a métrica que ela produz. Quais artefatos cada uma lê, e o seu equivalente em YAML, estão na tabela de avaliadores da Referência de configuração.

ClasseAssinatura
ExactMatch(*, criterion, field=None, expected_field=None, strip=True, casefold=False)
Contains(*, criterion, field=None, expected_field=None)
Regex(*, criterion, pattern, field=None, pass_if="match")
JsonSchema(*, criterion, schema, field=None)
RubricJudge(*, criterion, provider, model, rubric_text=None, rubric_file=None, api_key_env=None, base_url=None, temperature=0, max_tokens=512, timeout_s=60.0)
Groundedness(*, provider, model, criterion="groundedness", **options)
CitationSupport(*, provider, model, criterion="citation_support", **options)
CitationValidity(*, criterion="citations_valid", require_citations=False)
HitRate, Recall(k=None, *, criterion=None, relevance_unit="doc"), k é 5 por padrão
MRR, NDCG(k=None, *, criterion=None, relevance_unit="doc"), k é 10 por padrão
AgentMaxSteps(max_steps, *, criterion=None)
AgentToolCalled(tool_name, *, min_calls=1, criterion=None)
AgentNoToolLoop(*, max_repeats=2, criterion="agent_no_tool_loop")
AgentToolSequence(*, ordered=True, criterion="agent_tool_sequence")
AgentNoUndeclaredTool(*, criterion="agent_no_undeclared_tool")
AgentConstraintsSatisfied(constraints=(), *, criterion="agent_constraints_satisfied")
AgentRoute(*, criterion="agent_route")
AgentToolPermissions(permissions, *, criterion="agent_tool_permissions")
AgentMaxHandoffs(max_handoffs, *, criterion=None)
ConversationCompleted(*, criterion="conversation_completed")
ConversationJudgecomo RubricJudge
PredictiveCorrect, PredictiveRecall, PredictivePrecision(*, criterion, positive=True, field="label", expected_field="label")
AbsoluteError(*, criterion, target_range, field="label", expected_field="label")
Brier, PredictiveRanking(*, criterion, positive=True, field="score", expected_field="label")
LogLoss(*, clip, criterion, positive=True, field="score", expected_field="label")
CustomEvaluator(func, *, criterion, reads=("output", "expected"), cacheable=False, version=None, value_type="binary", score_range=None)

provider é "anthropic", "openai" ou "openai_compatible". Um juiz lê a sua chave da variável de ambiente que api_key_env nomeia (ANTHROPIC_API_KEY ou OPENAI_API_KEY por padrão) e é cobrado por esse provedor. Groundedness e CitationSupport recebem as demais configurações de RubricJudge por **options. O juiz de probabilidade, o classificador baseado em modelo e a cascata não têm classe no SDK; existem apenas em YAML.

ConversationCompleted e ConversationJudge leem um artefato conversation/v1 que o seu sistema registra. O Oloproof não conduz a conversa: a sua aplicação executa cada turno e registra a transcrição. Veja Agentes.

@evaluator

def evaluator(*, criterion, reads=("output", "expected"), cacheable=False, version=None, value_type="binary", score_range=None)

Envolve uma função de um argumento, o caso, em um CustomEvaluator. O caso tem output, expected e scenario, e artifacts(name) retorna os payloads de um tipo registrado. A função pode ser def ou async def. Um avaliador binário retorna True ou False; um avaliador de pontuação declara value_type="score" e score_range=(low, high) e retorna um número. Uma exceção lançada pela função registra o caso como faltante para aquele critério, nunca como falha.

reads deve listar todo campo que a função lê (input, output, expected, metadata, metadata.<key> ou artifacts.<name>), porque o julgamento em cache tem exatamente esses como chave. Os julgamentos só são reaproveitados entre execuções com cacheable=True. O código-fonte do módulo que a define entra na versão, então editá-lo os invalida. O YAML não pode nomear um avaliador personalizado.

Diagnóstico

diagnose e adiagnose

def diagnose(run_id, **kwargs) -> InterventionResult
async def adiagnose(run_id, *, system, evaluators, intervention, criterion, control=True, top_k=None, reranker=None, reranker_root=None, store=None, concurrency=None) -> InterventionResult

Executa de novo os casos reprovados de uma execução armazenada sob uma intervenção: "gold-context", "top-k" (com top_k) ou "reranker" (com reranker). system e evaluators devem ser as versões que a execução usou; uma versão diferente é recusada antes que qualquer coisa seja executada. Com control=True uma nova amostra de controle roda ao lado da intervenção, para que uma mudança possa ser distinguida da variação entre execuções. diagnose é a forma síncrona e, dentro de um loop em execução, se comporta como evaluate. Veja RAG para o fluxo de trabalho.

InterventionResult contém o id da execução de origem, a intervenção, se ela foi suportada, as execuções de intervenção e de controle, um desfecho por caso, e um DiagnosisReport de entradas CaseDiagnosis quando um foi produzido.

Replay de agentes

def supports_replay(system) -> bool
def checkpoint_for(trajectory, step_index) -> AgentCheckpoint | None
async def replay_case(system, *, scenario_id, trajectory, checkpoint, change) -> ReplayOutcome
def label_case(outcome) -> CaseDiagnosis
def label_cases(outcomes) -> tuple[CaseDiagnosis, ...]
def unnecessary_steps(labels) -> tuple[UnnecessaryStep, ...]

O replay é algo que o seu sistema faz, não algo que o Oloproof simula. Um sistema só o suporta implementando async def replay(self, trajectory, *, checkpoint, change) -> AgentTrajectory, que retorna o que o agente fez do checkpoint em diante; o Oloproof emenda o prefixo registrado e compara. A sua aplicação cuida do próprio estado, das sessões e dos efeitos colaterais das ferramentas, inclusive de reiniciá-los antes de um replay. supports_replay informa se um sistema declara o método.

replay_case é uma corrotina: use await nela, ou chame-a por asyncio.run. Ela executa um controle (o mesmo checkpoint com ReplayChange(kind="resume")) antes do replay, e não tenta o replay quando o controle não reproduz a gravação. change é ReplayChange(kind="drop_step", step_index=...) ou ReplayChange(kind="resume"). checkpoint_for escolhe o último checkpoint registrado estritamente antes de um passo, ou None, caso em que o desfecho é descartado como no_checkpoint_recorded sem tocar no sistema.

ReplayOutcome traz scenario_id, change, os status terminais do replay e do controle, e discarded com um motivo quando o caso não gera evidência. Um caso descartado não é um caso reprovado. label_case transforma um desfecho em um CaseDiagnosis com um FailureLabel e o seu LabelReason; unnecessary_steps lista os passos cuja remoção deixou o desfecho intacto. Veja Agentes.

Rótulos humanos e confiança nos avaliadores

def record_label(*, run_id, scenario_id, criterion, passed, labelled_by, note=None, purpose="measurement", sample_index=0, config="oloproof.yaml", store=None, ...) -> HumanLabel

Armazena o veredicto de aprovação ou reprovação de uma pessoa sobre um caso de uma execução armazenada. Os rótulos alimentam oloproof evaluators validate, que mede a concordância de um juiz com eles (AgreementResult) e registra o seu status (RegistryEntry). Os argumentos adicionais measurement_sample_* vinculam um rótulo a uma amostra de medição; oloproof labels export e oloproof labels import da CLI os preenchem para você. Veja Juízes.

Políticas em código

ReleasePolicy, IntervalThresholdRule, ObservedCountRule e DecisionRule (a união das duas) montam uma política sem arquivo. Os campos delas são os campos de release.yaml da Referência de configuração; uma regra de intervalo recebe direction (min ou max) e threshold em vez de min: ou max:. As regras de comparação não têm classe exportada; escreva-as em release.yaml e passe o caminho.

from oloproof import IntervalThresholdRule, ReleasePolicy

policy = ReleasePolicy(
    rules=(IntervalThresholdRule(id="accuracy", metric="correct_label", direction="min", threshold=0.8),),
)

Outras exportações

NomeO que é
ConcurrencyConfigLimites system e judge, como em oloproof.yaml.
TransientErrorLance-a a partir de um sistema, com retryable=True, para que a chamada seja tentada de novo com backoff.
ArtifactRefA referência que um artefato registrado retorna: o seu tipo e o seu digest.
__version__A versão do pacote instalado.