← Blog
/6 min read/Adrien

Cori vs Agent Harnesses

Agent harnesses can reach the same outcome through different paths, with wide variation in execution time, tool calls, and tokens. Cori turns the settled path into code.

engineeringbenchmarks

Give an agent the same task three times and it may take three different paths to the same result.

The destination can be identical. The route rarely is. Execution time moves. Tool calls move. Token use moves. Each run is a new interpretation of work the agent may already have completed successfully.

That is the problem behind this benchmark. It gives us a broader way to test agent harnesses: ask each one to solve a realistic multi-tool task and capture the procedure as a Cori workflow, then compare the fresh Agent LLM runtime with the captured Cori code runtime. We grade the resulting Workspace state, not the confidence of the final answer.

Ten tasks across the operating week

The fixtures are synthetic. The work is ordinary: daily queues, weekly reviews, meeting prep, onboarding, leave, and finance reporting. These are the jobs people already hand to agent harnesses, with the same mix of reads, business rules, writes, and controlled side effects.

Support inbox triage

b1 · support
Search inboxClassify messagesWrite queueApply labelsDraft digest

SLA breach pack

b2 · support
Read casesCalculate deadlinesWrite resultsFill reportDraft email

Lead follow-up queue

b3 · sales
Read leadsRank leadsUpdate sheetDraft email

Customer meeting prep

b4 · sales
Read calendarRead docsRead emailCreate briefUpdate eventDraft email

New-hire onboarding pack

b5 · hr
Read sheetFill templateCreate eventUpdate sheetDraft email

Pre-approved PTO processing

b6 · hr
Read sheetCount workdaysUpdate balanceCreate eventDraft email

Weekly operating review

b7 · management
Read projectsAssign RAGWrite KPIsCreate reportDraft email

Meeting action register

b8 · management
Read notesExtract actionsDeduplicateWrite trackerDraft email

Expense policy audit

b9 · finance
Read expensesApply policyWrite auditCreate reportDraft email

Budget variance deck

b10 · finance
Read budgetCalculate varianceCreate slidesDraft email

No task is difficult because of one action. The difficulty sits between them: several systems, exact output contracts, and side effects that must stay controlled.

Variance is an operating property

We ran fresh agents three times on each of ten multi-step Google Workspace tasks. The fixtures were equivalent, and outcomes were graded from Workspace state — not from the agent's final message.

On support inbox triage, one run made 9 tool calls. Another made 26. The 9-call run passed. The 26-call run missed a required digest and failed.

That's the part of agent reliability that averages hide.

Across those tasks, the median run-to-run coefficient of variation was:

  • 23.4% for tool invocations
  • 13.9% for tokens
  • 11.3% for execution time

The tool path moved most.

Support triage ranged from 9 to 26 calls. Expense auditing, 10 to 21. Customer meeting prep burned between 254,000 and 671,000 tokens.

And a stable-looking run can hide the uncertainty somewhere else. Budget variance reporting used eight or nine tool calls and roughly 282,000 to 307,000 tokens every time — but wall time ranged from 91 to 160 seconds.

Three fresh-agent runsValues: run 1 · run 2 · run 3
Workflow Duration0–3 min Tokens0–700k Tool calls0–30
b1Support inbox triage 1.90, 2.18 and 2.22 minutes 370,089, 468,691 and 435,531 tokens 9, 26 and 26 tool calls
b2SLA breach pack 1.31, 1.84 and 1.26 minutes 181,007, 294,047 and 151,847 tokens 6, 10 and 5 tool calls
b3Lead follow-up queue 1.05, 0.99 and 0.94 minutes 199,209, 191,331 and 192,264 tokens 16, 14 and 14 tool calls
b4Customer meeting prep 1.45, 2.44 and 2.00 minutes 254,093, 539,750 and 671,287 tokens 16, 24 and 30 tool calls
b5New-hire onboarding 1.86, 1.88 and 2.09 minutes 374,921, 276,794 and 257,534 tokens 20, 18 and 18 tool calls
b6Pre-approved PTO 1.25, 1.57 and 1.52 minutes 280,360, 255,315 and 312,950 tokens 18, 18 and 30 tool calls
b7Weekly operating review 1.68, 2.00 and 2.08 minutes 271,168, 272,166 and 304,045 tokens 14, 18 and 16 tool calls
b8Meeting action register 1.07, 0.90 and 0.91 minutes 196,468, 166,171 and 142,707 tokens 7, 6 and 5 tool calls
b9Expense policy audit 2.07, 1.52 and 2.37 minutes 527,353, 294,750 and 477,767 tokens 13, 10 and 21 tool calls
b10Budget variance deck 1.75, 2.67 and 1.52 minutes 281,988, 296,298 and 306,816 tokens 9, 8 and 8 tool calls

