How do I track errors in an AI agent in production?
Report every failure with the agent context attached: which agent and version, the session, and the tool and action it was running. Add a breadcrumb for each model call and tool call, so the error arrives with the steps that led to it. Runheed's Node.js and Python SDKs have setAgent (set_agent) and breadcrumbs for this.
Why agent failures are hard to debug from logs
- The crash is often several steps after the cause: a tool returned bad data, the model acted on it, and a later tool threw.
- One session interleaves model calls, tool calls and retries, so its log lines are spread between other sessions.
- The same exception can come from different tools, and without the tool name every one of them looks alike.
What to record with each error
- Agent context: agent name and version, session id, the tool being called and the action (for example tool_call or plan).
- Breadcrumbs: one per model call and per tool call, with a short summary of the input and whether it succeeded. The SDK keeps the last 100.
- The release, so you can tell whether a new prompt or model version started the failures.
- The exception itself, with its stack trace. Uncaught exceptions are captured automatically once the SDK is initialized.
Node.js and TypeScript
import runheed from 'runheed';
runheed.init({ dsn: process.env.RUNHEED_DSN!, environment: 'production', release: 'support-agent@1.4.0' });
export async function callTool(sessionId: string, tool: string, input: unknown) {
runheed.setAgent({ name: 'support-agent', version: '1.4.0', sessionId, toolName: tool, action: 'tool_call' });
runheed.addBreadcrumb({ category: 'tool', message: `call ${tool}`, level: 'info' });
try {
const result = await tools[tool](input);
runheed.addBreadcrumb({ category: 'tool', message: `${tool} ok`, level: 'info' });
return result;
} catch (err) {
// Pass the session and tool as extra too: the agent context is per process,
// so a server running many sessions at once should not rely on it alone.
runheed.captureException(err as Error, { sessionId, tool });
throw err;
}
}Python
import os, runheed
runheed.init(dsn=os.environ["RUNHEED_DSN"], environment="production", release="support-agent@1.4.0")
def call_tool(session_id: str, tool: str, args: dict):
runheed.set_agent(name="support-agent", version="1.4.0", session_id=session_id, tool_name=tool, action="tool_call")
runheed.add_breadcrumb(message=f"call {tool}", category="tool")
try:
result = TOOLS[tool](**args)
runheed.add_breadcrumb(message=f"{tool} ok", category="tool")
return result
except Exception as e:
runheed.capture_exception(e, extra={"session_id": session_id, "tool": tool})
raisePython's logging module is captured as breadcrumbs by default, so log lines your agent already writes show up in the trail before the error.
Keep prompts and user data out of the report
Runheed stores only what your code sends. Summarize tool inputs in breadcrumbs instead of attaching whole prompts, and use the beforeSend (before_send) hook to edit or drop any event before it leaves your app. Secret request headers are redacted on arrival. The details are on is it safe.
Read it back with your coding agent
Connect Claude Code or Cursor and ask "which tool fails most in the support agent this week?" or "show the breadcrumbs for the newest error in session 8f2c". runheed_get_error returns the agent context with the stack trace, and runheed_get_error_context returns the whole session trail. Setup for each client is under Connect your agent.
Questions
- Is this the same as LLM tracing or observability?
- No. Tracing tools record every model call for evals, cost and latency. Runheed records failures, groups repeats, and hands them to a coding agent to fix. The two answer different questions; see the LangSmith comparison for the details.
- Does it record my prompts or model outputs?
- Only if your code attaches them. The SDK sends the exception, the breadcrumbs you add, the agent context and the request details, and beforeSend can strip anything before it is sent.
- Which agent frameworks does it work with?
- Any framework in Node.js, TypeScript or Python, because the calls go where your tool calls already happen. Other languages can post JSON to the ingest endpoint.
- How are repeated failures counted?
- Repeats of the same error are grouped into one error with a count. Every event counts toward the plan's monthly limit (50,000 on Solo); events over it are rejected, never billed.