Skip to main content
This topic explains how to run evaluations from code with the LaunchDarkly Python AI SDK or Node.js AI SDK. In addition to running evaluations in the playground, you can run them from your own code. This lets you use your own generation code against a dataset, score each output, and send the results to LaunchDarkly. LaunchDarkly stores the results. With the Python and Node.js AI SDKs, you can:
  • Generate an output for every row of a dataset, using a handler for your model provider or a handler that you write.
  • Score each output with deterministic scorers that you write in code, with LaunchDarkly judges, or with both.
  • Grade the tool calls an agent makes to reach its answer, such as which tools it calls, in what order, and with what arguments.
  • Define datasets and tools inline in your code, or use datasets and tools from the LaunchDarkly Library.
  • Use the pass or fail result of a run to set your script’s exit code, for example in a CI workflow.
To learn more about the concepts behind this feature, read Evaluations from code.

How evaluations from code work

A single call to run() generates an output for each dataset row and scores it. Then, it returns the run URL, the summary, and whether the run passed. LaunchDarkly derives each row verdict from the scores, and the SDK reads the run summary to report whether the run passed. To learn more, read How evaluations from code work. Keep the following in mind as you write code to run evaluations:
  • The SDK needs an API access token and an SDK key.
    • API access token: Resolves datasets, tools, and judges, creates the evaluation and the run, and polls the summary.
    • SDK key: Sends every generation and criterion result to LaunchDarkly as an event. Results reach LaunchDarkly only through this channel.
  • Every call to run() creates a new evaluation. Use a new key for each new run, such as one that includes a timestamp. To retry a failed run, reuse its key.
  • If your handler raises an error for a row, LaunchDarkly records the row as ERROR and the other rows continue.
  • The SDK does not retry a handler for a row that raises an error.

Prerequisites

To run your first evaluation, you need:
  • A LaunchDarkly project.
  • One of the following AI SDKs:
  • An API access token and the environment’s server-side SDK key. To learn how to get them, read Get your credentials.
  • One handler package for the model provider you generate with, and the API key or credentials for that provider. You do not need a provider key to verify your setup. To learn how, read Run your first evaluation in Python or Run your first evaluation in Node.js.
  • A dataset, either in the Library or defined inline in your code. To learn more, read Datasets.
Depending on how you score rows and what your agent does, you might also need:
  • A judge, if you score with LaunchDarkly judges. The judge must exist in the project as a judge config. To learn more, read Judges.
  • A tool definition for each tool your agent calls, in the Library or inline in your code. To learn more, read Tools.

Get your credentials

The SDK needs two credentials: an API access token and an SDK key. In LaunchDarkly, the API access token is called the Eval API key. To learn what each credential does, read How evaluations from code work.
The SDK key is required. Without it, no result is ingested and every run times out. init_evaluations() in Python and initEvaluations() in Node.js raise an error immediately if the key is missing.

Generate your credentials

To generate your credentials in LaunchDarkly:
  1. Click Evaluations in the side navigation.
  2. Click Run evaluations, then choose From code. The “Run evals from code” dialog appears.
  3. Choose how you want to set up:
    • Set up with an agent gives you instructions to hand to your agent.
    • Set up manually gives you example code for the language and provider you select. The “Connect your code” dialog appears.
  4. (Optional) If you plan to use the credentials in CI or other automation, check Create a service token under Eval API key.
  5. Click Generate keys. The “Finish setup” dialog appears with your new credentials and a .env file.
  6. Copy the credentials, the .env file, and the information specific to your choice:
    • Set up with an agent: The instructions for your agent.
    • Set up manually: Choose your programming language and preferred provider to generate an install command and a code example.
  7. Click Done.
You can also create an API access token and copy an SDK key yourself. To learn how, read API access tokens and SDK keys. If you create the token yourself, assign a role that allows reading datasets and tools, and creating evaluations and evaluation runs, in the target project. The Writer role works.

Write the .env file

