autoevals

repository·main·Indexed 21 days ago

https://github.com/braintrustdata/autoevals

A universal library for evaluating AI model outputs available in Python and TypeScript. It supports various evaluation methods including LLM-as-a-judge (e.g., Factuality), RAG evaluations (e.g., context precision, faithfulness), embedding similarity, heuristics, and composite evaluations. The library allows for custom LLM-based evaluators via LLMClassifier and integrates with the Braintrust platform for observability and logging.

Tokens
7.5K
Snippets
21
Records
32
Agent score
76%

What's inside autoevals

  1. Use LLM-as-a-judge scorers

    main

    LLM-as-a-judge scorers use language models to evaluate outputs based on semantic understanding. They typically return a score between 0 and 1. Available scorers include:

    • Factuality: Checks if the output is factually consistent with the expected ground truth given an input.
    • Battle: Compares output against expected to see which is better.
    • ClosedQA: Evaluates answers to closed-ended questions.
    • Humor: Evaluates if the output is humorous.
    • Security: Checks for security vulnerabilities or unsafe content.
    • Moderation: Uses OpenAI's moderation API to check for policy violations (sexual content, hate speech, etc.).
    • Sql: Evaluates SQL query correctness.
    • Summary: Evaluates the quality of text summaries.
    • Translation: Evaluates translation quality.
    import { Factuality } from "autoevals";
    
    const result = await Factuality({
      input: "What is the capital of France?",
      output: "Paris",
      expected: "The capital of France is Paris",
    });
    // Score: 1.0
  2. Use RAG (Retrieval-Augmented Generation) scorers

    main

    RAG scorers evaluate RAG systems by assessing both context retrieval and answer generation quality. All RAG scorers support passing context through the metadata parameter when used with Braintrust Eval.

    Key RAG scorers include:

    • ContextRelevancy: How relevant the retrieved context is to the question.
    • ContextRecall: How well the context supports the expected answer.
    • ContextPrecision: Whether relevant context appears before irrelevant context.
    • ContextEntityRecall: Whether the context contains entities from the expected answer.
    • Faithfulness: Whether the answer's claims are supported by the context.
    • AnswerRelevancy: How relevant the answer is to the question.
    • AnswerSimilarity: Semantic similarity between answer and expected answer.
    • AnswerCorrectness: A combination of factuality and semantic similarity.
    from autoevals.ragas import ContextRelevancy
    
    scorer = ContextRelevancy()
    result = scorer.eval(
        input="What is the capital of France?",
        output="Paris",
        context=[
            "Paris is the capital of France.",
            "Berlin is the capital of Germany."
        ]
    )
  3. Interpret Scorer Scores

    main

    While interpretation varies by scorer type (e.g., binary scorers like ExactMatch only return 0 or 1), the following general guidelines apply to continuous scores:

    Score RangeInterpretation
    1.0Perfect match or complete correctness
    0.8 - 0.99Very good, minor differences
    0.6 - 0.79Acceptable, some issues
    0.4 - 0.59Moderate quality, significant issues
    0.2 - 0.39Poor quality, major issues
    0.0 - 0.19Unacceptable or completely wrong
  4. Configure custom AI providers and Braintrust Gateway

    main

    Autoevals can route requests to non-OpenAI providers using the following environment variable priority:

    1. OPENAI_BASE_URL: Used for OpenAI-compatible APIs.
    2. BRAINTRUST_AI_GATEWAY_URL: Used if OPENAI_BASE_URL is not set.
    3. Default: Braintrust Gateway.

    To use the Braintrust Gateway, set the BRAINTRUST_API_KEY environment variable. This allows you to use models like claude-3-5-sonnet-latest via an OpenAI-compatible interface.

    # Example using Braintrust Gateway to access Claude
    from autoevals.llm import *
    
    evaluator = Factuality(model="claude-3-5-sonnet-latest")
    result = evaluator(output, expected, input=input)
  5. Configure publishing requirements

    main

    To successfully publish autoevals, the following infrastructure must be in place:

    • GitHub Environments: The environments publish (which requires reviewers) and publish-dry-run must be configured in the repository settings.
    • Trusted Publishers:
      • npm autoevals and PyPI autoevals must be configured as Trusted Publishers using OIDC.
      • Crucial: They must be configured to use the publish environment. The environment claim is what restricts publishing to the gated jobs.
    • Slack Notifications (Optional): To enable notifications, configure the SLACK_SDK_RELEASE_CHANNEL variable and the SLACK_BOT_TOKEN secret.
  6. Release the autoevals packages

    main

    The autoevals npm and PyPI packages are published together at a shared version via a single GitHub Actions workflow (.github/workflows/publish.yaml). A single approval gate controls both lanes; if one fails, neither is released.

    Release Types

    • stable (default): Publishes npm autoevals@<v> (with provenance) and PyPI autoevals==<v> (with attestation). Creates tags js-<v> and py-<v> and two GitHub Releases.
    • prerelease: Publishes the committed version to the npm rc dist-tag. No GitHub release is created.

    Release Workflow

    1. Sync Versions: Bump the version in both package.json and py/autoevals/version.py simultaneously.
    2. Merge: Merge the version bump into the main branch.
    3. Trigger Workflow: Run the publish workflow with release_type=stable and the full 40-character sha of the merged commit.
    4. Approve: Approve the publish environment when the workflow reaches the approval gate.
    # Example workflow invocation parameters
    release_type: stable
    sha: <40-char-commit-sha>
  7. Run LLM-based evaluations in Python

    main

    Autoevals provides model-graded evaluators like Factuality. By default, these use the OPENAI_API_KEY environment variable. You can run evaluations synchronously by calling the evaluator instance directly, or asynchronously using the .eval_async() method.

    Evaluators return a result object containing a score (typically in the range [0, 1]) and metadata (which may include a rationale).

    from autoevals.llm import *
    import asyncio
    
    # Create a new LLM-based evaluator
    evaluator = Factuality()
    
    input = "Which country has the highest population?"
    output = "People's Republic of China"
    expected = "China"
    
    # Using the synchronous API
    result = evaluator(output, expected, input=input)
    print(f"Factuality score (sync): {result.score}")
    print(f"Factuality metadata (sync): {result.metadata['rationale']}")
    
    # Using the asynchronous API
    async def main():
        result = await evaluator.eval_async(output, expected, input=input)
        print(f"Factuality score (async): {result.score}")
        print(f"Factuality metadata (async): {result.metadata['rationale']}")
    
    asyncio.run(main())
  8. Run LLM-based evaluations in TypeScript

    main

    In TypeScript, LLM-based evaluators like Factuality are imported and called as asynchronous functions. Pass an object containing output, expected, and optionally input to the evaluator.

    The result object includes a score and an optional metadata object containing a rationale.

    import { Factuality } from "autoevals";
    
    (async () => {
      const input = "Which country has the highest population?";
      const output = "People's Republic of China";
      const expected = "China";
    
      const result = await Factuality({ output, expected, input });
      console.log(`Factuality score: ${result.score}`);
      console.log(`Factuality metadata: ${result.metadata?.rationale}`);
    })();
  9. Perform local publishing checks

    main

    Before attempting a release, run these commands locally to ensure version synchronization and package integrity:

    1. Check Version Sync: Verify package.json and py/autoevals/version.py match.
    2. Build JS: Install dependencies and build the TypeScript project.
    3. Build Python: Build the Python distribution and use twine to check the integrity of the built artifacts.
    python3 .github/scripts/check_version_sync.py
    pnpm install --frozen-lockfile && pnpm run build
    uv build && uvx twine check dist/*
  10. Configure default settings for scorers

    main

    Use the init() function to set global defaults for all scorers, such as the OpenAI client and the default LLM model. This prevents having to pass these parameters to every individual scorer call.

    TypeScript Example:

    import { init } from "autoevals";
    import OpenAI from "openai";
    
    init({
      client: new OpenAI({ apiKey: "..." }),
      defaultModel: "gpt-5-mini",
    });

    Python Example:

    from autoevals import init
    from openai import OpenAI
    
    init(OpenAI(api_key="..."), default_model="gpt-5-mini")