| name | langsmith_run_evals |
| description | Guidance for writing run_evals.py scripts that use LangSmith evaluate() with a dataset ID. |
Overview
This skill provides guidance on writing a run_evals.py script that runs evaluations using LangSmith's evaluate() function with a pre-existing dataset.
Before Writing run_evals.py
Always ask the user for:
- Evaluator/scoring function: What metric to use (e.g., exact match on label, custom scorer, LLM-as-judge)
- Experiment naming conventions: How to name experiments for tracking
Key Components of run_evals.py
-
Load the prompt from prompt.txt - The prompt file should be read and used in the target function.
-
Use a hardcoded dataset ID - Do NOT create a new dataset on each run. Use the dataset ID from the one-time upload script.
-
Define a target function - This is the function that will be evaluated. It takes an input dict and returns an output dict.
-
Define an evaluator - This scores the target function's output against the expected output.
-
Call langsmith.evaluate() - Pass the target function, dataset ID, and evaluators.
Anthropic Model Names (Claude 4.5 family)
When using Anthropic models via langchain_anthropic, use these model IDs:
- claude-sonnet-4-5 - Best balance of intelligence, speed, and cost
- claude-haiku-4-5 - Fastest model with near-frontier intelligence
- claude-opus-4-5 - Premium model with maximum intelligence
Reference: https://docs.anthropic.com/en/docs/about-claude/models/all-models
Example Structure
from langsmith import Client, evaluate
from langchain_openai import ChatOpenAI
DATASET_ID = "your-dataset-id-here"
PROMPT_FILE = "prompt.txt"
with open(PROMPT_FILE) as f:
prompt = f.read()
model = ChatOpenAI(model="gpt-4o", temperature=0)
def target(inputs: dict) -> dict:
response = model.invoke([
{"role": "system", "content": prompt},
{"role": "user", "content": inputs["text"]},
])
return {"label": response.content}
def exact_match(outputs: dict, reference_outputs: dict) -> dict:
match = outputs.get("label") == reference_outputs.get("label")
return {"score": int(match), "key": "exact_match"}
results = evaluate(
target,
data=DATASET_ID,
evaluators=[exact_match],
experiment_prefix="my-experiment",
)
print(f"Results: {results.aggregate_metrics}")
Best Practices
- Keep dataset creation separate from evaluation (use create_dataset.py for upload, run_evals.py for evaluation)
- Use structured output when the model needs to return specific formats
- Save results locally (CSV) in addition to LangSmith for easy analysis
- Use descriptive experiment prefixes to track iterations
- Always use
max_concurrency=5 when calling evaluate() by default
CRITICAL: Parsing evaluate() Results
The evaluate() function returns an iterator of result dicts. Each result has this structure:
for result in results:
run = result["run"]
example = result["example"]
eval_results = result["evaluation_results"]
outputs = run.outputs
example_id = example.id
inputs = example.inputs
ref_outputs = example.outputs
for er in eval_results.get("results", []):
if er.key == "accuracy":
score = er.score
WRONG (common mistake):
outputs = result.get("outputs")
outputs = result.outputs
CORRECT:
outputs = result["run"].outputs
Limiting Examples for Testing
When iterating on run_evals.py to make sure it works correctly, limit to a small number of examples (e.g., 5) to save time and cost. Only run the full dataset once the script is confirmed working.
To limit examples, use client.list_examples() with a limit:
from langsmith import Client, evaluate
client = Client()
MAX_EXAMPLES = 5
if MAX_EXAMPLES:
data = list(client.list_examples(dataset_id=DATASET_ID, limit=MAX_EXAMPLES))
else:
data = DATASET_ID
results = evaluate(
target,
data=data,
evaluators=[exact_match],
experiment_prefix="my-experiment",
max_concurrency=5,
)
Common Evaluators
- Exact match: Compare output label to expected label exactly
- Contains: Check if expected value is contained in output
- LLM-as-judge: Use another LLM to score the output
- Custom metrics: F1 score, precision, recall for classification tasks