If you generated your credentials in LaunchDarkly, the “Finish setup” dialog gives you a .env file with your credentials that you can download. It does not include your project key or dataset key. Add LD_PROJECT_KEY and LD_DATASET_KEY to it. Otherwise, create a .env file. Keep only secrets and project identifiers in your .env file. Model names, tool keys, judge keys, and thresholds live in your scripts. For security, add the .env to your .gitignore file. Here is an example:
.env file

Add your provider credentials

LaunchDarkly credentials and model provider credentials authorize different things. Your LaunchDarkly credentials let the SDK create the evaluation, report results, and read the run summary. Your provider credentials let your handler call the model. Add your provider’s API key to your .env file, such as OPENAI_API_KEY or ANTHROPIC_API_KEY. If your provider uses other credentials, such as Amazon Bedrock through a LangChain handler or a custom handler, configure them the way that provider’s SDK expects. To learn more, read Choose a provider handler. To write your own handler, read Use a custom handler.

Choose a provider handler

The handler argument to run() accepts any LaunchDarkly handler. Each handler reads the provider, model, mode, parameters, and instructions or messages from the generation argument. Set generation.provider and generation.mode to match the handler. The handler packages for each SDK are:
PackageFactoryUse when
launchdarkly-ai-openai-messagescreate_openai_messages_handler()OpenAI, single-turn or tool-calling chat
launchdarkly-ai-openai-agentscreate_openai_agent_handler()OpenAI Agents SDK
launchdarkly-ai-claude-messagescreate_claude_messages_handler()Anthropic Messages API
launchdarkly-ai-claude-agentscreate_claude_agents_handler()Claude Agent SDK
launchdarkly-ai-langchain-messagescreate_langchain_messages_handler()Any LangChain chat model
launchdarkly-ai-langchain-agentscreate_langchain_agents_handler()LangChain agents
Your own functioncreate_handler()A provider that the SDK has no package for, an internal gateway, or replaying stored outputs. To learn more, read Use a custom handler.
To use a different provider, install its handler package, pass its factory as handler, and set generation.provider and generation.mode to match. For example, to generate with Anthropic:
Set ANTHROPIC_API_KEY in your .env file for this handler. If no package fits, write a custom handler. To learn how, read Use a custom handler.

Use a custom handler

A custom handler is an async function that calls your model and returns the output. Wrap it with create_handler() in Python or createHandler() in Node.js to declare the provider and mode it supports. The SDK calls it once for each row. Use a custom handler to call a provider the SDK has no package for, to call an internal gateway, or to replay stored outputs. Here is an example:
The first argument to create_handler() or createHandler() sets the provider and mode that the handler serves. The handler receives the following arguments:
  • config holds the provider, model, parameters, instructions or messages, and the tool definitions from generation.
  • user_input is the rendered row input.
  • tool_handlers maps each tool key to the function you passed in tools.
  • variables holds the row variables plus the rendered input and expected_output.
Return a dict with output. Add usage with input_tokens and output_tokens when you have them.
LaunchDarkly records the usage on the row. To test a handler that calls no model, read Run your first evaluation in Python or Run your first evaluation in Node.js.

Install the SDK

The functions for running evaluations ship in the AI SDK package for your language: launchdarkly-ai-server for Python and @launchdarkly/ai-node for Node.js. You also install one handler package for each model provider you generate with. In Python, also install the base launchdarkly-server-sdk. The examples in this topic let init_evaluations() create the LaunchDarkly client that sends the results, and that client ships in the base SDK. You can omit it if your application already initializes a LaunchDarkly client and passes it to the SDK, or if the base SDK does not run on your platform. To learn more, read Bring your own LaunchDarkly client. In Node.js, @launchdarkly/ai-node includes the base Node.js SDK. Do not install the base Node.js SDK separately. Install the SDK and the handler package for the provider you chose in the previous section. For example, to install the SDK and a handler:
Shell (Python)

How verdicts work

A criterion is a judge or scorer that grades each row. Each criterion has a threshold, which is the score a row must meet to pass that criterion. For a detailed explanation of how LaunchDarkly decides the verdicts, read How verdicts work.

AI SDKs

This feature is available for the following AI SDKs:

Python AI

Run your first evaluation in Python