Figure 1. The three fresh-agent trials for each workflow. Values are listed in run order; duration is in minutes and token labels are rounded to the nearest thousand. Dot positions use the full recorded values. Tool calls count distinct command lifecycle IDs — a single command may contain several external API calls.

Three trials per task is a small sample. These are descriptive results, not a universal estimate of agent variance. But the production question shows up immediately:

Which version of the path are you provisioning for?

The average doesn't tell you how many calls the next run will make. It doesn't tell you where it will retry, what it will reread, or whether it will find a new detour through a system that has side effects.

Your tools feel the variance too

Tool calls aren't private thoughts. They're load — on Gmail, Sheets, Drive, Calendar, your database, your API, whatever internal system sits behind the agent.

A different path means a different number of network requests, auth checks, rate-limit opportunities, partial side effects, and places to stop halfway through. Your infrastructure feels every decision the model improvises.

The prompt becomes a patch log

When an agent misses a case, the natural fix is to improve the prompt.

diff
--- process-prompt-v2.md
+++ process-prompt-v2-final-reviewed-OK.md
 [...]
+Remember to create the digest.
+Check that the counts match.
+Don't send the email.
+If the sheet is empty, look in the archive.
+Verify the draft before finishing.

Each line covers a failure you've already seen. None of them cover the failures you haven't.

The prompt slowly becomes operational code written in prose. But unlike code, it doesn't define one execution path. A new instruction changes the model's whole decision surface — it may fix the missing digest while adding more reads, a different tool order, or a new branch you now have to watch.

So the doubt compounds. When will this fail again? Which case have we not prompted for? How many calls will the repaired prompt make? What state gets left behind if it stops midway?

That isn't only a model-quality problem. It's a process that has never settled.

Worse: the prompt can disagree with itself

There is a failure mode beyond accumulation. The patch that fixes run twelve can contradict the rule added after run three — and both remain active.

This isn't hypothetical, or limited to prompts written in a hurry. Anthropic recently described finding conflicting guidance inside Claude Code itself: its system prompt, skills, and user requests could ask for documentation where appropriate while also saying not to add comments. Claude could usually infer the intent, but first had to decide which instruction should win.

process-prompt.mditeration 12
18   Keep every customer reply under 100 words. Never exceed this limit. existing rule
47 + For escalations, write at least 250 words and include the full case history. new fix
≤ 100 words ≥ 250 words

Both rules enter the same context. The next run has to decide which one loses.

Figure 2. A prompt patch can repair one observed failure while making the specification internally inconsistent. Nothing in the diff forces that conflict to be resolved before the next run.

That is worse than ordinary variance. The ambiguity is now part of the specification. A successful run doesn't prove the prompt is coherent; it only tells you which side the model chose that time.

Use the brain where the process changes

Cori treats the agent as a design-time collaborator — the same split I wrote about last week.

Let it inspect the live system, understand the task, try tools, recover from mistakes, and verify the result. That exploration is worth paying for. Then capture the procedure it found as an explicit workflow.

At runtime, the computer executes that workflow. Inputs are declared. Tool requirements are visible. Control flow is fixed. Retries are policies rather than improvisations. Every step shows up in a trace.

The agent comes back when the process changes — not because Tuesday arrived.

In the same benchmark, unchanged Cori workflows replayed all 30 task trials successfully. They executed 294 CLI and code activities, and every one completed on its first attempt. Replay averaged 13.5 seconds against 100.6 for fresh agents, and used no runtime LLM tokens.

Those speed and token numbers are nice, but they're downstream of the change that matters: runtime stopped being a new interpretation of the task.

Agents should help us use computers

The goal isn't to get agents out of the work. It's to stop spending general-purpose reasoning on settled mechanics.

We want agents to help us understand systems, design processes, and adapt when reality changes. We don't need an overqualified brain rediscovering the same six API calls every morning.

Variance is useful while you're still looking for the process.

Once you know the process, variance is debt.

Use the agent to decide what the computer should do. Then let the computer do it.

Try it on something you repeat

Give your agent the Cori skill:

bash
npx skills add cori-do/cori

Then work with the agent as usual. When it has found a result worth repeating, say save_workflow. The skill turns the settled procedure into a workflow folder you can inspect, edit, and commit.

Run it directly from that folder:

bash
cori run ./path/to/workflow

Start with a task you already repeat. The second run is where the difference becomes obvious.