Improve from real calls

Improve an agent from real calls

The fastest way to improve an agent is to hand a coding agent a call that went wrong, let it fix the cause, and let it prove the fix by talking to the agent itself. You need no test script to start: the call is the test.

1. Copy the transcript

Where the call happenedHow to copy it
curb dev previewCopy for coding agent in the conversation header: the transcript with the skill map, the tools and the system prompt (The preview)
Hosted agent, dashboardOpen the call on the Calls page, open the Copy or download menu, choose Copy transcript: every turn and tool call as Markdown
Hosted agent, coding agent connectedName the call; the agent reads it with agent_get_call and agent_get_call_timeline
curb dev, curb saynpx curb conversations --last 5

2. Have the coding agent improve it

Paste the transcript into your coding agent in the project folder, with one sentence about what should have happened:

Here is a call. The agent promised a callback but never recorded one. Find out why, fix the
agent, and keep this call as a scenario so it stays fixed.

<paste the transcript>

A project from npm create curb.js tells a coding agent how to work: its AGENTS.md names the checks below, and the full guide is in node_modules/curb/docs/agent-guide/.

Before it changes a prompt, the coding agent should ask where the behaviour comes from. Most wrong calls are one of these:

What happenedUsually the causeFix
Used a tool it should not have had yetThe tool is always renderedRender it only when state allows it
Promised something it cannot doNo tool for it in that stateRender the tool, or stop offering it
Opened the wrong skillThe skill’s descriptionRewrite it as a routing rule, with “NOT for”
Forgot something from earlier, or asked for it twiceuseState in a skill that unloaded, or the transcript windowMove it to a store (Skill lifecycle)
Unknown tool after the caller changed topicThe tool is not rendered now: its skill unloaded, or its gate resetMove the gate’s state to a store, or read the skill again
Misheard a nameSpeech recognitionboostedPhrases on kugelaudio.stt()
Said a name wrongText to speechA pronunciation dictionary

3. Let the agent test itself

The coding agent runs the same loop you would, with no browser or microphone:

npx curb check                                  # does it build?
npx curb say --new "<the caller's first line>"  # replay the call, one line per turn
npx curb say "<the caller's next line>"
npx curb test                                   # do whole conversations still pass?

It reads the tool calls and context lines of each turn, not just the reply. --fake <tool> keeps a booking or an email from happening for real. Each curb say and curb test turn calls the agent’s LLM, so it costs tokens like a real call.

Then it keeps the call, in a scenario file under src/agent/, usually in the skill’s folder. When the fix changes the call, keep the caller’s lines that still make sense and rewrite the others:

// src/agent/callback.scenario.ts
import { scenario } from "curb/testing";

export default scenario({
  name: "records the callback it promises",
  turns: ["Nobody is answering at your office", "Yes, call me on 030 555 0100"],
  fakes: { request_callback: { ok: true, message: "The callback is recorded." } },
  expect: ({ called }) => [called("request_callback")],
});

curb test now fails if this ever breaks again (Testing).

4. Listen, then ship

Text checks cannot hear timing, interruptions or pronunciation. Run npm run dev and call the agent once. Then deploy with npx curb deploy, or from a browser project with agent_publish.

Next steps