To run your first evaluation, complete the following steps in order.
Verify your setup in Python
Before you make any model calls, check that your credentials, dataset key, and event path work. The following script uses a custom handler that calls no model and returns a fixed output. It needs only your LaunchDarkly credentials. No provider key is required. Here is the script:
Python AI SDK
Save the script as verify_setup.py and run it:
Shell (Python)
If the script prints a URL, your credentials, dataset key, and event path work. If it fails or times out, read Troubleshooting.
Run the evaluation in Python
The following script runs every row of the dataset through OpenAI and reports the results to LaunchDarkly. It uses no criteria, which makes it a generation-only run. Every row that produces an output passes. Here is the script:
Python AI SDK
Save the script as run_first_eval.py and run it:
Shell (Python)
If the run times out or no results appear in LaunchDarkly, read Troubleshooting.
Review your results in Python
The script prints four lines: the run ID, a URL, the summary, and whether the run passed. Here is an example:
Python AI SDK
Open the URL to review the run in LaunchDarkly. You can also find the run from the Evaluations page. To learn how, read Review evaluation runs.The run_id and stored_verdict labels come from the script. The result object that the SDK returns has run_id, url, summary, and passed. The script prints result.summary directly. This means the summary uses the dataclass representation with snake_case field names, not JSON. The row counts vary by run.The terminal shows a short result that is useful in CI, and LaunchDarkly shows the detailed result. The process exits with code 0 when result.passed is true, and with 1 otherwise.The run URL has the following format:
Python AI SDK
The default base URI is https://app.launchdarkly.com. To use another LaunchDarkly host, set LD_UI_BASE_URI, or pass ui_base_uri to init_evaluations(). The SDK URL-encodes the project key, evaluation ID, and run ID in the path. Here is an example:
Python AI SDK
Keep the following in mind about run():
  • Every call creates a new evaluation. Use a new key for each new run, such as one that includes a timestamp.
  • dataset is the dataset key from the Library, not its ID.
  • generation.mode is required when you provide generation directly. Use completion with a messages handler and agent with an agent handler.
  • generation.instructions is one system message, and generation.messages is a full message list. Do not pass both.
  • concurrency bounds how many rows run at once. The default is 10.
  • Large datasets might need poll_timeout_seconds above the default of 180.

Use an inline dataset in Python

An inline dataset is a test set that your script brings with it. Instead of passing a dataset key, you pass the dataset values directly from your code. To learn more, read Define datasets and tools in code.Inline dataset rows use camelCase field names, such as expectedOutput. Uploaded dataset files and DatasetRow use expected_output instead. Here is an example:
Python AI SDK
The inline dataset must be non-empty. Each row accepts only input, expectedOutput, variables, metadata, and rowIdx. The SDK rejects any other field. input must be a non-empty string. expectedOutput is optional and must be a string when supplied. variables and metadata must be JSON-serializable objects. rowIdx is optional and, when supplied, must match the row’s zero-based position.

Score rows in Python

You can score rows with scorers, LaunchDarkly judges, or both in the same run. To learn how scores become verdicts, read How verdicts work.A Scorer wraps a local function. The function receives the DatasetRow and the generated output. It returns a finite number from 0 to 1. Nothing else is accepted. A yes-or-no check returns 1.0 or 0.0. A row passes a scorer when its score meets the threshold.DatasetRow exposes row_index, input, expected_output, variables, and metadata. The rendered input and expected output are also available in variables. Here is an example of a scorer:
Python AI SDK
A Judge references a judge config by key. The SDK uses your SDK key to resolve the judge once per run, before it creates any records. A missing or disabled judge fails the run up front. Here is an example of a judge:
Python AI SDK
To use judges and scorers in the same run, pass both in criteria. The following example scores every row with a LaunchDarkly judge and a local scorer:
Python AI SDK
Judge keys and scorer names share one namespace. They must be unique within a run, without regard to case.Because a judge is a model call, one of your handlers must serve the judge’s provider. If the judge uses a different provider than generation, pass both handlers in handlers. The SDK selects the handler whose provider and mode match the generation or judge. Pass exactly one of handler and handlers. To learn more, read Judges and scorers.For example, to generate with OpenAI and grade with Anthropic:
Python AI SDK
The judge config determines which provider the judge uses. The handler pool supplies the matching handler.

