Linking Traces

Link evaluation test cases and turns to their traces for full observability.

Overview

When you run evaluations through an AI Connection, Confident AI can link each result back to the trace your AI app produced. This gives you full observability—jump straight from an evaluation result to the exact trace that generated it.

There are two flavors of trace linking:

  • Linking test cases to traces for single-turn evaluations
  • Linking turns to traces for multi-turn evaluations and red-team attacks

Both work by passing an identifier (testCaseId or turnId) from your payload into your tracing setup.

Linking Test Cases to Traces

For single-turn evaluations, you can link each test case to its corresponding trace for full observability. This is done by including testCaseId in your payload (enabled by default) and passing it to your tracing setup.

Include testCaseId in your payload configuration and ensure your AI connection is configured to accept it.

1{
2 "input": golden.input,
3 "testCaseId": testCaseId
4}

Then, pass the testCaseId to your tracing implementation:

1from deepeval.tracing import observe, update_current_trace
2
3@observe()
4def llm_app(input: str, test_case_id: str):
5 update_current_trace(test_case_id=test_case_id)
6
7 response = llm.generate(user=input)
8 return response
9
10@app.post("/generate")
11def generate(request: dict):
12 test_case_id = request.get("testCaseId")
13 response = llm_app(request["input"], test_case_id)
14 return {"output": response}

Once linked, you can view the full trace for each test case directly from the evaluation results, making it easy to debug failures and understand model behavior.

Linking Turns to Traces

For multi-turn evaluations and multi-turn red-team attacks, Confident AI calls your endpoint once per turn. Each turn has its own turnId that you can pass to your tracing setup. This links each turn’s trace to the specific turn in the conversation, letting you view traces per-turn from the evaluation or assessment results.

Per-turn trace linkage only works when your AI Connection’s payload includes both testCaseId and turnId. Both are in the default JSON payload template — only custom payloads need to ensure they reference these variables.

Include turnId in your payload configuration:

1{
2 "input": golden.input,
3 "turnId": turnId,
4 "state": state
5}

Then, pass the turnId to your tracing implementation:

1from deepeval.tracing import observe, update_current_trace
2
3@observe()
4def llm_app(input: str, turn_id: str):
5 update_current_trace(turn_id=turn_id)
6
7 response = llm.generate(user=input)
8 return response
9
10@app.post("/generate")
11def generate(request: dict):
12 turn_id = request.get("turnId")
13 response = llm_app(request["input"], turn_id)
14 return {"output": response}

With turnId linked, each turn in the conversation gets a “View trace” button — click it from the evaluation results or the risk assessment side drawer to see the full trace for that specific turn.

Next Steps

With traces linked to your evaluation results, you can debug failures end-to-end. Explore related observability and connection features next.