shortest_response picked one winner from a batch — the response with the fewest words. What if you need the word count of every response in the batch, not just the minimum?
I'd need to keep all of them. Instead of min(...), I'd collect every output with its count. Some kind of map — one count per prompt.
One count per prompt is exactly right. A list comprehension does the map in one line: call the agent, split the output into words, count them. The structure mirrors what you already know:
agent = Agent(model)
result = [len(agent.run_sync(p).output.split()) for p in prompts]Why create the agent once outside the comprehension? Couldn't I write Agent(model) inside the brackets for each prompt?
You could, and it would work — but you'd instantiate a new agent object on every iteration. One agent, many runs. The agent is just configuration; .run_sync() is the actual call. Keep the configuration outside the loop and the call inside:
def batch_word_counts(prompts: list) -> list:
agent = Agent(model)
return [len(agent.run_sync(p).output.split()) for p in prompts]I'm chaining these like functions now — agent output into .split() into len(), all in one expression. That's three operations on an AI response without a single intermediate variable.
And you get back a plain list of integers — something you can average, plot, or feed into the next agent as context. Word count per prompt becomes a signal: very short responses may mean the model is uncertain or the prompt is ambiguous.
So the list isn't just a convenience — it's a measurement. I could use this to audit which prompts produce verbose answers versus tight ones before shipping a pipeline to my team.
Exactly. Audit first, ship second. A list of word counts takes two seconds to scan — you'll catch the runaway 400-word response before your CFO does. The Week 3 quiz will ask you to combine this map pattern with the structured output shapes from Week 2 — two weeks of technique in one challenge.
The pattern is a single list comprehension:
agent = Agent(model)
return [len(agent.run_sync(p).output.split()) for p in prompts]Three chained operations per iteration: .run_sync(p) calls the model, .output extracts the string, .split() tokenises on whitespace, len(...) counts the tokens.
Why instantiate outside the loop? Agent(model) is configuration — it wires the model and any system prompt. Creating it once and reusing it across calls is correct and slightly cheaper. The live network call happens inside .run_sync(), not at construction time.
What the list gives you: a word-count signal per prompt. Short outputs (< 10 words) often indicate ambiguity or refusal; long outputs (> 150 words) suggest the prompt needs a length constraint. Inspect the distribution before running a batch at scale.
shortest_response picked one winner from a batch — the response with the fewest words. What if you need the word count of every response in the batch, not just the minimum?
I'd need to keep all of them. Instead of min(...), I'd collect every output with its count. Some kind of map — one count per prompt.
One count per prompt is exactly right. A list comprehension does the map in one line: call the agent, split the output into words, count them. The structure mirrors what you already know:
agent = Agent(model)
result = [len(agent.run_sync(p).output.split()) for p in prompts]Why create the agent once outside the comprehension? Couldn't I write Agent(model) inside the brackets for each prompt?
You could, and it would work — but you'd instantiate a new agent object on every iteration. One agent, many runs. The agent is just configuration; .run_sync() is the actual call. Keep the configuration outside the loop and the call inside:
def batch_word_counts(prompts: list) -> list:
agent = Agent(model)
return [len(agent.run_sync(p).output.split()) for p in prompts]I'm chaining these like functions now — agent output into .split() into len(), all in one expression. That's three operations on an AI response without a single intermediate variable.
And you get back a plain list of integers — something you can average, plot, or feed into the next agent as context. Word count per prompt becomes a signal: very short responses may mean the model is uncertain or the prompt is ambiguous.
So the list isn't just a convenience — it's a measurement. I could use this to audit which prompts produce verbose answers versus tight ones before shipping a pipeline to my team.
Exactly. Audit first, ship second. A list of word counts takes two seconds to scan — you'll catch the runaway 400-word response before your CFO does. The Week 3 quiz will ask you to combine this map pattern with the structured output shapes from Week 2 — two weeks of technique in one challenge.
The pattern is a single list comprehension:
agent = Agent(model)
return [len(agent.run_sync(p).output.split()) for p in prompts]Three chained operations per iteration: .run_sync(p) calls the model, .output extracts the string, .split() tokenises on whitespace, len(...) counts the tokens.
Why instantiate outside the loop? Agent(model) is configuration — it wires the model and any system prompt. Creating it once and reusing it across calls is correct and slightly cheaper. The live network call happens inside .run_sync(), not at construction time.
What the list gives you: a word-count signal per prompt. Short outputs (< 10 words) often indicate ambiguity or refusal; long outputs (> 150 words) suggest the prompt needs a length constraint. Inspect the distribution before running a batch at scale.
Create a free account to get started. Paid plans unlock all tracks.