Judge the tool trajectory in Python

A judge can grade the tool trajectory, which is how the agent reached its answer. The SDK records every tool call the row makes and renders it into {{message_history}} between the row input and the output. To learn more, read Tool trajectory.Scorers cannot see the trajectory, because a scorer receives only the row and the output. Use a judge for trajectory assertions.To judge the tool trajectory, complete the following steps in order.
Write the tool implementation in Python
The function receives the parsed arguments and returns a JSON-serializable value. Here is an example:
Python AI SDK
Make the tool available to the run in Python
Either create the tool in the Library, or define it inline.To use a Library tool, create a tool in the Library with the key lookup_order and the same schema as the inline example in this step. The argument names in the schema must match the arguments your implementation reads. In your script, resolve the tool with await evals.tools.get(), providing the tool key and its implementation. evals.tools.get() supplies the Library schema and description.To define the tool inline instead, construct an EvalTool with the key, the implementation, the schema, and the description. To learn more, read Define datasets and tools in code. Here is an example:
Python AI SDK
The tools argument receives the EvalTool:
Python AI SDK
Inline tool keys must be lowercase and unique within a run. The schema must be a JSON object. To move a tool into the Library, create the corresponding Library tool and change the code to use evals.tools.get(). The tool implementation remains in your application.
Build a dataset with rows that need the tool in Python
A trajectory judge can only grade rows that have a reason to call the tool. The example dataset has five rows:
  • Two rows that need one call each, for orders A19 and B20.
  • One row for an unknown order, to grade whether the agent reports the miss instead of inventing a status.
  • One row that needs two calls, to grade ordering and that both results reach the answer.
  • One control row that needs no tool, to keep the judge honest about unused tools.
Upload the dataset to the Library as a JSONL file. Here is an example dataset:
Python AI SDK (JSONL dataset file)
Create the judge and write its rubric in Python
Create a judge in LaunchDarkly. Put only the grading criteria in the system prompt. Do not add {{message_history}} to the system prompt, because the judge config’s default assistant message already carries it. The SDK appends the JSON score format instructions. Do not restate them. Here is an example system prompt:
Judge system prompt
Keep the clause about an unused tool. Without it, the judge fails every row whose correct behavior is to call nothing.
Run the trajectory evaluation in Python
Here is an example:
Python AI SDK
For a row that called one tool, {{message_history}} renders like this:
Python AI SDK
Keep the following in mind when you design a rubric:
  • Tools available lists what the model could call. A rubric can use it to grade tool selection.
  • A row with tools that called none of them reads No tool calls were made while producing the response.
  • A run with no tools adds no trajectory block. Do not point a trajectory judge at a dataset with no tool rows.
  • A failed call shows error: in place of result:. This is what makes recovery gradeable.
  • Provider built-in tools run inside the provider. They never appear in the trajectory.
  • The trajectory is capped per row. To learn about the limits, read Limits.

Node.js (server-side) AI

Run your first evaluation in Node.js

