DeepEvaldeepeval 4.2 ยท Python 3.9+
0%
1
Curious builder0 XP earned ยท 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
23 small wins to finish your pathNext lesson โ†’

Task completion: did the agent finish the job

Faithfulness graded the answer. Once a run has steps in it, there is a different question: did the whole run actually do what the user asked?

Example
from deepeval.metrics import TaskCompletionMetric

for golden in dataset.evals_iterator(metrics=[TaskCompletionMetric(model=PretendJudge())],
                                     display_config=DisplayConfig(show_indicator=False)):
    support_bot(golden.input)

TaskCompletionMetric reads the trace, not a test case you built. It works out what the task was and what the outcome was from the run itself, then scores how well one matches the other.

It needs tracing, and it needs nothing else: no expected answer, no documents. That makes it the first metric in this course you could point at a live agent.

The order question passed and the refund question scored 0.33, even though the bot answered it perfectly well. That score is the stand-in judge showing its limits: it compares words, and the answer never repeats how long or take. A real judge reads it as a complete answer.

This is worth knowing in general, not only here. A judged score is an opinion from a particular judge, and when a score looks wrong the judge is the first thing to check, not the bot.

A question the bot cannot answer

Example
missing = EvaluationDataset(goldens=[Golden(input="Where is order Z99?")])
for golden in missing.evals_iterator(metrics=[TaskCompletionMetric(model=PretendJudge())],
                                     display_config=DisplayConfig(show_indicator=False)):
    support_bot(golden.input)

Nothing in the policy mentions order Z99. The retriever from lesson 13 matches on any shared word, so the question found the line about A17, and the bot answered confidently about the wrong order.

Nothing crashed. No document was invented. The run still failed, because task completion compares what was asked with what came out, and the customer asked about a different order.

What the judge was asked

python
@answers("task_completion.TaskAndOutcome")
def task_and_outcome(prompt, judge):
    trace = json.loads(prompt[prompt.rindex("trace:") + 6:prompt.rindex("JSON:")])
    return {"task": " ".join(map(str, trace["input"].values())), "outcome": str(trace["output"])}
python
@answers("task_completion.TaskCompletionVerdict")
def task_verdict(prompt, judge):
    task, outcome = section(prompt, "Task"), section(prompt, "Actual outcome")
    return {"verdict": share(task, outcome), "reason": f"The outcome covers {share(task, outcome):.0%} of the task."}

The first question hands the judge the trace as JSON and asks for the task and the outcome. The second asks how much of the task the outcome covers, as a number from 0 to 1. This judge answers it with the same word comparison as everything else.

The three other trajectory metrics
DeepEval has three more metrics that read a whole trace: step efficiency, plan adherence and plan quality. They need the same tracing, and lesson 22 names them among what this course leaves out.
Try it yourself
  • Add a golden the policy does cover and compare the two scores in one run.
  • Give the bot a friendlier answer when it finds nothing and see whether the score moves.

Slow is fine. Stopping is the only problem.