prompttools Documentation

repository·main·Indexed 25 days ago

https://github.com/hegelai/prompttools

An open-source, self-hostable toolkit for testing, experimenting with, and evaluating LLMs, vector databases, and prompts. It provides abstractions like Experiments and Harnesses to evaluate providers including OpenAI, Anthropic, Google, and HuggingFace, as well as vector databases like ChromaDB, Weaviate, and Pinecone. Features include a local Streamlit playground, RAG evaluation, and support for integrating evaluations into CI/CD workflows.

Tokens
28.6K
Snippets
81
Records
129
Agent score
81%

What's inside prompttools

  1. Overview of prompttools usage patterns

    main

    PromptTools provides tools for testing and experimenting with prompts, allowing developers to evaluate prompts using code and notebooks. There are two primary workflows:

    1. Notebook Experiments: Run experiments in notebooks to evaluate LLM outputs.
    2. Unit Testing: Turn evaluations into unit tests and integrate them into CI/CD workflows (e.g., via GitHub Actions).
  2. Explore the prompttools package structure

    main

    The prompttools package is organized into several specialized subpackages for managing prompt engineering workflows:

    • prompttools.experiment: Tools for running and managing prompt experiments.
    • prompttools.harness: Frameworks for testing and evaluating prompts.
    • prompttools.mock: Utilities for mocking LLM responses and behaviors.
    • prompttools.prompttest: Specific tools for testing prompt quality and consistency.
    • prompttools.requests: Utilities for handling LLM requests.
    • prompttools.utils: General purpose utility functions.
  3. Understand the difference between Experiments and Harnesses in prompttools

    main

    The prompttools library uses two primary abstractions for managing LLM evaluations:

    1. Experiments: The base abstraction for running evaluations.
    2. Harnesses: Higher-level abstractions built on top of experiments. Harnesses manage abstractions over inputs. For example, a harness might freeze specific model arguments while varying prompt templates or user inputs, automatically constructing the underlying experiments and tracking which templates and inputs were used for each prompt.
  4. Understand Experiments and Harnesses in prompttools

    main

    The prompttools library uses two primary abstractions for testing and evaluating LLM outputs:

    1. Experiments: A low-level abstraction that takes the Cartesian product of possible inputs for an LLM API. It constructs and asynchronously executes requests using all combinations of the provided inputs.
    2. Harnesses: A higher-level abstraction that wraps experiments to provide more automated detail and simplified workflows.

    Use an Experiment when you need fine-grained control over the specific parameters being varied across multiple API calls.

  5. Experiment with Vector Databases and RAG

    main

    Use prompttools to evaluate vector database performance and Retrieval Augmented Generation (RAG) workflows. Supported experiments include:

    • RAG Evaluation: Combine vector database experiments with LLMs to evaluate the entire RAG pipeline.
    • Vector DB Specific Experiments:
      • ChromaDB: Test different embedding functions and query parameters, evaluating results via ranking correlation.
      • Weaviate: Compare different vectorizers, configurations, and query functions.
      • LanceDB: Test various embedding functions and query methods.
      • Qdrant: Explore different querying methods, including vector-based queries.
      • Pinecone: Test different data ingestion and querying strategies.
  6. Run LLM experiments in notebooks using PromptTemplateExperimentationHarness

    main

    To run experiments in a notebook, use PromptTemplateExperimentationHarness to manage prompt templates and user inputs. You can define a custom evaluation function (eval_fn) to score results, run the harness, and then use .evaluate() to apply your metric and .visualize() to display the results as a table in the notebook.

    For built-in evaluation functions, you can use prompttools.utils.similarity for semantic similarity comparisons.

    from prompttools.harness import PromptTemplateExperimentationHarness
    from typing import Dict
    
    
    def eval_fn(prompt: str, results: Dict, metadata: Dict) -> float:
        # Your logic here, or use a built-in one such as `prompttools.utils.similarity`.
        pass
    
    prompt_templates = [
        "Answer the following question: {{input}}",
        "Respond to the following query: {{input}}"
    ]
    
    user_inputs = [
        {"input": "Who was the first president?"},
        {"input": "Who was the first president of India?"}
    ]
    
    harness = PromptTemplateExperimentationHarness("text-davinci-003",
                                                 prompt_templates,
                                                 user_inputs)
    
    
    harness.run()
    harness.evaluate("metric_name", eval_fn)
    harness.visualize()  # The results will be displayed as a table in your notebook
  7. Create unit tests for prompts using @prompttest

    main

    Use the @prompttest.prompttest decorator to transform a completion function into a unit test (referred to as a prompttest). This allows you to execute and evaluate experiments as part of your testing suite or CI/CD workflow.

    The decorator requires metric_name, an eval_fn, and a list of prompts.

    Your evaluation function (eval_fn) must accept one of the following parameter signatures:

    • input_pair: Tuple[str, Dict[str, str]], results: Dict, metadata: Dict
    • prompt: str, results: Dict, metadata: Dict
    • messages: List[Dict[str,str]], results: Dict, metadata: Dict
    import prompttools.prompttest as prompttest
    import os
    
    @prompttest.prompttest(
        metric_name="is_valid_json",
        eval_fn=validate_json.evaluate,
        prompts=[create_json_prompt()],
    )
    def json_completion_fn(prompt: str):
        response = None
        if os.getenv("DEBUG", default=False):
            response = mock_openai_completion_fn(**{"prompt": prompt})
        else:
            response = openai.completions.create(prompt)
        return response.choices[0].text
  8. Create unit tests with @prompttest

    main

    In prompttools, unit tests for prompts are called prompttests. You can transform a completion function into an efficient unit test using the @prompttest.prompttest decorator. This decorator executes and evaluates experiments, allowing you to test prompts over time against specific metrics.

    To use it, provide the following arguments to the decorator:

    • metric_name: A string name for the metric being tested.
    • eval_fn: The evaluation function used to validate the output.
    • prompts: A list of prompt templates or strings to be tested.

    Example usage:

    import prompttools.prompttest as prompttest
    
    @prompttest.prompttest(
        metric_name="is_valid_json",
        eval_fn=validate_json.evaluate,
        prompts=[create_json_prompt()],
    )
    def json_completion_fn(prompt: str):
        response = None
        if os.getenv("DEBUG", default=False):
            response = mock_openai_completion_fn(**{"prompt": prompt})
        else:
            response = openai.completions.create(prompt)
        return response.choices[0].text
    import prompttools.prompttest as prompttest
    
    @prompttest.prompttest(
        metric_name="is_valid_json",
        eval_fn=validate_json.evaluate,
        prompts=[create_json_prompt()],
    )
    def json_completion_fn(prompt: str):
        response = None
        if os.getenv("DEBUG", default=False):
            response = mock_openai_completion_fn(**{"prompt": prompt})
        else:
            response = openai.completions.create(prompt)
        return response.choices[0].text
  9. Initialize an Experiment

    main

    There are two ways to initialize an Experiment class:

    1. Direct Initialization: Wrap your test parameters in list objects and pass them directly into the __init__ method of the specific experiment class (e.g., OpenAIChatExperiment).
    2. Using initialize method: Define two dictionaries—one containing the parameters you want to test (varying) and one containing the parameters you want to keep constant (frozen). Pass these dictionaries to the initialize class method.