To run your first evaluation, complete the following steps in order.
Verify your setup in Node.js
Before you make any model calls, check that your credentials, dataset key, and event path work. The following script uses a custom handler that calls no model and returns a fixed output. It needs only your LaunchDarkly credentials. No provider key is required. Here is the script:
Node.js (server-side) AI SDK
Save the script as verify_setup.mjs and run it:
Shell (Node.js)
If the script prints a URL, your credentials, dataset key, and event path work. If it fails or times out, read Troubleshooting.
Run the evaluation in Node.js
The following script runs every row of the dataset through OpenAI and reports the results to LaunchDarkly. It uses no criteria, which makes it a generation-only run. Every row that produces an output passes. Here is the script:
Node.js (server-side) AI SDK
Save the script as run_first_eval.mjs and run it:
Shell (Node.js)
If the run times out or no results appear in LaunchDarkly, read Troubleshooting.
Review your results in Node.js
The script prints four lines: the run ID, a URL, the summary, and whether the run passed. Here is an example:
Node.js (server-side) AI SDK
Open the URL to review the run in LaunchDarkly. You can also find the run from the Evaluations page. To learn how, read Review evaluation runs.The run_id and stored_verdict labels come from the script. The result object that the SDK returns has runId, url, summary, and passed. The script prints the summary as JSON with camelCase field names. The row counts vary by run.The terminal shows a short result that is useful in CI, and LaunchDarkly shows the detailed result. The process exits with code 0 when result.passed is true, and with 1 otherwise.The run URL has the following format:
Node.js (server-side) AI SDK
The default base URI is https://app.launchdarkly.com. To use another LaunchDarkly host, set LD_UI_BASE_URI, or pass uiBaseUri. The SDK URL-encodes the project key, evaluation ID, and run ID in the path.Keep the following in mind about run():
  • Every call creates a new evaluation. Use a new key for each new run, such as one that includes a timestamp.
  • dataset is the dataset key from the Library, not its ID.
  • generation.mode is required when you provide generation directly. Use completion with a messages handler and agent with an agent handler.
  • Use generation.messages with a messages handler and generation.instructions with an agent handler. Do not pass both.
  • concurrency bounds how many rows run at once. The default is 10.
  • Large datasets might need pollTimeoutSeconds above the default of 180.

Use an inline dataset in Node.js

An inline dataset is a test set that your script brings with it. Instead of passing a dataset key, you pass the dataset values directly from your code. To learn more, read Define datasets and tools in code.Inline dataset rows use camelCase field names, such as expectedOutput. Uploaded dataset files use expected_output instead. Here is an example:
Node.js (server-side) AI SDK
The inline dataset must be non-empty. Each row accepts only input, expectedOutput, variables, metadata, and rowIdx. input must be a non-empty string. expectedOutput is optional and must be a string when supplied. variables and metadata must be JSON-serializable objects. rowIdx is optional and, when supplied, must match the row’s zero-based position.

Score rows in Node.js

You can score rows with scorers, LaunchDarkly judges, or both in the same run. To learn how scores become verdicts, read How verdicts work.A Scorer wraps a local function. The function receives the DatasetRow and the generated output. It returns a finite number from 0 to 1. Nothing else is accepted. A yes-or-no check returns 1.0 or 0.0. A row passes a scorer when its score meets the threshold.DatasetRow exposes rowIndex, input, expectedOutput, variables, and metadata. The rendered input and expected output are also available in variables. Here is an example of a scorer:
Node.js (server-side) AI SDK
A Judge references a judge config by key. The SDK uses your SDK key to resolve the judge once per run, before it creates any records. A missing or disabled judge fails the run up front. Here is an example of a judge:
Node.js (server-side) AI SDK
To use judges and scorers in the same run, pass both in criteria. The following example scores every row with a LaunchDarkly judge and a local scorer:
Node.js (server-side) AI SDK
Judge keys and scorer names share one namespace. They must be unique within a run, without regard to case.Because a judge is a model call, one of your handlers must serve the judge’s provider. If the judge uses a different provider than generation, pass both handlers in handlers. The SDK selects the handler whose provider and mode match the generation or judge. Pass exactly one of handler and handlers. To learn more, read Judges and scorers.For example, to generate with OpenAI and grade with Anthropic:
Node.js (server-side) AI SDK
The judge config determines which provider the judge uses. The handler pool supplies the matching handler.

Judge the tool trajectory in Node.js

A judge can grade the tool trajectory, which is how the agent reached its answer. The SDK records every tool call the row makes and renders it into {{message_history}} between the row input and the output. To learn more, read Tool trajectory.Scorers cannot see the trajectory, because a scorer receives only the row and the output. Use a judge for trajectory assertions.To judge the tool trajectory, complete the following steps in order.
Write the tool implementation in Node.js
The function receives the parsed arguments and returns a JSON-serializable value. Here is an example:
Node.js (server-side) AI SDK
Make the tool available to the run in Node.js
Either create the tool in the Library, or define it inline.To use a Library tool, create a tool in the Library with the key lookup_order and the same schema as the inline example in this step. The argument names in the schema must match the arguments your implementation reads. In your script, resolve the tool with await evals.tools.get(), providing the tool key and its implementation. evals.tools.get() supplies the Library schema and description, and pins the tool version for the run.To define the tool inline instead, construct an EvalTool with the key, the implementation, the schema, and the description. To learn more, read Define datasets and tools in code. Here is an example:
Node.js (server-side) AI SDK
The tools argument receives the EvalTool:
Node.js (server-side) AI SDK
Inline tool keys must be lowercase and unique within a run. To move a tool into the Library, create the corresponding Library tool and change the code to use evals.tools.get(). The tool implementation remains in your application.
Build a dataset with rows that need the tool in Node.js
A trajectory judge can only grade rows that have a reason to call the tool. The example dataset has five rows:
  • Two rows that need one call each, for orders A19 and B20.
  • One row for an unknown order, to grade whether the agent reports the miss instead of inventing a status.
  • One row that needs two calls, to grade ordering and that both results reach the answer.
  • One control row that needs no tool, to keep the judge honest about unused tools.
Pass the rows as an inline dataset. Here is an example dataset:
Node.js (server-side) AI SDK
Create the judge and write its rubric in Node.js
Create a judge in LaunchDarkly. Put only the grading criteria in the system prompt. Do not add {{message_history}} to the system prompt, because the judge config’s default assistant message already carries it. The SDK appends the JSON score format instructions. Do not restate them. Here is an example system prompt:
Judge system prompt
Keep the clause about an unused tool. Without it, the judge fails every row whose correct behavior is to call nothing.
Run the trajectory evaluation in Node.js
Here is an example:
Node.js (server-side) AI SDK
For a row that called one tool, {{message_history}} renders like this:
Node.js (server-side) AI SDK
Keep the following in mind when you design a rubric:
  • Tools available lists what the model could call. A rubric can use it to grade tool selection.
  • A row with tools that called none of them reads No tool calls were made while producing the response.
  • A run with no tools adds no trajectory block. Do not point a trajectory judge at a dataset with no tool rows.
  • A failed call shows error: in place of result:. This is what makes recovery gradeable.
  • Provider built-in tools run inside the provider. They never appear in the trajectory.
  • The trajectory is capped per row. To learn about the limits, read Limits.

Run evaluations in CI

The script in Run your first evaluation in Python or Run your first evaluation in Node.js exits with code 0 when the stored run passes, and with 1 when it does not. Most CI systems treat a non-zero exit code as a failed step. This means the result of a run can fail a build or block a release. Keep the following in mind when you run in CI:
  • Store credentials as secrets: Add LD_API_TOKEN and LD_SDK_KEY, the project key, and any provider key as secrets in your CI system. Pass them to the job as environment variables. Do not commit them.
  • Use a unique run key for each new run: Every run creates a new evaluation. A timestamp works, and you can also include the CI run number.
  • Retry a failed run with the same key: To retry a run that failed, run the script again with the same run key.
  • Create Library assets first: Library datasets, tools, and judges must exist in the project before the job runs. Inline datasets and inline tools live in your code and travel with your repository.
  • Raise limits for large datasets: Large datasets might need poll_timeout_seconds in Python, or pollTimeoutSeconds in Node.js, above the default of 180.
  • Open the run URL for details: The terminal shows a short result, and LaunchDarkly shows the detailed result.

Options

This section lists the arguments and settings that control a run.

Run options

Pass the key of the LaunchDarkly project that holds the dataset, tools, and judges when you initialize evaluations. In Python, pass project_key to init_evaluations(). In Node.js, pass projectKey to initEvaluations(), or set LD_PROJECT_KEY. The run() function accepts the following arguments:
ArgumentDescription
key(Required) The key for the evaluation. Use a new key for each new run. To retry a failed run, reuse its key.
dataset(Required) The dataset key from the Library, not its ID, or a list of inline dataset rows.
handler(Required unless you pass handlers) A LaunchDarkly handler or a custom handler function.
generation(Required) The provider, model, mode, parameters, and either instructions or messages. mode is required when you provide generation directly. Use instructions for one system message and messages for a full message list. Do not pass both.
toolsA list of EvalTool objects. Use evals.tools.get() for Library tools or construct an EvalTool for an inline tool.
criteriaA list of Judge and Scorer objects. With no criteria, every row that produces an output passes.
handlersA list of handlers used when generation and judges require different provider or mode combinations. Pass exactly one of handler and handlers.
concurrencyHow many rows run at once. Defaults to 10.
poll_interval_secondsHow many seconds the SDK waits between checks of the run summary. Defaults to 2 seconds.
poll_timeout_secondsHow long the SDK waits for the run to finish. Large datasets might need a higher value. Defaults to 180 seconds.

Scorer settings

A Scorer accepts the following settings:
SettingDescription
name(Required) The name of the scorer. Names and judge keys share one namespace and must be unique within a run, without regard to case.
fn(Required) The function that receives the DatasetRow and the output, and returns a number from 0 to 1.
thresholdThe score a row must meet to pass. Defaults to 1.0, which means a row passes only on a perfect score. Lower it for graded scorers.
success_direction"higher_is_better" or "lower_is_better". Use "lower_is_better" for a scorer that counts something unwanted. Defaults to "higher_is_better".

Judge settings

A Judge accepts the following settings:
SettingDescription
key(Required) The key of the judge config.
thresholdThe score a row must meet to pass. A row passes when the judge score meets it. Defaults to 0.5.
ground_truth_contextReplaces the expected output as the reference the judge grades against.
The success direction of a judge lives on the judge config in LaunchDarkly. You do not set it in code.

Limits

The following limits apply to evaluation runs that you start from code:
LimitValueWhat happens when exceeded
Uploaded dataset file sizeUnder 32 MBThe upload fails validation and LaunchDarkly shows an error.
Rows in an uploaded datasetFewer than 10,000The upload fails validation and LaunchDarkly shows an error.
The SDK records up to 50 tool calls per row, and up to 2,000 characters for each set of tool arguments or each result. For the default concurrency, poll_timeout_seconds, and pollTimeoutSeconds values, read Run options.

Troubleshooting

This table includes possible errors and their solutions:
SymptomLikely causeResolution
ImportError for EvalTool, create_handler, or another name this guide importsThe installed SDK is too old.Install launchdarkly-ai-server 1.0.0 or later.
EvaluationsError: No LaunchDarkly SDK key providedLD_SDK_KEY is not set. Every path needs it.Set LD_SDK_KEY in your environment or .env file, then run the script again.
The run times out and no results appearThe SDK key is missing or wrong, which means LaunchDarkly ingests no results.Set LD_SDK_KEY to the server-side SDK key for the environment you want results in.
HTTP 401The API access token is missing or invalid.Check LD_API_TOKEN. Create a new token if the old one expired.
HTTP 403The token lacks a dataset, tool, evaluation, or run permission.Use the Writer role, or update the custom role to allow reading datasets and tools and creating evaluations and evaluation runs in the target project.
HTTP 404The project key, dataset key, tool key, or judge key does not exist in the project you passed.Check that all of the keys belong to the same project.
The run fails before it creates any records, and names a tool keyA tool key you passed in tools is not in the Library and was not defined inline.Create the tool in the Library with the same key, or define it inline.
Judge resolution fails before the run startsThe SDK key is wrong, the judge config does not exist or has been disabled, or your handler cannot serve the judge’s provider.Check LD_SDK_KEY, confirm the judge config exists and is enabled, and confirm your handler can serve the judge’s provider. If the judge uses a different provider, include handlers for both providers in handlers.
The run stays pendingNot every row was accepted, or events did not flush.Confirm that every row was accepted and that your script calls shutdown() so events flush. Raise poll_timeout_seconds for large datasets.
The trajectory judge fails rows that need no toolThe rubric penalizes an unused tool.Add the unused-tool clause to the rubric, or point the judge at a dataset where every row needs the tool.